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