d7659b5c86a9f110f657f893ab24230dff6f4d22
[ghc-hetmet.git] / compiler / nativeGen / RegAlloc / Liveness.hs
1 -----------------------------------------------------------------------------
2 --
3 -- The register liveness determinator
4 --
5 -- (c) The University of Glasgow 2004
6 --
7 -----------------------------------------------------------------------------
8 {-# OPTIONS -Wall -fno-warn-name-shadowing #-}
9
10 module RegAlloc.Liveness (
11         RegSet,
12         RegMap, emptyRegMap,
13         BlockMap, emptyBlockMap,
14         LiveCmmTop,
15         InstrSR   (..),
16         LiveInstr (..),
17         Liveness (..),
18         LiveInfo (..),
19         LiveBasicBlock,
20
21         mapBlockTop,    mapBlockTopM,
22         mapGenBlockTop, mapGenBlockTopM,
23         stripLive,
24         stripLiveBlock,
25         slurpConflicts,
26         slurpReloadCoalesce,
27         eraseDeltasLive,
28         patchEraseLive,
29         patchRegsLiveInstr,
30         reverseBlocksInTops,
31         regLiveness,
32         natCmmTopToLive
33   ) where
34
35
36 import Reg
37 import Instruction
38
39 import BlockId
40 import Cmm hiding (RegSet)
41 import PprCmm()
42
43 import Digraph
44 import Outputable
45 import Unique
46 import UniqSet
47 import UniqFM
48 import UniqSupply
49 import Bag
50 import State
51 import FastString
52
53 import Data.List
54 import Data.Maybe
55
56 -----------------------------------------------------------------------------
57 type RegSet = UniqSet Reg
58
59 type RegMap a = UniqFM a
60
61 emptyRegMap :: UniqFM a
62 emptyRegMap = emptyUFM
63
64 type BlockMap a = BlockEnv a
65
66 emptyBlockMap :: BlockEnv a
67 emptyBlockMap = emptyBlockEnv
68
69
70 -- | A top level thing which carries liveness information.
71 type LiveCmmTop instr
72         = GenCmmTop
73                 CmmStatic
74                 LiveInfo
75                 [SCC (LiveBasicBlock instr)]
76
77
78 -- | The register allocator also wants to use SPILL/RELOAD meta instructions,
79 --      so we'll keep those here.
80 data InstrSR instr
81         -- | A real machine instruction
82         = Instr  instr
83
84         -- | spill this reg to a stack slot
85         | SPILL  Reg Int
86
87         -- | reload this reg from a stack slot
88         | RELOAD Int Reg
89
90 instance Instruction instr => Instruction (InstrSR instr) where
91         regUsageOfInstr i
92          = case i of
93                 Instr  instr    -> regUsageOfInstr instr
94                 SPILL  reg _    -> RU [reg] []
95                 RELOAD _ reg    -> RU [] [reg]
96
97         patchRegsOfInstr i f
98          = case i of
99                 Instr instr     -> Instr (patchRegsOfInstr instr f)
100                 SPILL  reg slot -> SPILL (f reg) slot
101                 RELOAD slot reg -> RELOAD slot (f reg)
102
103         isJumpishInstr i
104          = case i of
105                 Instr instr     -> isJumpishInstr instr
106                 _               -> False
107
108         jumpDestsOfInstr i
109          = case i of
110                 Instr instr     -> jumpDestsOfInstr instr 
111                 _               -> []
112
113         patchJumpInstr i f
114          = case i of
115                 Instr instr     -> Instr (patchJumpInstr instr f)
116                 _               -> i
117
118         mkSpillInstr            = error "mkSpillInstr[InstrSR]: Not making SPILL meta-instr"
119         mkLoadInstr             = error "mkLoadInstr[InstrSR]: Not making LOAD meta-instr"
120
121         takeDeltaInstr i
122          = case i of
123                 Instr instr     -> takeDeltaInstr instr
124                 _               -> Nothing
125
126         isMetaInstr i
127          = case i of
128                 Instr instr     -> isMetaInstr instr
129                 _               -> False
130
131         mkRegRegMoveInstr r1 r2 = Instr (mkRegRegMoveInstr r1 r2)
132
133         takeRegRegMoveInstr i
134          = case i of
135                 Instr instr     -> takeRegRegMoveInstr instr
136                 _               -> Nothing
137
138         mkJumpInstr target      = map Instr (mkJumpInstr target)
139                 
140
141
142 -- | An instruction with liveness information.
143 data LiveInstr instr
144         = LiveInstr (InstrSR instr) (Maybe Liveness)
145
146 -- | Liveness information.
147 --      The regs which die are ones which are no longer live in the *next* instruction
148 --      in this sequence.
149 --      (NB. if the instruction is a jump, these registers might still be live
150 --      at the jump target(s) - you have to check the liveness at the destination
151 --      block to find out).
152
153 data Liveness
154         = Liveness
155         { liveBorn      :: RegSet       -- ^ registers born in this instruction (written to for first time).
156         , liveDieRead   :: RegSet       -- ^ registers that died because they were read for the last time.
157         , liveDieWrite  :: RegSet }     -- ^ registers that died because they were clobbered by something.
158
159
160 -- | Stash regs live on entry to each basic block in the info part of the cmm code.
161 data LiveInfo
162         = LiveInfo
163                 [CmmStatic]                     -- cmm static stuff
164                 (Maybe BlockId)                 -- id of the first block
165                 (Maybe (BlockMap RegSet))       -- argument locals live on entry to this block
166
167 -- | A basic block with liveness information.
168 type LiveBasicBlock instr
169         = GenBasicBlock (LiveInstr instr)
170
171
172 instance Outputable instr
173       => Outputable (InstrSR instr) where
174
175         ppr (Instr realInstr)
176            = ppr realInstr
177
178         ppr (SPILL reg slot)
179            = hcat [
180                 ptext (sLit "\tSPILL"),
181                 char ' ',
182                 ppr reg,
183                 comma,
184                 ptext (sLit "SLOT") <> parens (int slot)]
185
186         ppr (RELOAD slot reg)
187            = hcat [
188                 ptext (sLit "\tRELOAD"),
189                 char ' ',
190                 ptext (sLit "SLOT") <> parens (int slot),
191                 comma,
192                 ppr reg]
193
194 instance Outputable instr 
195       => Outputable (LiveInstr instr) where
196
197         ppr (LiveInstr instr Nothing)
198          = ppr instr
199
200         ppr (LiveInstr instr (Just live))
201          =  ppr instr
202                 $$ (nest 8
203                         $ vcat
204                         [ pprRegs (ptext (sLit "# born:    ")) (liveBorn live)
205                         , pprRegs (ptext (sLit "# r_dying: ")) (liveDieRead live)
206                         , pprRegs (ptext (sLit "# w_dying: ")) (liveDieWrite live) ]
207                     $+$ space)
208
209          where  pprRegs :: SDoc -> RegSet -> SDoc
210                 pprRegs name regs
211                  | isEmptyUniqSet regs  = empty
212                  | otherwise            = name <> (hcat $ punctuate space $ map ppr $ uniqSetToList regs)
213
214 instance Outputable LiveInfo where
215         ppr (LiveInfo static firstId liveOnEntry)
216                 =  (vcat $ map ppr static)
217                 $$ text "# firstId     = " <> ppr firstId
218                 $$ text "# liveOnEntry = " <> ppr liveOnEntry
219
220
221
222 -- | map a function across all the basic blocks in this code
223 --
224 mapBlockTop
225         :: (LiveBasicBlock instr -> LiveBasicBlock instr)
226         -> LiveCmmTop instr -> LiveCmmTop instr
227
228 mapBlockTop f cmm
229         = evalState (mapBlockTopM (\x -> return $ f x) cmm) ()
230
231
232 -- | map a function across all the basic blocks in this code (monadic version)
233 --
234 mapBlockTopM
235         :: Monad m
236         => (LiveBasicBlock instr -> m (LiveBasicBlock instr))
237         -> LiveCmmTop instr -> m (LiveCmmTop instr)
238
239 mapBlockTopM _ cmm@(CmmData{})
240         = return cmm
241
242 mapBlockTopM f (CmmProc header label params sccs)
243  = do   sccs'   <- mapM (mapSCCM f) sccs
244         return  $ CmmProc header label params sccs'
245
246 mapSCCM :: Monad m => (a -> m b) -> SCC a -> m (SCC b)
247 mapSCCM f (AcyclicSCC x)        
248  = do   x'      <- f x
249         return  $ AcyclicSCC x'
250
251 mapSCCM f (CyclicSCC xs)
252  = do   xs'     <- mapM f xs
253         return  $ CyclicSCC xs'
254
255
256 -- map a function across all the basic blocks in this code
257 mapGenBlockTop
258         :: (GenBasicBlock             i -> GenBasicBlock            i)
259         -> (GenCmmTop d h (ListGraph i) -> GenCmmTop d h (ListGraph i))
260
261 mapGenBlockTop f cmm
262         = evalState (mapGenBlockTopM (\x -> return $ f x) cmm) ()
263
264
265 -- | map a function across all the basic blocks in this code (monadic version)
266 mapGenBlockTopM
267         :: Monad m
268         => (GenBasicBlock            i  -> m (GenBasicBlock            i))
269         -> (GenCmmTop d h (ListGraph i) -> m (GenCmmTop d h (ListGraph i)))
270
271 mapGenBlockTopM _ cmm@(CmmData{})
272         = return cmm
273
274 mapGenBlockTopM f (CmmProc header label params (ListGraph blocks))
275  = do   blocks' <- mapM f blocks
276         return  $ CmmProc header label params (ListGraph blocks')
277
278
279 -- | Slurp out the list of register conflicts and reg-reg moves from this top level thing.
280 --      Slurping of conflicts and moves is wrapped up together so we don't have
281 --      to make two passes over the same code when we want to build the graph.
282 --
283 slurpConflicts 
284         :: Instruction instr
285         => LiveCmmTop instr 
286         -> (Bag (UniqSet Reg), Bag (Reg, Reg))
287
288 slurpConflicts live
289         = slurpCmm (emptyBag, emptyBag) live
290
291  where  slurpCmm   rs  CmmData{}                = rs
292         slurpCmm   rs (CmmProc info _ _ sccs)
293                 = foldl' (slurpSCC info) rs sccs
294
295         slurpSCC  info rs (AcyclicSCC b)        
296                 = slurpBlock info rs b
297
298         slurpSCC  info rs (CyclicSCC bs)
299                 = foldl'  (slurpBlock info) rs bs
300
301         slurpBlock info rs (BasicBlock blockId instrs)  
302                 | LiveInfo _ _ (Just blockLive) <- info
303                 , Just rsLiveEntry              <- lookupBlockEnv blockLive blockId
304                 , (conflicts, moves)            <- slurpLIs rsLiveEntry rs instrs
305                 = (consBag rsLiveEntry conflicts, moves)
306
307                 | otherwise
308                 = panic "Liveness.slurpConflicts: bad block"
309
310         slurpLIs rsLive (conflicts, moves) []
311                 = (consBag rsLive conflicts, moves)
312
313         slurpLIs rsLive rs (LiveInstr _ Nothing     : lis)      
314                 = slurpLIs rsLive rs lis
315                 
316         slurpLIs rsLiveEntry (conflicts, moves) (LiveInstr instr (Just live) : lis)
317          = let
318                 -- regs that die because they are read for the last time at the start of an instruction
319                 --      are not live across it.
320                 rsLiveAcross    = rsLiveEntry `minusUniqSet` (liveDieRead live)
321
322                 -- regs live on entry to the next instruction.
323                 --      be careful of orphans, make sure to delete dying regs _after_ unioning
324                 --      in the ones that are born here.
325                 rsLiveNext      = (rsLiveAcross `unionUniqSets` (liveBorn     live))
326                                                 `minusUniqSet`  (liveDieWrite live)
327
328                 -- orphan vregs are the ones that die in the same instruction they are born in.
329                 --      these are likely to be results that are never used, but we still
330                 --      need to assign a hreg to them..
331                 rsOrphans       = intersectUniqSets
332                                         (liveBorn live)
333                                         (unionUniqSets (liveDieWrite live) (liveDieRead live))
334
335                 --
336                 rsConflicts     = unionUniqSets rsLiveNext rsOrphans
337
338           in    case takeRegRegMoveInstr instr of
339                  Just rr        -> slurpLIs rsLiveNext
340                                         ( consBag rsConflicts conflicts
341                                         , consBag rr moves) lis
342
343                  Nothing        -> slurpLIs rsLiveNext
344                                         ( consBag rsConflicts conflicts
345                                         , moves) lis
346
347
348 -- | For spill\/reloads
349 --
350 --      SPILL  v1, slot1
351 --      ...
352 --      RELOAD slot1, v2
353 --
354 --      If we can arrange that v1 and v2 are allocated to the same hreg it's more likely
355 --      the spill\/reload instrs can be cleaned and replaced by a nop reg-reg move.
356 --
357 --
358 slurpReloadCoalesce 
359         :: Instruction instr
360         => LiveCmmTop instr
361         -> Bag (Reg, Reg)
362
363 slurpReloadCoalesce live
364         = slurpCmm emptyBag live
365
366  where  slurpCmm cs CmmData{}   = cs
367         slurpCmm cs (CmmProc _ _ _ sccs)
368                 = slurpComp cs (flattenSCCs sccs)
369
370         slurpComp  cs blocks
371          = let  (moveBags, _)   = runState (slurpCompM blocks) emptyUFM
372            in   unionManyBags (cs : moveBags)
373
374         slurpCompM blocks
375          = do   -- run the analysis once to record the mapping across jumps.
376                 mapM_   (slurpBlock False) blocks
377
378                 -- run it a second time while using the information from the last pass.
379                 --      We /could/ run this many more times to deal with graphical control
380                 --      flow and propagating info across multiple jumps, but it's probably
381                 --      not worth the trouble.
382                 mapM    (slurpBlock True) blocks
383
384         slurpBlock propagate (BasicBlock blockId instrs)
385          = do   -- grab the slot map for entry to this block
386                 slotMap         <- if propagate
387                                         then getSlotMap blockId
388                                         else return emptyUFM
389
390                 (_, mMoves)     <- mapAccumLM slurpLI slotMap instrs
391                 return $ listToBag $ catMaybes mMoves
392
393         slurpLI :: Instruction instr
394                 => UniqFM Reg                           -- current slotMap
395                 -> LiveInstr instr
396                 -> State (UniqFM [UniqFM Reg])          -- blockId -> [slot -> reg]
397                                                         --      for tracking slotMaps across jumps
398
399                          ( UniqFM Reg                   -- new slotMap
400                          , Maybe (Reg, Reg))            -- maybe a new coalesce edge
401
402         slurpLI slotMap li
403
404                 -- remember what reg was stored into the slot
405                 | LiveInstr (SPILL reg slot) _  <- li
406                 , slotMap'                      <- addToUFM slotMap slot reg
407                 = return (slotMap', Nothing)
408
409                 -- add an edge betwen the this reg and the last one stored into the slot
410                 | LiveInstr (RELOAD slot reg) _ <- li
411                 = case lookupUFM slotMap slot of
412                         Just reg2
413                          | reg /= reg2  -> return (slotMap, Just (reg, reg2))
414                          | otherwise    -> return (slotMap, Nothing)
415
416                         Nothing         -> return (slotMap, Nothing)
417
418                 -- if we hit a jump, remember the current slotMap
419                 | LiveInstr (Instr instr) _     <- li
420                 , targets                       <- jumpDestsOfInstr instr
421                 , not $ null targets
422                 = do    mapM_   (accSlotMap slotMap) targets
423                         return  (slotMap, Nothing)
424
425                 | otherwise
426                 = return (slotMap, Nothing)
427
428         -- record a slotmap for an in edge to this block
429         accSlotMap slotMap blockId
430                 = modify (\s -> addToUFM_C (++) s blockId [slotMap])
431
432         -- work out the slot map on entry to this block
433         --      if we have slot maps for multiple in-edges then we need to merge them.
434         getSlotMap blockId
435          = do   map             <- get
436                 let slotMaps    = fromMaybe [] (lookupUFM map blockId)
437                 return          $ foldr mergeSlotMaps emptyUFM slotMaps
438
439         mergeSlotMaps :: UniqFM Reg -> UniqFM Reg -> UniqFM Reg
440         mergeSlotMaps map1 map2
441                 = listToUFM
442                 $ [ (k, r1)     | (k, r1)       <- ufmToList map1
443                                 , case lookupUFM map2 k of
444                                         Nothing -> False
445                                         Just r2 -> r1 == r2 ]
446
447
448 -- | Strip away liveness information, yielding NatCmmTop
449 stripLive 
450         :: (Outputable instr, Instruction instr)
451         => LiveCmmTop instr 
452         -> NatCmmTop instr
453
454 stripLive live
455         = stripCmm live
456
457  where  stripCmm (CmmData sec ds)       = CmmData sec ds
458
459         stripCmm (CmmProc (LiveInfo info (Just first_id) _) label params sccs)
460          = let  final_blocks    = flattenSCCs sccs
461                 
462                 -- make sure the block that was first in the input list
463                 --      stays at the front of the output. This is the entry point
464                 --      of the proc, and it needs to come first.
465                 ((first':_), rest')
466                                 = partition ((== first_id) . blockId) final_blocks
467
468            in   CmmProc info label params
469                           (ListGraph $ map stripLiveBlock $ first' : rest')
470
471         -- procs used for stg_split_markers don't contain any blocks, and have no first_id.
472         stripCmm (CmmProc (LiveInfo info Nothing _) label params [])
473          =      CmmProc info label params (ListGraph [])
474
475         -- If the proc has blocks but we don't know what the first one was, then we're dead.
476         stripCmm proc
477                  = pprPanic "RegAlloc.Liveness.stripLive: no first_id on proc" (ppr proc)
478                         
479
480 -- | Strip away liveness information from a basic block,
481 --      and make real spill instructions out of SPILL, RELOAD pseudos along the way.
482
483 stripLiveBlock
484         :: Instruction instr
485         => LiveBasicBlock instr
486         -> NatBasicBlock instr
487
488 stripLiveBlock (BasicBlock i lis)
489  =      BasicBlock i instrs'
490
491  where  (instrs', _)
492                 = runState (spillNat [] lis) 0
493
494         spillNat acc []
495          =      return (reverse acc)
496
497         spillNat acc (LiveInstr (SPILL reg slot) _ : instrs)
498          = do   delta   <- get
499                 spillNat (mkSpillInstr reg delta slot : acc) instrs
500
501         spillNat acc (LiveInstr (RELOAD slot reg) _ : instrs)
502          = do   delta   <- get
503                 spillNat (mkLoadInstr reg delta slot : acc) instrs
504
505         spillNat acc (LiveInstr (Instr instr) _ : instrs)
506          | Just i <- takeDeltaInstr instr
507          = do   put i
508                 spillNat acc instrs
509
510         spillNat acc (LiveInstr (Instr instr) _ : instrs)
511          =      spillNat (instr : acc) instrs
512
513
514 -- | Erase Delta instructions.
515
516 eraseDeltasLive 
517         :: Instruction instr
518         => LiveCmmTop instr
519         -> LiveCmmTop instr
520
521 eraseDeltasLive cmm
522         = mapBlockTop eraseBlock cmm
523  where
524         eraseBlock (BasicBlock id lis)
525                 = BasicBlock id
526                 $ filter (\(LiveInstr i _) -> not $ isJust $ takeDeltaInstr i)
527                 $ lis
528
529
530 -- | Patch the registers in this code according to this register mapping.
531 --      also erase reg -> reg moves when the reg is the same.
532 --      also erase reg -> reg moves when the destination dies in this instr.
533
534 patchEraseLive
535         :: Instruction instr
536         => (Reg -> Reg)
537         -> LiveCmmTop instr -> LiveCmmTop instr
538
539 patchEraseLive patchF cmm
540         = patchCmm cmm
541  where
542         patchCmm cmm@CmmData{}  = cmm
543
544         patchCmm (CmmProc info label params sccs)
545          | LiveInfo static id (Just blockMap)   <- info
546          = let  
547                 patchRegSet set = mkUniqSet $ map patchF $ uniqSetToList set
548                 blockMap'       = mapBlockEnv patchRegSet blockMap
549
550                 info'           = LiveInfo static id (Just blockMap')
551            in   CmmProc info' label params $ map patchSCC sccs
552
553          | otherwise
554          = panic "RegAlloc.Liveness.patchEraseLive: no blockMap"
555
556         patchSCC (AcyclicSCC b)  = AcyclicSCC (patchBlock b)
557         patchSCC (CyclicSCC  bs) = CyclicSCC  (map patchBlock bs)
558
559         patchBlock (BasicBlock id lis)
560                 = BasicBlock id $ patchInstrs lis
561
562         patchInstrs []          = []
563         patchInstrs (li : lis)
564
565                 | LiveInstr i (Just live)       <- li'
566                 , Just (r1, r2) <- takeRegRegMoveInstr i
567                 , eatMe r1 r2 live
568                 = patchInstrs lis
569
570                 | otherwise
571                 = li' : patchInstrs lis
572
573                 where   li'     = patchRegsLiveInstr patchF li
574
575         eatMe   r1 r2 live
576                 -- source and destination regs are the same
577                 | r1 == r2      = True
578
579                 -- desination reg is never used
580                 | elementOfUniqSet r2 (liveBorn live)
581                 , elementOfUniqSet r2 (liveDieRead live) || elementOfUniqSet r2 (liveDieWrite live)
582                 = True
583
584                 | otherwise     = False
585
586
587 -- | Patch registers in this LiveInstr, including the liveness information.
588 --
589 patchRegsLiveInstr
590         :: Instruction instr
591         => (Reg -> Reg)
592         -> LiveInstr instr -> LiveInstr instr
593
594 patchRegsLiveInstr patchF li
595  = case li of
596         LiveInstr instr Nothing
597          -> LiveInstr (patchRegsOfInstr instr patchF) Nothing
598
599         LiveInstr instr (Just live)
600          -> LiveInstr
601                 (patchRegsOfInstr instr patchF)
602                 (Just live
603                         { -- WARNING: have to go via lists here because patchF changes the uniq in the Reg
604                           liveBorn      = mkUniqSet $ map patchF $ uniqSetToList $ liveBorn live
605                         , liveDieRead   = mkUniqSet $ map patchF $ uniqSetToList $ liveDieRead live
606                         , liveDieWrite  = mkUniqSet $ map patchF $ uniqSetToList $ liveDieWrite live })
607
608
609 --------------------------------------------------------------------------------
610 -- | Convert a NatCmmTop to a LiveCmmTop, with empty liveness information
611
612 natCmmTopToLive 
613         :: Instruction instr
614         => NatCmmTop instr
615         -> LiveCmmTop instr
616
617 natCmmTopToLive (CmmData i d)
618         = CmmData i d
619
620 natCmmTopToLive (CmmProc info lbl params (ListGraph []))
621         = CmmProc (LiveInfo info Nothing Nothing)
622                   lbl params []
623
624 natCmmTopToLive (CmmProc info lbl params (ListGraph blocks@(first : _)))
625  = let  first_id        = blockId first
626         sccs            = sccBlocks blocks
627         sccsLive        = map (fmap (\(BasicBlock l instrs) -> 
628                                         BasicBlock l (map (\i -> LiveInstr (Instr i) Nothing) instrs)))
629                         $ sccs
630                                 
631    in   CmmProc (LiveInfo info (Just first_id) Nothing)
632                 lbl params sccsLive
633
634
635 sccBlocks 
636         :: Instruction instr
637         => [NatBasicBlock instr] 
638         -> [SCC (NatBasicBlock instr)]
639
640 sccBlocks blocks = stronglyConnCompFromEdgedVertices graph
641   where
642         getOutEdges :: Instruction instr => [instr] -> [BlockId]
643         getOutEdges instrs = concat $ map jumpDestsOfInstr instrs
644
645         graph = [ (block, getUnique id, map getUnique (getOutEdges instrs))
646                 | block@(BasicBlock id instrs) <- blocks ]
647
648
649 ---------------------------------------------------------------------------------
650 -- Annotate code with register liveness information
651 --
652 regLiveness
653         :: (Outputable instr, Instruction instr)
654         => LiveCmmTop instr
655         -> UniqSM (LiveCmmTop instr)
656
657 regLiveness (CmmData i d)
658         = returnUs $ CmmData i d
659
660 regLiveness (CmmProc info lbl params [])
661         | LiveInfo static mFirst _      <- info
662         = returnUs $ CmmProc
663                         (LiveInfo static mFirst (Just emptyBlockEnv))
664                         lbl params []
665
666 regLiveness (CmmProc info lbl params sccs)
667         | LiveInfo static mFirst _      <- info
668         = let   (ann_sccs, block_live)  = computeLiveness sccs
669
670           in    returnUs $ CmmProc (LiveInfo static mFirst (Just block_live))
671                            lbl params ann_sccs
672
673
674 -- -----------------------------------------------------------------------------
675 -- | Check ordering of Blocks
676 --      The computeLiveness function requires SCCs to be in reverse dependent order.
677 --      If they're not the liveness information will be wrong, and we'll get a bad allocation.
678 --      Better to check for this precondition explicitly or some other poor sucker will
679 --      waste a day staring at bad assembly code..
680 --      
681 checkIsReverseDependent
682         :: Instruction instr
683         => [SCC (LiveBasicBlock instr)]         -- ^ SCCs of blocks that we're about to run the liveness determinator on.
684         -> Maybe BlockId                        -- ^ BlockIds that fail the test (if any)
685         
686 checkIsReverseDependent sccs'
687  = go emptyUniqSet sccs'
688
689  where  go _ []
690          = Nothing
691         
692         go blocksSeen (AcyclicSCC block : sccs)
693          = let  dests           = slurpJumpDestsOfBlock block
694                 blocksSeen'     = unionUniqSets blocksSeen $ mkUniqSet [blockId block]
695                 badDests        = dests `minusUniqSet` blocksSeen'
696            in   case uniqSetToList badDests of
697                  []             -> go blocksSeen' sccs
698                  bad : _        -> Just bad
699                 
700         go blocksSeen (CyclicSCC blocks : sccs)
701          = let  dests           = unionManyUniqSets $ map slurpJumpDestsOfBlock blocks
702                 blocksSeen'     = unionUniqSets blocksSeen $ mkUniqSet $ map blockId blocks
703                 badDests        = dests `minusUniqSet` blocksSeen'
704            in   case uniqSetToList badDests of
705                  []             -> go blocksSeen' sccs
706                  bad : _        -> Just bad
707                 
708         slurpJumpDestsOfBlock (BasicBlock _ instrs)
709                 = unionManyUniqSets
710                 $ map (mkUniqSet . jumpDestsOfInstr) 
711                         [ i | LiveInstr i _ <- instrs]
712
713
714 -- | If we've compute liveness info for this code already we have to reverse
715 --   the SCCs in each top to get them back to the right order so we can do it again.
716 reverseBlocksInTops :: LiveCmmTop instr -> LiveCmmTop instr
717 reverseBlocksInTops top
718  = case top of
719         CmmData{}                       -> top
720         CmmProc info lbl params sccs    -> CmmProc info lbl params (reverse sccs)
721
722         
723 -- | Computing liveness
724 --      
725 --  On entry, the SCCs must be in "reverse" order: later blocks may transfer
726 --  control to earlier ones only, else `panic`.
727 -- 
728 --  The SCCs returned are in the *opposite* order, which is exactly what we
729 --  want for the next pass.
730 --
731 computeLiveness
732         :: (Outputable instr, Instruction instr)
733         => [SCC (LiveBasicBlock instr)]
734         -> ([SCC (LiveBasicBlock instr)],       -- instructions annotated with list of registers
735                                                 -- which are "dead after this instruction".
736                BlockMap RegSet)                 -- blocks annontated with set of live registers
737                                                 -- on entry to the block.
738
739 computeLiveness sccs
740  = case checkIsReverseDependent sccs of
741         Nothing         -> livenessSCCs emptyBlockMap [] sccs
742         Just bad        -> pprPanic "RegAlloc.Liveness.computeLivenss"
743                                 (vcat   [ text "SCCs aren't in reverse dependent order"
744                                         , text "bad blockId" <+> ppr bad 
745                                         , ppr sccs])
746
747 livenessSCCs
748        :: Instruction instr
749        => BlockMap RegSet
750        -> [SCC (LiveBasicBlock instr)]          -- accum
751        -> [SCC (LiveBasicBlock instr)]
752        -> ( [SCC (LiveBasicBlock instr)]
753           , BlockMap RegSet)
754
755 livenessSCCs blockmap done [] 
756         = (done, blockmap)
757
758 livenessSCCs blockmap done (AcyclicSCC block : sccs)
759  = let  (blockmap', block')     = livenessBlock blockmap block
760    in   livenessSCCs blockmap' (AcyclicSCC block' : done) sccs
761
762 livenessSCCs blockmap done
763         (CyclicSCC blocks : sccs) =
764         livenessSCCs blockmap' (CyclicSCC blocks':done) sccs
765  where      (blockmap', blocks')
766                 = iterateUntilUnchanged linearLiveness equalBlockMaps
767                                       blockmap blocks
768
769             iterateUntilUnchanged
770                 :: (a -> b -> (a,c)) -> (a -> a -> Bool)
771                 -> a -> b
772                 -> (a,c)
773
774             iterateUntilUnchanged f eq a b
775                 = head $
776                   concatMap tail $
777                   groupBy (\(a1, _) (a2, _) -> eq a1 a2) $
778                   iterate (\(a, _) -> f a b) $
779                   (a, panic "RegLiveness.livenessSCCs")
780
781
782             linearLiveness 
783                 :: Instruction instr
784                 => BlockMap RegSet -> [LiveBasicBlock instr]
785                 -> (BlockMap RegSet, [LiveBasicBlock instr])
786
787             linearLiveness = mapAccumL livenessBlock
788
789                 -- probably the least efficient way to compare two
790                 -- BlockMaps for equality.
791             equalBlockMaps a b
792                 = a' == b'
793               where a' = map f $ blockEnvToList a
794                     b' = map f $ blockEnvToList b
795                     f (key,elt) = (key, uniqSetToList elt)
796
797
798
799 -- | Annotate a basic block with register liveness information.
800 --
801 livenessBlock
802         :: Instruction instr
803         => BlockMap RegSet
804         -> LiveBasicBlock instr
805         -> (BlockMap RegSet, LiveBasicBlock instr)
806
807 livenessBlock blockmap (BasicBlock block_id instrs)
808  = let
809         (regsLiveOnEntry, instrs1)
810                 = livenessBack emptyUniqSet blockmap [] (reverse instrs)
811         blockmap'       = extendBlockEnv blockmap block_id regsLiveOnEntry
812
813         instrs2         = livenessForward regsLiveOnEntry instrs1
814
815         output          = BasicBlock block_id instrs2
816
817    in   ( blockmap', output)
818
819 -- | Calculate liveness going forwards,
820 --      filling in when regs are born
821
822 livenessForward
823         :: Instruction instr
824         => RegSet                       -- regs live on this instr
825         -> [LiveInstr instr] -> [LiveInstr instr]
826
827 livenessForward _           []  = []
828 livenessForward rsLiveEntry (li@(LiveInstr instr mLive) : lis)
829         | Nothing               <- mLive
830         = li : livenessForward rsLiveEntry lis
831
832         | Just live     <- mLive
833         , RU _ written  <- regUsageOfInstr instr
834         = let
835                 -- Regs that are written to but weren't live on entry to this instruction
836                 --      are recorded as being born here.
837                 rsBorn          = mkUniqSet
838                                 $ filter (\r -> not $ elementOfUniqSet r rsLiveEntry) written
839
840                 rsLiveNext      = (rsLiveEntry `unionUniqSets` rsBorn)
841                                         `minusUniqSet` (liveDieRead live)
842                                         `minusUniqSet` (liveDieWrite live)
843
844         in LiveInstr instr (Just live { liveBorn = rsBorn })
845                 : livenessForward rsLiveNext lis
846
847 livenessForward _ _             = panic "RegLiveness.livenessForward: no match"
848
849
850 -- | Calculate liveness going backwards,
851 --      filling in when regs die, and what regs are live across each instruction
852
853 livenessBack
854         :: Instruction instr 
855         => RegSet                       -- regs live on this instr
856         -> BlockMap RegSet              -- regs live on entry to other BBs
857         -> [LiveInstr instr]            -- instructions (accum)
858         -> [LiveInstr instr]            -- instructions
859         -> (RegSet, [LiveInstr instr])
860
861 livenessBack liveregs _        done []  = (liveregs, done)
862
863 livenessBack liveregs blockmap acc (instr : instrs)
864  = let  (liveregs', instr')     = liveness1 liveregs blockmap instr
865    in   livenessBack liveregs' blockmap (instr' : acc) instrs
866
867
868 -- don't bother tagging comments or deltas with liveness
869 liveness1 
870         :: Instruction instr
871         => RegSet 
872         -> BlockMap RegSet 
873         -> LiveInstr instr
874         -> (RegSet, LiveInstr instr)
875
876 liveness1 liveregs _ (LiveInstr instr _)
877         | isMetaInstr instr
878         = (liveregs, LiveInstr instr Nothing)
879
880 liveness1 liveregs blockmap (LiveInstr instr _)
881
882         | not_a_branch
883         = (liveregs1, LiveInstr instr
884                         (Just $ Liveness
885                         { liveBorn      = emptyUniqSet
886                         , liveDieRead   = mkUniqSet r_dying
887                         , liveDieWrite  = mkUniqSet w_dying }))
888
889         | otherwise
890         = (liveregs_br, LiveInstr instr
891                         (Just $ Liveness
892                         { liveBorn      = emptyUniqSet
893                         , liveDieRead   = mkUniqSet r_dying_br
894                         , liveDieWrite  = mkUniqSet w_dying }))
895
896         where
897             RU read written = regUsageOfInstr instr
898
899             -- registers that were written here are dead going backwards.
900             -- registers that were read here are live going backwards.
901             liveregs1   = (liveregs `delListFromUniqSet` written)
902                                     `addListToUniqSet` read
903
904             -- registers that are not live beyond this point, are recorded
905             --  as dying here.
906             r_dying     = [ reg | reg <- read, reg `notElem` written,
907                               not (elementOfUniqSet reg liveregs) ]
908
909             w_dying     = [ reg | reg <- written,
910                              not (elementOfUniqSet reg liveregs) ]
911
912             -- union in the live regs from all the jump destinations of this
913             -- instruction.
914             targets      = jumpDestsOfInstr instr -- where we go from here
915             not_a_branch = null targets
916
917             targetLiveRegs target
918                   = case lookupBlockEnv blockmap target of
919                                 Just ra -> ra
920                                 Nothing -> emptyRegMap
921
922             live_from_branch = unionManyUniqSets (map targetLiveRegs targets)
923
924             liveregs_br = liveregs1 `unionUniqSets` live_from_branch
925
926             -- registers that are live only in the branch targets should
927             -- be listed as dying here.
928             live_branch_only = live_from_branch `minusUniqSet` liveregs
929             r_dying_br  = uniqSetToList (mkUniqSet r_dying `unionUniqSets`
930                                         live_branch_only)
931
932