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