Make CPS account for on-stack arguments when doing the stack check
[ghc-hetmet.git] / compiler / cmm / CmmBrokenBlock.hs
index b367216..af47e8d 100644 (file)
@@ -12,11 +12,18 @@ module CmmBrokenBlock (
 import Cmm
 import CLabel
 
+import ClosureInfo
+
 import Maybes
 import Panic
 import Unique
 import UniqFM
 
+-- This module takes a 'CmmBasicBlock' which might have 'CmmCall'
+-- statements in it with 'CmmSafe' set and breaks it up at each such call.
+-- It also collects information about the block for later use
+-- by the CPS algorithm.
+
 -----------------------------------------------------------------------------
 -- Data structures
 -----------------------------------------------------------------------------
@@ -35,7 +42,7 @@ data BrokenBlock
 
       brokenBlockTargets :: [BlockId],
                                 -- ^ Blocks that this block could
-                                -- branch to one either by conditional
+                                -- branch to either by conditional
                                 -- branches or via the last statement
 
       brokenBlockExit :: FinalStmt
@@ -45,11 +52,13 @@ data BrokenBlock
 -- | How a block could be entered
 data BlockEntryInfo
   = FunctionEntry              -- ^ Block is the beginning of a function
+      CmmInfo                   -- ^ Function header info
       CLabel                    -- ^ The function name
       CmmFormals                -- ^ Aguments to function
 
   | ContinuationEntry          -- ^ Return point of a function call
       CmmFormals                -- ^ return values (argument to continuation)
+      C_SRT                     -- ^ SRT for the continuation's info table
 
   | ControlEntry               -- ^ Any other kind of block.
                                 -- Only entered due to control flow.
@@ -78,7 +87,7 @@ data FinalStmt
       BlockId                   -- ^ Target of the 'CmmGoto'
                                 -- (must be a 'ContinuationEntry')
       CmmCallTarget             -- ^ The function to call
-      CmmFormals                -- ^ Results from call
+      CmmHintFormals                -- ^ Results from call
                                 -- (redundant with ContinuationEntry)
       CmmActuals                -- ^ Arguments to call
 
@@ -106,6 +115,8 @@ breakBlock uniques (BasicBlock ident stmts) entry =
       breakBlock' uniques current_id entry exits accum_stmts stmts =
           case stmts of
             [] -> panic "block doesn't end in jump, goto, return or switch"
+
+            -- Last statement.  Make the 'BrokenBlock'
             [CmmJump target arguments] ->
                 [BrokenBlock current_id entry accum_stmts
                              exits
@@ -122,6 +133,9 @@ breakBlock uniques (BasicBlock ident stmts) entry =
                 [BrokenBlock current_id entry accum_stmts
                              (mapMaybe id targets ++ exits)
                              (FinalSwitch expr targets)]
+
+            -- These shouldn't happen in the middle of a block.
+            -- They would cause dead code.
             (CmmJump _ _:_) -> panic "jump in middle of block"
             (CmmReturn _:_) -> panic "return in middle of block"
             (CmmBranch _:_) -> panic "branch in middle of block"
@@ -129,18 +143,27 @@ breakBlock uniques (BasicBlock ident stmts) entry =
 
             -- Detect this special case to remain an inverse of
             -- 'cmmBlockFromBrokenBlock'
+            {- TODO: Interferes with proc point detection
             [CmmCall target results arguments,
              CmmBranch next_id] -> [block]
               where
                 block = do_call current_id entry accum_stmts exits next_id
                                 target results arguments
-            (CmmCall target results arguments:stmts) -> block : rest
-              where
-                next_id = BlockId $ head uniques
-                block = do_call current_id entry accum_stmts exits next_id
-                                target results arguments
-                rest = breakBlock' (tail uniques) next_id
-                                   (ContinuationEntry results) [] [] stmts
+             -}
+
+            -- Break the block on safe calls (the main job of this function)
+            (CmmCall target results arguments (CmmSafe srt):stmts) ->
+                block : rest
+                where
+                  next_id = BlockId $ head uniques
+                  block = do_call current_id entry accum_stmts exits next_id
+                                  target results arguments
+                  rest = breakBlock' (tail uniques) next_id
+                                     (ContinuationEntry (map fst results) srt)
+                                     [] [] stmts
+
+            -- Default case.  Just keep accumulating statements
+            -- and branch targets.
             (s:stmts) ->
                 breakBlock' uniques current_id entry
                             (cond_branch_target s++exits)
@@ -169,7 +192,7 @@ cmmBlockFromBrokenBlock (BrokenBlock ident _ stmts _ exit) =
             FinalJump target arguments -> [CmmJump target arguments]
             FinalSwitch expr targets -> [CmmSwitch expr targets]
             FinalCall branch_target call_target results arguments ->
-                [CmmCall call_target results arguments,
+                [CmmCall call_target results arguments (panic "needed SRT from cmmBlockFromBrokenBlock"),
                  CmmBranch branch_target]
 
 -----------------------------------------------------------------------------