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
-----------------------------------------------------------------------------
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
-- | 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
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
[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"
block = do_call current_id entry accum_stmts exits next_id
target results arguments
-}
- (CmmCall target results arguments 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
+
+ -- 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)