Switch more uniqFromSupply+splitUniqSupply's to takeUniqFromSupply
[ghc-hetmet.git] / compiler / nativeGen / RegAlloc / Liveness.hs
index 61e800f..903fa4c 100644 (file)
@@ -18,7 +18,7 @@ module RegAlloc.Liveness (
        LiveInfo (..),
        LiveBasicBlock,
 
-       mapBlockTop,    mapBlockTopM,
+       mapBlockTop,    mapBlockTopM,   mapSCCM,
        mapGenBlockTop, mapGenBlockTopM,
        stripLive,
        stripLiveBlock,
@@ -27,11 +27,10 @@ module RegAlloc.Liveness (
        eraseDeltasLive,
        patchEraseLive,
        patchRegsLiveInstr,
+       reverseBlocksInTops,
        regLiveness,
        natCmmTopToLive
   ) where
-
-
 import Reg
 import Instruction
 
@@ -51,6 +50,9 @@ import FastString
 
 import Data.List
 import Data.Maybe
+import Data.Map                        (Map)
+import Data.Set                        (Set)
+import qualified Data.Map      as Map
 
 -----------------------------------------------------------------------------
 type RegSet = UniqSet Reg
@@ -159,9 +161,11 @@ data Liveness
 -- | Stash regs live on entry to each basic block in the info part of the cmm code.
 data LiveInfo
        = LiveInfo
-               [CmmStatic]                     -- cmm static stuff
-               (Maybe BlockId)                 -- id of the first block
-               (Maybe (BlockMap RegSet))       -- argument locals live on entry to this block
+               [CmmStatic]                             -- cmm static stuff
+               (Maybe BlockId)                         -- id of the first block
+               (Maybe (BlockMap RegSet))               -- argument locals live on entry to this block
+               (Map BlockId (Set Int))                 -- stack slots live on entry to this block
+
 
 -- | A basic block with liveness information.
 type LiveBasicBlock instr
@@ -211,10 +215,11 @@ instance Outputable instr
                 | otherwise            = name <> (hcat $ punctuate space $ map ppr $ uniqSetToList regs)
 
 instance Outputable LiveInfo where
-       ppr (LiveInfo static firstId liveOnEntry)
+       ppr (LiveInfo static firstId liveVRegsOnEntry liveSlotsOnEntry)
                =  (vcat $ map ppr static)
-               $$ text "# firstId     = " <> ppr firstId
-               $$ text "# liveOnEntry = " <> ppr liveOnEntry
+               $$ text "# firstId          = " <> ppr firstId
+               $$ text "# liveVRegsOnEntry = " <> ppr liveVRegsOnEntry
+               $$ text "# liveSlotsOnEntry = " <> text (show liveSlotsOnEntry)
 
 
 
@@ -298,9 +303,9 @@ slurpConflicts live
                = foldl'  (slurpBlock info) rs bs
 
        slurpBlock info rs (BasicBlock blockId instrs)  
-               | LiveInfo _ _ (Just blockLive) <- info
-               , Just rsLiveEntry              <- lookupBlockEnv blockLive blockId
-               , (conflicts, moves)            <- slurpLIs rsLiveEntry rs instrs
+               | LiveInfo _ _ (Just blockLive) _ <- info
+               , Just rsLiveEntry                <- lookupBlockEnv blockLive blockId
+               , (conflicts, moves)              <- slurpLIs rsLiveEntry rs instrs
                = (consBag rsLiveEntry conflicts, moves)
 
                | otherwise
@@ -355,21 +360,30 @@ slurpConflicts live
 --
 --
 slurpReloadCoalesce 
-       :: Instruction instr
+       :: forall instr. Instruction instr
        => LiveCmmTop instr
        -> Bag (Reg, Reg)
 
 slurpReloadCoalesce live
        = slurpCmm emptyBag live
 
- where slurpCmm cs CmmData{}   = cs
+ where 
+        slurpCmm :: Bag (Reg, Reg)
+                 -> GenCmmTop t t1 [SCC (LiveBasicBlock instr)]
+                 -> Bag (Reg, Reg)
+        slurpCmm cs CmmData{}  = cs
        slurpCmm cs (CmmProc _ _ _ sccs)
                = slurpComp cs (flattenSCCs sccs)
 
+        slurpComp :: Bag (Reg, Reg)
+                     -> [LiveBasicBlock instr]
+                     -> Bag (Reg, Reg)
        slurpComp  cs blocks
         = let  (moveBags, _)   = runState (slurpCompM blocks) emptyUFM
           in   unionManyBags (cs : moveBags)
 
+        slurpCompM :: [LiveBasicBlock instr]
+                   -> State (UniqFM [UniqFM Reg]) [Bag (Reg, Reg)]
        slurpCompM blocks
         = do   -- run the analysis once to record the mapping across jumps.
                mapM_   (slurpBlock False) blocks
@@ -380,6 +394,8 @@ slurpReloadCoalesce live
                --      not worth the trouble.
                mapM    (slurpBlock True) blocks
 
+        slurpBlock :: Bool -> LiveBasicBlock instr
+                   -> State (UniqFM [UniqFM Reg]) (Bag (Reg, Reg))
        slurpBlock propagate (BasicBlock blockId instrs)
         = do   -- grab the slot map for entry to this block
                slotMap         <- if propagate
@@ -389,8 +405,7 @@ slurpReloadCoalesce live
                (_, mMoves)     <- mapAccumLM slurpLI slotMap instrs
                return $ listToBag $ catMaybes mMoves
 
-       slurpLI :: Instruction instr
-               => UniqFM Reg                           -- current slotMap
+       slurpLI :: UniqFM Reg                           -- current slotMap
                -> LiveInstr instr
                -> State (UniqFM [UniqFM Reg])          -- blockId -> [slot -> reg]
                                                        --      for tracking slotMaps across jumps
@@ -455,7 +470,7 @@ stripLive live
 
  where stripCmm (CmmData sec ds)       = CmmData sec ds
 
-       stripCmm (CmmProc (LiveInfo info (Just first_id) _) label params sccs)
+       stripCmm (CmmProc (LiveInfo info (Just first_id) _ _) label params sccs)
         = let  final_blocks    = flattenSCCs sccs
                
                -- make sure the block that was first in the input list
@@ -468,7 +483,7 @@ stripLive live
                           (ListGraph $ map stripLiveBlock $ first' : rest')
 
        -- procs used for stg_split_markers don't contain any blocks, and have no first_id.
-       stripCmm (CmmProc (LiveInfo info Nothing _) label params [])
+       stripCmm (CmmProc (LiveInfo info Nothing _ _) label params [])
         =      CmmProc info label params (ListGraph [])
 
        -- If the proc has blocks but we don't know what the first one was, then we're dead.
@@ -529,7 +544,6 @@ eraseDeltasLive cmm
 -- | Patch the registers in this code according to this register mapping.
 --     also erase reg -> reg moves when the reg is the same.
 --     also erase reg -> reg moves when the destination dies in this instr.
-
 patchEraseLive
        :: Instruction instr
        => (Reg -> Reg)
@@ -541,12 +555,12 @@ patchEraseLive patchF cmm
        patchCmm cmm@CmmData{}  = cmm
 
        patchCmm (CmmProc info label params sccs)
-        | LiveInfo static id (Just blockMap)   <- info
+        | LiveInfo static id (Just blockMap) mLiveSlots <- info
         = let  
                patchRegSet set = mkUniqSet $ map patchF $ uniqSetToList set
                blockMap'       = mapBlockEnv patchRegSet blockMap
 
-               info'           = LiveInfo static id (Just blockMap')
+               info'           = LiveInfo static id (Just blockMap') mLiveSlots
           in   CmmProc info' label params $ map patchSCC sccs
 
         | otherwise
