[commit: ghc] master: Fixes for the stack layout algorithm to handle join points (f68b427)

Simon Marlow marlowsd at gmail.com
Mon Jul 30 15:06:27 CEST 2012


Repository : ssh://darcs.haskell.org//srv/darcs/ghc

On branch  : master

http://hackage.haskell.org/trac/ghc/changeset/f68b42728f05444185aac065faee8b736e9770a1

>---------------------------------------------------------------

commit f68b42728f05444185aac065faee8b736e9770a1
Author: Simon Marlow <marlowsd at gmail.com>
Date:   Thu Jul 19 09:44:57 2012 +0100

    Fixes for the stack layout algorithm to handle join points

>---------------------------------------------------------------

 compiler/cmm/CmmLayoutStack.hs |   89 +++++++++++++++++++++++-----------------
 1 files changed, 51 insertions(+), 38 deletions(-)

diff --git a/compiler/cmm/CmmLayoutStack.hs b/compiler/cmm/CmmLayoutStack.hs
index 5f44013..7dc1210 100644
--- a/compiler/cmm/CmmLayoutStack.hs
+++ b/compiler/cmm/CmmLayoutStack.hs
@@ -325,9 +325,9 @@ handleLastNode procpoints liveness cont_info stackmaps
        return $ lastCall cont_lbl wORD_SIZE wORD_SIZE (sm_ret_off stack0)
             -- one word each for args and results: the return address
 
-    CmmBranch{..}     ->  handleProcPoints
-    CmmCondBranch{..} ->  handleProcPoints
-    CmmSwitch{..}     ->  handleProcPoints
+    CmmBranch{..}     ->  handleBranches
+    CmmCondBranch{..} ->  handleBranches
+    CmmSwitch{..}     ->  handleBranches
 
   where
      -- Calls and ForeignCalls are handled the same way:
@@ -365,13 +365,13 @@ handleLastNode procpoints liveness cont_info stackmaps
      -- proc point, we have to set up the stack to match what the proc
      -- point is expecting.
      --
-     handleProcPoints :: UniqSM ( [CmmNode O O]
+     handleBranches :: UniqSM ( [CmmNode O O]
                                 , ByteOff
                                 , CmmNode O C
                                 , [CmmBlock]
                                 , BlockEnv StackMap )
 
-     handleProcPoints
+     handleBranches
          -- Note [diamond proc point]
        | Just l <- futureContinuation middle
        , (nub $ filter (`setMember` procpoints) $ successors last) == [l]
@@ -387,50 +387,63 @@ handleLastNode procpoints liveness cont_info stackmaps
                 , out)
 
         | otherwise = do
-          pps <- mapM handleProcPoint (successors last)
+          pps <- mapM handleBranch (successors last)
           let lbl_map :: LabelMap Label
               lbl_map = mapFromList [ (l,tmp) | (l,tmp,_,_) <- pps ]
-              fix_lbl l = mapLookup l lbl_map `orElse` l
+              fix_lbl l = mapFindWithDefault l l lbl_map
           return ( []
                  , 0
                  , mapSuccessors fix_lbl last
                  , concat [ blk | (_,_,_,blk) <- pps ]
                  , mapFromList [ (l, sm) | (l,_,sm,_) <- pps ] )
 
-     -- For each proc point that is a successor of this block
-     --   (a) if the proc point already has a stackmap, we need to
-     --       shuffle the current stack to make it look the same.
-     --       We have to insert a new block to make this happen.
-     --   (b) otherwise, call "allocate live stack0" to make the
-     --       stack map for the proc point
-     handleProcPoint :: BlockId
-                     -> UniqSM (BlockId, BlockId, StackMap, [CmmBlock])
-     handleProcPoint l
-        | not (l `setMember` procpoints) = return (l, l, stack0, [])
-        | otherwise = do
-           tmp_lbl <- liftM mkBlockId $ getUniqueM
-           let
-               (stack2, assigs) =
-                  case mapLookup l stackmaps of
-                    Just pp_sm -> (pp_sm, fixupStack stack0 pp_sm)
-                    Nothing    ->
+     -- For each successor of this block
+     handleBranch :: BlockId -> UniqSM (BlockId, BlockId, StackMap, [CmmBlock])
+     handleBranch l
+        --   (a) if the successor already has a stackmap, we need to
+        --       shuffle the current stack to make it look the same.
+        --       We have to insert a new block to make this happen.
+        | Just stack2 <- mapLookup l stackmaps
+        = do
+             let assigs = fixupStack stack0 stack2
+             (tmp_lbl, block) <- makeFixupBlock sp0 l stack2 assigs
+             return (l, tmp_lbl, stack2, block)
+
+        --   (b) if the successor is a proc point, save everything
+        --       on the stack.
+        | l `setMember` procpoints
+        = do
+             let cont_args = mapFindWithDefault 0 l cont_info
+                 (stack2, assigs) =
                       --pprTrace "first visit to proc point"
                       --             (ppr l <+> ppr stack1) $
-                      (stack1, assigs)
-                      where
-                       cont_args = mapFindWithDefault 0 l cont_info
-                       (stack1, assigs) =
-                           setupStackFrame l liveness (sm_ret_off stack0)
+                      setupStackFrame l liveness (sm_ret_off stack0)
                                                        cont_args stack0
-
-               sp_off = sp0 - sm_sp stack2
-
-               block = blockJoin (CmmEntry tmp_lbl)
-                                 (maybeAddSpAdj sp_off (blockFromList assigs))
-                                 (CmmBranch l)
-           --
-           return (l, tmp_lbl, stack2, [block])
-
+             --
+             (tmp_lbl, block) <- makeFixupBlock sp0 l stack2 assigs
+             return (l, tmp_lbl, stack2, block)
+
+        --   (c) otherwise, the current StackMap is the StackMap for
+        --       the continuation.  But we must remember to remove any
+        --       variables from the StackMap that are *not* live at
+        --       the destination, because this StackMap might be used
+        --       by fixupStack if this is a join point.
+        | otherwise = return (l, l, stack1, [])
+        where live = mapFindWithDefault (panic "handleBranch") l liveness
+              stack1 = stack0 { sm_regs = filterUFM is_live (sm_regs stack0) }
+              is_live (r,_) = r `elemRegSet` live
+
+
+makeFixupBlock :: ByteOff -> Label -> StackMap -> [CmmNode O O] -> UniqSM (Label, [CmmBlock])
+makeFixupBlock sp0 l stack assigs
+  | null assigs && sp0 == sm_sp stack = return (l, [])
+  | otherwise = do
+    tmp_lbl <- liftM mkBlockId $ getUniqueM
+    let sp_off = sp0 - sm_sp stack
+        block = blockJoin (CmmEntry tmp_lbl)
+                          (maybeAddSpAdj sp_off (blockFromList assigs))
+                          (CmmBranch l)
+    return (tmp_lbl, [block])
 
   
 -- Sp is currently pointing to current_sp,





More information about the Cvs-ghc mailing list