add a function to help identify unique predecessors
authorNorman Ramsey <nr@eecs.harvard.edu>
Sat, 15 Sep 2007 20:17:46 +0000 (20:17 +0000)
committerNorman Ramsey <nr@eecs.harvard.edu>
Sat, 15 Sep 2007 20:17:46 +0000 (20:17 +0000)
compiler/cmm/CmmZipUtil.hs

index c7a027e..f970547 100644 (file)
@@ -1,11 +1,14 @@
 
 module CmmZipUtil
   ( zipPreds
+  , givesUniquePredecessorTo
   )
 where
 import Prelude hiding (last, unzip)
 import ZipCfg
+
 import Maybes
+import UniqSet
 
 -- | Compute the predecessors of each *reachable* block
 zipPreds :: LastNode l => LGraph m l -> BlockEnv BlockSet
@@ -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
+                       (delOneFromUniqSet single id, extendBlockSet multi id)
+                   else
+                       (extendBlockSet single id, multi)
+              
+    
+