summaryrefslogtreecommitdiff
path: root/compiler/nativeGen/CFG.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/nativeGen/CFG.hs')
-rw-r--r--compiler/nativeGen/CFG.hs18
1 files changed, 18 insertions, 0 deletions
diff --git a/compiler/nativeGen/CFG.hs b/compiler/nativeGen/CFG.hs
index b19db02b13..155e5bcac4 100644
--- a/compiler/nativeGen/CFG.hs
+++ b/compiler/nativeGen/CFG.hs
@@ -24,6 +24,7 @@ module CFG
, getSuccEdgesSorted, weightedEdgeList
, getEdgeInfo
, getCfgNodes, hasNode
+ , loopMembers
--Construction/Misc
, getCfg, getCfgProc, pprEdgeWeights, sanityCheckCfg
@@ -636,3 +637,20 @@ optimizeCFG weights (CmmProc info _lab _live graph) cfg =
| CmmSource (CmmBranch {}) <- source = True
| CmmSource (CmmCondBranch {}) <- source = True
| otherwise = False
+
+-- | Determine loop membership of blocks based on SCC analysis
+-- Ideally we would replace this with a variant giving us loop
+-- levels instead but the SCC code will do for now.
+loopMembers :: CFG -> LabelMap Bool
+loopMembers cfg =
+ foldl' (flip setLevel) mapEmpty sccs
+ where
+ mkNode :: BlockId -> Node BlockId BlockId
+ mkNode bid = DigraphNode bid bid (getSuccessors cfg bid)
+ nodes = map mkNode (setElems $ getCfgNodes cfg)
+
+ sccs = stronglyConnCompFromEdgedVerticesOrd nodes
+
+ setLevel :: SCC BlockId -> LabelMap Bool -> LabelMap Bool
+ setLevel (AcyclicSCC bid) m = mapInsert bid False m
+ setLevel (CyclicSCC bids) m = foldl' (\m k -> mapInsert k True m) m bids