2 -- | Put common type definitions here to break recursive module dependencies.
4 module RegAlloc.Linear.Base (
14 -- the allocator monad
21 import RegAlloc.Linear.FreeRegs
22 import RegAlloc.Linear.StackMap
33 -- | Used to store the register assignment on entry to a basic block.
34 -- We use this to handle join points, where multiple branch instructions
35 -- target a particular label. We have to insert fixup code to make
36 -- the register assignments from the different sources match up.
39 = BlockMap (FreeRegs, RegMap Loc)
42 -- | Where a vreg is currently stored
43 -- A temporary can be marked as living in both a register and memory
44 -- (InBoth), for example if it was recently loaded from a spill location.
45 -- This makes it cheap to spill (no save instruction required), but we
46 -- have to be careful to turn this into InReg if the value in the
47 -- register is changed.
49 -- This is also useful when a temporary is about to be clobbered. We
50 -- save it in a spill location, but mark it as InBoth because the current
51 -- instruction might still want to read it.
54 -- | vreg is in a register
55 = InReg {-# UNPACK #-} !RegNo
57 -- | vreg is held in a stack slot
58 | InMem {-# UNPACK #-} !StackSlot
61 -- | vreg is held in both a register and a stack slot
62 | InBoth {-# UNPACK #-} !RegNo
63 {-# UNPACK #-} !StackSlot
64 deriving (Eq, Show, Ord)
66 instance Outputable Loc where
70 -- | Get the reg numbers stored in this Loc.
71 regsOfLoc :: Loc -> [RegNo]
72 regsOfLoc (InReg r) = [r]
73 regsOfLoc (InBoth r _) = [r]
74 regsOfLoc (InMem _) = []
77 -- | Reasons why instructions might be inserted by the spiller.
78 -- Used when generating stats for -ddrop-asm-stats.
81 -- | vreg was spilled to a slot so we could use its
82 -- current hreg for another vreg
85 -- | vreg was moved because its hreg was clobbered
86 | SpillClobber !Unique
88 -- | vreg was loaded from a spill slot
91 -- | reg-reg move inserted during join to targets
94 -- | reg-mem move inserted during join to targets
98 -- | Used to carry interesting stats out of the register allocator.
101 { ra_spillInstrs :: UniqFM [Int] }
104 -- | The register alloctor state
109 -- | the current mapping from basic blocks to
110 -- the register assignments at the beginning of that block.
111 ra_blockassig :: BlockAssignment
113 -- | free machine registers
114 , ra_freeregs :: {-#UNPACK#-}!FreeRegs
116 -- | assignment of temps to locations
117 , ra_assig :: RegMap Loc
119 -- | current stack delta
122 -- | free stack slots for spilling
123 , ra_stack :: StackMap
125 -- | unique supply for generating names for join point fixup blocks.
126 , ra_us :: UniqSupply
128 -- | Record why things were spilled, for -ddrop-asm-stats.
129 -- Just keep a list here instead of a map of regs -> reasons.
130 -- We don't want to slow down the allocator if we're not going to emit the stats.
131 , ra_spills :: [SpillReason] }
134 -- | The register allocator monad type.
136 = RegM { unReg :: RA_State -> (# RA_State, a #) }