module CmmLive
( CmmLocalLive
, CmmGlobalLive
, cmmLocalLiveness
, cmmGlobalLiveness
, liveLattice
, noLiveOnEntry, xferLive, gen, kill, gen_kill
)
where
import DynFlags
import BlockId
import Cmm
import CmmUtils
import PprCmmExpr ()
import Hoopl
import Maybes
import Outputable
type CmmLive r = RegSet r
type CmmLocalLive = CmmLive LocalReg
type CmmGlobalLive = CmmLive GlobalReg
liveLattice :: Ord r => DataflowLattice (CmmLive r)
liveLattice = DataflowLattice "live LocalReg's" emptyRegSet add
where add _ (OldFact old) (NewFact new) =
(changeIf $ sizeRegSet join > sizeRegSet old, join)
where !join = plusRegSet old new
type BlockEntryLiveness r = BlockEnv (CmmLive r)
cmmLocalLiveness :: DynFlags -> CmmGraph -> BlockEntryLiveness LocalReg
cmmLocalLiveness dflags graph =
check $ dataflowAnalBwd graph [] $ analBwd liveLattice (xferLive dflags)
where entry = g_entry graph
check facts = noLiveOnEntry entry
(expectJust "check" $ mapLookup entry facts) facts
cmmGlobalLiveness :: DynFlags -> CmmGraph -> BlockEntryLiveness GlobalReg
cmmGlobalLiveness dflags graph =
dataflowAnalBwd graph [] $ analBwd liveLattice (xferLive dflags)
noLiveOnEntry :: BlockId -> CmmLive LocalReg -> a -> a
noLiveOnEntry bid in_fact x =
if nullRegSet in_fact then x
else pprPanic "LocalReg's live-in to graph" (ppr bid <+> ppr in_fact)
gen :: UserOfRegs r a => DynFlags -> a -> RegSet r -> RegSet r
gen dflags a live = foldRegsUsed dflags extendRegSet live a
kill :: DefinerOfRegs r a => DynFlags -> a -> RegSet r -> RegSet r
kill dflags a live = foldRegsDefd dflags deleteFromRegSet live a
gen_kill :: (DefinerOfRegs r a, UserOfRegs r a)
=> DynFlags -> a -> CmmLive r -> CmmLive r
gen_kill dflags a = gen dflags a . kill dflags a
xferLive :: forall r . ( UserOfRegs r (CmmNode O O)
, DefinerOfRegs r (CmmNode O O)
, UserOfRegs r (CmmNode O C)
, DefinerOfRegs r (CmmNode O C))
=> DynFlags -> BwdTransfer CmmNode (CmmLive r)
xferLive dflags = mkBTransfer3 fst mid lst
where fst _ f = f
mid :: CmmNode O O -> CmmLive r -> CmmLive r
mid n f = gen_kill dflags n f
lst :: CmmNode O C -> FactBase (CmmLive r) -> CmmLive r
lst n f = gen_kill dflags n $ joinOutFacts liveLattice n f