Instrument linear register allocator.
[ghc-hetmet.git] / compiler / nativeGen / RegAllocLinear.hs
1 -----------------------------------------------------------------------------
2 --
3 -- The register allocator
4 --
5 -- (c) The University of Glasgow 2004
6 --
7 -----------------------------------------------------------------------------
8
9 {-
10 The algorithm is roughly:
11  
12   1) Compute strongly connected components of the basic block list.
13
14   2) Compute liveness (mapping from pseudo register to
15      point(s) of death?).
16
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.
24
25      For each instruction:
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?)
34
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
38                   the list is empty:
39                   - Find a temporary to spill.  Pick one that is
40                     not used in this instruction (ToDo: not
41                     used for a while...)
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).
47
48         (c) Update the current assignment
49
50         (d) If the intstruction 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.
54               else,
55                 Update the block id->assignment mapping with the current
56                 assignment.
57
58         (e) Delete all register assignments for temps which are read
59             (only) and die here.  Update the free register list.
60
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).
64
65         (g) For each temporary *written* by this instruction:
66             Allocate a real register as for (b), spilling something
67             else if necessary.
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.
71
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.
75
76         (i) Rewrite the instruction with the new mapping.
77
78         (j) For each spilled reg known to be now dead, re-add its stack slot
79             to the free list.
80
81 -}
82
83 module RegAllocLinear (
84         regAlloc,
85         RegAllocStats
86   ) where
87
88 #include "HsVersions.h"
89
90 import MachRegs
91 import MachInstrs
92 import RegAllocInfo
93 import RegLiveness
94 import Cmm
95
96 import Digraph
97 import Unique           ( Uniquable(getUnique), Unique )
98 import UniqSet
99 import UniqFM
100 import UniqSupply
101 import Outputable
102
103 #ifndef DEBUG
104 import Data.Maybe       ( fromJust )
105 #endif
106 import Data.List        ( nub, partition, mapAccumL)
107 import Control.Monad    ( when )
108 import Data.Word
109 import Data.Bits
110
111
112 -- -----------------------------------------------------------------------------
113 -- The free register set
114
115 -- This needs to be *efficient*
116
117 {- Here's an inefficient 'executable specification' of the FreeRegs data type:
118 type FreeRegs = [RegNo]
119
120 noFreeRegs = 0
121 releaseReg n f = if n `elem` f then f else (n : f)
122 initFreeRegs = allocatableRegs
123 getFreeRegs cls f = filter ( (==cls) . regClass . RealReg ) f
124 allocateReg f r = filter (/= r) f
125 -}
126
127 #if defined(powerpc_TARGET_ARCH)
128
129 -- The PowerPC has 32 integer and 32 floating point registers.
130 -- This is 32bit PowerPC, so Word64 is inefficient - two Word32s are much
131 -- better.
132 -- Note that when getFreeRegs scans for free registers, it starts at register
133 -- 31 and counts down. This is a hack for the PowerPC - the higher-numbered
134 -- registers are callee-saves, while the lower regs are caller-saves, so it
135 -- makes sense to start at the high end.
136 -- Apart from that, the code does nothing PowerPC-specific, so feel free to
137 -- add your favourite platform to the #if (if you have 64 registers but only
138 -- 32-bit words).
139
140 data FreeRegs = FreeRegs !Word32 !Word32
141               deriving( Show )  -- The Show is used in an ASSERT
142
143 noFreeRegs :: FreeRegs
144 noFreeRegs = FreeRegs 0 0
145
146 releaseReg :: RegNo -> FreeRegs -> FreeRegs
147 releaseReg r (FreeRegs g f)
148     | r > 31    = FreeRegs g (f .|. (1 `shiftL` (fromIntegral r - 32)))
149     | otherwise = FreeRegs (g .|. (1 `shiftL` fromIntegral r)) f
150     
151 initFreeRegs :: FreeRegs
152 initFreeRegs = foldr releaseReg noFreeRegs allocatableRegs
153
154 getFreeRegs :: RegClass -> FreeRegs -> [RegNo]  -- lazilly
155 getFreeRegs cls (FreeRegs g f)
156     | RcDouble <- cls = go f (0x80000000) 63
157     | RcInteger <- cls = go g (0x80000000) 31
158     where
159         go x 0 i = []
160         go x m i | x .&. m /= 0 = i : (go x (m `shiftR` 1) $! i-1)
161                  | otherwise    = go x (m `shiftR` 1) $! i-1
162
163 allocateReg :: RegNo -> FreeRegs -> FreeRegs
164 allocateReg r (FreeRegs g f) 
165     | r > 31    = FreeRegs g (f .&. complement (1 `shiftL` (fromIntegral r - 32)))
166     | otherwise = FreeRegs (g .&. complement (1 `shiftL` fromIntegral r)) f
167
168 #else
169
170 -- If we have less than 32 registers, or if we have efficient 64-bit words,
171 -- we will just use a single bitfield.
172
173 #if defined(alpha_TARGET_ARCH)
174 type FreeRegs = Word64
175 #else
176 type FreeRegs = Word32
177 #endif
178
179 noFreeRegs :: FreeRegs
180 noFreeRegs = 0
181
182 releaseReg :: RegNo -> FreeRegs -> FreeRegs
183 releaseReg n f = f .|. (1 `shiftL` n)
184
185 initFreeRegs :: FreeRegs
186 initFreeRegs = foldr releaseReg noFreeRegs allocatableRegs
187
188 getFreeRegs :: RegClass -> FreeRegs -> [RegNo]  -- lazilly
189 getFreeRegs cls f = go f 0
190   where go 0 m = []
191         go n m 
192           | n .&. 1 /= 0 && regClass (RealReg m) == cls
193           = m : (go (n `shiftR` 1) $! (m+1))
194           | otherwise
195           = go (n `shiftR` 1) $! (m+1)
196         -- ToDo: there's no point looking through all the integer registers
197         -- in order to find a floating-point one.
198
199 allocateReg :: RegNo -> FreeRegs -> FreeRegs
200 allocateReg r f = f .&. complement (1 `shiftL` fromIntegral r)
201
202 #endif
203
204 -- -----------------------------------------------------------------------------
205 -- The assignment of virtual registers to stack slots
206
207 -- We have lots of stack slots. Memory-to-memory moves are a pain on most
208 -- architectures. Therefore, we avoid having to generate memory-to-memory moves
209 -- by simply giving every virtual register its own stack slot.
210
211 -- The StackMap stack map keeps track of virtual register - stack slot
212 -- associations and of which stack slots are still free. Once it has been
213 -- associated, a stack slot is never "freed" or removed from the StackMap again,
214 -- it remains associated until we are done with the current CmmProc.
215
216 type StackSlot = Int
217 data StackMap = StackMap [StackSlot] (UniqFM StackSlot)
218
219 emptyStackMap :: StackMap
220 emptyStackMap = StackMap [0..maxSpillSlots] emptyUFM
221
222 getStackSlotFor :: StackMap -> Unique -> (StackMap,Int)
223 getStackSlotFor fs@(StackMap [] reserved) reg
224         = panic "RegAllocLinear.getStackSlotFor: out of stack slots"
225 getStackSlotFor fs@(StackMap (freeSlot:stack') reserved) reg =
226     case lookupUFM reserved reg of
227         Just slot -> (fs,slot)
228         Nothing -> (StackMap stack' (addToUFM reserved reg freeSlot), freeSlot)
229
230 -- -----------------------------------------------------------------------------
231 -- Top level of the register allocator
232
233 -- Allocate registers
234 regAlloc 
235         :: LiveCmmTop
236         -> UniqSM (NatCmmTop, Maybe RegAllocStats)
237
238 regAlloc cmm@(CmmData sec d) 
239         = return
240                 ( CmmData sec d
241                 , Nothing )
242         
243 regAlloc cmm@(CmmProc (LiveInfo info _ _) lbl params [])
244         = return
245                 ( CmmProc info lbl params []
246                 , Nothing )
247         
248 regAlloc cmm@(CmmProc static lbl params comps)
249         | LiveInfo info (Just first_id) block_live      <- static
250         = do    
251                 -- do register allocation on each component.
252                 (final_blocks, stats)
253                         <- linearRegAlloc block_live 
254                         $ map (\b -> case b of 
255                                         BasicBlock i [b]        -> AcyclicSCC b
256                                         BasicBlock i bs         -> CyclicSCC  bs)
257                         $ comps
258
259                 -- make sure the block that was first in the input list
260                 --      stays at the front of the output
261                 let ((first':_), rest')
262                                 = partition ((== first_id) . blockId) final_blocks
263
264                 return  ( CmmProc info lbl params (first' : rest')
265                         , Just stats)
266         
267
268
269 -- -----------------------------------------------------------------------------
270 -- Linear sweep to allocate registers
271
272 data Loc = InReg   {-# UNPACK #-} !RegNo
273          | InMem   {-# UNPACK #-} !Int          -- stack slot
274          | InBoth  {-# UNPACK #-} !RegNo
275                    {-# UNPACK #-} !Int          -- stack slot
276   deriving (Eq, Show, Ord)
277
278 {- 
279 A temporary can be marked as living in both a register and memory
280 (InBoth), for example if it was recently loaded from a spill location.
281 This makes it cheap to spill (no save instruction required), but we
282 have to be careful to turn this into InReg if the value in the
283 register is changed.
284
285 This is also useful when a temporary is about to be clobbered.  We
286 save it in a spill location, but mark it as InBoth because the current
287 instruction might still want to read it.
288 -}
289
290 #ifdef DEBUG
291 instance Outputable Loc where
292   ppr l = text (show l)
293 #endif
294
295
296 -- | Do register allocation on some basic blocks.
297 --
298 linearRegAlloc
299         :: BlockMap RegSet              -- ^ live regs on entry to each basic block
300         -> [SCC LiveBasicBlock]         -- ^ instructions annotated with "deaths"
301         -> UniqSM ([NatBasicBlock], RegAllocStats)
302
303 linearRegAlloc block_live sccs
304  = do   us      <- getUs
305         let (block_assig', stackMap', stats, blocks) =
306                 runR emptyBlockMap initFreeRegs emptyRegMap emptyStackMap us
307                         $ linearRA_SCCs block_live [] sccs
308
309         return  (blocks, stats)
310
311 linearRA_SCCs block_live blocksAcc []
312         = return $ reverse blocksAcc
313
314 linearRA_SCCs block_live blocksAcc (AcyclicSCC block : sccs) 
315  = do   blocks' <- processBlock block_live block
316         linearRA_SCCs block_live 
317                 ((reverse blocks') ++ blocksAcc)
318                 sccs
319
320 linearRA_SCCs block_live blocksAcc (CyclicSCC blocks : sccs) 
321  = do   blockss' <- mapM (processBlock block_live) blocks
322         linearRA_SCCs block_live
323                 (reverse (concat blockss') ++ blocksAcc)
324                 sccs
325                 
326
327 -- | Do register allocation on this basic block
328 --
329 processBlock
330         :: BlockMap RegSet              -- ^ live regs on entry to each basic block
331         -> LiveBasicBlock               -- ^ block to do register allocation on
332         -> RegM [NatBasicBlock]         -- ^ block with registers allocated
333
334 processBlock block_live (BasicBlock id instrs)
335  = do   initBlock id
336         (instrs', fixups)
337                 <- linearRA block_live [] [] instrs
338
339         return  $ BasicBlock id instrs' : fixups
340
341
342 -- | Load the freeregs and current reg assignment into the RegM state
343 --      for the basic block with this BlockId.
344 initBlock :: BlockId -> RegM ()
345 initBlock id
346  = do   block_assig     <- getBlockAssigR
347         case lookupUFM block_assig id of
348                 -- no prior info about this block: assume everything is
349                 -- free and the assignment is empty.
350                 Nothing
351                  -> do  setFreeRegsR    initFreeRegs
352                         setAssigR       emptyRegMap
353
354                 -- load info about register assignments leading into this block.
355                 Just (freeregs, assig)
356                  -> do  setFreeRegsR    freeregs
357                         setAssigR       assig
358
359
360 linearRA
361         :: BlockMap RegSet
362         -> [Instr] -> [NatBasicBlock] -> [LiveInstr]
363         -> RegM ([Instr], [NatBasicBlock])
364
365 linearRA block_live instr_acc fixups []
366         = return (reverse instr_acc, fixups)
367
368 linearRA block_live instr_acc fixups (instr:instrs)
369  = do   (instr_acc', new_fixups) <- raInsn block_live instr_acc instr
370         linearRA block_live instr_acc' (new_fixups++fixups) instrs
371
372 -- -----------------------------------------------------------------------------
373 -- Register allocation for a single instruction
374
375 type BlockAssignment = BlockMap (FreeRegs, RegMap Loc)
376
377 raInsn  :: BlockMap RegSet              -- Live temporaries at each basic block
378         -> [Instr]                      -- new instructions (accum.)
379         -> LiveInstr                    -- the instruction (with "deaths")
380         -> RegM (
381              [Instr],                   -- new instructions
382              [NatBasicBlock]            -- extra fixup blocks
383            )
384
385 raInsn block_live new_instrs (Instr instr@(COMMENT _) Nothing)
386  = return (new_instrs, [])
387
388 raInsn block_live new_instrs (Instr instr@(DELTA n) Nothing)  
389  = do
390     setDeltaR n
391     return (new_instrs, [])
392
393 raInsn block_live new_instrs (Instr instr (Just live))
394  = do
395     assig    <- getAssigR
396
397     -- If we have a reg->reg move between virtual registers, where the
398     -- src register is not live after this instruction, and the dst
399     -- register does not already have an assignment,
400     -- and the source register is assigned to a register, not to a spill slot,
401     -- then we can eliminate the instruction.
402     -- (we can't eliminitate it if the source register is on the stack, because
403     --  we do not want to use one spill slot for different virtual registers)
404     case isRegRegMove instr of
405         Just (src,dst)  | src `elementOfUniqSet` (liveDieRead live), 
406                           isVirtualReg dst,
407                           not (dst `elemUFM` assig),
408                           Just (InReg _) <- (lookupUFM assig src) -> do
409            case src of
410               RealReg i -> setAssigR (addToUFM assig dst (InReg i))
411                 -- if src is a fixed reg, then we just map dest to this
412                 -- reg in the assignment.  src must be an allocatable reg,
413                 -- otherwise it wouldn't be in r_dying.
414               _virt -> case lookupUFM assig src of
415                          Nothing -> panic "raInsn"
416                          Just loc ->
417                            setAssigR (addToUFM (delFromUFM assig src) dst loc)
418
419            -- we have elimianted this instruction
420            {-
421            freeregs <- getFreeRegsR
422            assig <- getAssigR
423            pprTrace "raInsn" (text "ELIMINATED: " <> docToSDoc (pprInstr instr) $$ ppr r_dying <+> ppr w_dying $$ text (show freeregs) $$ ppr assig) $ do
424            -}
425            return (new_instrs, [])
426
427         other -> genRaInsn block_live new_instrs instr 
428                         (uniqSetToList $ liveDieRead live) 
429                         (uniqSetToList $ liveDieWrite live)
430
431
432 raInsn block_live new_instrs li
433         = pprPanic "raInsn" (text "no match for:" <> ppr li)
434
435
436 genRaInsn block_live new_instrs instr r_dying w_dying =
437     case regUsage instr              of { RU read written ->
438     case partition isRealReg written of { (real_written1,virt_written) ->
439     do
440     let 
441         real_written = [ r | RealReg r <- real_written1 ]
442
443         -- we don't need to do anything with real registers that are
444         -- only read by this instr.  (the list is typically ~2 elements,
445         -- so using nub isn't a problem).
446         virt_read = nub (filter isVirtualReg read)
447     -- in
448
449     -- (a) save any temporaries which will be clobbered by this instruction
450     clobber_saves <- saveClobberedTemps real_written r_dying
451
452     {-
453     freeregs <- getFreeRegsR
454     assig <- getAssigR
455     pprTrace "raInsn" (docToSDoc (pprInstr instr) $$ ppr r_dying <+> ppr w_dying $$ ppr virt_read <+> ppr virt_written $$ text (show freeregs) $$ ppr assig) $ do
456     -}
457
458     -- (b), (c) allocate real regs for all regs read by this instruction.
459     (r_spills, r_allocd) <- 
460         allocateRegsAndSpill True{-reading-} virt_read [] [] virt_read
461
462     -- (d) Update block map for new destinations
463     -- NB. do this before removing dead regs from the assignment, because
464     -- these dead regs might in fact be live in the jump targets (they're
465     -- only dead in the code that follows in the current basic block).
466     (fixup_blocks, adjusted_instr)
467         <- joinToTargets block_live [] instr (jumpDests instr [])
468
469     -- (e) Delete all register assignments for temps which are read
470     --     (only) and die here.  Update the free register list.
471     releaseRegs r_dying
472
473     -- (f) Mark regs which are clobbered as unallocatable
474     clobberRegs real_written
475
476     -- (g) Allocate registers for temporaries *written* (only)
477     (w_spills, w_allocd) <- 
478         allocateRegsAndSpill False{-writing-} virt_written [] [] virt_written
479
480     -- (h) Release registers for temps which are written here and not
481     -- used again.
482     releaseRegs w_dying
483
484     let
485         -- (i) Patch the instruction
486         patch_map = listToUFM   [ (t,RealReg r) | 
487                                   (t,r) <- zip virt_read r_allocd
488                                           ++ zip virt_written w_allocd ]
489
490         patched_instr = patchRegs adjusted_instr patchLookup
491         patchLookup x = case lookupUFM patch_map x of
492                                 Nothing -> x
493                                 Just y  -> y
494     -- in
495
496     -- pprTrace "patched" (docToSDoc (pprInstr patched_instr)) $ do
497
498     -- (j) free up stack slots for dead spilled regs
499     -- TODO (can't be bothered right now)
500
501     return (patched_instr : w_spills ++ reverse r_spills
502                  ++ clobber_saves ++ new_instrs,
503             fixup_blocks)
504   }}
505
506 -- -----------------------------------------------------------------------------
507 -- releaseRegs
508
509 releaseRegs regs = do
510   assig <- getAssigR
511   free <- getFreeRegsR
512   loop assig free regs 
513  where
514   loop assig free _ | free `seq` False = undefined
515   loop assig free [] = do setAssigR assig; setFreeRegsR free; return ()
516   loop assig free (RealReg r : rs) = loop assig (releaseReg r free) rs
517   loop assig free (r:rs) = 
518      case lookupUFM assig r of
519         Just (InBoth real _) -> loop (delFromUFM assig r) (releaseReg real free) rs
520         Just (InReg real) -> loop (delFromUFM assig r) (releaseReg real free) rs
521         _other            -> loop (delFromUFM assig r) free rs
522
523 -- -----------------------------------------------------------------------------
524 -- Clobber real registers
525
526 {-
527 For each temp in a register that is going to be clobbered:
528   - if the temp dies after this instruction, do nothing
529   - otherwise, put it somewhere safe (another reg if possible,
530     otherwise spill and record InBoth in the assignment).
531
532 for allocateRegs on the temps *read*,
533   - clobbered regs are allocatable.
534
535 for allocateRegs on the temps *written*, 
536   - clobbered regs are not allocatable.
537 -}
538
539 saveClobberedTemps
540    :: [RegNo]              -- real registers clobbered by this instruction
541    -> [Reg]                -- registers which are no longer live after this insn
542    -> RegM [Instr]         -- return: instructions to spill any temps that will
543                            -- be clobbered.
544
545 saveClobberedTemps [] _ = return [] -- common case
546 saveClobberedTemps clobbered dying =  do
547   assig <- getAssigR
548   let
549         to_spill  = [ (temp,reg) | (temp, InReg reg) <- ufmToList assig,
550                                    reg `elem` clobbered,
551                                    temp `notElem` map getUnique dying  ]
552   -- in
553   (instrs,assig') <- clobber assig [] to_spill
554   setAssigR assig'
555   return instrs
556  where
557   clobber assig instrs [] = return (instrs,assig)
558   clobber assig instrs ((temp,reg):rest)
559     = do
560         --ToDo: copy it to another register if possible
561         (spill,slot) <- spillR (RealReg reg) temp
562         recordSpill (SpillClobber temp)
563
564         let new_assign  = addToUFM assig temp (InBoth reg slot)
565         clobber new_assign (spill : COMMENT FSLIT("spill clobber") : instrs) rest
566
567 clobberRegs :: [RegNo] -> RegM ()
568 clobberRegs [] = return () -- common case
569 clobberRegs clobbered = do
570   freeregs <- getFreeRegsR
571   setFreeRegsR $! foldr allocateReg freeregs clobbered
572   assig <- getAssigR
573   setAssigR $! clobber assig (ufmToList assig)
574  where
575     -- if the temp was InReg and clobbered, then we will have
576     -- saved it in saveClobberedTemps above.  So the only case
577     -- we have to worry about here is InBoth.  Note that this
578     -- also catches temps which were loaded up during allocation
579     -- of read registers, not just those saved in saveClobberedTemps.
580   clobber assig [] = assig
581   clobber assig ((temp, InBoth reg slot) : rest)
582         | reg `elem` clobbered
583         = clobber (addToUFM assig temp (InMem slot)) rest
584   clobber assig (entry:rest)
585         = clobber assig rest 
586
587 -- -----------------------------------------------------------------------------
588 -- allocateRegsAndSpill
589
590 -- This function does several things:
591 --   For each temporary referred to by this instruction,
592 --   we allocate a real register (spilling another temporary if necessary).
593 --   We load the temporary up from memory if necessary.
594 --   We also update the register assignment in the process, and
595 --   the list of free registers and free stack slots.
596
597 allocateRegsAndSpill
598         :: Bool                 -- True <=> reading (load up spilled regs)
599         -> [Reg]                -- don't push these out
600         -> [Instr]              -- spill insns
601         -> [RegNo]              -- real registers allocated (accum.)
602         -> [Reg]                -- temps to allocate
603         -> RegM ([Instr], [RegNo])
604
605 allocateRegsAndSpill reading keep spills alloc []
606   = return (spills,reverse alloc)
607
608 allocateRegsAndSpill reading keep spills alloc (r:rs) = do
609   assig <- getAssigR
610   case lookupUFM assig r of
611   -- case (1a): already in a register
612      Just (InReg my_reg) ->
613         allocateRegsAndSpill reading keep spills (my_reg:alloc) rs
614
615   -- case (1b): already in a register (and memory)
616   -- NB1. if we're writing this register, update its assignemnt to be
617   -- InReg, because the memory value is no longer valid.
618   -- NB2. This is why we must process written registers here, even if they
619   -- are also read by the same instruction.
620      Just (InBoth my_reg mem) -> do
621         when (not reading) (setAssigR (addToUFM assig r (InReg my_reg)))
622         allocateRegsAndSpill reading keep spills (my_reg:alloc) rs
623
624   -- Not already in a register, so we need to find a free one...
625      loc -> do
626         freeregs <- getFreeRegsR
627
628         case getFreeRegs (regClass r) freeregs of
629
630         -- case (2): we have a free register
631           my_reg:_ -> do
632             spills'   <- loadTemp reading r loc my_reg spills
633             let new_loc 
634                  | Just (InMem slot) <- loc, reading = InBoth my_reg slot
635                  | otherwise                         = InReg my_reg
636             setAssigR (addToUFM assig r $! new_loc)
637             setFreeRegsR (allocateReg my_reg freeregs)
638             allocateRegsAndSpill reading keep spills' (my_reg:alloc) rs
639
640         -- case (3): we need to push something out to free up a register
641           [] -> do
642             let
643               keep' = map getUnique keep
644               candidates1 = [ (temp,reg,mem)
645                             | (temp, InBoth reg mem) <- ufmToList assig,
646                               temp `notElem` keep', regClass (RealReg reg) == regClass r ]
647               candidates2 = [ (temp,reg)
648                             | (temp, InReg reg) <- ufmToList assig,
649                               temp `notElem` keep', regClass (RealReg reg) == regClass r  ]
650             -- in
651             ASSERT2(not (null candidates1 && null candidates2), 
652                     text (show freeregs) <+> ppr r <+> ppr assig) do
653
654             case candidates1 of
655
656              -- we have a temporary that is in both register and mem,
657              -- just free up its register for use.
658              -- 
659              (temp,my_reg,slot):_ -> do
660                 spills' <- loadTemp reading r loc my_reg spills
661                 let     
662                   assig1  = addToUFM assig temp (InMem slot)
663                   assig2  = addToUFM assig1 r (InReg my_reg)
664                 -- in
665                 setAssigR assig2
666                 allocateRegsAndSpill reading keep spills' (my_reg:alloc) rs
667
668              -- otherwise, we need to spill a temporary that currently
669              -- resides in a register.
670
671
672              [] -> do
673
674                 -- TODO: plenty of room for optimisation in choosing which temp
675                 -- to spill.  We just pick the first one that isn't used in 
676                 -- the current instruction for now.
677
678                 let (temp_to_push_out, my_reg) = myHead "regalloc" candidates2
679
680                 (spill_insn, slot) <- spillR (RealReg my_reg) temp_to_push_out
681                 let spill_store  = (if reading then id else reverse)
682                                         [ COMMENT FSLIT("spill alloc") 
683                                         , spill_insn ]
684
685                 -- record that this temp was spilled
686                 recordSpill (SpillAlloc temp_to_push_out)
687
688                 -- update the register assignment
689                 let assig1  = addToUFM assig temp_to_push_out   (InMem slot)
690                 let assig2  = addToUFM assig1 r                 (InReg my_reg)
691                 setAssigR assig2
692
693                 -- if need be, load up a spilled temp into the reg we've just freed up.
694                 spills' <- loadTemp reading r loc my_reg spills
695
696                 allocateRegsAndSpill reading keep
697                         (spill_store ++ spills')
698                         (my_reg:alloc) rs
699
700
701 -- | Load up a spilled temporary if we need to.
702 loadTemp
703         :: Bool
704         -> Reg          -- the temp being loaded
705         -> Maybe Loc    -- the current location of this temp
706         -> RegNo        -- the hreg to load the temp into
707         -> [Instr]
708         -> RegM [Instr]
709
710 loadTemp True vreg (Just (InMem slot)) hreg spills
711  = do
712         insn <- loadR (RealReg hreg) slot
713         recordSpill (SpillLoad $ getUnique vreg)
714         return  $  COMMENT FSLIT("spill load") : insn : spills
715
716 loadTemp _ _ _ _ spills =
717    return spills
718
719
720 myHead s [] = panic s
721 myHead s (x:xs) = x
722
723 -- -----------------------------------------------------------------------------
724 -- Joining a jump instruction to its targets
725
726 -- The first time we encounter a jump to a particular basic block, we
727 -- record the assignment of temporaries.  The next time we encounter a
728 -- jump to the same block, we compare our current assignment to the
729 -- stored one.  They might be different if spilling has occrred in one
730 -- branch; so some fixup code will be required to match up the
731 -- assignments.
732
733 joinToTargets
734         :: BlockMap RegSet
735         -> [NatBasicBlock]
736         -> Instr
737         -> [BlockId]
738         -> RegM ([NatBasicBlock], Instr)
739
740 joinToTargets block_live new_blocks instr []
741   = return (new_blocks, instr)
742
743 joinToTargets block_live new_blocks instr (dest:dests) = do
744   block_assig <- getBlockAssigR
745   assig <- getAssigR
746   let
747         -- adjust the assignment to remove any registers which are not
748         -- live on entry to the destination block.
749         adjusted_assig = filterUFM_Directly still_live assig
750
751         live_set = lookItUp "joinToTargets" block_live dest
752         still_live uniq _ = uniq `elemUniqSet_Directly` live_set
753
754         -- and free up those registers which are now free.
755         to_free =
756           [ r | (reg, loc) <- ufmToList assig, 
757                 not (elemUniqSet_Directly reg live_set), 
758                 r <- regsOfLoc loc ]
759
760         regsOfLoc (InReg r)    = [r]
761         regsOfLoc (InBoth r _) = [r]
762         regsOfLoc (InMem _)    = []
763   -- in
764   case lookupUFM block_assig dest of
765         -- Nothing <=> this is the first time we jumped to this
766         -- block.
767         Nothing -> do
768           freeregs <- getFreeRegsR
769           let freeregs' = foldr releaseReg freeregs to_free 
770           setBlockAssigR (addToUFM block_assig dest 
771                                 (freeregs',adjusted_assig))
772           joinToTargets block_live new_blocks instr dests
773
774         Just (freeregs,dest_assig)
775
776            -- the assignments match
777            | ufmToList dest_assig == ufmToList adjusted_assig
778            -> joinToTargets block_live new_blocks instr dests
779
780            -- need fixup code
781            | otherwise
782            -> do
783                delta <- getDeltaR
784                
785                let graph = makeRegMovementGraph adjusted_assig dest_assig
786                let sccs  = stronglyConnCompR graph
787                fixUpInstrs <- mapM (handleComponent delta instr) sccs
788
789                block_id <- getUniqueR
790                let block = BasicBlock (BlockId block_id) $
791                        concat fixUpInstrs ++ mkBranchInstr dest
792
793                let instr' = patchJump instr dest (BlockId block_id)
794
795                joinToTargets block_live (block : new_blocks) instr' dests
796
797
798 -- | Construct a graph of register/spill movements.
799 --
800 --      We cut some corners by
801 --      a) not handling cyclic components
802 --      b) not handling memory-to-memory moves.
803 --
804 --      Cyclic components seem to occur only very rarely,
805 --      and we don't need memory-to-memory moves because we
806 --      make sure that every temporary always gets its own
807 --      stack slot.
808
809 makeRegMovementGraph :: RegMap Loc -> RegMap Loc -> [(Unique, Loc, [Loc])]
810 makeRegMovementGraph adjusted_assig dest_assig
811  = let
812         mkNodes src vreg
813          = expandNode vreg src
814          $ lookupWithDefaultUFM_Directly
815                 dest_assig
816                 (panic "RegisterAlloc.joinToTargets")
817                 vreg
818
819    in   [ node  | (vreg, src) <- ufmToList adjusted_assig
820                 , node <- mkNodes src vreg ]
821
822 -- The InBoth handling is a little tricky here.  If
823 -- the destination is InBoth, then we must ensure that
824 -- the value ends up in both locations.  An InBoth
825 -- destination must conflict with an InReg or InMem
826 -- source, so we expand an InBoth destination as
827 -- necessary.  An InBoth source is slightly different:
828 -- we only care about the register that the source value
829 -- is in, so that we can move it to the destinations.
830
831 expandNode vreg loc@(InReg src) (InBoth dst mem)
832         | src == dst = [(vreg, loc, [InMem mem])]
833         | otherwise  = [(vreg, loc, [InReg dst, InMem mem])]
834
835 expandNode vreg loc@(InMem src) (InBoth dst mem)
836         | src == mem = [(vreg, loc, [InReg dst])]
837         | otherwise  = [(vreg, loc, [InReg dst, InMem mem])]
838
839 expandNode vreg loc@(InBoth _ src) (InMem dst)
840         | src == dst = [] -- guaranteed to be true
841
842 expandNode vreg loc@(InBoth src _) (InReg dst)
843         | src == dst = []
844
845 expandNode vreg loc@(InBoth src _) dst
846         = expandNode vreg (InReg src) dst
847
848 expandNode vreg src dst
849         | src == dst = []
850         | otherwise  = [(vreg, src, [dst])]
851
852
853 -- | Make a move instruction between these two locations so we
854 --      can join together allocations for different basic blocks.
855 --
856 makeMove :: Int -> Unique -> Loc -> Loc -> RegM Instr
857 makeMove delta vreg (InReg src) (InReg dst)
858  = do   recordSpill (SpillJoinRR vreg)
859         return  $ mkRegRegMoveInstr (RealReg src) (RealReg dst)
860
861 makeMove delta vreg (InMem src) (InReg dst)
862  = do   recordSpill (SpillJoinRM vreg)
863         return  $ mkLoadInstr (RealReg dst) delta src
864
865 makeMove delta vreg (InReg src) (InMem dst)
866  = do   recordSpill (SpillJoinRM vreg)
867         return  $ mkSpillInstr (RealReg src) delta dst
868
869 makeMove delta vreg src dst
870         = panic $ "makeMove " ++ show vreg ++ " (" ++ show src ++ ") ("
871                 ++ show dst ++ ")"
872                 ++ " (workaround: use -fviaC)"
873
874
875 -- we have eliminated any possibility of single-node cylces
876 -- in expandNode above.
877 handleComponent :: Int -> Instr -> SCC (Unique, Loc, [Loc]) -> RegM [Instr]
878 handleComponent delta instr (AcyclicSCC (vreg,src,dsts))
879          = mapM (makeMove delta vreg src) dsts
880
881 -- we can not have cycles that involve memory
882 -- locations as source nor as single destination
883 -- because memory locations (stack slots) are
884 -- allocated exclusively for a virtual register and
885 -- therefore can not require a fixup
886 handleComponent delta instr (CyclicSCC ((vreg,src@(InReg sreg),dsts):rest))
887  = do
888         spill_id <- getUniqueR
889         (saveInstr,slot)        <- spillR (RealReg sreg) spill_id
890         remainingFixUps         <- mapM (handleComponent delta instr) (stronglyConnCompR rest)
891         restoreAndFixInstr      <- getRestoreMoves dsts slot
892         return ([instr] ++ concat remainingFixUps ++ restoreAndFixInstr)
893
894         where
895         getRestoreMoves [r@(InReg reg), mem@(InMem _)] slot
896          = do
897                 restoreToReg    <- loadR (RealReg reg) slot
898                 moveInstr       <- makeMove delta vreg r mem
899                 return $ [COMMENT FSLIT("spill join move"), restoreToReg, moveInstr]
900
901         getRestoreMoves [InReg reg] slot
902                 = loadR (RealReg reg) slot >>= return . (:[])
903
904         getRestoreMoves [InMem _] _     = panic "getRestoreMoves can not handle memory only restores"
905         getRestoreMoves _ _             = panic "getRestoreMoves unknown case"
906
907
908 handleComponent delta instr (CyclicSCC _)
909  = panic "Register Allocator: handleComponent cyclic"
910
911
912
913 -- -----------------------------------------------------------------------------
914 -- The register allocator's monad.  
915
916 -- Here we keep all the state that the register allocator keeps track
917 -- of as it walks the instructions in a basic block.
918
919 data RA_State 
920   = RA_State {
921         ra_blockassig :: BlockAssignment,
922                 -- The current mapping from basic blocks to 
923                 -- the register assignments at the beginning of that block.
924         ra_freeregs   :: {-#UNPACK#-}!FreeRegs, -- free machine registers
925         ra_assig      :: RegMap Loc,    -- assignment of temps to locations
926         ra_delta      :: Int,           -- current stack delta
927         ra_stack      :: StackMap,      -- free stack slots for spilling
928         ra_us         :: UniqSupply,    -- unique supply for generating names
929                                         -- for fixup blocks.
930
931         -- Record why things were spilled, for -ddrop-asm-stats.
932         --      Just keep a list here instead of a map of regs -> reasons.
933         --      We don't want to slow down the allocator if we're not going to emit the stats.
934         ra_spills     :: [SpillReason]
935   }
936
937 newtype RegM a = RegM { unReg :: RA_State -> (# RA_State, a #) }
938
939
940 instance Monad RegM where
941   m >>= k   =  RegM $ \s -> case unReg m s of { (# s, a #) -> unReg (k a) s }
942   return a  =  RegM $ \s -> (# s, a #)
943
944 runR :: BlockAssignment -> FreeRegs -> RegMap Loc -> StackMap -> UniqSupply
945   -> RegM a -> (BlockAssignment, StackMap, RegAllocStats, a)
946 runR block_assig freeregs assig stack us thing =
947   case unReg thing (RA_State{ ra_blockassig=block_assig, ra_freeregs=freeregs,
948                         ra_assig=assig, ra_delta=0{-???-}, ra_stack=stack,
949                         ra_us = us, ra_spills = [] }) of
950         (# state'@RA_State{ ra_blockassig=block_assig, ra_stack=stack', ra_spills=spills' }, returned_thing #)
951                 -> (block_assig, stack', makeRAStats state', returned_thing)
952
953 spillR :: Reg -> Unique -> RegM (Instr, Int)
954 spillR reg temp = RegM $ \ s@RA_State{ra_delta=delta, ra_stack=stack} ->
955   let (stack',slot) = getStackSlotFor stack temp
956       instr  = mkSpillInstr reg delta slot
957   in
958   (# s{ra_stack=stack'}, (instr,slot) #)
959
960 loadR :: Reg -> Int -> RegM Instr
961 loadR reg slot = RegM $ \ s@RA_State{ra_delta=delta} ->
962   (# s, mkLoadInstr reg delta slot #)
963
964 getFreeRegsR :: RegM FreeRegs
965 getFreeRegsR = RegM $ \ s@RA_State{ra_freeregs = freeregs} ->
966   (# s, freeregs #)
967
968 setFreeRegsR :: FreeRegs -> RegM ()
969 setFreeRegsR regs = RegM $ \ s ->
970   (# s{ra_freeregs = regs}, () #)
971
972 getAssigR :: RegM (RegMap Loc)
973 getAssigR = RegM $ \ s@RA_State{ra_assig = assig} ->
974   (# s, assig #)
975
976 setAssigR :: RegMap Loc -> RegM ()
977 setAssigR assig = RegM $ \ s ->
978   (# s{ra_assig=assig}, () #)
979
980 getBlockAssigR :: RegM BlockAssignment
981 getBlockAssigR = RegM $ \ s@RA_State{ra_blockassig = assig} ->
982   (# s, assig #)
983
984 setBlockAssigR :: BlockAssignment -> RegM ()
985 setBlockAssigR assig = RegM $ \ s ->
986   (# s{ra_blockassig = assig}, () #)
987
988 setDeltaR :: Int -> RegM ()
989 setDeltaR n = RegM $ \ s ->
990   (# s{ra_delta = n}, () #)
991
992 getDeltaR :: RegM Int
993 getDeltaR = RegM $ \s -> (# s, ra_delta s #)
994
995 getUniqueR :: RegM Unique
996 getUniqueR = RegM $ \s ->
997   case splitUniqSupply (ra_us s) of
998     (us1, us2) -> (# s{ra_us = us2}, uniqFromSupply us1 #)
999
1000 -- | Record that a spill instruction was inserted, for profiling.
1001 recordSpill :: SpillReason -> RegM ()
1002 recordSpill spill
1003         = RegM $ \s -> (# s { ra_spills = spill : ra_spills s}, () #)
1004
1005 -- -----------------------------------------------------------------------------
1006
1007 -- | Reasons why instructions might be inserted by the spiller.
1008 --      Used when generating stats for -ddrop-asm-stats.
1009 --
1010 data SpillReason
1011         = SpillAlloc    !Unique -- ^ vreg was spilled to a slot so we could use its
1012                                 --      current hreg for another vreg
1013         | SpillClobber  !Unique -- ^ vreg was moved because its hreg was clobbered
1014         | SpillLoad     !Unique -- ^ vreg was loaded from a spill slot
1015
1016         | SpillJoinRR   !Unique -- ^ reg-reg move inserted during join to targets
1017         | SpillJoinRM   !Unique -- ^ reg-mem move inserted during join to targets
1018
1019
1020 -- | Used to carry interesting stats out of the register allocator.
1021 data RegAllocStats
1022         = RegAllocStats
1023         { ra_spillInstrs        :: UniqFM [Int] }
1024
1025
1026 -- | Make register allocator stats from its final state.
1027 makeRAStats :: RA_State -> RegAllocStats
1028 makeRAStats state
1029         = RegAllocStats
1030         { ra_spillInstrs        = binSpillReasons (ra_spills state) }
1031
1032
1033 -- | Build a map of how many times each reg was alloced, clobbered, loaded etc.
1034 binSpillReasons
1035         :: [SpillReason] -> UniqFM [Int]
1036
1037 binSpillReasons reasons
1038         = addListToUFM_C
1039                 (zipWith (+))
1040                 emptyUFM
1041                 (map (\reason -> case reason of
1042                         SpillAlloc r    -> (r, [1, 0, 0, 0, 0])
1043                         SpillClobber r  -> (r, [0, 1, 0, 0, 0])
1044                         SpillLoad r     -> (r, [0, 0, 1, 0, 0])
1045                         SpillJoinRR r   -> (r, [0, 0, 0, 1, 0])
1046                         SpillJoinRM r   -> (r, [0, 0, 0, 0, 1])) reasons)
1047
1048
1049 -- -----------------------------------------------------------------------------
1050 -- Utils
1051
1052 #ifdef DEBUG
1053 my_fromJust s p Nothing  = pprPanic ("fromJust: " ++ s) p
1054 my_fromJust s p (Just x) = x
1055 #else
1056 my_fromJust _ _ = fromJust
1057 #endif
1058
1059 lookItUp :: Uniquable b => String -> UniqFM a -> b -> a
1060 lookItUp str fm x = my_fromJust str (ppr (getUnique x)) (lookupUFM fm x)