spillNatBlock,
slurpConflicts,
slurpReloadCoalesce,
- lifetimeCount,
eraseDeltasLive,
patchEraseLive,
patchRegsLiveInstr,
) where
-#include "HsVersions.h"
-
+import BlockId
import MachRegs
import MachInstrs
import PprMach
import UniqSupply
import Bag
import State
+import FastString
import Data.List
import Data.Maybe
= ppr instr
$$ (nest 8
$ vcat
- [ pprRegs (ptext SLIT("# born: ")) (liveBorn live)
- , pprRegs (ptext SLIT("# r_dying: ")) (liveDieRead live)
- , pprRegs (ptext SLIT("# w_dying: ")) (liveDieWrite live) ]
+ [ pprRegs (ptext (sLit "# born: ")) (liveBorn live)
+ , pprRegs (ptext (sLit "# r_dying: ")) (liveDieRead live)
+ , pprRegs (ptext (sLit "# w_dying: ")) (liveDieWrite live) ]
$+$ space)
where pprRegs :: SDoc -> RegSet -> SDoc
= (consBag rsLiveEntry conflicts, moves)
| otherwise
- = error "RegLiveness.slurpBlock: bad block"
+ = panic "RegLiveness.slurpBlock: bad block"
slurpLIs rsLive (conflicts, moves) []
= (consBag rsLive conflicts, moves)
, moves) lis
--- | For spill/reloads
+-- | For spill\/reloads
--
-- SPILL v1, slot1
-- ...
-- RELOAD slot1, v2
--
-- If we can arrange that v1 and v2 are allocated to the same hreg it's more likely
--- the spill/reload instrs can be cleaned and replaced by a nop reg-reg move.
+-- the spill\/reload instrs can be cleaned and replaced by a nop reg-reg move.
--
--
slurpReloadCoalesce :: LiveCmmTop -> Bag (Reg, Reg)
= spillNat (instr : acc) instrs
--- | Slurp out a map of how many times each register was live upon entry to an instruction.
-
-lifetimeCount
- :: LiveCmmTop
- -> UniqFM (Reg, Int) -- ^ reg -> (reg, count)
-
-lifetimeCount cmm
- = countCmm emptyUFM cmm
- where
- countCmm fm CmmData{} = fm
- countCmm fm (CmmProc info _ _ (ListGraph blocks))
- = foldl' (countComp info) fm blocks
-
- countComp info fm (BasicBlock _ blocks)
- = foldl' (countBlock info) fm blocks
-
- countBlock info fm (BasicBlock blockId instrs)
- | LiveInfo _ _ blockLive <- info
- , Just rsLiveEntry <- lookupUFM blockLive blockId
- = countLIs rsLiveEntry fm instrs
-
- | otherwise
- = error "RegLiveness.countBlock: bad block"
-
- countLIs _ fm [] = fm
- countLIs rsLive fm (Instr _ Nothing : lis) = countLIs rsLive fm lis
-
- countLIs rsLiveEntry fm (Instr _ (Just live) : lis)
- = let
- rsLiveAcross = rsLiveEntry `minusUniqSet` (liveDieRead live)
-
- rsLiveNext = (rsLiveAcross `unionUniqSets` (liveBorn live))
- `minusUniqSet` (liveDieWrite live)
-
- add r fm = addToUFM_C
- (\(r1, l1) (_, l2) -> (r1, l1 + l2))
- fm r (r, 1)
-
- fm' = foldUniqSet add fm rsLiveEntry
- in countLIs rsLiveNext fm' lis
-
-
-- | Erase Delta instructions.
eraseDeltasLive :: LiveCmmTop -> LiveCmmTop
sccBlocks :: [NatBasicBlock] -> [SCC NatBasicBlock]
-sccBlocks blocks = stronglyConnComp graph
+sccBlocks blocks = stronglyConnCompFromEdgedVertices graph
where
getOutEdges :: [Instr] -> [BlockId]
getOutEdges instrs = foldl' (\a x -> jumpDests x a) [] instrs
concatMap tail $
groupBy (\(a1, _) (a2, _) -> eq a1 a2) $
iterate (\(a, _) -> f a b) $
- (a, error "RegisterAlloc.livenessSCCs")
+ (a, panic "RegLiveness.livenessSCCs")
linearLiveness :: BlockMap RegSet -> [NatBasicBlock]