X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Fcmm%2FCmmZipUtil.hs;h=a91d76f31d1b4c7033e3a8a9eebf73de707c9110;hp=2dcb55fe2ef0526563f115435d022bf32d1d7967;hb=edc0bafd3fcd01b85a2e8894e5dfe149eb0e0857;hpb=8b7eaa404043294bd4cb4a0322ac1f7115bad6a0 diff --git a/compiler/cmm/CmmZipUtil.hs b/compiler/cmm/CmmZipUtil.hs index 2dcb55f..a91d76f 100644 --- a/compiler/cmm/CmmZipUtil.hs +++ b/compiler/cmm/CmmZipUtil.hs @@ -1,13 +1,16 @@ -{-# OPTIONS -Wall -fno-warn-name-shadowing #-} -module CmmZipUtil + +module CmmZipUtil ( zipPreds + , givesUniquePredecessorTo ) where +import BlockId import Prelude hiding (last, unzip) -import ZipCfg +import ZipCfg + import Maybes --- | Compute the predecessors of each *reachable* block +-- | Compute the predecessors of each /reachable/ block zipPreds :: LastNode l => LGraph m l -> BlockEnv BlockSet zipPreds g = foldl add emptyBlockEnv (postorder_dfs g) where add env block@(Block id _) = @@ -15,3 +18,22 @@ zipPreds g = foldl add emptyBlockEnv (postorder_dfs g) let preds = lookupBlockEnv env sid `orElse` emptyBlockSet in extendBlockEnv env sid (extendBlockSet preds id)) env (succs block) + +-- | Tell if a graph gives a block a unique predecessor. For +-- efficiency, this function is designed to be partially applied. + +givesUniquePredecessorTo :: LastNode l => LGraph m l -> BlockId -> Bool +givesUniquePredecessorTo g = \id -> elemBlockSet id singlePreds + -- accumulates a pair of sets: the set of all blocks containing a single + -- predecessor, and the set of all blocks containing at least two predecessors + where (singlePreds, _) = fold_blocks add (emptyBlockSet, emptyBlockSet) g + add b (single, multi) = foldl add_pred (single, multi) (succs b) + add_pred pair@(single, multi) id = + if elemBlockSet id multi then pair + else if elemBlockSet id single then + (removeBlockSet single id, extendBlockSet multi id) + else + (extendBlockSet single id, multi) + + +