f9705478228d4ba10ce8db847ef1edf4ba7b2aa2
[ghc-hetmet.git] / compiler / cmm / CmmZipUtil.hs
1
2 module CmmZipUtil
3   ( zipPreds
4   , givesUniquePredecessorTo
5   )
6 where
7 import Prelude hiding (last, unzip)
8 import ZipCfg
9
10 import Maybes
11 import UniqSet
12
13 -- | Compute the predecessors of each *reachable* block
14 zipPreds :: LastNode l => LGraph m l -> BlockEnv BlockSet
15 zipPreds g = foldl add emptyBlockEnv (postorder_dfs g)
16     where add env block@(Block id _) =
17             foldl (\env sid ->
18                        let preds = lookupBlockEnv env sid `orElse` emptyBlockSet
19                        in  extendBlockEnv env sid (extendBlockSet preds id))
20             env (succs block)
21
22 -- | Tell if a graph gives a block a unique predecessor.  For
23 -- efficiency, this function is designed to be partially applied.
24
25 givesUniquePredecessorTo :: LastNode l => LGraph m l -> BlockId -> Bool
26 givesUniquePredecessorTo g = \id -> elemBlockSet id singlePreds
27     -- | accumulates a pair of sets: the set of all blocks containing a single 
28     -- predecessor, and the set of all blocks containing at least two predecessors
29     where (singlePreds, _) = fold_blocks add (emptyBlockSet, emptyBlockSet) g
30           add b (single, multi) = foldl add_pred (single, multi) (succs b)
31           add_pred pair@(single, multi) id =
32               if elemBlockSet id multi then pair
33               else if elemBlockSet id single then
34                        (delOneFromUniqSet single id, extendBlockSet multi id)
35                    else
36                        (extendBlockSet single id, multi)
37               
38     
39