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