@@ -617,7 +631,7 @@ natCmmTopToLive (CmmData i d)
        = CmmData i d
 
 natCmmTopToLive (CmmProc info lbl params (ListGraph []))
-       = CmmProc (LiveInfo info Nothing Nothing)
+       = CmmProc (LiveInfo info Nothing Nothing Map.empty)
                  lbl params []
 
 natCmmTopToLive (CmmProc info lbl params (ListGraph blocks@(first : _)))
@@ -627,7 +641,7 @@ natCmmTopToLive (CmmProc info lbl params (ListGraph blocks@(first : _)))
                                        BasicBlock l (map (\i -> LiveInstr (Instr i) Nothing) instrs)))
                        $ sccs
                                
-   in  CmmProc (LiveInfo info (Just first_id) Nothing)
+   in  CmmProc (LiveInfo info (Just first_id) Nothing Map.empty)
                lbl params sccsLive
 
 
@@ -657,22 +671,19 @@ regLiveness (CmmData i d)
        = returnUs $ CmmData i d
 
 regLiveness (CmmProc info lbl params [])
-       | LiveInfo static mFirst _      <- info
+       | LiveInfo static mFirst _ _    <- info
        = returnUs $ CmmProc
-                       (LiveInfo static mFirst (Just emptyBlockEnv))
+                       (LiveInfo static mFirst (Just emptyBlockEnv) Map.empty)
                        lbl params []
 
 regLiveness (CmmProc info lbl params sccs)
-       | LiveInfo static mFirst _      <- info
+       | LiveInfo static mFirst _ liveSlotsOnEntry     <- info
        = let   (ann_sccs, block_live)  = computeLiveness sccs
 
-         in    returnUs $ CmmProc (LiveInfo static mFirst (Just block_live))
+         in    returnUs $ CmmProc (LiveInfo static mFirst (Just block_live) liveSlotsOnEntry)
                           lbl params ann_sccs
 
 
-
-
-
 -- -----------------------------------------------------------------------------
 -- | Check ordering of Blocks
 --     The computeLiveness function requires SCCs to be in reverse dependent order.
@@ -688,7 +699,7 @@ checkIsReverseDependent
 checkIsReverseDependent sccs'
  = go emptyUniqSet sccs'
 
- where         go blockssSeen []
+ where         go _ []
         = Nothing
        
        go blocksSeen (AcyclicSCC block : sccs)
@@ -707,12 +718,21 @@ checkIsReverseDependent sccs'
                 []             -> go blocksSeen' sccs
                 bad : _        -> Just bad
                
-       slurpJumpDestsOfBlock (BasicBlock blockId instrs)
+       slurpJumpDestsOfBlock (BasicBlock _ instrs)
                = unionManyUniqSets
                $ map (mkUniqSet . jumpDestsOfInstr) 
                        [ i | LiveInstr i _ <- instrs]
-       
 
+
+-- | If we've compute liveness info for this code already we have to reverse
+--   the SCCs in each top to get them back to the right order so we can do it again.
+reverseBlocksInTops :: LiveCmmTop instr -> LiveCmmTop instr
+reverseBlocksInTops top
+ = case top of
+       CmmData{}                       -> top
+       CmmProc info lbl params sccs    -> CmmProc info lbl params (reverse sccs)
+
+       
 -- | Computing liveness
 --     
 --  On entry, the SCCs must be in "reverse" order: later blocks may transfer