2 % (c) The AQUA Project, Glasgow University, 1993-1995
6 #include "HsVersions.h"
7 #include "../../includes/platform.h"
8 #include "../../includes/GhcConstants.h"
11 FutureLive(..), RegLiveness(..), RegUsage(..), Reg(..),
12 MachineRegisters(..), MachineCode(..),
14 mkReg, runRegAllocate,
17 -- And, for self-sufficiency
18 CLabel, OrdList, PrimKind, UniqSet(..), UniqFM,
24 import CLabelInfo ( CLabel )
27 import Maybes ( maybeToBool, Maybe(..) )
28 import OrdList -- ( mkUnitList, mkSeqList, mkParList, OrdList )
31 import PrimKind ( PrimKind(..) )
36 #if ! OMIT_NATIVE_CODEGEN
39 import SparcCode -- ( SparcInstr, SparcRegs ) -- for specializing
42 runRegAllocate :: SparcRegs -> [Int] -> (OrdList SparcInstr) -> [SparcInstr]
46 import AlphaCode -- ( AlphaInstr, AlphaRegs ) -- for specializing
49 runRegAllocate :: AlphaRegs -> [Int] -> (OrdList AlphaInstr) -> [AlphaInstr]
57 %************************************************************************
59 \subsection[Reg]{Real registers}
61 %************************************************************************
63 Static Registers correspond to actual machine registers. These should
64 be avoided until the last possible moment.
66 Dynamic registers are allocated on the fly, usually to represent a single
67 value in the abstract assembly code (i.e. dynamic registers are usually
68 single assignment). Ultimately, they are mapped to available machine
69 registers before spitting out the code.
73 data Reg = FixedReg FAST_INT -- A pre-allocated machine register
75 | MappedReg FAST_INT -- A dynamically allocated machine register
77 | MemoryReg Int PrimKind -- A machine "register" actually held in a memory
78 -- allocated table of registers which didn't fit
81 | UnmappedReg Unique PrimKind -- One of an infinite supply of registers,
82 -- always mapped to one of the earlier two
84 -- No thanks: deriving (Eq)
86 mkReg :: Unique -> PrimKind -> Reg
89 instance Text Reg where
90 showsPrec _ (FixedReg i) = showString "%" . shows IBOX(i)
91 showsPrec _ (MappedReg i) = showString "%" . shows IBOX(i)
92 showsPrec _ (MemoryReg i _) = showString "%M" . shows i
93 showsPrec _ (UnmappedReg i _) = showString "%U" . shows i
96 instance Outputable Reg where
97 ppr sty r = ppStr (show r)
100 cmpReg (FixedReg i) (FixedReg i') = cmp_ihash i i'
101 cmpReg (MappedReg i) (MappedReg i') = cmp_ihash i i'
102 cmpReg (MemoryReg i _) (MemoryReg i' _) = cmp_i i i'
103 cmpReg (UnmappedReg u _) (UnmappedReg u' _) = cmpUnique u u'
108 if tag1 _LT_ tag2 then LT_ else GT_
110 tagReg (FixedReg _) = (ILIT(1) :: FAST_INT)
111 tagReg (MappedReg _) = ILIT(2)
112 tagReg (MemoryReg _ _) = ILIT(3)
113 tagReg (UnmappedReg _ _) = ILIT(4)
115 cmp_i :: Int -> Int -> TAG_
116 cmp_i a1 a2 = if a1 == a2 then EQ_ else if a1 < a2 then LT_ else GT_
118 cmp_ihash :: FAST_INT -> FAST_INT -> TAG_
119 cmp_ihash a1 a2 = if a1 _EQ_ a2 then EQ_ else if a1 _LT_ a2 then LT_ else GT_
121 instance Eq Reg where
122 a == b = case cmpReg a b of { EQ_ -> True; _ -> False }
123 a /= b = case cmpReg a b of { EQ_ -> False; _ -> True }
125 instance Ord Reg where
126 a <= b = case cmpReg a b of { LT_ -> True; EQ_ -> True; GT__ -> False }
127 a < b = case cmpReg a b of { LT_ -> True; EQ_ -> False; GT__ -> False }
128 a >= b = case cmpReg a b of { LT_ -> False; EQ_ -> True; GT__ -> True }
129 a > b = case cmpReg a b of { LT_ -> False; EQ_ -> False; GT__ -> True }
130 #ifdef __GLASGOW_HASKELL__
131 _tagCmp a b = case cmpReg a b of { LT_ -> _LT; EQ_ -> _EQ; GT__ -> _GT }
134 instance NamedThing Reg where
135 -- the *only* method that should be defined is "getTheUnique"!
136 -- (so we can use UniqFMs/UniqSets on Regs
137 getTheUnique (UnmappedReg u _) = u
138 getTheUnique (FixedReg i) = mkPseudoUnique1 IBOX(i)
139 getTheUnique (MappedReg i) = mkPseudoUnique2 IBOX(i)
140 getTheUnique (MemoryReg i _) = mkPseudoUnique3 i
143 This is the generic register allocator.
145 %************************************************************************
147 \subsection[RegPlace]{Map Stix registers to {\em real} registers}
149 %************************************************************************
151 An important point: The @regUsage@ function for a particular assembly language
152 must not refer to fixed registers, such as Hp, SpA, etc. The source and destination
153 lists should only refer to dynamically allocated registers or static registers
154 from the free list. As far as we are concerned, the fixed registers simply don't
155 exist (for allocation purposes, anyway).
159 class MachineRegisters a where
160 mkMRegs :: [Int] -> a
161 possibleMRegs :: PrimKind -> a -> [Int]
162 useMReg :: a -> FAST_INT -> a
163 useMRegs :: a -> [Int] -> a
164 freeMReg :: a -> FAST_INT -> a
165 freeMRegs :: a -> [Int] -> a
167 type RegAssignment = FiniteMap Reg Reg
168 type RegConflicts = FiniteMap Int (UniqSet Reg)
172 (FiniteMap CLabel (UniqSet Reg))
181 = RF (UniqSet Reg) -- in use
186 = RI (UniqSet Reg) -- in use
187 (UniqSet Reg) -- sources
188 (UniqSet Reg) -- destinations
200 class MachineCode a where
202 -- flatten :: OrdList a -> [a]
203 regUsage :: a -> RegUsage
204 regLiveness :: a -> RegLiveness -> RegLiveness
205 patchRegs :: a -> (Reg -> Reg) -> a
206 spillReg :: Reg -> Reg -> OrdList a
207 loadReg :: Reg -> Reg -> OrdList a
211 First we try something extremely simple.
212 If that fails, we have to do things the hard way.
217 :: (MachineRegisters a, MachineCode b)
223 runRegAllocate regs reserve_regs instrs =
226 Nothing -> hairyAlloc
228 flatInstrs = flattenOrdList instrs
229 simpleAlloc = simpleRegAlloc regs [] emptyFM flatInstrs
230 hairyAlloc = hairyRegAlloc regs reserve_regs flatInstrs
234 Here is the simple register allocator. Just dole out registers until
235 we run out, or until one gets clobbered before its last use. Don't
236 do anything fancy with branches. Just pretend that you've got a block
237 of straight-line code and hope for the best. Experience indicates that
238 this approach will suffice for about 96 percent of the code blocks that
244 :: (MachineRegisters a, MachineCode b)
245 => a -- registers to select from
246 -> [Reg] -- live static registers
247 -> RegAssignment -- mapping of dynamics to statics
251 simpleRegAlloc _ _ _ [] = Just []
252 simpleRegAlloc free live env (instr:instrs) =
253 if null deadSrcs && maybeToBool newAlloc && maybeToBool instrs2 then
254 Just (instr3 : instrs3)
258 instr3 = patchRegs instr (lookup env2)
260 (srcs, dsts) = case regUsage instr of { RU s d -> (uniqSetToList s, uniqSetToList d) }
262 lookup env x = case lookupFM env x of {Just y -> y; Nothing -> x}
264 deadSrcs = [r | r@(UnmappedReg _ _) <- srcs, lookup env r `not_elem` live]
265 newDsts = [r | r@(UnmappedReg _ _) <- dsts, r `not_elem` keysFM env]
267 newAlloc = foldr allocateNewReg (Just (free, [])) newDsts
268 (free2, new) = case newAlloc of Just x -> x
270 env2 = env `addListToFM` new
272 live2 = map snd new ++ [x | x <- live, x `not_elem` dsts]
274 instrs2 = simpleRegAlloc free2 live2 env2 instrs
275 instrs3 = case instrs2 of Just x -> x
278 :: MachineRegisters a
280 -> Maybe (a, [(Reg, Reg)])
281 -> Maybe (a, [(Reg, Reg)])
283 allocateNewReg _ Nothing = Nothing
285 allocateNewReg d@(UnmappedReg _ pk) (Just (free, prs)) =
286 if null choices then Nothing
287 else Just (free2, prs2)
289 choices = possibleMRegs pk free
291 free2 = free `useMReg` (case reg of {IBOX(reg2) -> reg2} )
292 prs2 = ((d, MappedReg (case reg of {IBOX(reg2) -> reg2})) : prs)
296 Here is the ``clever'' bit. First go backward (i.e. left), looking for
297 the last use of dynamic registers. Then go forward (i.e. right), filling
298 registers with static placements.
303 :: (MachineRegisters a, MachineCode b)
309 hairyRegAlloc regs reserve_regs instrs =
310 case mapAccumB (doRegAlloc reserve_regs)
311 (RH regs' 1 emptyFM) noFuture instrs
312 of (RH _ loc' _, _, instrs') ->
313 if loc' == 1 then instrs' else
314 case mapAccumB do_RegAlloc_Nil
315 (RH regs'' loc' emptyFM) noFuture (flattenOrdList (patchMem instrs'))
316 of ((RH _ loc'' _),_,instrs'') ->
317 if loc'' == loc' then instrs'' else panic "runRegAllocate"
319 regs' = regs `useMRegs` reserve_regs
320 regs'' = mkMRegs reserve_regs `asTypeOf` regs
322 do_RegAlloc_Nil = doRegAlloc [] -- out here to avoid CAF (sigh)
324 :: (MachineRegisters a, MachineCode b)
328 -> (RegHistory a, RegFuture, b)
330 noFuture :: RegFuture
331 noFuture = RF emptyUniqSet (FL emptyUniqSet emptyFM) emptyFM
334 Here we patch instructions that reference ``registers'' which are really in
335 memory somewhere (the mapping is under the control of the machine-specific
336 code generator). We place the appropriate load sequences before any instructions
337 that use memory registers as sources, and we place the appropriate spill sequences
338 after any instructions that use memory registers as destinations. The offending
339 instructions are rewritten with new dynamic registers, so we have to run register
340 allocation again after all of this is said and done.
349 patchMem cs = foldr (mkSeqList . patchMem') mkEmptyList cs
357 if null memSrcs && null memDsts then mkUnitList instr
359 (foldr mkParList mkEmptyList loadSrcs)
361 (foldr mkParList mkEmptyList spillDsts))
364 (RU srcs dsts) = regUsage instr
366 memToDyn (MemoryReg i pk) = UnmappedReg (mkBuiltinUnique i) pk
367 memToDyn other = other
369 memSrcs = [ r | r@(MemoryReg _ _) <- uniqSetToList srcs]
370 memDsts = [ r | r@(MemoryReg _ _) <- uniqSetToList dsts]
372 loadSrcs = map load memSrcs
373 spillDsts = map spill memDsts
375 load mem = loadReg mem (memToDyn mem)
376 spill mem = spillReg (memToDyn mem) mem
378 instr' = mkUnitList (patchRegs instr memToDyn)
385 :: (MachineRegisters a, MachineCode b)
390 -> (RegHistory a, RegFuture, b)
392 doRegAlloc reserved_regs free_env in_use instr = (free_env', in_use', instr')
394 (free_env', instr') = doRegAlloc' reserved_regs free_env info instr
395 (in_use', info) = getUsage in_use instr
405 -> (RegFuture, RegInfo a)
407 getUsage (RF next_in_use future reg_conflicts) instr =
408 (RF in_use' future' reg_conflicts',
409 RI in_use' srcs dsts last_used reg_conflicts')
410 where (RU srcs dsts) = regUsage instr
411 (RL in_use future') = regLiveness instr (RL next_in_use future)
412 live_through = in_use `minusUniqSet` dsts
413 last_used = [ r | r <- uniqSetToList srcs,
414 not (r `elementOfUniqSet` (fstFL future) || r `elementOfUniqSet` in_use)]
415 in_use' = srcs `unionUniqSets` live_through
416 reg_conflicts' = case new_conflicts of
418 _ -> addListToFM reg_conflicts new_conflicts
419 new_conflicts = if isEmptyUniqSet live_dynamics then []
420 else [ (r, merge_conflicts r)
421 | r <- extractMappedRegNos (uniqSetToList dsts) ]
422 merge_conflicts reg = case lookupFM reg_conflicts reg of
423 Nothing -> live_dynamics
424 Just conflicts -> conflicts `unionUniqSets` live_dynamics
425 live_dynamics = mkUniqSet
426 [ r | r@(UnmappedReg _ _) <- uniqSetToList live_through ]
429 :: (MachineRegisters a, MachineCode b)
436 doRegAlloc' reserved (RH frs loc env) (RI in_use srcs dsts lastu conflicts) instr =
438 (RH frs'' loc' env'', patchRegs instr dynToStatic)
442 -- free up new registers
444 free = extractMappedRegNos (map dynToStatic lastu)
446 -- (1) free registers that are used last as source operands in this instruction
447 frs_not_in_use = frs `useMRegs` (extractMappedRegNos (uniqSetToList in_use))
448 frs' = (frs_not_in_use `freeMRegs` free) `useMRegs` reserved
450 -- (2) allocate new registers for the destination operands
451 -- allocate registers for new dynamics
453 new_dynamix = [ r | r@(UnmappedReg _ _) <- uniqSetToList dsts, r `not_elem` keysFM env ]
455 (frs'', loc', new) = foldr allocateNewRegs (frs', loc, []) new_dynamix
457 env' = addListToFM env new
459 env'' = delListFromFM env' lastu
461 dynToStatic :: Reg -> Reg
462 dynToStatic dyn@(UnmappedReg _ _) =
463 case lookupFM env' dyn of
465 Nothing -> trace "Lost register; possibly a floating point type error in a _ccall_?" dyn
466 dynToStatic other = other
469 :: MachineRegisters a
470 => Reg -> (a, Int, [(Reg, Reg)]) -> (a, Int, [(Reg, Reg)])
472 allocateNewRegs d@(UnmappedReg _ pk) (fs, mem, lst) = (fs', mem', (d, f) : lst)
473 where (fs', f, mem') = case acceptable fs of
474 [] -> (fs, MemoryReg mem pk, mem + 1)
475 (IBOX(x2):_) -> (fs `useMReg` x2, MappedReg x2, mem)
477 acceptable regs = filter no_conflict (possibleMRegs pk regs)
478 no_conflict reg = case lookupFM conflicts reg of
480 Just conflicts -> not (d `elementOfUniqSet` conflicts)
484 extractMappedRegNos :: [Reg] -> [Int]
486 extractMappedRegNos regs
489 ex (MappedReg i) acc = IBOX(i) : acc -- we'll take it
490 ex _ acc = acc -- leave it out
493 We keep a local copy of the Prelude function \tr{notElem},
494 so that it can be specialised. (Hack me gently. [WDP 94/11])
497 not_elem x (y:ys) = x /= y && not_elem x ys