X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Fcmm%2FCmmLiveZ.hs;h=7bafc919d2ea043b7514eeeaf13a00b8770a9ffd;hp=b239ae37115621e666d5a953e5a70a86a17731e8;hb=e6243a818496aad82b6f47511d3bd9bc800f747d;hpb=176fa33f17dd78355cc572e006d2ab26898e2c69 diff --git a/compiler/cmm/CmmLiveZ.hs b/compiler/cmm/CmmLiveZ.hs index b239ae3..7bafc91 100644 --- a/compiler/cmm/CmmLiveZ.hs +++ b/compiler/cmm/CmmLiveZ.hs @@ -3,7 +3,7 @@ module CmmLiveZ ( CmmLive , cmmLivenessZ , liveLattice - , middleLiveness, lastLiveness + , middleLiveness, lastLiveness, noLiveOnEntry ) where @@ -19,6 +19,7 @@ import ZipDataflow import ZipCfgCmmRep import Maybes +import Outputable import UniqSet ----------------------------------------------------------------------------- @@ -30,7 +31,7 @@ type CmmLive = RegSet -- | The dataflow lattice liveLattice :: DataflowLattice CmmLive -liveLattice = DataflowLattice "live LocalReg's" emptyUniqSet add False +liveLattice = DataflowLattice "live LocalReg's" emptyUniqSet add True where add new old = let join = unionUniqSets new old in (if sizeUniqSet join > sizeUniqSet old then aTx else noTx) join @@ -42,13 +43,22 @@ type BlockEntryLiveness = BlockEnv CmmLive -- | Calculated liveness info for a CmmGraph ----------------------------------------------------------------------------- cmmLivenessZ :: CmmGraph -> FuelMonad BlockEntryLiveness -cmmLivenessZ g = liftM zdfFpFacts $ (res :: FuelMonad (CmmBackwardFixedPoint CmmLive)) +cmmLivenessZ g@(LGraph entry _ _) = + liftM (check . zdfFpFacts) (res :: FuelMonad (CmmBackwardFixedPoint CmmLive)) where res = zdfSolveFrom emptyBlockEnv "liveness analysis" liveLattice transfers emptyUniqSet (graphOfLGraph g) transfers = BackwardTransfers first middle last first live _ = live middle = flip middleLiveness last = flip lastLiveness + check facts = + noLiveOnEntry entry (expectJust "check" $ lookupBlockEnv facts entry) facts + +-- | On entry to the procedure, there had better not be any LocalReg's live-in. +noLiveOnEntry :: BlockId -> CmmLive -> a -> a +noLiveOnEntry bid in_fact x = + if isEmptyUniqSet in_fact then x + else pprPanic "LocalReg's live-in to graph" (ppr bid <+> ppr in_fact) -- | The transfer equations use the traditional 'gen' and 'kill' -- notations, which should be familiar from the dragon book. @@ -56,20 +66,18 @@ gen, kill :: UserOfLocalRegs a => a -> RegSet -> RegSet gen a live = foldRegsUsed extendRegSet live a kill a live = foldRegsUsed delOneFromUniqSet live a +-- Why aren't these function using the typeclasses on Middle and Last? middleLiveness :: Middle -> CmmLive -> CmmLive -middleLiveness m = middle m - where middle (MidComment {}) = id - middle (MidAssign lhs expr) = gen expr . kill lhs - middle (MidStore addr rval) = gen addr . gen rval - middle (MidUnsafeCall tgt ress args) = gen tgt . gen args . kill ress - middle (MidAddToContext ra args) = gen ra . gen args +middleLiveness (MidComment {}) live = live +middleLiveness (MidAssign lhs expr) live = gen expr $ kill lhs live +middleLiveness (MidStore addr rval) live = gen addr $ gen rval live +middleLiveness (MidForeignCall _ tgt _ args) _ = gen tgt $ gen args emptyUniqSet lastLiveness :: Last -> (BlockId -> CmmLive) -> CmmLive lastLiveness l env = last l - where last (LastReturn _) = emptyUniqSet - last (LastJump e _) = gen e $ emptyUniqSet - last (LastBranch id) = env id - last (LastCall tgt (Just k) _) = gen tgt $ env k - last (LastCall tgt Nothing _) = gen tgt $ emptyUniqSet - last (LastCondBranch e t f) = gen e $ unionUniqSets (env t) (env f) - last (LastSwitch e tbl) = gen e $ unionManyUniqSets $ map env (catMaybes tbl) + where last (LastBranch id) = env id + last (LastCall tgt Nothing _ _) = gen tgt $ emptyUniqSet + last (LastCall tgt (Just k) _ _) = gen tgt $ env k + last (LastCondBranch e t f) = gen e $ unionUniqSets (env t) (env f) + last (LastSwitch e tbl) = + gen e $ unionManyUniqSets $ map env (catMaybes tbl)