where
-import RegLiveness
-import RegAllocInfo
-import MachRegs
-import MachInstrs
+import RegAlloc.Liveness
+import Instruction
+import Reg
import Cmm
import State
import Outputable
import Data.List
-import Data.Maybe
-- | Spill all these virtual regs to memory
-- address the spill slot directly.
--
regSpill
- :: [LiveCmmTop] -- ^ the code
+ :: Instruction instr
+ => [LiveCmmTop instr] -- ^ the code
-> UniqSet Int -- ^ available stack slots
- -> UniqSet Reg -- ^ the regs to spill
+ -> UniqSet VirtualReg -- ^ the regs to spill
-> UniqSM
- ([LiveCmmTop] -- code will spill instructions
+ ([LiveCmmTop instr] -- code will spill instructions
, UniqSet Int -- left over slots
, SpillStats ) -- stats about what happened during spilling
= do instrss' <- mapM (regSpill_instr regSlotMap) instrs
return $ BasicBlock i (concat instrss')
+
+regSpill_instr
+ :: Instruction instr
+ => UniqFM Int
+ -> LiveInstr instr -> SpillM [LiveInstr instr]
+
+-- | The thing we're spilling shouldn't already have spill or reloads in it
+regSpill_instr _ SPILL{}
+ = panic "regSpill_instr: unexpected SPILL"
+
+regSpill_instr _ RELOAD{}
+ = panic "regSpill_instr: unexpected RELOAD"
+
+
regSpill_instr _ li@(Instr _ Nothing)
= do return [li]
(Instr instr (Just _))
= do
-- work out which regs are read and written in this instr
- let RU rlRead rlWritten = regUsage instr
+ let RU rlRead rlWritten = regUsageOfInstr instr
-- sometimes a register is listed as being read more than once,
-- nub this so we don't end up inserting two lots of spill code.
let postfixes = concat mPostfixes
-- final code
- let instrs' = map (\i -> Instr i Nothing) prefixes
- ++ [ Instr instr3 Nothing ]
- ++ map (\i -> Instr i Nothing) postfixes
+ let instrs' = prefixes
+ ++ [Instr instr3 Nothing]
+ ++ postfixes
return
{- $ pprTrace "* regSpill_instr spill"
| otherwise = panic "RegSpill.spillRead: no slot defined for spilled reg"
+
spillWrite regSlotMap instr reg
| Just slot <- lookupUFM regSlotMap reg
= do (instr', nReg) <- patchInstr reg instr
| otherwise = panic "RegSpill.spillWrite: no slot defined for spilled reg"
+
spillModify regSlotMap instr reg
| Just slot <- lookupUFM regSlotMap reg
= do (instr', nReg) <- patchInstr reg instr
-- | rewrite uses of this virtual reg in an instr to use a different virtual reg
-patchInstr :: Reg -> Instr -> SpillM (Instr, Reg)
+patchInstr
+ :: Instruction instr
+ => Reg -> instr -> SpillM (instr, Reg)
+
patchInstr reg instr
= do nUnique <- newUnique
- let nReg = renameVirtualReg nUnique reg
+ let nReg = case reg of
+ RegVirtual vr -> RegVirtual (renameVirtualReg nUnique vr)
+ RegReal{} -> panic "RegAlloc.Graph.Spill.patchIntr: not patching real reg"
let instr' = patchReg1 reg nReg instr
return (instr', nReg)
-patchReg1 :: Reg -> Reg -> Instr -> Instr
+patchReg1
+ :: Instruction instr
+ => Reg -> Reg -> instr -> instr
+
patchReg1 old new instr
= let patchF r
| r == old = new
| otherwise = r
- in patchRegs instr patchF
+ in patchRegsOfInstr instr patchF
------------------------------------------------------