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