summaryrefslogtreecommitdiff
path: root/compiler/cmm/CmmLive.hs
diff options
context:
space:
mode:
authorEdward Z. Yang <ezyang@mit.edu>2011-06-17 14:06:43 +0100
committerEdward Z. Yang <ezyang@mit.edu>2011-06-17 14:07:50 +0100
commit1687dab3968edf161e6eb759ff1041c7adb201f2 (patch)
treeb39612ae5767c4238e60a091b474cfc64668de5d /compiler/cmm/CmmLive.hs
parentb11585feecb1a131c6b1632fc5867b49e98c4333 (diff)
downloadhaskell-1687dab3968edf161e6eb759ff1041c7adb201f2.tar.gz
Refactor CmmLive and CmmSpillReload.
* Move dead assignment elimination to CmmLive * Kill off dead code in CmmSpillReload related to non-splitting procpoints case * Refactor dual liveness transfer function to more closely mimic CmmLive's liveness transfer. Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
Diffstat (limited to 'compiler/cmm/CmmLive.hs')
-rw-r--r--compiler/cmm/CmmLive.hs27
1 files changed, 26 insertions, 1 deletions
diff --git a/compiler/cmm/CmmLive.hs b/compiler/cmm/CmmLive.hs
index 8baad04dc9..ca3ab095ed 100644
--- a/compiler/cmm/CmmLive.hs
+++ b/compiler/cmm/CmmLive.hs
@@ -6,7 +6,8 @@ module CmmLive
( CmmLive
, cmmLiveness
, liveLattice
- , noLiveOnEntry, xferLive
+ , noLiveOnEntry, xferLive, gen, kill, gen_kill
+ , removeDeadAssignments
)
where
@@ -65,13 +66,37 @@ gen_kill :: (DefinerOfLocalRegs a, UserOfLocalRegs a) => a -> CmmLive -> CmmLive
gen_kill a = gen a . kill a
-- | The transfer function
+-- EZY: Bits of this analysis are duplicated in CmmSpillReload, though
+-- it's not really easy to efficiently reuse all of this. Keep in mind
+-- if you need to update this analysis.
xferLive :: BwdTransfer CmmNode CmmLive
xferLive = mkBTransfer3 fst mid lst
where fst _ f = f
mid :: CmmNode O O -> CmmLive -> CmmLive
mid n f = gen_kill n f
lst :: CmmNode O C -> FactBase CmmLive -> CmmLive
+ -- slightly inefficient: kill is unnecessary for emptyRegSet
lst n f = gen_kill n
$ case n of CmmCall{} -> emptyRegSet
CmmForeignCall{} -> emptyRegSet
_ -> joinOutFacts liveLattice n f
+
+-----------------------------------------------------------------------------
+-- Removing assignments to dead variables
+-----------------------------------------------------------------------------
+
+removeDeadAssignments :: CmmGraph -> FuelUniqSM CmmGraph
+removeDeadAssignments g =
+ liftM fst $ dataflowPassBwd g [] $ analRewBwd liveLattice xferLive rewrites
+ where rewrites = deepBwdRw3 nothing middle nothing
+ -- Beware: deepBwdRw with one polymorphic function seems more reasonable here,
+ -- but GHC panics while compiling, see bug #4045.
+ middle :: CmmNode O O -> Fact O CmmLive -> CmmReplGraph O O
+ middle (CmmAssign (CmmLocal reg') _) live | not (reg' `elemRegSet` live) = return $ Just emptyGraph
+ -- XXX maybe this should be somewhere else...
+ middle (CmmAssign lhs (CmmReg rhs)) _ | lhs == rhs = return $ Just emptyGraph
+ middle (CmmStore lhs (CmmLoad rhs _)) _ | lhs == rhs = return $ Just emptyGraph
+ middle _ _ = return Nothing
+
+ nothing :: CmmNode e x -> Fact x CmmLive -> CmmReplGraph e x
+ nothing _ _ = return Nothing