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