NCG: Refactor LiveCmmTop to hold a list of SCCs instead of abusing ListGraph
[ghc-hetmet.git] / compiler / nativeGen / RegAlloc / Linear / Main.hs
1 {-# OPTIONS -fno-warn-missing-signatures #-}
2 -----------------------------------------------------------------------------
3 --
4 -- The register allocator
5 --
6 -- (c) The University of Glasgow 2004
7 --
8 -----------------------------------------------------------------------------
9
10 {-
11 The algorithm is roughly:
12  
13   1) Compute strongly connected components of the basic block list.
14
15   2) Compute liveness (mapping from pseudo register to
16      point(s) of death?).
17
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.
25
26      For each instruction:
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?)
35
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
39                   the list is empty:
40                   - Find a temporary to spill.  Pick one that is
41                     not used in this instruction (ToDo: not
42                     used for a while...)
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).
48
49         (c) Update the current assignment
50
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.
55               else,
56                 Update the block id->assignment mapping with the current
57                 assignment.
58
59         (e) Delete all register assignments for temps which are read
60             (only) and die here.  Update the free register list.
61
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).
65
66         (g) For each temporary *written* by this instruction:
67             Allocate a real register as for (b), spilling something
68             else if necessary.
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.
72
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.
76
77         (i) Rewrite the instruction with the new mapping.
78
79         (j) For each spilled reg known to be now dead, re-add its stack slot
80             to the free list.
81
82 -}
83
84 module RegAlloc.Linear.Main (
85         regAlloc,
86         module  RegAlloc.Linear.Base,
87         module  RegAlloc.Linear.Stats
88   ) where
89
90 #include "HsVersions.h"
91
92
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 TargetReg
100 import RegAlloc.Liveness
101 import Instruction
102 import Reg
103
104 import BlockId
105 import Cmm hiding (RegSet)
106
107 import Digraph
108 import Unique
109 import UniqSet
110 import UniqFM
111 import UniqSupply
112 import Outputable
113
114 import Data.Maybe
115 import Data.List
116 import Control.Monad
117
118 #include "../includes/stg/MachRegs.h"
119
120
121 -- -----------------------------------------------------------------------------
122 -- Top level of the register allocator
123
124 -- Allocate registers
125 regAlloc 
126         :: (Outputable instr, Instruction instr)
127         => LiveCmmTop instr
128         -> UniqSM (NatCmmTop instr, Maybe RegAllocStats)
129
130 regAlloc (CmmData sec d) 
131         = return
132                 ( CmmData sec d
133                 , Nothing )
134         
135 regAlloc (CmmProc (LiveInfo info _ _) lbl params [])
136         = return ( CmmProc info lbl params (ListGraph [])
137                  , Nothing )
138         
139 regAlloc (CmmProc static lbl params sccs)
140         | LiveInfo info (Just first_id) (Just block_live)       <- static
141         = do    
142                 -- do register allocation on each component.
143                 (final_blocks, stats)
144                         <- linearRegAlloc first_id block_live sccs
145
146                 -- make sure the block that was first in the input list
147                 --      stays at the front of the output
148                 let ((first':_), rest')
149                                 = partition ((== first_id) . blockId) final_blocks
150
151                 return  ( CmmProc info lbl params (ListGraph (first' : rest'))
152                         , Just stats)
153         
154 -- bogus. to make non-exhaustive match warning go away.
155 regAlloc (CmmProc _ _ _ _)
156         = panic "RegAllocLinear.regAlloc: no match"
157
158
159 -- -----------------------------------------------------------------------------
160 -- Linear sweep to allocate registers
161
162
163 -- | Do register allocation on some basic blocks.
164 --   But be careful to allocate a block in an SCC only if it has
165 --   an entry in the block map or it is the first block.
166 --
167 linearRegAlloc
168         :: (Outputable instr, Instruction instr)
169         => BlockId                      -- ^ the first block
170         -> BlockMap RegSet              -- ^ live regs on entry to each basic block
171         -> [SCC (LiveBasicBlock instr)] -- ^ instructions annotated with "deaths"
172         -> UniqSM ([NatBasicBlock instr], RegAllocStats)
173
174 linearRegAlloc first_id block_live sccs
175  = do   us      <- getUs
176         let (_, _, stats, blocks) =
177                 runR emptyBlockMap initFreeRegs emptyRegMap emptyStackMap us
178                         $ linearRA_SCCs first_id block_live [] sccs
179
180         return  (blocks, stats)
181
182 linearRA_SCCs _ _ blocksAcc []
183         = return $ reverse blocksAcc
184
185 linearRA_SCCs first_id block_live blocksAcc (AcyclicSCC block : sccs) 
186  = do   blocks' <- processBlock block_live block
187         linearRA_SCCs first_id block_live 
188                 ((reverse blocks') ++ blocksAcc)
189                 sccs
190
191 linearRA_SCCs first_id block_live blocksAcc (CyclicSCC blocks : sccs) 
192  = do
193         blockss' <- process first_id block_live blocks [] (return [])
194         linearRA_SCCs first_id block_live
195                 (reverse (concat blockss') ++ blocksAcc)
196                 sccs
197
198 {- from John Dias's patch 2008/10/16:
199    The linear-scan allocator sometimes allocates a block
200    before allocating one of its predecessors, which could lead to 
201    inconsistent allocations. Make it so a block is only allocated
202    if a predecessor has set the "incoming" assignments for the block, or
203    if it's the procedure's entry block.
204
205    BL 2009/02: Careful. If the assignment for a block doesn't get set for
206    some reason then this function will loop. We should probably do some 
207    more sanity checking to guard against this eventuality.
208 -}
209                 
210 process _ _ [] []         accum 
211         = return $ reverse accum
212
213 process first_id block_live [] next_round accum 
214         = process first_id block_live next_round [] accum
215
216 process first_id block_live (b@(BasicBlock id _) : blocks) next_round accum 
217  = do   
218         block_assig <- getBlockAssigR
219
220         if isJust (lookupBlockEnv block_assig id) 
221              || id == first_id
222          then do 
223                 b'  <- processBlock block_live b
224                 process first_id block_live blocks next_round (b' : accum)
225
226          else   process first_id block_live blocks (b : next_round) accum
227
228
229 -- | Do register allocation on this basic block
230 --
231 processBlock
232         :: (Outputable instr, Instruction instr)
233         => BlockMap RegSet              -- ^ live regs on entry to each basic block
234         -> LiveBasicBlock instr         -- ^ block to do register allocation on
235         -> RegM [NatBasicBlock instr]   -- ^ block with registers allocated
236
237 processBlock block_live (BasicBlock id instrs)
238  = do   initBlock id
239         (instrs', fixups)
240                 <- linearRA block_live [] [] id instrs
241         return  $ BasicBlock id instrs' : fixups
242
243
244 -- | Load the freeregs and current reg assignment into the RegM state
245 --      for the basic block with this BlockId.
246 initBlock :: BlockId -> RegM ()
247 initBlock id
248  = do   block_assig     <- getBlockAssigR
249         case lookupBlockEnv block_assig id of
250                 -- no prior info about this block: assume everything is
251                 -- free and the assignment is empty.
252                 Nothing
253                  -> do  -- pprTrace "initFreeRegs" (text $ show initFreeRegs) (return ())
254                  
255                         setFreeRegsR    initFreeRegs
256                         setAssigR       emptyRegMap
257
258                 -- load info about register assignments leading into this block.
259                 Just (freeregs, assig)
260                  -> do  setFreeRegsR    freeregs
261                         setAssigR       assig
262
263
264 -- | Do allocation for a sequence of instructions.
265 linearRA
266         :: (Outputable instr, Instruction instr)
267         => BlockMap RegSet                      -- ^ map of what vregs are live on entry to each block.
268         -> [instr]                              -- ^ accumulator for instructions already processed.
269         -> [NatBasicBlock instr]                -- ^ accumulator for blocks of fixup code.
270         -> BlockId                              -- ^ id of the current block, for debugging.
271         -> [LiveInstr instr]                    -- ^ liveness annotated instructions in this block.
272
273         -> RegM ( [instr]                       --   instructions after register allocation
274                 , [NatBasicBlock instr])        --   fresh blocks of fixup code.
275
276
277 linearRA _          accInstr accFixup _ []
278         = return 
279                 ( reverse accInstr              -- instrs need to be returned in the correct order.
280                 , accFixup)                     -- it doesn't matter what order the fixup blocks are returned in.
281
282
283 linearRA block_live accInstr accFixups id (instr:instrs)
284  = do
285         (accInstr', new_fixups) 
286                 <- raInsn block_live accInstr id instr
287
288         linearRA block_live accInstr' (new_fixups ++ accFixups) id instrs
289
290
291 -- | Do allocation for a single instruction.
292 raInsn  
293         :: (Outputable instr, Instruction instr)
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 instr                      -- ^ the instr to have its regs allocated, with liveness info.
298         -> RegM 
299                 ( [instr]                       -- new instructions
300                 , [NatBasicBlock instr])        -- extra fixup blocks
301
302 raInsn _     new_instrs _ (Instr ii Nothing)  
303         | Just n        <- takeDeltaInstr ii
304         = do    setDeltaR n
305                 return (new_instrs, [])
306
307 raInsn _     new_instrs _ (Instr ii Nothing)
308         | isMetaInstr ii
309         = return (new_instrs, [])
310
311
312 raInsn block_live new_instrs id (Instr instr (Just live))
313  = do
314     assig    <- getAssigR
315
316     -- If we have a reg->reg move between virtual registers, where the
317     -- src register is not live after this instruction, and the dst
318     -- register does not already have an assignment,
319     -- and the source register is assigned to a register, not to a spill slot,
320     -- then we can eliminate the instruction.
321     -- (we can't eliminitate it if the source register is on the stack, because
322     --  we do not want to use one spill slot for different virtual registers)
323     case takeRegRegMoveInstr instr of
324         Just (src,dst)  | src `elementOfUniqSet` (liveDieRead live), 
325                           isVirtualReg dst,
326                           not (dst `elemUFM` assig),
327                           Just (InReg _) <- (lookupUFM assig src) -> do
328            case src of
329               (RegReal rr) -> setAssigR (addToUFM assig dst (InReg rr))
330                 -- if src is a fixed reg, then we just map dest to this
331                 -- reg in the assignment.  src must be an allocatable reg,
332                 -- otherwise it wouldn't be in r_dying.
333               _virt -> case lookupUFM assig src of
334                          Nothing -> panic "raInsn"
335                          Just loc ->
336                            setAssigR (addToUFM (delFromUFM assig src) dst loc)
337
338            -- we have eliminated this instruction
339           {-
340           freeregs <- getFreeRegsR
341           assig <- getAssigR
342           pprTrace "raInsn" (text "ELIMINATED: " <> docToSDoc (pprInstr instr) 
343                         $$ ppr r_dying <+> ppr w_dying $$ text (show freeregs) $$ ppr assig) $ do
344           -}
345            return (new_instrs, [])
346
347         _ -> genRaInsn block_live new_instrs id instr 
348                         (uniqSetToList $ liveDieRead live) 
349                         (uniqSetToList $ liveDieWrite live)
350
351
352 raInsn _ _ _ instr
353         = pprPanic "raInsn" (text "no match for:" <> ppr instr)
354
355
356
357
358 genRaInsn block_live new_instrs block_id instr r_dying w_dying =
359     case regUsageOfInstr instr              of { RU read written ->
360     do
361     let real_written    = [ rr  | (RegReal     rr) <- written ]
362     let virt_written    = [ vr  | (RegVirtual  vr) <- written ]
363
364     -- we don't need to do anything with real registers that are
365     -- only read by this instr.  (the list is typically ~2 elements,
366     -- so using nub isn't a problem).
367     let virt_read       = nub [ vr      | (RegVirtual vr) <- read ]
368
369     -- (a) save any temporaries which will be clobbered by this instruction
370     clobber_saves       <- saveClobberedTemps real_written r_dying
371
372     -- debugging
373 {-  freeregs <- getFreeRegsR
374     assig    <- getAssigR
375     pprTrace "genRaInsn" 
376         (ppr instr 
377                 $$ text "r_dying      = " <+> ppr r_dying 
378                 $$ text "w_dying      = " <+> ppr w_dying 
379                 $$ text "virt_read    = " <+> ppr virt_read 
380                 $$ text "virt_written = " <+> ppr virt_written 
381                 $$ text "freeregs     = " <+> text (show freeregs)
382                 $$ text "assig        = " <+> ppr assig)
383         $ do
384 -}
385
386     -- (b), (c) allocate real regs for all regs read by this instruction.
387     (r_spills, r_allocd) <- 
388         allocateRegsAndSpill True{-reading-} virt_read [] [] virt_read
389
390     -- (d) Update block map for new destinations
391     -- NB. do this before removing dead regs from the assignment, because
392     -- these dead regs might in fact be live in the jump targets (they're
393     -- only dead in the code that follows in the current basic block).
394     (fixup_blocks, adjusted_instr)
395         <- joinToTargets block_live block_id instr
396
397     -- (e) Delete all register assignments for temps which are read
398     --     (only) and die here.  Update the free register list.
399     releaseRegs r_dying
400
401     -- (f) Mark regs which are clobbered as unallocatable
402     clobberRegs real_written
403
404     -- (g) Allocate registers for temporaries *written* (only)
405     (w_spills, w_allocd) <- 
406         allocateRegsAndSpill False{-writing-} virt_written [] [] virt_written
407
408     -- (h) Release registers for temps which are written here and not
409     -- used again.
410     releaseRegs w_dying
411
412     let
413         -- (i) Patch the instruction
414         patch_map 
415                 = listToUFM
416                         [ (t, RegReal r) 
417                                 | (t, r) <- zip virt_read    r_allocd
418                                          ++ zip virt_written w_allocd ]
419
420         patched_instr 
421                 = patchRegsOfInstr adjusted_instr patchLookup
422
423         patchLookup x 
424                 = case lookupUFM patch_map x of
425                         Nothing -> x
426                         Just y  -> y
427
428
429     -- (j) free up stack slots for dead spilled regs
430     -- TODO (can't be bothered right now)
431
432     -- erase reg->reg moves where the source and destination are the same.
433     --  If the src temp didn't die in this instr but happened to be allocated
434     --  to the same real reg as the destination, then we can erase the move anyway.
435     let squashed_instr  = case takeRegRegMoveInstr patched_instr of
436                                 Just (src, dst)
437                                  | src == dst   -> []
438                                 _               -> [patched_instr]
439
440     let code = squashed_instr ++ w_spills ++ reverse r_spills
441                 ++ clobber_saves ++ new_instrs
442
443 --    pprTrace "patched-code" ((vcat $ map (docToSDoc . pprInstr) code)) $ do
444 --    pprTrace "pached-fixup" ((ppr fixup_blocks)) $ do
445
446     return (code, fixup_blocks)
447
448   }
449
450 -- -----------------------------------------------------------------------------
451 -- releaseRegs
452
453 releaseRegs regs = do
454   assig <- getAssigR
455   free <- getFreeRegsR
456   loop assig free regs 
457  where
458   loop _     free _ | free `seq` False = undefined
459   loop assig free [] = do setAssigR assig; setFreeRegsR free; return ()
460   loop assig free (RegReal rr : rs) = loop assig (releaseReg rr free) rs
461   loop assig free (r:rs) = 
462      case lookupUFM assig r of
463         Just (InBoth real _) -> loop (delFromUFM assig r) (releaseReg real free) rs
464         Just (InReg real) -> loop (delFromUFM assig r) (releaseReg real free) rs
465         _other            -> loop (delFromUFM assig r) free rs
466
467
468 -- -----------------------------------------------------------------------------
469 -- Clobber real registers
470
471 -- For each temp in a register that is going to be clobbered:
472 --      - if the temp dies after this instruction, do nothing
473 --      - otherwise, put it somewhere safe (another reg if possible,
474 --              otherwise spill and record InBoth in the assignment).
475 --      - for allocateRegs on the temps *read*,
476 --      - clobbered regs are allocatable.
477 --
478 --      for allocateRegs on the temps *written*, 
479 --        - clobbered regs are not allocatable.
480 --
481 --      TODO:   instead of spilling, try to copy clobbered
482 --              temps to another register if possible.
483 --
484
485
486 saveClobberedTemps
487         :: Instruction instr
488         => [RealReg]            -- real registers clobbered by this instruction
489         -> [Reg]                -- registers which are no longer live after this insn
490         -> RegM [instr]         -- return: instructions to spill any temps that will
491                                 -- be clobbered.
492
493 saveClobberedTemps [] _ 
494         = return []
495
496 saveClobberedTemps clobbered dying 
497  = do
498         assig   <- getAssigR
499         let to_spill  
500                 = [ (temp,reg) 
501                         | (temp, InReg reg) <- ufmToList assig
502                         , any (realRegsAlias reg) clobbered
503                         , temp `notElem` map getUnique dying  ]
504
505         (instrs,assig') <- clobber assig [] to_spill
506         setAssigR assig'
507         return instrs
508
509    where
510         clobber assig instrs [] 
511                 = return (instrs, assig)
512
513         clobber assig instrs ((temp, reg) : rest)
514          = do
515                 (spill, slot)   <- spillR (RegReal reg) temp
516
517                 -- record why this reg was spilled for profiling
518                 recordSpill (SpillClobber temp)
519
520                 let new_assign  = addToUFM assig temp (InBoth reg slot)
521
522                 clobber new_assign (spill : instrs) rest
523
524
525
526 -- | Mark all these regal regs as allocated,
527 --      and kick out their vreg assignments.
528 --
529 clobberRegs :: [RealReg] -> RegM ()
530 clobberRegs []  
531         = return ()
532
533 clobberRegs clobbered 
534  = do
535         freeregs        <- getFreeRegsR
536         setFreeRegsR $! foldr allocateReg freeregs clobbered
537
538         assig           <- getAssigR
539         setAssigR $! clobber assig (ufmToList assig)
540
541    where
542         -- if the temp was InReg and clobbered, then we will have
543         -- saved it in saveClobberedTemps above.  So the only case
544         -- we have to worry about here is InBoth.  Note that this
545         -- also catches temps which were loaded up during allocation
546         -- of read registers, not just those saved in saveClobberedTemps.
547
548         clobber assig [] 
549                 = assig
550
551         clobber assig ((temp, InBoth reg slot) : rest)
552                 | any (realRegsAlias reg) clobbered
553                 = clobber (addToUFM assig temp (InMem slot)) rest
554  
555         clobber assig (_:rest)
556                 = clobber assig rest 
557
558 -- -----------------------------------------------------------------------------
559 -- allocateRegsAndSpill
560
561 -- This function does several things:
562 --   For each temporary referred to by this instruction,
563 --   we allocate a real register (spilling another temporary if necessary).
564 --   We load the temporary up from memory if necessary.
565 --   We also update the register assignment in the process, and
566 --   the list of free registers and free stack slots.
567
568 allocateRegsAndSpill
569         :: Instruction instr
570         => Bool                 -- True <=> reading (load up spilled regs)
571         -> [VirtualReg]         -- don't push these out
572         -> [instr]              -- spill insns
573         -> [RealReg]            -- real registers allocated (accum.)
574         -> [VirtualReg]         -- temps to allocate
575         -> RegM ( [instr]
576                 , [RealReg])
577
578 allocateRegsAndSpill _       _    spills alloc []
579         = return (spills, reverse alloc)
580
581 allocateRegsAndSpill reading keep spills alloc (r:rs) 
582  = do   assig <- getAssigR
583         case lookupUFM assig r of
584                 -- case (1a): already in a register
585                 Just (InReg my_reg) ->
586                         allocateRegsAndSpill reading keep spills (my_reg:alloc) rs
587
588                 -- case (1b): already in a register (and memory)
589                 -- NB1. if we're writing this register, update its assignemnt to be
590                 -- InReg, because the memory value is no longer valid.
591                 -- NB2. This is why we must process written registers here, even if they
592                 -- are also read by the same instruction.
593                 Just (InBoth my_reg _) 
594                  -> do  when (not reading) (setAssigR (addToUFM assig r (InReg my_reg)))
595                         allocateRegsAndSpill reading keep spills (my_reg:alloc) rs
596
597                 -- Not already in a register, so we need to find a free one...
598                 loc -> allocRegsAndSpill_spill reading keep spills alloc r rs loc assig
599         
600
601 allocRegsAndSpill_spill reading keep spills alloc r rs loc assig
602  = do
603         freeRegs                <- getFreeRegsR
604         let freeRegs_thisClass  = getFreeRegs (classOfVirtualReg r) freeRegs
605
606         case freeRegs_thisClass of
607
608          -- case (2): we have a free register
609          (my_reg : _) -> 
610            do   spills'   <- loadTemp reading r loc my_reg spills
611
612                 let new_loc 
613                         -- if the tmp was in a slot, then now its in a reg as well
614                         | Just (InMem slot) <- loc
615                         , reading 
616                         = InBoth my_reg slot
617
618                         -- tmp has been loaded into a reg
619                         | otherwise
620                         = InReg my_reg
621
622                 setAssigR       (addToUFM assig r $! new_loc)
623                 setFreeRegsR $  allocateReg my_reg freeRegs
624
625                 allocateRegsAndSpill reading keep spills' (my_reg : alloc) rs
626
627
628           -- case (3): we need to push something out to free up a register
629          [] -> 
630            do   let keep' = map getUnique keep
631
632                 -- the vregs we could kick out that are already in a slot
633                 let candidates_inBoth
634                         = [ (temp, reg, mem)
635                                 | (temp, InBoth reg mem) <- ufmToList assig
636                                 , temp `notElem` keep'
637                                 , targetClassOfRealReg reg == classOfVirtualReg r ]
638
639                 -- the vregs we could kick out that are only in a reg
640                 --      this would require writing the reg to a new slot before using it.
641                 let candidates_inReg
642                         = [ (temp, reg)
643                                 | (temp, InReg reg)     <- ufmToList assig
644                                 , temp `notElem` keep'
645                                 , targetClassOfRealReg reg == classOfVirtualReg r ]
646
647                 let result
648
649                         -- we have a temporary that is in both register and mem,
650                         -- just free up its register for use.
651                         | (temp, my_reg, slot) : _      <- candidates_inBoth
652                         = do    spills' <- loadTemp reading r loc my_reg spills
653                                 let assig1  = addToUFM assig temp (InMem slot)
654                                 let assig2  = addToUFM assig1 r   (InReg my_reg)
655
656                                 setAssigR assig2
657                                 allocateRegsAndSpill reading keep spills' (my_reg:alloc) rs
658
659                         -- otherwise, we need to spill a temporary that currently
660                         -- resides in a register.
661                         | (temp_to_push_out, (my_reg :: RealReg)) : _
662                                         <- candidates_inReg
663                         = do
664                                 (spill_insn, slot) <- spillR (RegReal my_reg) temp_to_push_out
665                                 let spill_store  = (if reading then id else reverse)
666                                                         [ -- COMMENT (fsLit "spill alloc") 
667                                                            spill_insn ]
668
669                                 -- record that this temp was spilled
670                                 recordSpill (SpillAlloc temp_to_push_out)
671
672                                 -- update the register assignment
673                                 let assig1  = addToUFM assig temp_to_push_out   (InMem slot)
674                                 let assig2  = addToUFM assig1 r                 (InReg my_reg)
675                                 setAssigR assig2
676
677                                 -- if need be, load up a spilled temp into the reg we've just freed up.
678                                 spills' <- loadTemp reading r loc my_reg spills
679
680                                 allocateRegsAndSpill reading keep
681                                         (spill_store ++ spills')
682                                         (my_reg:alloc) rs
683
684
685                         -- there wasn't anything to spill, so we're screwed.
686                         | otherwise
687                         = pprPanic ("RegAllocLinear.allocRegsAndSpill: no spill candidates\n")
688                         $ vcat 
689                                 [ text "allocating vreg:  " <> text (show r)
690                                 , text "assignment:       " <> text (show $ ufmToList assig) 
691                                 , text "freeRegs:         " <> text (show freeRegs) 
692                                 , text "initFreeRegs:     " <> text (show initFreeRegs) ]
693
694                 result
695                 
696
697 -- | Load up a spilled temporary if we need to.
698 loadTemp
699         :: Instruction instr
700         => Bool
701         -> VirtualReg   -- the temp being loaded
702         -> Maybe Loc    -- the current location of this temp
703         -> RealReg      -- the hreg to load the temp into
704         -> [instr]
705         -> RegM [instr]
706
707 loadTemp True vreg (Just (InMem slot)) hreg spills
708  = do
709         insn <- loadR (RegReal hreg) slot
710         recordSpill (SpillLoad $ getUnique vreg)
711         return  $  {- COMMENT (fsLit "spill load") : -} insn : spills
712
713 loadTemp _ _ _ _ spills =
714    return spills
715