diff options
author | Ben.Lippmeier@anu.edu.au <unknown> | 2009-02-15 05:51:58 +0000 |
---|---|---|
committer | Ben.Lippmeier@anu.edu.au <unknown> | 2009-02-15 05:51:58 +0000 |
commit | b04a210e26ca57242fd052f2aa91011a80b76299 (patch) | |
tree | 6f26993cc3ef37f4555087bd80da4195edcda4ed /compiler/nativeGen/RegAlloc/Graph/Spill.hs | |
parent | 77ed23d51b968505b3ad8541c075657ae94f0ea3 (diff) | |
download | haskell-b04a210e26ca57242fd052f2aa91011a80b76299.tar.gz |
NCG: Split up the native code generator into arch specific modules
- nativeGen/Instruction defines a type class for a generic
instruction set. Each of the instruction sets we have,
X86, PPC and SPARC are instances of it.
- The register alloctors use this type class when they need
info about a certain register or instruction, such as
regUsage, mkSpillInstr, mkJumpInstr, patchRegs..
- nativeGen/Platform defines some data types enumerating
the architectures and operating systems supported by the
native code generator.
- DynFlags now keeps track of the current build platform, and
the PositionIndependentCode module uses this to decide what
to do instead of relying of #ifdefs.
- It's not totally retargetable yet. Some info info about the
build target is still hardwired, but I've tried to contain
most of it to a single module, TargetRegs.
- Moved the SPILL and RELOAD instructions into LiveInstr.
- Reg and RegClass now have their own modules, and are shared
across all architectures.
Diffstat (limited to 'compiler/nativeGen/RegAlloc/Graph/Spill.hs')
-rw-r--r-- | compiler/nativeGen/RegAlloc/Graph/Spill.hs | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/compiler/nativeGen/RegAlloc/Graph/Spill.hs b/compiler/nativeGen/RegAlloc/Graph/Spill.hs index b5a645188f..e6e5622a02 100644 --- a/compiler/nativeGen/RegAlloc/Graph/Spill.hs +++ b/compiler/nativeGen/RegAlloc/Graph/Spill.hs @@ -10,9 +10,8 @@ module RegAlloc.Graph.Spill ( where import RegAlloc.Liveness -import RegAllocInfo -import Regs -import Instrs +import Instruction +import Reg import Cmm import State @@ -35,11 +34,12 @@ import Data.Maybe -- 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 -> UniqSM - ([LiveCmmTop] -- code will spill instructions + ([LiveCmmTop instr] -- code will spill instructions , UniqSet Int -- left over slots , SpillStats ) -- stats about what happened during spilling @@ -75,6 +75,20 @@ regSpill_block regSlotMap (BasicBlock i instrs) = 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] @@ -82,7 +96,7 @@ regSpill_instr regSlotMap (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. @@ -109,9 +123,9 @@ regSpill_instr regSlotMap 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" @@ -139,6 +153,7 @@ spillRead regSlotMap instr reg | 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 @@ -152,6 +167,7 @@ spillWrite regSlotMap instr reg | 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 @@ -168,19 +184,25 @@ spillModify regSlotMap instr reg -- | 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 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 ------------------------------------------------------ |