Fix scoped type variables for expression type signatures
[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)  | src `elem` r_dying, 
514                           isVirtualReg dst,
515                           not (dst `elemUFM` assig) -> do
516            case src of
517               RealReg i -> setAssigR (addToUFM assig dst (InReg i))
518                 -- if src is a fixed reg, then we just map dest to this
519                 -- reg in the assignment.  src must be an allocatable reg,
520                 -- otherwise it wouldn't be in r_dying.
521               _virt -> case lookupUFM assig src of
522                          Nothing -> panic "raInsn"
523                          Just loc ->
524                            setAssigR (addToUFM (delFromUFM assig src) dst loc)
525
526            -- we have elimianted this instruction
527            {-
528            freeregs <- getFreeRegsR
529            assig <- getAssigR
530            pprTrace "raInsn" (text "ELIMINATED: " <> docToSDoc (pprInstr instr) $$ ppr r_dying <+> ppr w_dying $$ text (show freeregs) $$ ppr assig) $ do
531            -}
532            return (new_instrs, [])
533
534         other -> genRaInsn block_live new_instrs instr r_dying w_dying
535
536
537 genRaInsn block_live new_instrs instr r_dying w_dying =
538     case regUsage instr              of { RU read written ->
539     case partition isRealReg written of { (real_written1,virt_written) ->
540     do
541     let 
542         real_written = [ r | RealReg r <- real_written1 ]
543
544         -- we don't need to do anything with real registers that are
545         -- only read by this instr.  (the list is typically ~2 elements,
546         -- so using nub isn't a problem).
547         virt_read = nub (filter isVirtualReg read)
548     -- in
549
550     -- (a) save any temporaries which will be clobbered by this instruction
551     clobber_saves <- saveClobberedTemps real_written r_dying
552
553     {-
554     freeregs <- getFreeRegsR
555     assig <- getAssigR
556     pprTrace "raInsn" (docToSDoc (pprInstr instr) $$ ppr r_dying <+> ppr w_dying $$ ppr virt_read <+> ppr virt_written $$ text (show freeregs) $$ ppr assig) $ do
557     -}
558
559     -- (b), (c) allocate real regs for all regs read by this instruction.
560     (r_spills, r_allocd) <- 
561         allocateRegsAndSpill True{-reading-} virt_read [] [] virt_read
562
563     -- (d) Update block map for new destinations
564     -- NB. do this before removing dead regs from the assignment, because
565     -- these dead regs might in fact be live in the jump targets (they're
566     -- only dead in the code that follows in the current basic block).
567     (fixup_blocks, adjusted_instr)
568         <- joinToTargets block_live [] instr (jumpDests instr [])
569
570     -- (e) Delete all register assignments for temps which are read
571     --     (only) and die here.  Update the free register list.
572     releaseRegs r_dying
573
574     -- (f) Mark regs which are clobbered as unallocatable
575     clobberRegs real_written
576
577     -- (g) Allocate registers for temporaries *written* (only)
578     (w_spills, w_allocd) <- 
579         allocateRegsAndSpill False{-writing-} virt_written [] [] virt_written
580
581     -- (h) Release registers for temps which are written here and not
582     -- used again.
583     releaseRegs w_dying
584
585     let
586         -- (i) Patch the instruction
587         patch_map = listToUFM   [ (t,RealReg r) | 
588                                   (t,r) <- zip virt_read r_allocd
589                                           ++ zip virt_written w_allocd ]
590
591         patched_instr = patchRegs adjusted_instr patchLookup
592         patchLookup x = case lookupUFM patch_map x of
593                                 Nothing -> x
594                                 Just y  -> y
595     -- in
596
597     -- pprTrace "patched" (docToSDoc (pprInstr patched_instr)) $ do
598
599     -- (j) free up stack slots for dead spilled regs
600     -- TODO (can't be bothered right now)
601
602     return (patched_instr : w_spills ++ reverse r_spills
603                  ++ clobber_saves ++ new_instrs,
604             fixup_blocks)
605   }}
606
607 -- -----------------------------------------------------------------------------
608 -- releaseRegs
609
610 releaseRegs regs = do
611   assig <- getAssigR
612   free <- getFreeRegsR
613   loop assig free regs 
614  where
615   loop assig free _ | free `seq` False = undefined
616   loop assig free [] = do setAssigR assig; setFreeRegsR free; return ()
617   loop assig free (RealReg r : rs) = loop assig (releaseReg r free) rs
618   loop assig free (r:rs) = 
619      case lookupUFM assig r of
620         Just (InBoth real _) -> loop (delFromUFM assig r) (releaseReg real free) rs
621         Just (InReg real) -> loop (delFromUFM assig r) (releaseReg real free) rs
622         _other            -> loop (delFromUFM assig r) free rs
623
624 -- -----------------------------------------------------------------------------
625 -- Clobber real registers
626
627 {-
628 For each temp in a register that is going to be clobbered:
629   - if the temp dies after this instruction, do nothing
630   - otherwise, put it somewhere safe (another reg if possible,
631     otherwise spill and record InBoth in the assignment).
632
633 for allocateRegs on the temps *read*,
634   - clobbered regs are allocatable.
635
636 for allocateRegs on the temps *written*, 
637   - clobbered regs are not allocatable.
638 -}
639
640 saveClobberedTemps
641    :: [RegNo]              -- real registers clobbered by this instruction
642    -> [Reg]                -- registers which are no longer live after this insn
643    -> RegM [Instr]         -- return: instructions to spill any temps that will
644                            -- be clobbered.
645
646 saveClobberedTemps [] _ = return [] -- common case
647 saveClobberedTemps clobbered dying =  do
648   assig <- getAssigR
649   let
650         to_spill  = [ (temp,reg) | (temp, InReg reg) <- ufmToList assig,
651                                    reg `elem` clobbered,
652                                    temp `notElem` map getUnique dying  ]
653   -- in
654   (instrs,assig') <- clobber assig [] to_spill
655   setAssigR assig'
656   return instrs
657  where
658   clobber assig instrs [] = return (instrs,assig)
659   clobber assig instrs ((temp,reg):rest)
660     = do
661         --ToDo: copy it to another register if possible
662       (spill,slot) <- spillR (RealReg reg) temp
663       clobber (addToUFM assig temp (InBoth reg slot)) (spill:instrs) rest
664
665 clobberRegs :: [RegNo] -> RegM ()
666 clobberRegs [] = return () -- common case
667 clobberRegs clobbered = do
668   freeregs <- getFreeRegsR
669   setFreeRegsR $! foldr allocateReg freeregs clobbered
670   assig <- getAssigR
671   setAssigR $! clobber assig (ufmToList assig)
672  where
673     -- if the temp was InReg and clobbered, then we will have
674     -- saved it in saveClobberedTemps above.  So the only case
675     -- we have to worry about here is InBoth.  Note that this
676     -- also catches temps which were loaded up during allocation
677     -- of read registers, not just those saved in saveClobberedTemps.
678   clobber assig [] = assig
679   clobber assig ((temp, InBoth reg slot) : rest)
680         | reg `elem` clobbered
681         = clobber (addToUFM assig temp (InMem slot)) rest
682   clobber assig (entry:rest)
683         = clobber assig rest 
684
685 -- -----------------------------------------------------------------------------
686 -- allocateRegsAndSpill
687
688 -- This function does several things:
689 --   For each temporary referred to by this instruction,
690 --   we allocate a real register (spilling another temporary if necessary).
691 --   We load the temporary up from memory if necessary.
692 --   We also update the register assignment in the process, and
693 --   the list of free registers and free stack slots.
694
695 allocateRegsAndSpill
696         :: Bool                 -- True <=> reading (load up spilled regs)
697         -> [Reg]                -- don't push these out
698         -> [Instr]              -- spill insns
699         -> [RegNo]              -- real registers allocated (accum.)
700         -> [Reg]                -- temps to allocate
701         -> RegM ([Instr], [RegNo])
702
703 allocateRegsAndSpill reading keep spills alloc []
704   = return (spills,reverse alloc)
705
706 allocateRegsAndSpill reading keep spills alloc (r:rs) = do
707   assig <- getAssigR
708   case lookupUFM assig r of
709   -- case (1a): already in a register
710      Just (InReg my_reg) ->
711         allocateRegsAndSpill reading keep spills (my_reg:alloc) rs
712
713   -- case (1b): already in a register (and memory)
714   -- NB1. if we're writing this register, update its assignemnt to be
715   -- InReg, because the memory value is no longer valid.
716   -- NB2. This is why we must process written registers here, even if they
717   -- are also read by the same instruction.
718      Just (InBoth my_reg mem) -> do
719         when (not reading) (setAssigR (addToUFM assig r (InReg my_reg)))
720         allocateRegsAndSpill reading keep spills (my_reg:alloc) rs
721
722   -- Not already in a register, so we need to find a free one...
723      loc -> do
724         freeregs <- getFreeRegsR
725
726         case getFreeRegs (regClass r) freeregs of
727
728         -- case (2): we have a free register
729           my_reg:_ -> do
730             spills'   <- do_load reading loc my_reg spills
731             let new_loc 
732                  | Just (InMem slot) <- loc, reading = InBoth my_reg slot
733                  | otherwise                         = InReg my_reg
734             setAssigR (addToUFM assig r $! new_loc)
735             setFreeRegsR (allocateReg my_reg freeregs)
736             allocateRegsAndSpill reading keep spills' (my_reg:alloc) rs
737
738         -- case (3): we need to push something out to free up a register
739           [] -> do
740             let
741               keep' = map getUnique keep
742               candidates1 = [ (temp,reg,mem)
743                             | (temp, InBoth reg mem) <- ufmToList assig,
744                               temp `notElem` keep', regClass (RealReg reg) == regClass r ]
745               candidates2 = [ (temp,reg)
746                             | (temp, InReg reg) <- ufmToList assig,
747                               temp `notElem` keep', regClass (RealReg reg) == regClass r  ]
748             -- in
749             ASSERT2(not (null candidates1 && null candidates2), 
750                     text (show freeregs) <+> ppr r <+> ppr assig) do
751
752             case candidates1 of
753
754              -- we have a temporary that is in both register and mem,
755              -- just free up its register for use.
756              -- 
757              (temp,my_reg,slot):_ -> do
758                 spills' <- do_load reading loc my_reg spills
759                 let     
760                   assig1  = addToUFM assig temp (InMem slot)
761                   assig2  = addToUFM assig1 r (InReg my_reg)
762                 -- in
763                 setAssigR assig2
764                 allocateRegsAndSpill reading keep spills' (my_reg:alloc) rs
765
766              -- otherwise, we need to spill a temporary that currently
767              -- resides in a register.
768              [] -> do
769                 let
770                   (temp_to_push_out, my_reg) = myHead "regalloc" candidates2
771                   -- TODO: plenty of room for optimisation in choosing which temp
772                   -- to spill.  We just pick the first one that isn't used in 
773                   -- the current instruction for now.
774                 -- in
775                 (spill_insn,slot) <- spillR (RealReg my_reg) temp_to_push_out
776                 let     
777                   assig1  = addToUFM assig temp_to_push_out (InMem slot)
778                   assig2  = addToUFM assig1 r (InReg my_reg)
779                 -- in
780                 setAssigR assig2
781                 spills' <- do_load reading loc my_reg spills
782                 allocateRegsAndSpill reading keep (spill_insn:spills')
783                         (my_reg:alloc) rs
784   where
785         -- load up a spilled temporary if we need to
786         do_load True (Just (InMem slot)) reg spills = do
787            insn <- loadR (RealReg reg) slot
788            return (insn : spills)
789         do_load _ _ _ spills = 
790            return spills
791
792 myHead s [] = panic s
793 myHead s (x:xs) = x
794
795 -- -----------------------------------------------------------------------------
796 -- Joining a jump instruction to its targets
797
798 -- The first time we encounter a jump to a particular basic block, we
799 -- record the assignment of temporaries.  The next time we encounter a
800 -- jump to the same block, we compare our current assignment to the
801 -- stored one.  They might be different if spilling has occrred in one
802 -- branch; so some fixup code will be required to match up the
803 -- assignments.
804
805 joinToTargets
806         :: BlockMap RegSet
807         -> [NatBasicBlock]
808         -> Instr
809         -> [BlockId]
810         -> RegM ([NatBasicBlock], Instr)
811
812 joinToTargets block_live new_blocks instr []
813   = return (new_blocks, instr)
814 joinToTargets block_live new_blocks instr (dest:dests) = do
815   block_assig <- getBlockAssigR
816   assig <- getAssigR
817   let
818         -- adjust the assignment to remove any registers which are not
819         -- live on entry to the destination block.
820         adjusted_assig = filterUFM_Directly still_live assig
821         still_live uniq _ = uniq `elemUniqSet_Directly` live_set
822
823         -- and free up those registers which are now free.
824         to_free =
825           [ r | (reg, loc) <- ufmToList assig, 
826                 not (elemUniqSet_Directly reg live_set), 
827                 r <- regsOfLoc loc ]
828
829         regsOfLoc (InReg r)    = [r]
830         regsOfLoc (InBoth r _) = [r]
831         regsOfLoc (InMem _)    = []
832   -- in
833   case lookupUFM block_assig dest of
834         -- Nothing <=> this is the first time we jumped to this
835         -- block.
836         Nothing -> do
837           freeregs <- getFreeRegsR
838           let freeregs' = foldr releaseReg freeregs to_free 
839           stack <- getStackR
840           setBlockAssigR (addToUFM block_assig dest 
841                                 (freeregs',stack,adjusted_assig))
842           joinToTargets block_live new_blocks instr dests
843
844         Just (freeregs,stack,dest_assig)
845            | ufmToList dest_assig == ufmToList adjusted_assig
846            -> -- ok, the assignments match
847              joinToTargets block_live new_blocks instr dests
848            | otherwise
849            -> -- need fixup code
850              do
851                delta <- getDeltaR
852                -- Construct a graph of register/spill movements and
853                -- untangle it component by component.
854                -- 
855                -- We cut some corners by
856                -- a) not handling cyclic components
857                -- b) not handling memory-to-memory moves.
858                --
859                -- Cyclic components seem to occur only very rarely,
860                -- and we don't need memory-to-memory moves because we
861                -- make sure that every temporary always gets its own
862                -- stack slot.
863                
864                let graph = [ node | (vreg, src) <- ufmToList adjusted_assig,
865                                     node <- mkNodes src vreg ]
866
867                    sccs = stronglyConnCompR graph
868                    
869                    mkNodes src vreg = 
870                         expandNode src (lookupWithDefaultUFM_Directly
871                                           dest_assig
872                                           (panic "RegisterAlloc.joinToTargets")
873                                           vreg)
874
875                 -- The InBoth handling is a little tricky here.  If
876                 -- the destination is InBoth, then we must ensure that
877                 -- the value ends up in both locations.  An InBoth
878                 -- destination must conflict with an InReg or InMem
879                 -- source, so we expand an InBoth destination as
880                 -- necessary.  An InBoth source is slightly different:
881                 -- we only care about the register that the source value
882                 -- is in, so that we can move it to the destinations.
883
884                    expandNode loc@(InReg src) (InBoth dst mem)
885                         | src == dst = [(loc, loc, [InMem dst])]
886                         | otherwise  = [(loc, loc, [InReg dst, InMem mem])]
887                    expandNode loc@(InMem src) (InBoth dst mem)
888                         | src == mem = [(loc, loc, [InReg dst])]
889                         | otherwise  = [(loc, loc, [InReg dst, InMem mem])]
890                    expandNode loc@(InBoth _ src) (InMem dst)
891                         | src == dst = [] -- guaranteed to be true
892                    expandNode loc@(InBoth src _) (InReg dst)
893                         | src == dst = []
894                    expandNode loc@(InBoth src _) dst
895                         = expandNode (InReg src) dst
896                    expandNode src dst
897                         | src == dst = []
898                         | otherwise  = [(src, src, [dst])]
899
900                 -- we have eliminated any possibility of single-node cylces
901                 -- in expandNode above.
902                    handleComponent (AcyclicSCC (src,_,dsts))
903                        = map (makeMove src) dsts
904                    handleComponent (CyclicSCC things)
905                        = panic $ "Register Allocator: handleComponent: cyclic"
906                                  ++ " (workaround: use -fviaC)"
907                    
908                    makeMove (InReg src) (InReg dst)
909                        = mkRegRegMoveInstr (RealReg src) (RealReg dst)
910                    makeMove (InMem src) (InReg dst)
911                        = mkLoadInstr (RealReg dst) delta src
912                    makeMove (InReg src) (InMem dst)
913                        = mkSpillInstr (RealReg src) delta dst
914                    makeMove src dst
915                        = panic $ "makeMove (" ++ show src ++ ") ("
916                                  ++ show dst ++ ")"
917                                  ++ " (workaround: use -fviaC)"
918              
919                block_id <- getUniqueR
920                let block = BasicBlock (BlockId block_id) $
921                        concatMap handleComponent sccs ++ mkBranchInstr dest
922                let instr' = patchJump instr dest (BlockId block_id)
923                joinToTargets block_live (block : new_blocks) instr' dests
924   where
925         live_set = lookItUp "joinToTargets" block_live dest
926
927 -- -----------------------------------------------------------------------------
928 -- The register allocator's monad.  
929
930 -- Here we keep all the state that the register allocator keeps track
931 -- of as it walks the instructions in a basic block.
932
933 data RA_State 
934   = RA_State {
935         ra_blockassig :: BlockAssignment,
936                 -- The current mapping from basic blocks to 
937                 -- the register assignments at the beginning of that block.
938         ra_freeregs   :: {-#UNPACK#-}!FreeRegs, -- free machine registers
939         ra_assig      :: RegMap Loc,    -- assignment of temps to locations
940         ra_delta      :: Int,           -- current stack delta
941         ra_stack      :: FreeStack,     -- free stack slots for spilling
942         ra_us         :: UniqSupply     -- unique supply for generating names
943                                         -- for fixup blocks.
944   }
945
946 newtype RegM a = RegM { unReg :: RA_State -> (# RA_State, a #) }
947
948 instance Monad RegM where
949   m >>= k   =  RegM $ \s -> case unReg m s of { (# s, a #) -> unReg (k a) s }
950   return a  =  RegM $ \s -> (# s, a #)
951
952 runR :: BlockAssignment -> FreeRegs -> RegMap Loc -> FreeStack -> UniqSupply
953   -> RegM a -> (BlockAssignment, a)
954 runR block_assig freeregs assig stack us thing =
955   case unReg thing (RA_State{ ra_blockassig=block_assig, ra_freeregs=freeregs,
956                         ra_assig=assig, ra_delta=0{-???-}, ra_stack=stack,
957                         ra_us = us }) of
958         (# RA_State{ ra_blockassig=block_assig }, returned_thing #)
959                 -> (block_assig, returned_thing)
960
961 spillR :: Reg -> Unique -> RegM (Instr, Int)
962 spillR reg temp = RegM $ \ s@RA_State{ra_delta=delta, ra_stack=stack} ->
963   let (stack',slot) = getFreeStackSlotFor stack temp
964       instr  = mkSpillInstr reg delta slot
965   in
966   (# s{ra_stack=stack'}, (instr,slot) #)
967
968 loadR :: Reg -> Int -> RegM Instr
969 loadR reg slot = RegM $ \ s@RA_State{ra_delta=delta, ra_stack=stack} ->
970   (# s, mkLoadInstr reg delta slot #)
971
972 freeSlotR :: Int -> RegM ()
973 freeSlotR slot = RegM $ \ s@RA_State{ra_stack=stack} ->
974   (# s{ra_stack=freeStackSlot stack slot}, () #)
975
976 getFreeRegsR :: RegM FreeRegs
977 getFreeRegsR = RegM $ \ s@RA_State{ra_freeregs = freeregs} ->
978   (# s, freeregs #)
979
980 setFreeRegsR :: FreeRegs -> RegM ()
981 setFreeRegsR regs = RegM $ \ s ->
982   (# s{ra_freeregs = regs}, () #)
983
984 getAssigR :: RegM (RegMap Loc)
985 getAssigR = RegM $ \ s@RA_State{ra_assig = assig} ->
986   (# s, assig #)
987
988 setAssigR :: RegMap Loc -> RegM ()
989 setAssigR assig = RegM $ \ s ->
990   (# s{ra_assig=assig}, () #)
991
992 getStackR :: RegM FreeStack
993 getStackR = RegM $ \ s@RA_State{ra_stack = stack} ->
994   (# s, stack #)
995
996 setStackR :: FreeStack -> RegM ()
997 setStackR stack = RegM $ \ s ->
998   (# s{ra_stack=stack}, () #)
999
1000 getBlockAssigR :: RegM BlockAssignment
1001 getBlockAssigR = RegM $ \ s@RA_State{ra_blockassig = assig} ->
1002   (# s, assig #)
1003
1004 setBlockAssigR :: BlockAssignment -> RegM ()
1005 setBlockAssigR assig = RegM $ \ s ->
1006   (# s{ra_blockassig = assig}, () #)
1007
1008 setDeltaR :: Int -> RegM ()
1009 setDeltaR n = RegM $ \ s ->
1010   (# s{ra_delta = n}, () #)
1011
1012 getDeltaR :: RegM Int
1013 getDeltaR = RegM $ \s -> (# s, ra_delta s #)
1014
1015 getUniqueR :: RegM Unique
1016 getUniqueR = RegM $ \s ->
1017   case splitUniqSupply (ra_us s) of
1018     (us1, us2) -> (# s{ra_us = us2}, uniqFromSupply us1 #)
1019
1020 -- -----------------------------------------------------------------------------
1021 -- Utils
1022
1023 #ifdef DEBUG
1024 my_fromJust s p Nothing  = pprPanic ("fromJust: " ++ s) p
1025 my_fromJust s p (Just x) = x
1026 #else
1027 my_fromJust _ _ = fromJust
1028 #endif
1029
1030 lookItUp :: Uniquable b => String -> UniqFM a -> b -> a
1031 lookItUp str fm x = my_fromJust str (ppr (getUnique x)) (lookupUFM fm x)