2 -- | Put common type definitions here to break recursive module dependencies.
4 module RegAlloc.Linear.Base (
12 -- the allocator monad
19 import RegAlloc.Linear.FreeRegs
20 import RegAlloc.Linear.StackMap
31 -- | Used to store the register assignment on entry to a basic block.
32 -- We use this to handle join points, where multiple branch instructions
33 -- target a particular label. We have to insert fixup code to make
34 -- the register assignments from the different sources match up.
37 = BlockMap (FreeRegs, RegMap Loc)
40 -- | Where a vreg is currently stored
41 -- A temporary can be marked as living in both a register and memory
42 -- (InBoth), for example if it was recently loaded from a spill location.
43 -- This makes it cheap to spill (no save instruction required), but we
44 -- have to be careful to turn this into InReg if the value in the
45 -- register is changed.
47 -- This is also useful when a temporary is about to be clobbered. We
48 -- save it in a spill location, but mark it as InBoth because the current
49 -- instruction might still want to read it.
52 -- | vreg is in a register
53 = InReg {-# UNPACK #-} !RegNo
55 -- | vreg is held in a stack slot
56 | InMem {-# UNPACK #-} !StackSlot
59 -- | vreg is held in both a register and a stack slot
60 | InBoth {-# UNPACK #-} !RegNo
61 {-# UNPACK #-} !StackSlot
62 deriving (Eq, Show, Ord)
64 instance Outputable Loc where
68 -- | Reasons why instructions might be inserted by the spiller.
69 -- Used when generating stats for -ddrop-asm-stats.
72 -- | vreg was spilled to a slot so we could use its
73 -- current hreg for another vreg
76 -- | vreg was moved because its hreg was clobbered
77 | SpillClobber !Unique
79 -- | vreg was loaded from a spill slot
82 -- | reg-reg move inserted during join to targets
85 -- | reg-mem move inserted during join to targets
89 -- | Used to carry interesting stats out of the register allocator.
92 { ra_spillInstrs :: UniqFM [Int] }
95 -- | The register alloctor state
99 -- | the current mapping from basic blocks to
100 -- the register assignments at the beginning of that block.
101 { ra_blockassig :: BlockAssignment
103 -- | free machine registers
104 , ra_freeregs :: {-#UNPACK#-}!FreeRegs
106 -- | assignment of temps to locations
107 , ra_assig :: RegMap Loc
109 -- | current stack delta
112 -- | free stack slots for spilling
113 , ra_stack :: StackMap
115 -- | unique supply for generating names for join point fixup blocks.
116 , ra_us :: UniqSupply
118 -- | Record why things were spilled, for -ddrop-asm-stats.
119 -- Just keep a list here instead of a map of regs -> reasons.
120 -- We don't want to slow down the allocator if we're not going to emit the stats.
121 , ra_spills :: [SpillReason] }
124 -- | The register allocator monad type.
126 = RegM { unReg :: RA_State -> (# RA_State, a #) }