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 [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 [[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 [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 ()
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.
301 -> RegM ( [instr] -- instructions after register allocation
302 , [NatBasicBlock instr]) -- fresh blocks of fixup code.
305 linearRA _ accInstr accFixup _ []
307 ( reverse accInstr -- instrs need to be returned in the correct order.
308 , accFixup) -- it doesn't matter what order the fixup blocks are returned in.
311 linearRA block_live accInstr accFixups id (instr:instrs)
313 (accInstr', new_fixups)
314 <- raInsn block_live accInstr id instr
316 linearRA block_live accInstr' (new_fixups ++ accFixups) id instrs
319 -- | Do allocation for a single instruction.
321 :: (Outputable instr, Instruction instr)
322 => BlockMap RegSet -- ^ map of what vregs are love on entry to each block.
323 -> [instr] -- ^ accumulator for instructions already processed.
324 -> BlockId -- ^ the id of the current block, for debugging
325 -> LiveInstr instr -- ^ the instr to have its regs allocated, with liveness info.
327 ( [instr] -- new instructions
328 , [NatBasicBlock instr]) -- extra fixup blocks
330 raInsn _ new_instrs _ (LiveInstr ii Nothing)
331 | Just n <- takeDeltaInstr ii
333 return (new_instrs, [])
335 raInsn _ new_instrs _ (LiveInstr ii Nothing)
337 = return (new_instrs, [])
340 raInsn block_live new_instrs id (LiveInstr (Instr instr) (Just live))
344 -- If we have a reg->reg move between virtual registers, where the
345 -- src register is not live after this instruction, and the dst
346 -- register does not already have an assignment,
347 -- and the source register is assigned to a register, not to a spill slot,
348 -- then we can eliminate the instruction.
349 -- (we can't eliminate it if the source register is on the stack, because
350 -- we do not want to use one spill slot for different virtual registers)
351 case takeRegRegMoveInstr instr of
352 Just (src,dst) | src `elementOfUniqSet` (liveDieRead live),
354 not (dst `elemUFM` assig),
355 Just (InReg _) <- (lookupUFM assig src) -> do
357 (RegReal rr) -> setAssigR (addToUFM assig dst (InReg rr))
358 -- if src is a fixed reg, then we just map dest to this
359 -- reg in the assignment. src must be an allocatable reg,
360 -- otherwise it wouldn't be in r_dying.
361 _virt -> case lookupUFM assig src of
362 Nothing -> panic "raInsn"
364 setAssigR (addToUFM (delFromUFM assig src) dst loc)
366 -- we have eliminated this instruction
368 freeregs <- getFreeRegsR
370 pprTrace "raInsn" (text "ELIMINATED: " <> docToSDoc (pprInstr instr)
371 $$ ppr r_dying <+> ppr w_dying $$ text (show freeregs) $$ ppr assig) $ do
373 return (new_instrs, [])
375 _ -> genRaInsn block_live new_instrs id instr
376 (uniqSetToList $ liveDieRead live)
377 (uniqSetToList $ liveDieWrite live)
381 = pprPanic "raInsn" (text "no match for:" <> ppr instr)
384 genRaInsn :: (Instruction instr, Outputable instr)
391 -> RegM ([instr], [NatBasicBlock instr])
393 genRaInsn block_live new_instrs block_id instr r_dying w_dying =
394 case regUsageOfInstr instr of { RU read written ->
396 let real_written = [ rr | (RegReal rr) <- written ]
397 let virt_written = [ vr | (RegVirtual vr) <- written ]
399 -- we don't need to do anything with real registers that are
400 -- only read by this instr. (the list is typically ~2 elements,
401 -- so using nub isn't a problem).
402 let virt_read = nub [ vr | (RegVirtual vr) <- read ]
404 -- (a) save any temporaries which will be clobbered by this instruction
405 clobber_saves <- saveClobberedTemps real_written r_dying
408 {- freeregs <- getFreeRegsR
412 $$ text "r_dying = " <+> ppr r_dying
413 $$ text "w_dying = " <+> ppr w_dying
414 $$ text "virt_read = " <+> ppr virt_read
415 $$ text "virt_written = " <+> ppr virt_written
416 $$ text "freeregs = " <+> text (show freeregs)
417 $$ text "assig = " <+> ppr assig)
421 -- (b), (c) allocate real regs for all regs read by this instruction.
422 (r_spills, r_allocd) <-
423 allocateRegsAndSpill True{-reading-} virt_read [] [] virt_read
425 -- (d) Update block map for new destinations
426 -- NB. do this before removing dead regs from the assignment, because
427 -- these dead regs might in fact be live in the jump targets (they're
428 -- only dead in the code that follows in the current basic block).
429 (fixup_blocks, adjusted_instr)
430 <- joinToTargets block_live block_id instr
432 -- (e) Delete all register assignments for temps which are read
433 -- (only) and die here. Update the free register list.
436 -- (f) Mark regs which are clobbered as unallocatable
437 clobberRegs real_written
439 -- (g) Allocate registers for temporaries *written* (only)
440 (w_spills, w_allocd) <-
441 allocateRegsAndSpill False{-writing-} virt_written [] [] virt_written
443 -- (h) Release registers for temps which are written here and not
448 -- (i) Patch the instruction
452 | (t, r) <- zip virt_read r_allocd
453 ++ zip virt_written w_allocd ]
456 = patchRegsOfInstr adjusted_instr patchLookup
459 = case lookupUFM patch_map x of
464 -- (j) free up stack slots for dead spilled regs
465 -- TODO (can't be bothered right now)
467 -- erase reg->reg moves where the source and destination are the same.
468 -- If the src temp didn't die in this instr but happened to be allocated
469 -- to the same real reg as the destination, then we can erase the move anyway.
470 let squashed_instr = case takeRegRegMoveInstr patched_instr of
475 let code = squashed_instr ++ w_spills ++ reverse r_spills
476 ++ clobber_saves ++ new_instrs
478 -- pprTrace "patched-code" ((vcat $ map (docToSDoc . pprInstr) code)) $ do
479 -- pprTrace "pached-fixup" ((ppr fixup_blocks)) $ do
481 return (code, fixup_blocks)
485 -- -----------------------------------------------------------------------------
488 releaseRegs :: [Reg] -> RegM ()
489 releaseRegs regs = do
494 loop _ free _ | free `seq` False = undefined
495 loop assig free [] = do setAssigR assig; setFreeRegsR free; return ()
496 loop assig free (RegReal rr : rs) = loop assig (releaseReg rr free) rs
497 loop assig free (r:rs) =
498 case lookupUFM assig r of
499 Just (InBoth real _) -> loop (delFromUFM assig r) (releaseReg real free) rs
500 Just (InReg real) -> loop (delFromUFM assig r) (releaseReg real free) rs
501 _other -> loop (delFromUFM assig r) free rs
504 -- -----------------------------------------------------------------------------
505 -- Clobber real registers
507 -- For each temp in a register that is going to be clobbered:
508 -- - if the temp dies after this instruction, do nothing
509 -- - otherwise, put it somewhere safe (another reg if possible,
510 -- otherwise spill and record InBoth in the assignment).
511 -- - for allocateRegs on the temps *read*,
512 -- - clobbered regs are allocatable.
514 -- for allocateRegs on the temps *written*,
515 -- - clobbered regs are not allocatable.
517 -- TODO: instead of spilling, try to copy clobbered
518 -- temps to another register if possible.
523 :: (Outputable instr, Instruction instr)
524 => [RealReg] -- real registers clobbered by this instruction
525 -> [Reg] -- registers which are no longer live after this insn
526 -> RegM [instr] -- return: instructions to spill any temps that will
529 saveClobberedTemps [] _
532 saveClobberedTemps clobbered dying
537 | (temp, InReg reg) <- ufmToList assig
538 , any (realRegsAlias reg) clobbered
539 , temp `notElem` map getUnique dying ]
541 (instrs,assig') <- clobber assig [] to_spill
546 clobber assig instrs []
547 = return (instrs, assig)
549 clobber assig instrs ((temp, reg) : rest)
551 (spill, slot) <- spillR (RegReal reg) temp
553 -- record why this reg was spilled for profiling
554 recordSpill (SpillClobber temp)
556 let new_assign = addToUFM assig temp (InBoth reg slot)
558 clobber new_assign (spill : instrs) rest
562 -- | Mark all these real regs as allocated,
563 -- and kick out their vreg assignments.
565 clobberRegs :: [RealReg] -> RegM ()
569 clobberRegs clobbered
571 freeregs <- getFreeRegsR
572 setFreeRegsR $! foldr allocateReg freeregs clobbered
575 setAssigR $! clobber assig (ufmToList assig)
578 -- if the temp was InReg and clobbered, then we will have
579 -- saved it in saveClobberedTemps above. So the only case
580 -- we have to worry about here is InBoth. Note that this
581 -- also catches temps which were loaded up during allocation
582 -- of read registers, not just those saved in saveClobberedTemps.
587 clobber assig ((temp, InBoth reg slot) : rest)
588 | any (realRegsAlias reg) clobbered
589 = clobber (addToUFM assig temp (InMem slot)) rest
591 clobber assig (_:rest)
594 -- -----------------------------------------------------------------------------
595 -- allocateRegsAndSpill
597 -- Why are we performing a spill?
598 data SpillLoc = ReadMem StackSlot -- reading from register only in memory
599 | WriteNew -- writing to a new variable
600 | WriteMem -- writing to register only in memory
601 -- Note that ReadNew is not valid, since you don't want to be reading
602 -- from an uninitialized register. We also don't need the location of
603 -- the register in memory, since that will be invalidated by the write.
604 -- Technically, we could coalesce WriteNew and WriteMem into a single
605 -- entry as well. -- EZY
607 -- This function does several things:
608 -- For each temporary referred to by this instruction,
609 -- we allocate a real register (spilling another temporary if necessary).
610 -- We load the temporary up from memory if necessary.
611 -- We also update the register assignment in the process, and
612 -- the list of free registers and free stack slots.
615 :: (Outputable instr, Instruction instr)
616 => Bool -- True <=> reading (load up spilled regs)
617 -> [VirtualReg] -- don't push these out
618 -> [instr] -- spill insns
619 -> [RealReg] -- real registers allocated (accum.)
620 -> [VirtualReg] -- temps to allocate
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 ([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
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 =