1 {-# OPTIONS -fno-warn-missing-signatures #-}
2 -----------------------------------------------------------------------------
4 -- The register allocator
6 -- (c) The University of Glasgow 2004
8 -----------------------------------------------------------------------------
11 The algorithm is roughly:
13 1) Compute strongly connected components of the basic block list.
15 2) Compute liveness (mapping from pseudo register to
18 3) Walk instructions in each basic block. We keep track of
19 (a) Free real registers (a bitmap?)
20 (b) Current assignment of temporaries to machine registers and/or
21 spill slots (call this the "assignment").
22 (c) Partial mapping from basic block ids to a virt-to-loc mapping.
23 When we first encounter a branch to a basic block,
24 we fill in its entry in this table with the current mapping.
27 (a) For each real register clobbered by this instruction:
28 If a temporary resides in it,
29 If the temporary is live after this instruction,
30 Move the temporary to another (non-clobbered & free) reg,
31 or spill it to memory. Mark the temporary as residing
32 in both memory and a register if it was spilled (it might
33 need to be read by this instruction).
34 (ToDo: this is wrong for jump instructions?)
36 (b) For each temporary *read* by the instruction:
37 If the temporary does not have a real register allocation:
38 - Allocate a real register from the free list. If
40 - Find a temporary to spill. Pick one that is
41 not used in this instruction (ToDo: not
43 - generate a spill instruction
44 - If the temporary was previously spilled,
45 generate an instruction to read the temp from its spill loc.
46 (optimisation: if we can see that a real register is going to
47 be used soon, then don't use it for allocation).
49 (c) Update the current assignment
51 (d) If the intstruction is a branch:
52 if the destination block already has a register assignment,
53 Generate a new block with fixup code and redirect the
54 jump to the new block.
56 Update the block id->assignment mapping with the current
59 (e) Delete all register assignments for temps which are read
60 (only) and die here. Update the free register list.
62 (f) Mark all registers clobbered by this instruction as not free,
63 and mark temporaries which have been spilled due to clobbering
64 as in memory (step (a) marks then as in both mem & reg).
66 (g) For each temporary *written* by this instruction:
67 Allocate a real register as for (b), spilling something
69 - except when updating the assignment, drop any memory
70 locations that the temporary was previously in, since
71 they will be no longer valid after this instruction.
73 (h) Delete all register assignments for temps which are
74 written and die here (there should rarely be any). Update
75 the free register list.
77 (i) Rewrite the instruction with the new mapping.
79 (j) For each spilled reg known to be now dead, re-add its stack slot
84 module RegAlloc.Linear.Main (
86 module RegAlloc.Linear.Base,
87 module RegAlloc.Linear.Stats
90 #include "HsVersions.h"
93 import RegAlloc.Linear.State
94 import RegAlloc.Linear.Base
95 import RegAlloc.Linear.StackMap
96 import RegAlloc.Linear.FreeRegs
97 import RegAlloc.Linear.Stats
98 import RegAlloc.Linear.JoinToTargets
99 import RegAlloc.Liveness
107 import Cmm hiding (RegSet)
121 #include "../includes/MachRegs.h"
124 -- -----------------------------------------------------------------------------
125 -- Top level of the register allocator
127 -- Allocate registers
130 -> UniqSM (NatCmmTop, Maybe RegAllocStats)
132 regAlloc (CmmData sec d)
137 regAlloc (CmmProc (LiveInfo info _ _) lbl params (ListGraph []))
138 = return ( CmmProc info lbl params (ListGraph [])
141 regAlloc (CmmProc static lbl params (ListGraph comps))
142 | LiveInfo info (Just first_id) block_live <- static
144 -- do register allocation on each component.
145 (final_blocks, stats)
146 <- linearRegAlloc first_id block_live
147 $ map (\b -> case b of
148 BasicBlock _ [b] -> AcyclicSCC b
149 BasicBlock _ bs -> CyclicSCC bs)
152 -- make sure the block that was first in the input list
153 -- stays at the front of the output
154 let ((first':_), rest')
155 = partition ((== first_id) . blockId) final_blocks
157 return ( CmmProc info lbl params (ListGraph (first' : rest'))
160 -- bogus. to make non-exhaustive match warning go away.
161 regAlloc (CmmProc _ _ _ _)
162 = panic "RegAllocLinear.regAlloc: no match"
165 -- -----------------------------------------------------------------------------
166 -- Linear sweep to allocate registers
169 -- | Do register allocation on some basic blocks.
170 -- But be careful to allocate a block in an SCC only if it has
171 -- an entry in the block map or it is the first block.
174 :: BlockId -- ^ the first block
175 -> BlockMap RegSet -- ^ live regs on entry to each basic block
176 -> [SCC LiveBasicBlock] -- ^ instructions annotated with "deaths"
177 -> UniqSM ([NatBasicBlock], RegAllocStats)
179 linearRegAlloc first_id block_live sccs
181 let (_, _, stats, blocks) =
182 runR emptyBlockMap initFreeRegs emptyRegMap emptyStackMap us
183 $ linearRA_SCCs first_id block_live [] sccs
185 return (blocks, stats)
187 linearRA_SCCs _ _ blocksAcc []
188 = return $ reverse blocksAcc
190 linearRA_SCCs first_id block_live blocksAcc (AcyclicSCC block : sccs)
191 = do blocks' <- processBlock block_live block
192 linearRA_SCCs first_id block_live
193 ((reverse blocks') ++ blocksAcc)
196 linearRA_SCCs first_id block_live blocksAcc (CyclicSCC blocks : sccs)
198 blockss' <- process first_id block_live blocks [] (return [])
199 linearRA_SCCs first_id block_live
200 (reverse (concat blockss') ++ blocksAcc)
203 {- from John Dias's patch 2008/10/16:
204 The linear-scan allocator sometimes allocates a block
205 before allocating one of its predecessors, which could lead to
206 inconsistent allocations. Make it so a block is only allocated
207 if a predecessor has set the "incoming" assignments for the block, or
208 if it's the procedure's entry block.
210 BL 2009/02: Careful. If the assignment for a block doesn't get set for
211 some reason then this function will loop. We should probably do some
212 more sanity checking to guard against this eventuality.
215 process _ _ [] [] accum
216 = return $ reverse accum
218 process first_id block_live [] next_round accum
219 = process first_id block_live next_round [] accum
221 process first_id block_live (b@(BasicBlock id _) : blocks) next_round accum
223 block_assig <- getBlockAssigR
225 if isJust (lookupBlockEnv block_assig id)
228 b' <- processBlock block_live b
229 process first_id block_live blocks next_round (b' : accum)
231 else process first_id block_live blocks (b : next_round) accum
234 -- | Do register allocation on this basic block
237 :: BlockMap RegSet -- ^ live regs on entry to each basic block
238 -> LiveBasicBlock -- ^ block to do register allocation on
239 -> RegM [NatBasicBlock] -- ^ block with registers allocated
241 processBlock block_live (BasicBlock id instrs)
244 <- linearRA block_live [] [] id instrs
245 return $ BasicBlock id instrs' : fixups
248 -- | Load the freeregs and current reg assignment into the RegM state
249 -- for the basic block with this BlockId.
250 initBlock :: BlockId -> RegM ()
252 = do block_assig <- getBlockAssigR
253 case lookupBlockEnv block_assig id of
254 -- no prior info about this block: assume everything is
255 -- free and the assignment is empty.
257 -> do setFreeRegsR initFreeRegs
258 setAssigR emptyRegMap
260 -- load info about register assignments leading into this block.
261 Just (freeregs, assig)
262 -> do setFreeRegsR freeregs
266 -- | Do allocation for a sequence of instructions.
268 :: BlockMap RegSet -- ^ map of what vregs are live on entry to each block.
269 -> [Instr] -- ^ accumulator for instructions already processed.
270 -> [NatBasicBlock] -- ^ accumulator for blocks of fixup code.
271 -> BlockId -- ^ id of the current block, for debugging.
272 -> [LiveInstr] -- ^ liveness annotated instructions in this block.
274 -> RegM ( [Instr] -- instructions after register allocation
275 , [NatBasicBlock]) -- fresh blocks of fixup code.
278 linearRA _ accInstr accFixup _ []
280 ( reverse accInstr -- instrs need to be returned in the correct order.
281 , accFixup) -- it doesn't matter what order the fixup blocks are returned in.
284 linearRA block_live accInstr accFixups id (instr:instrs)
286 (accInstr', new_fixups)
287 <- raInsn block_live accInstr id instr
289 linearRA block_live accInstr' (new_fixups ++ accFixups) id instrs
292 -- | Do allocation for a single instruction.
294 :: BlockMap RegSet -- ^ map of what vregs are love on entry to each block.
295 -> [Instr] -- ^ accumulator for instructions already processed.
296 -> BlockId -- ^ the id of the current block, for debugging
297 -> LiveInstr -- ^ the instr to have its regs allocated, with liveness info.
299 ( [Instr] -- new instructions
300 , [NatBasicBlock]) -- extra fixup blocks
302 raInsn _ new_instrs _ (Instr (COMMENT _) Nothing)
303 = return (new_instrs, [])
305 raInsn _ new_instrs _ (Instr (DELTA n) Nothing)
308 return (new_instrs, [])
310 raInsn block_live new_instrs id (Instr instr (Just live))
314 -- If we have a reg->reg move between virtual registers, where the
315 -- src register is not live after this instruction, and the dst
316 -- register does not already have an assignment,
317 -- and the source register is assigned to a register, not to a spill slot,
318 -- then we can eliminate the instruction.
319 -- (we can't eliminitate it if the source register is on the stack, because
320 -- we do not want to use one spill slot for different virtual registers)
321 case isRegRegMove instr of
322 Just (src,dst) | src `elementOfUniqSet` (liveDieRead live),
324 not (dst `elemUFM` assig),
325 Just (InReg _) <- (lookupUFM assig src) -> do
327 RealReg i -> setAssigR (addToUFM assig dst (InReg i))
328 -- if src is a fixed reg, then we just map dest to this
329 -- reg in the assignment. src must be an allocatable reg,
330 -- otherwise it wouldn't be in r_dying.
331 _virt -> case lookupUFM assig src of
332 Nothing -> panic "raInsn"
334 setAssigR (addToUFM (delFromUFM assig src) dst loc)
336 -- we have eliminated this instruction
338 freeregs <- getFreeRegsR
340 pprTrace "raInsn" (text "ELIMINATED: " <> docToSDoc (pprInstr instr)
341 $$ ppr r_dying <+> ppr w_dying $$ text (show freeregs) $$ ppr assig) $ do
343 return (new_instrs, [])
345 _ -> genRaInsn block_live new_instrs id instr
346 (uniqSetToList $ liveDieRead live)
347 (uniqSetToList $ liveDieWrite live)
351 = pprPanic "raInsn" (text "no match for:" <> ppr instr)
356 genRaInsn block_live new_instrs block_id instr r_dying w_dying =
357 case regUsage instr of { RU read written ->
358 case partition isRealReg written of { (real_written1,virt_written) ->
361 real_written = [ r | RealReg r <- real_written1 ]
363 -- we don't need to do anything with real registers that are
364 -- only read by this instr. (the list is typically ~2 elements,
365 -- so using nub isn't a problem).
366 virt_read = nub (filter isVirtualReg read)
369 -- (a) save any temporaries which will be clobbered by this instruction
370 clobber_saves <- saveClobberedTemps real_written r_dying
373 {- freeregs <- getFreeRegsR
376 (docToSDoc (pprInstr instr) $$ ppr r_dying <+> ppr w_dying $$ ppr virt_read <+> ppr virt_written
377 $$ text (show freeregs) $$ ppr assig)
381 -- (b), (c) allocate real regs for all regs read by this instruction.
382 (r_spills, r_allocd) <-
383 allocateRegsAndSpill True{-reading-} virt_read [] [] virt_read
385 -- (d) Update block map for new destinations
386 -- NB. do this before removing dead regs from the assignment, because
387 -- these dead regs might in fact be live in the jump targets (they're
388 -- only dead in the code that follows in the current basic block).
389 (fixup_blocks, adjusted_instr)
390 <- joinToTargets block_live block_id instr
392 -- (e) Delete all register assignments for temps which are read
393 -- (only) and die here. Update the free register list.
396 -- (f) Mark regs which are clobbered as unallocatable
397 clobberRegs real_written
399 -- (g) Allocate registers for temporaries *written* (only)
400 (w_spills, w_allocd) <-
401 allocateRegsAndSpill False{-writing-} virt_written [] [] virt_written
403 -- (h) Release registers for temps which are written here and not
408 -- (i) Patch the instruction
409 patch_map = listToUFM [ (t,RealReg r) |
410 (t,r) <- zip virt_read r_allocd
411 ++ zip virt_written w_allocd ]
413 patched_instr = patchRegs adjusted_instr patchLookup
414 patchLookup x = case lookupUFM patch_map x of
419 -- pprTrace "patched" (docToSDoc (pprInstr patched_instr)) $ do
421 -- (j) free up stack slots for dead spilled regs
422 -- TODO (can't be bothered right now)
424 -- erase reg->reg moves where the source and destination are the same.
425 -- If the src temp didn't die in this instr but happened to be allocated
426 -- to the same real reg as the destination, then we can erase the move anyway.
427 let squashed_instr = case isRegRegMove patched_instr of
432 let code = squashed_instr ++ w_spills ++ reverse r_spills
433 ++ clobber_saves ++ new_instrs
435 -- pprTrace "patched-code" ((vcat $ map (docToSDoc . pprInstr) code)) $ do
436 -- pprTrace "pached-fixup" ((ppr fixup_blocks)) $ do
438 return (code, fixup_blocks)
442 -- -----------------------------------------------------------------------------
445 releaseRegs regs = do
450 loop _ free _ | free `seq` False = undefined
451 loop assig free [] = do setAssigR assig; setFreeRegsR free; return ()
452 loop assig free (RealReg r : rs) = loop assig (releaseReg r free) rs
453 loop assig free (r:rs) =
454 case lookupUFM assig r of
455 Just (InBoth real _) -> loop (delFromUFM assig r) (releaseReg real free) rs
456 Just (InReg real) -> loop (delFromUFM assig r) (releaseReg real free) rs
457 _other -> loop (delFromUFM assig r) free rs
459 -- -----------------------------------------------------------------------------
460 -- Clobber real registers
463 For each temp in a register that is going to be clobbered:
464 - if the temp dies after this instruction, do nothing
465 - otherwise, put it somewhere safe (another reg if possible,
466 otherwise spill and record InBoth in the assignment).
468 for allocateRegs on the temps *read*,
469 - clobbered regs are allocatable.
471 for allocateRegs on the temps *written*,
472 - clobbered regs are not allocatable.
476 :: [RegNo] -- real registers clobbered by this instruction
477 -> [Reg] -- registers which are no longer live after this insn
478 -> RegM [Instr] -- return: instructions to spill any temps that will
481 saveClobberedTemps [] _ = return [] -- common case
482 saveClobberedTemps clobbered dying = do
485 to_spill = [ (temp,reg) | (temp, InReg reg) <- ufmToList assig,
486 reg `elem` clobbered,
487 temp `notElem` map getUnique dying ]
489 (instrs,assig') <- clobber assig [] to_spill
493 clobber assig instrs [] = return (instrs,assig)
494 clobber assig instrs ((temp,reg):rest)
496 --ToDo: copy it to another register if possible
497 (spill,slot) <- spillR (RealReg reg) temp
498 recordSpill (SpillClobber temp)
500 let new_assign = addToUFM assig temp (InBoth reg slot)
501 clobber new_assign (spill : COMMENT (fsLit "spill clobber") : instrs) rest
503 clobberRegs :: [RegNo] -> RegM ()
504 clobberRegs [] = return () -- common case
505 clobberRegs clobbered = do
506 freeregs <- getFreeRegsR
507 -- setFreeRegsR $! foldr grabReg freeregs clobbered
508 setFreeRegsR $! foldr allocateReg freeregs clobbered
511 setAssigR $! clobber assig (ufmToList assig)
513 -- if the temp was InReg and clobbered, then we will have
514 -- saved it in saveClobberedTemps above. So the only case
515 -- we have to worry about here is InBoth. Note that this
516 -- also catches temps which were loaded up during allocation
517 -- of read registers, not just those saved in saveClobberedTemps.
518 clobber assig [] = assig
519 clobber assig ((temp, InBoth reg slot) : rest)
520 | reg `elem` clobbered
521 = clobber (addToUFM assig temp (InMem slot)) rest
522 clobber assig (_:rest)
525 -- -----------------------------------------------------------------------------
526 -- allocateRegsAndSpill
528 -- This function does several things:
529 -- For each temporary referred to by this instruction,
530 -- we allocate a real register (spilling another temporary if necessary).
531 -- We load the temporary up from memory if necessary.
532 -- We also update the register assignment in the process, and
533 -- the list of free registers and free stack slots.
536 :: Bool -- True <=> reading (load up spilled regs)
537 -> [Reg] -- don't push these out
538 -> [Instr] -- spill insns
539 -> [RegNo] -- real registers allocated (accum.)
540 -> [Reg] -- temps to allocate
541 -> RegM ([Instr], [RegNo])
543 allocateRegsAndSpill _ _ spills alloc []
544 = return (spills,reverse alloc)
546 allocateRegsAndSpill reading keep spills alloc (r:rs) = do
548 case lookupUFM assig r of
549 -- case (1a): already in a register
550 Just (InReg my_reg) ->
551 allocateRegsAndSpill reading keep spills (my_reg:alloc) rs
553 -- case (1b): already in a register (and memory)
554 -- NB1. if we're writing this register, update its assignemnt to be
555 -- InReg, because the memory value is no longer valid.
556 -- NB2. This is why we must process written registers here, even if they
557 -- are also read by the same instruction.
558 Just (InBoth my_reg _) -> do
559 when (not reading) (setAssigR (addToUFM assig r (InReg my_reg)))
560 allocateRegsAndSpill reading keep spills (my_reg:alloc) rs
562 -- Not already in a register, so we need to find a free one...
564 freeregs <- getFreeRegsR
566 case getFreeRegs (regClass r) freeregs of
568 -- case (2): we have a free register
569 my_reg:_ -> {- pprTrace "alloc" (ppr r <+> ppr my_reg <+> ppr freeClass) $ -}
571 spills' <- loadTemp reading r loc my_reg spills
573 | Just (InMem slot) <- loc, reading = InBoth my_reg slot
574 | otherwise = InReg my_reg
575 setAssigR (addToUFM assig r $! new_loc)
576 setFreeRegsR $ allocateReg my_reg freeregs
577 allocateRegsAndSpill reading keep spills' (my_reg:alloc) rs
579 -- case (3): we need to push something out to free up a register
582 keep' = map getUnique keep
583 candidates1 = [ (temp,reg,mem)
584 | (temp, InBoth reg mem) <- ufmToList assig,
585 temp `notElem` keep', regClass (RealReg reg) == regClass r ]
586 candidates2 = [ (temp,reg)
587 | (temp, InReg reg) <- ufmToList assig,
588 temp `notElem` keep', regClass (RealReg reg) == regClass r ]
590 ASSERT2(not (null candidates1 && null candidates2),
591 text (show freeregs) <+> ppr r <+> ppr assig) do
595 -- we have a temporary that is in both register and mem,
596 -- just free up its register for use.
598 (temp,my_reg,slot):_ -> do
599 spills' <- loadTemp reading r loc my_reg spills
601 assig1 = addToUFM assig temp (InMem slot)
602 assig2 = addToUFM assig1 r (InReg my_reg)
605 allocateRegsAndSpill reading keep spills' (my_reg:alloc) rs
607 -- otherwise, we need to spill a temporary that currently
608 -- resides in a register.
613 -- TODO: plenty of room for optimisation in choosing which temp
614 -- to spill. We just pick the first one that isn't used in
615 -- the current instruction for now.
617 let (temp_to_push_out, my_reg)
618 = case candidates2 of
619 [] -> panic $ "RegAllocLinear.allocRegsAndSpill: no spill candidates"
620 ++ "assignment: " ++ show (ufmToList assig) ++ "\n"
623 (spill_insn, slot) <- spillR (RealReg my_reg) temp_to_push_out
624 let spill_store = (if reading then id else reverse)
625 [ COMMENT (fsLit "spill alloc")
628 -- record that this temp was spilled
629 recordSpill (SpillAlloc temp_to_push_out)
631 -- update the register assignment
632 let assig1 = addToUFM assig temp_to_push_out (InMem slot)
633 let assig2 = addToUFM assig1 r (InReg my_reg)
636 -- if need be, load up a spilled temp into the reg we've just freed up.
637 spills' <- loadTemp reading r loc my_reg spills
639 allocateRegsAndSpill reading keep
640 (spill_store ++ spills')
644 -- | Load up a spilled temporary if we need to.
647 -> Reg -- the temp being loaded
648 -> Maybe Loc -- the current location of this temp
649 -> RegNo -- the hreg to load the temp into
653 loadTemp True vreg (Just (InMem slot)) hreg spills
655 insn <- loadR (RealReg hreg) slot
656 recordSpill (SpillLoad $ getUnique vreg)
657 return $ COMMENT (fsLit "spill load") : insn : spills
659 loadTemp _ _ _ _ spills =