X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FnativeGen%2FRegLiveness.hs;h=81d993b6cdf75ec5058e39472af0342a659ab009;hb=589238c4c2712d29092086926cc48eeb5e9b8fa7;hp=8f313aeb50678fb228e7b34631f390c38b811b82;hpb=0168c633a9d209e978528f059193d19cdb5e6740;p=ghc-hetmet.git diff --git a/compiler/nativeGen/RegLiveness.hs b/compiler/nativeGen/RegLiveness.hs index 8f313ae..81d993b 100644 --- a/compiler/nativeGen/RegLiveness.hs +++ b/compiler/nativeGen/RegLiveness.hs @@ -6,6 +6,12 @@ -- ----------------------------------------------------------------------------- +{-# OPTIONS_GHC -w #-} +-- The above warning supression flag is a temporary kludge. +-- While working on this module you are encouraged to remove it and fix +-- any warnings in the module. See +-- http://hackage.haskell.org/trac/ghc/wiki/WorkingConventions#Warnings +-- for details module RegLiveness ( RegSet, @@ -178,14 +184,13 @@ mapGenBlockTopM f (CmmProc header label params blocks) return $ CmmProc header label params blocks' - - - --- | Slurp out the list of register conflicts from this top level thing. - -slurpConflicts :: LiveCmmTop -> Bag (UniqSet Reg) +-- | Slurp out the list of register conflicts and reg-reg moves from this top level thing. +-- Slurping of conflicts and moves is wrapped up together so we don't have +-- to make two passes over the same code when we want to build the graph. +-- +slurpConflicts :: LiveCmmTop -> (Bag (UniqSet Reg), Bag (Reg, Reg)) slurpConflicts live - = slurpCmm emptyBag live + = slurpCmm (emptyBag, emptyBag) live where slurpCmm rs CmmData{} = rs slurpCmm rs (CmmProc info _ _ blocks) @@ -197,12 +202,18 @@ slurpConflicts live slurpBlock info rs (BasicBlock blockId instrs) | LiveInfo _ _ blockLive <- info , Just rsLiveEntry <- lookupUFM blockLive blockId - = consBag rsLiveEntry $ slurpLIs rsLiveEntry rs instrs + , (conflicts, moves) <- slurpLIs rsLiveEntry rs instrs + = (consBag rsLiveEntry conflicts, moves) + + | otherwise + = error "RegLiveness.slurpBlock: bad block" + + slurpLIs rsLive (conflicts, moves) [] + = (consBag rsLive conflicts, moves) - slurpLIs rsLive rs [] = consBag rsLive rs slurpLIs rsLive rs (Instr _ Nothing : lis) = slurpLIs rsLive rs lis - slurpLIs rsLiveEntry rs (li@(Instr _ (Just live)) : lis) + slurpLIs rsLiveEntry (conflicts, moves) (li@(Instr instr (Just live)) : lis) = let -- regs that die because they are read for the last time at the start of an instruction -- are not live across it. @@ -224,7 +235,14 @@ slurpConflicts live -- rsConflicts = unionUniqSets rsLiveNext rsOrphans - in slurpLIs rsLiveNext (consBag rsConflicts rs) lis + in case isRegRegMove instr of + Just rr -> slurpLIs rsLiveNext + ( consBag rsConflicts conflicts + , consBag rr moves) lis + + Nothing -> slurpLIs rsLiveNext + ( consBag rsConflicts conflicts + , moves) lis -- | Strip away liveness information, yielding NatCmmTop @@ -245,25 +263,28 @@ stripLive live -- | Make real spill instructions out of SPILL, RELOAD pseudos spillNatBlock :: NatBasicBlock -> NatBasicBlock -spillNatBlock (BasicBlock i instrs) +spillNatBlock (BasicBlock i is) = BasicBlock i instrs' where (instrs', _) - = runState (mapM spillNat instrs) 0 + = runState (spillNat [] is) 0 - spillNat instr@(DELTA i) + spillNat acc [] + = return (reverse acc) + + spillNat acc (instr@(DELTA i) : instrs) = do put i - return instr + spillNat acc instrs - spillNat (SPILL reg slot) + spillNat acc (SPILL reg slot : instrs) = do delta <- get - return $ mkSpillInstr reg delta slot + spillNat (mkSpillInstr reg delta slot : acc) instrs - spillNat (RELOAD slot reg) + spillNat acc (RELOAD slot reg : instrs) = do delta <- get - return $ mkLoadInstr reg delta slot + spillNat (mkLoadInstr reg delta slot : acc) instrs - spillNat instr - = return instr + spillNat acc (instr : instrs) + = spillNat (instr : acc) instrs -- | Slurp out a map of how many times each register was live upon entry to an instruction. @@ -286,6 +307,9 @@ lifetimeCount cmm | LiveInfo _ _ blockLive <- info , Just rsLiveEntry <- lookupUFM blockLive blockId = countLIs rsLiveEntry fm instrs + + | otherwise + = error "RegLiveness.countBlock: bad block" countLIs rsLive fm [] = fm countLIs rsLive fm (Instr _ Nothing : lis) = countLIs rsLive fm lis