1 -----------------------------------------------------------------------------
3 -- The register allocator
5 -- (c) The University of Glasgow 2004
7 -----------------------------------------------------------------------------
10 The algorithm is roughly:
12 1) Compute strongly connected components of the basic block list.
14 2) Compute liveness (mapping from pseudo register to
17 3) Walk instructions in each basic block. We keep track of
18 (a) Free real registers (a bitmap?)
19 (b) Current assignment of temporaries to machine registers and/or
20 spill slots (call this the "assignment").
21 (c) Partial mapping from basic block ids to a virt-to-loc mapping.
22 When we first encounter a branch to a basic block,
23 we fill in its entry in this table with the current mapping.
26 (a) For each real register clobbered by this instruction:
27 If a temporary resides in it,
28 If the temporary is live after this instruction,
29 Move the temporary to another (non-clobbered & free) reg,
30 or spill it to memory. Mark the temporary as residing
31 in both memory and a register if it was spilled (it might
32 need to be read by this instruction).
33 (ToDo: this is wrong for jump instructions?)
35 (b) For each temporary *read* by the instruction:
36 If the temporary does not have a real register allocation:
37 - Allocate a real register from the free list. If
39 - Find a temporary to spill. Pick one that is
40 not used in this instruction (ToDo: not
42 - generate a spill instruction
43 - If the temporary was previously spilled,
44 generate an instruction to read the temp from its spill loc.
45 (optimisation: if we can see that a real register is going to
46 be used soon, then don't use it for allocation).
48 (c) Update the current assignment
50 (d) If the instruction is a branch:
51 if the destination block already has a register assignment,
52 Generate a new block with fixup code and redirect the
53 jump to the new block.
55 Update the block id->assignment mapping with the current
58 (e) Delete all register assignments for temps which are read
59 (only) and die here. Update the free register list.
61 (f) Mark all registers clobbered by this instruction as not free,
62 and mark temporaries which have been spilled due to clobbering
63 as in memory (step (a) marks then as in both mem & reg).
65 (g) For each temporary *written* by this instruction:
66 Allocate a real register as for (b), spilling something
68 - except when updating the assignment, drop any memory
69 locations that the temporary was previously in, since
70 they will be no longer valid after this instruction.
72 (h) Delete all register assignments for temps which are
73 written and die here (there should rarely be any). Update
74 the free register list.
76 (i) Rewrite the instruction with the new mapping.
78 (j) For each spilled reg known to be now dead, re-add its stack slot
83 module RegAlloc.Linear.Main (
85 module RegAlloc.Linear.Base,
86 module RegAlloc.Linear.Stats
89 #include "HsVersions.h"
92 import RegAlloc.Linear.State
93 import RegAlloc.Linear.Base
94 import RegAlloc.Linear.StackMap
95 import RegAlloc.Linear.FreeRegs
96 import RegAlloc.Linear.Stats
97 import RegAlloc.Linear.JoinToTargets
99 import RegAlloc.Liveness
104 import OldCmm hiding (RegSet)
117 #include "../includes/stg/MachRegs.h"
120 -- -----------------------------------------------------------------------------
121 -- Top level of the register allocator
123 -- Allocate registers
125 :: (Outputable instr, Instruction instr)
127 -> UniqSM (NatCmmTop instr, Maybe RegAllocStats)
129 regAlloc (CmmData sec d)
134 regAlloc (CmmProc (LiveInfo info _ _ _) lbl [])
135 = return ( CmmProc info lbl (ListGraph [])
138 regAlloc (CmmProc static lbl sccs)
139 | LiveInfo info (Just first_id) (Just block_live) _ <- static
141 -- do register allocation on each component.
142 (final_blocks, stats)
143 <- linearRegAlloc first_id block_live sccs
145 -- make sure the block that was first in the input list
146 -- stays at the front of the output
147 let ((first':_), rest')
148 = partition ((== first_id) . blockId) final_blocks
150 return ( CmmProc info lbl (ListGraph (first' : rest'))
153 -- bogus. to make non-exhaustive match warning go away.
154 regAlloc (CmmProc _ _ _)
155 = panic "RegAllocLinear.regAlloc: no match"
158 -- -----------------------------------------------------------------------------
159 -- Linear sweep to allocate registers
162 -- | Do register allocation on some basic blocks.
163 -- But be careful to allocate a block in an SCC only if it has
164 -- an entry in the block map or it is the first block.
167 :: (Outputable instr, Instruction instr)
168 => BlockId -- ^ the first block
169 -> BlockMap RegSet -- ^ live regs on entry to each basic block
170 -> [SCC (LiveBasicBlock instr)] -- ^ instructions annotated with "deaths"
171 -> UniqSM ([NatBasicBlock instr], RegAllocStats)
173 linearRegAlloc first_id block_live sccs
175 let (_, _, stats, blocks) =
176 runR emptyBlockMap initFreeRegs emptyRegMap emptyStackMap us
177 $ linearRA_SCCs first_id block_live [] sccs
179 return (blocks, stats)
181 linearRA_SCCs :: (Instruction instr, Outputable instr)
184 -> [NatBasicBlock instr]
185 -> [SCC (LiveBasicBlock instr)]
186 -> RegM FreeRegs [NatBasicBlock instr]
188 linearRA_SCCs _ _ blocksAcc []
189 = return $ reverse blocksAcc
191 linearRA_SCCs first_id block_live blocksAcc (AcyclicSCC block : sccs)
192 = do blocks' <- processBlock block_live block
193 linearRA_SCCs first_id block_live
194 ((reverse blocks') ++ blocksAcc)
197 linearRA_SCCs first_id block_live blocksAcc (CyclicSCC blocks : sccs)
199 blockss' <- process first_id block_live blocks [] (return []) False
200 linearRA_SCCs first_id block_live
201 (reverse (concat blockss') ++ blocksAcc)
204 {- from John Dias's patch 2008/10/16:
205 The linear-scan allocator sometimes allocates a block
206 before allocating one of its predecessors, which could lead to
207 inconsistent allocations. Make it so a block is only allocated
208 if a predecessor has set the "incoming" assignments for the block, or
209 if it's the procedure's entry block.
211 BL 2009/02: Careful. If the assignment for a block doesn't get set for
212 some reason then this function will loop. We should probably do some
213 more sanity checking to guard against this eventuality.
216 process :: (Instruction instr, Outputable instr)
219 -> [GenBasicBlock (LiveInstr instr)]
220 -> [GenBasicBlock (LiveInstr instr)]
221 -> [[NatBasicBlock instr]]
223 -> RegM FreeRegs [[NatBasicBlock instr]]
225 process _ _ [] [] accum _
226 = return $ reverse accum
228 process first_id block_live [] next_round accum madeProgress
231 {- BUGS: There are so many unreachable blocks in the code the warnings are overwhelming.
232 pprTrace "RegAlloc.Linear.Main.process: no progress made, bailing out."
233 ( text "Unreachable blocks:"
234 $$ vcat (map ppr next_round)) -}
235 = return $ reverse accum
238 = process first_id block_live
239 next_round [] accum False
241 process first_id block_live (b@(BasicBlock id _) : blocks)
242 next_round accum madeProgress
244 block_assig <- getBlockAssigR
246 if isJust (mapLookup id block_assig)
249 b' <- processBlock block_live b
250 process first_id block_live blocks
251 next_round (b' : accum) True
253 else process first_id block_live blocks
254 (b : next_round) accum madeProgress
257 -- | Do register allocation on this basic block
260 :: (Outputable instr, Instruction instr)
261 => BlockMap RegSet -- ^ live regs on entry to each basic block
262 -> LiveBasicBlock instr -- ^ block to do register allocation on
263 -> RegM FreeRegs [NatBasicBlock instr] -- ^ block with registers allocated
265 processBlock block_live (BasicBlock id instrs)
268 <- linearRA block_live [] [] id instrs
269 return $ BasicBlock id instrs' : fixups
272 -- | Load the freeregs and current reg assignment into the RegM state
273 -- for the basic block with this BlockId.
274 initBlock :: BlockId -> RegM FreeRegs ()
276 = do block_assig <- getBlockAssigR
277 case mapLookup id block_assig of
278 -- no prior info about this block: assume everything is
279 -- free and the assignment is empty.
281 -> do -- pprTrace "initFreeRegs" (text $ show initFreeRegs) (return ())
283 setFreeRegsR initFreeRegs
284 setAssigR emptyRegMap
286 -- load info about register assignments leading into this block.
287 Just (freeregs, assig)
288 -> do setFreeRegsR freeregs
292 -- | Do allocation for a sequence of instructions.
294 :: (Outputable instr, Instruction instr)
295 => BlockMap RegSet -- ^ map of what vregs are live on entry to each block.
296 -> [instr] -- ^ accumulator for instructions already processed.
297 -> [NatBasicBlock instr] -- ^ accumulator for blocks of fixup code.
298 -> BlockId -- ^ id of the current block, for debugging.
299 -> [LiveInstr instr] -- ^ liveness annotated instructions in this block.
302 ( [instr] -- instructions after register allocation
303 , [NatBasicBlock instr]) -- fresh blocks of fixup code.
306 linearRA _ accInstr accFixup _ []
308 ( reverse accInstr -- instrs need to be returned in the correct order.
309 , accFixup) -- it doesn't matter what order the fixup blocks are returned in.
312 linearRA block_live accInstr accFixups id (instr:instrs)
314 (accInstr', new_fixups)
315 <- raInsn block_live accInstr id instr
317 linearRA block_live accInstr' (new_fixups ++ accFixups) id instrs
320 -- | Do allocation for a single instruction.
322 :: (Outputable instr, Instruction instr)
323 => BlockMap RegSet -- ^ map of what vregs are love on entry to each block.
324 -> [instr] -- ^ accumulator for instructions already processed.
325 -> BlockId -- ^ the id of the current block, for debugging
326 -> LiveInstr instr -- ^ the instr to have its regs allocated, with liveness info.
328 ( [instr] -- new instructions
329 , [NatBasicBlock instr]) -- extra fixup blocks
331 raInsn _ new_instrs _ (LiveInstr ii Nothing)
332 | Just n <- takeDeltaInstr ii
334 return (new_instrs, [])
336 raInsn _ new_instrs _ (LiveInstr ii Nothing)
338 = return (new_instrs, [])
341 raInsn block_live new_instrs id (LiveInstr (Instr instr) (Just live))
345 -- If we have a reg->reg move between virtual registers, where the
346 -- src register is not live after this instruction, and the dst
347 -- register does not already have an assignment,
348 -- and the source register is assigned to a register, not to a spill slot,
349 -- then we can eliminate the instruction.
350 -- (we can't eliminate it if the source register is on the stack, because
351 -- we do not want to use one spill slot for different virtual registers)
352 case takeRegRegMoveInstr instr of
353 Just (src,dst) | src `elementOfUniqSet` (liveDieRead live),
355 not (dst `elemUFM` assig),
356 Just (InReg _) <- (lookupUFM assig src) -> do
358 (RegReal rr) -> setAssigR (addToUFM assig dst (InReg rr))
359 -- if src is a fixed reg, then we just map dest to this
360 -- reg in the assignment. src must be an allocatable reg,
361 -- otherwise it wouldn't be in r_dying.
362 _virt -> case lookupUFM assig src of
363 Nothing -> panic "raInsn"
365 setAssigR (addToUFM (delFromUFM assig src) dst loc)
367 -- we have eliminated this instruction
369 freeregs <- getFreeRegsR
371 pprTrace "raInsn" (text "ELIMINATED: " <> docToSDoc (pprInstr instr)
372 $$ ppr r_dying <+> ppr w_dying $$ text (show freeregs) $$ ppr assig) $ do
374 return (new_instrs, [])
376 _ -> genRaInsn block_live new_instrs id instr
377 (uniqSetToList $ liveDieRead live)
378 (uniqSetToList $ liveDieWrite live)
382 = pprPanic "raInsn" (text "no match for:" <> ppr instr)
385 genRaInsn :: (Instruction instr, Outputable instr)
392 -> RegM FreeRegs ([instr], [NatBasicBlock instr])
394 genRaInsn block_live new_instrs block_id instr r_dying w_dying =
395 case regUsageOfInstr instr of { RU read written ->
397 let real_written = [ rr | (RegReal rr) <- written ]
398 let virt_written = [ vr | (RegVirtual vr) <- written ]
400 -- we don't need to do anything with real registers that are
401 -- only read by this instr. (the list is typically ~2 elements,
402 -- so using nub isn't a problem).
403 let virt_read = nub [ vr | (RegVirtual vr) <- read ]
405 -- (a) save any temporaries which will be clobbered by this instruction
406 clobber_saves <- saveClobberedTemps real_written r_dying
409 {- freeregs <- getFreeRegsR
413 $$ text "r_dying = " <+> ppr r_dying
414 $$ text "w_dying = " <+> ppr w_dying
415 $$ text "virt_read = " <+> ppr virt_read
416 $$ text "virt_written = " <+> ppr virt_written
417 $$ text "freeregs = " <+> text (show freeregs)
418 $$ text "assig = " <+> ppr assig)
422 -- (b), (c) allocate real regs for all regs read by this instruction.
423 (r_spills, r_allocd) <-
424 allocateRegsAndSpill True{-reading-} virt_read [] [] virt_read
426 -- (d) Update block map for new destinations
427 -- NB. do this before removing dead regs from the assignment, because
428 -- these dead regs might in fact be live in the jump targets (they're
429 -- only dead in the code that follows in the current basic block).
430 (fixup_blocks, adjusted_instr)
431 <- joinToTargets block_live block_id instr
433 -- (e) Delete all register assignments for temps which are read
434 -- (only) and die here. Update the free register list.
437 -- (f) Mark regs which are clobbered as unallocatable
438 clobberRegs real_written
440 -- (g) Allocate registers for temporaries *written* (only)
441 (w_spills, w_allocd) <-
442 allocateRegsAndSpill False{-writing-} virt_written [] [] virt_written
444 -- (h) Release registers for temps which are written here and not
449 -- (i) Patch the instruction
453 | (t, r) <- zip virt_read r_allocd
454 ++ zip virt_written w_allocd ]
457 = patchRegsOfInstr adjusted_instr patchLookup
460 = case lookupUFM patch_map x of
465 -- (j) free up stack slots for dead spilled regs
466 -- TODO (can't be bothered right now)
468 -- erase reg->reg moves where the source and destination are the same.
469 -- If the src temp didn't die in this instr but happened to be allocated
470 -- to the same real reg as the destination, then we can erase the move anyway.
471 let squashed_instr = case takeRegRegMoveInstr patched_instr of
476 let code = squashed_instr ++ w_spills ++ reverse r_spills
477 ++ clobber_saves ++ new_instrs
479 -- pprTrace "patched-code" ((vcat $ map (docToSDoc . pprInstr) code)) $ do
480 -- pprTrace "pached-fixup" ((ppr fixup_blocks)) $ do
482 return (code, fixup_blocks)
486 -- -----------------------------------------------------------------------------
489 releaseRegs :: [Reg] -> RegM FreeRegs ()
490 releaseRegs regs = do
495 loop _ free _ | free `seq` False = undefined
496 loop assig free [] = do setAssigR assig; setFreeRegsR free; return ()
497 loop assig free (RegReal rr : rs) = loop assig (releaseReg rr free) rs
498 loop assig free (r:rs) =
499 case lookupUFM assig r of
500 Just (InBoth real _) -> loop (delFromUFM assig r) (releaseReg real free) rs
501 Just (InReg real) -> loop (delFromUFM assig r) (releaseReg real free) rs
502 _other -> loop (delFromUFM assig r) free rs
505 -- -----------------------------------------------------------------------------
506 -- Clobber real registers
508 -- For each temp in a register that is going to be clobbered:
509 -- - if the temp dies after this instruction, do nothing
510 -- - otherwise, put it somewhere safe (another reg if possible,
511 -- otherwise spill and record InBoth in the assignment).
512 -- - for allocateRegs on the temps *read*,
513 -- - clobbered regs are allocatable.
515 -- for allocateRegs on the temps *written*,
516 -- - clobbered regs are not allocatable.
518 -- TODO: instead of spilling, try to copy clobbered
519 -- temps to another register if possible.
524 :: (Outputable instr, Instruction instr)
525 => [RealReg] -- real registers clobbered by this instruction
526 -> [Reg] -- registers which are no longer live after this insn
527 -> RegM FreeRegs [instr] -- return: instructions to spill any temps that will
530 saveClobberedTemps [] _
533 saveClobberedTemps clobbered dying
538 | (temp, InReg reg) <- ufmToList assig
539 , any (realRegsAlias reg) clobbered
540 , temp `notElem` map getUnique dying ]
542 (instrs,assig') <- clobber assig [] to_spill
547 clobber assig instrs []
548 = return (instrs, assig)
550 clobber assig instrs ((temp, reg) : rest)
552 (spill, slot) <- spillR (RegReal reg) temp
554 -- record why this reg was spilled for profiling
555 recordSpill (SpillClobber temp)
557 let new_assign = addToUFM assig temp (InBoth reg slot)
559 clobber new_assign (spill : instrs) rest
563 -- | Mark all these real regs as allocated,
564 -- and kick out their vreg assignments.
566 clobberRegs :: [RealReg] -> RegM FreeRegs ()
570 clobberRegs clobbered
572 freeregs <- getFreeRegsR
573 setFreeRegsR $! foldr allocateReg freeregs clobbered
576 setAssigR $! clobber assig (ufmToList assig)
579 -- if the temp was InReg and clobbered, then we will have
580 -- saved it in saveClobberedTemps above. So the only case
581 -- we have to worry about here is InBoth. Note that this
582 -- also catches temps which were loaded up during allocation
583 -- of read registers, not just those saved in saveClobberedTemps.
588 clobber assig ((temp, InBoth reg slot) : rest)
589 | any (realRegsAlias reg) clobbered
590 = clobber (addToUFM assig temp (InMem slot)) rest
592 clobber assig (_:rest)
595 -- -----------------------------------------------------------------------------
596 -- allocateRegsAndSpill
598 -- Why are we performing a spill?
599 data SpillLoc = ReadMem StackSlot -- reading from register only in memory
600 | WriteNew -- writing to a new variable
601 | WriteMem -- writing to register only in memory
602 -- Note that ReadNew is not valid, since you don't want to be reading
603 -- from an uninitialized register. We also don't need the location of
604 -- the register in memory, since that will be invalidated by the write.
605 -- Technically, we could coalesce WriteNew and WriteMem into a single
606 -- entry as well. -- EZY
608 -- This function does several things:
609 -- For each temporary referred to by this instruction,
610 -- we allocate a real register (spilling another temporary if necessary).
611 -- We load the temporary up from memory if necessary.
612 -- We also update the register assignment in the process, and
613 -- the list of free registers and free stack slots.
616 :: (Outputable instr, Instruction instr)
617 => Bool -- True <=> reading (load up spilled regs)
618 -> [VirtualReg] -- don't push these out
619 -> [instr] -- spill insns
620 -> [RealReg] -- real registers allocated (accum.)
621 -> [VirtualReg] -- temps to allocate
622 -> RegM FreeRegs ( [instr] , [RealReg])
624 allocateRegsAndSpill _ _ spills alloc []
625 = return (spills, reverse alloc)
627 allocateRegsAndSpill reading keep spills alloc (r:rs)
628 = do assig <- getAssigR
629 let doSpill = allocRegsAndSpill_spill reading keep spills alloc r rs assig
630 case lookupUFM assig r of
631 -- case (1a): already in a register
632 Just (InReg my_reg) ->
633 allocateRegsAndSpill reading keep spills (my_reg:alloc) rs
635 -- case (1b): already in a register (and memory)
636 -- NB1. if we're writing this register, update its assignment to be
637 -- InReg, because the memory value is no longer valid.
638 -- NB2. This is why we must process written registers here, even if they
639 -- are also read by the same instruction.
640 Just (InBoth my_reg _)
641 -> do when (not reading) (setAssigR (addToUFM assig r (InReg my_reg)))
642 allocateRegsAndSpill reading keep spills (my_reg:alloc) rs
644 -- Not already in a register, so we need to find a free one...
645 Just (InMem slot) | reading -> doSpill (ReadMem slot)
646 | otherwise -> doSpill WriteMem
648 -- pprPanic "allocateRegsAndSpill: Cannot read from uninitialized register" (ppr r)
649 -- ToDo: This case should be a panic, but we
650 -- sometimes see an unreachable basic block which
651 -- triggers this because the register allocator
652 -- will start with an empty assignment.
655 | otherwise -> doSpill WriteNew
658 -- reading is redundant with reason, but we keep it around because it's
659 -- convenient and it maintains the recursive structure of the allocator. -- EZY
660 allocRegsAndSpill_spill :: (Instruction instr, Outputable instr)
669 -> RegM FreeRegs ([instr], [RealReg])
670 allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc
672 freeRegs <- getFreeRegsR
673 let freeRegs_thisClass = getFreeRegs (classOfVirtualReg r) freeRegs
675 case freeRegs_thisClass of
677 -- case (2): we have a free register
679 do spills' <- loadTemp r spill_loc my_reg spills
681 setAssigR (addToUFM assig r $! newLocation spill_loc my_reg)
682 setFreeRegsR $ allocateReg my_reg freeRegs
684 allocateRegsAndSpill reading keep spills' (my_reg : alloc) rs
687 -- case (3): we need to push something out to free up a register
689 do let keep' = map getUnique keep
691 -- the vregs we could kick out that are already in a slot
692 let candidates_inBoth
694 | (temp, InBoth reg mem) <- ufmToList assig
695 , temp `notElem` keep'
696 , targetClassOfRealReg reg == classOfVirtualReg r ]
698 -- the vregs we could kick out that are only in a reg
699 -- this would require writing the reg to a new slot before using it.
702 | (temp, InReg reg) <- ufmToList assig
703 , temp `notElem` keep'
704 , targetClassOfRealReg reg == classOfVirtualReg r ]
708 -- we have a temporary that is in both register and mem,
709 -- just free up its register for use.
710 | (temp, my_reg, slot) : _ <- candidates_inBoth
711 = do spills' <- loadTemp r spill_loc my_reg spills
712 let assig1 = addToUFM assig temp (InMem slot)
713 let assig2 = addToUFM assig1 r $! newLocation spill_loc my_reg
716 allocateRegsAndSpill reading keep spills' (my_reg:alloc) rs
718 -- otherwise, we need to spill a temporary that currently
719 -- resides in a register.
720 | (temp_to_push_out, (my_reg :: RealReg)) : _
723 (spill_insn, slot) <- spillR (RegReal my_reg) temp_to_push_out
724 let spill_store = (if reading then id else reverse)
725 [ -- COMMENT (fsLit "spill alloc")
728 -- record that this temp was spilled
729 recordSpill (SpillAlloc temp_to_push_out)
731 -- update the register assignment
732 let assig1 = addToUFM assig temp_to_push_out (InMem slot)
733 let assig2 = addToUFM assig1 r $! newLocation spill_loc my_reg
736 -- if need be, load up a spilled temp into the reg we've just freed up.
737 spills' <- loadTemp r spill_loc my_reg spills
739 allocateRegsAndSpill reading keep
740 (spill_store ++ spills')
744 -- there wasn't anything to spill, so we're screwed.
746 = pprPanic ("RegAllocLinear.allocRegsAndSpill: no spill candidates\n")
748 [ text "allocating vreg: " <> text (show r)
749 , text "assignment: " <> text (show $ ufmToList assig)
750 , text "freeRegs: " <> text (show freeRegs)
751 , text "initFreeRegs: " <> text (show initFreeRegs) ]
756 -- | Calculate a new location after a register has been loaded.
757 newLocation :: SpillLoc -> RealReg -> Loc
758 -- if the tmp was read from a slot, then now its in a reg as well
759 newLocation (ReadMem slot) my_reg = InBoth my_reg slot
760 -- writes will always result in only the register being available
761 newLocation _ my_reg = InReg my_reg
763 -- | Load up a spilled temporary if we need to (read from memory).
765 :: (Outputable instr, Instruction instr)
766 => VirtualReg -- the temp being loaded
767 -> SpillLoc -- the current location of this temp
768 -> RealReg -- the hreg to load the temp into
770 -> RegM FreeRegs [instr]
772 loadTemp vreg (ReadMem slot) hreg spills
774 insn <- loadR (RegReal hreg) slot
775 recordSpill (SpillLoad $ getUnique vreg)
776 return $ {- COMMENT (fsLit "spill load") : -} insn : spills
778 loadTemp _ _ _ spills =