X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Fcmm%2FCmmBrokenBlock.hs;h=526bdc1dd1508b8e47b83a68679b879d755d0b1a;hb=526c3af1dc98987b6949f4df73c0debccf9875bd;hp=f3c992898c4e57d014c503c15bbbd45b29ed3fd7;hpb=af452780391355f7008fe97e556ced25a3dd2d21;p=ghc-hetmet.git diff --git a/compiler/cmm/CmmBrokenBlock.hs b/compiler/cmm/CmmBrokenBlock.hs index f3c9928..526bdc1 100644 --- a/compiler/cmm/CmmBrokenBlock.hs +++ b/compiler/cmm/CmmBrokenBlock.hs @@ -1,3 +1,10 @@ +{-# OPTIONS -w #-} +-- The above warning supression flag is a temporary kludge. +-- While working on this module you are encouraged to remove it and fix +-- any warnings in the module. See +-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings +-- for details + module CmmBrokenBlock ( BrokenBlock(..), BlockEntryInfo(..), @@ -18,6 +25,7 @@ import CmmUtils import CLabel import MachOp (MachHint(..)) +import CgUtils (callerSaveVolatileRegs) import ClosureInfo import Maybes @@ -27,12 +35,6 @@ import UniqSupply import Unique import UniqFM -import MachRegs (callerSaveVolatileRegs) - -- HACK: this is part of the NCG so we shouldn't use this, but we need - -- it for now to eliminate the need for saved regs to be in CmmCall. - -- The long term solution is to factor callerSaveVolatileRegs - -- from nativeGen into codeGen - -- 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 @@ -64,16 +66,20 @@ data BrokenBlock } -- | How a block could be entered +-- See Note [An example of CPS conversion] data BlockEntryInfo = FunctionEntry -- ^ Block is the beginning of a function CmmInfo -- ^ Function header info CLabel -- ^ The function name - CmmFormals -- ^ Aguments to function + CmmFormalsWithoutKinds -- ^ Aguments to function + -- Only the formal parameters are live | ContinuationEntry -- ^ Return point of a function call - CmmFormals -- ^ return values (argument to continuation) + CmmFormalsWithoutKinds -- ^ return values (argument to continuation) C_SRT -- ^ SRT for the continuation's info table Bool -- ^ True <=> GC block so ignore stack size + -- Live variables, other than + -- the return values, are on the stack | ControlEntry -- ^ Any other kind of block. -- Only entered due to control flow. @@ -82,8 +88,41 @@ data BlockEntryInfo -- no return values, but some live might end up as -- params or possibly in the frame +{- Note [An example of CPS conversion] + +This is NR's and SLPJ's guess about how things might work; +it may not be consistent with the actual code (particularly +in the matter of what's in parameters and what's on the stack). + +f(x,y) { + if x>2 then goto L + x = x+1 +L: if x>1 then y = g(y) + else x = x+1 ; + return( x+y ) +} + BECOMES + +f(x,y) { // FunctionEntry + if x>2 then goto L + x = x+1 +L: // ControlEntry + if x>1 then push x; push f1; jump g(y) + else x=x+1; jump f2(x, y) +} + +f1(y) { // ContinuationEntry + pop x; jump f2(x, y); +} + +f2(x, y) { // ProcPointEntry + return (z+y); +} + +-} + data ContFormat = ContFormat - CmmHintFormals -- ^ return values (argument to continuation) + CmmFormals -- ^ return values (argument to continuation) C_SRT -- ^ SRT for the continuation's info table Bool -- ^ True <=> GC block so ignore stack size deriving (Eq) @@ -102,15 +141,16 @@ data FinalStmt CmmExpr -- ^ The function to call CmmActuals -- ^ Arguments of the call - | FinalCall -- ^ Same as 'CmmForeignCall' + | FinalCall -- ^ Same as 'CmmCallee' -- followed by 'CmmGoto' BlockId -- ^ Target of the 'CmmGoto' -- (must be a 'ContinuationEntry') CmmCallTarget -- ^ The function to call - CmmHintFormals -- ^ Results from call + CmmFormals -- ^ Results from call -- (redundant with ContinuationEntry) CmmActuals -- ^ Arguments to call C_SRT -- ^ SRT for the continuation's info table + CmmReturnInfo -- ^ Does the function return? Bool -- ^ True <=> GC block so ignore stack size | FinalSwitch -- ^ Same as a 'CmmSwitch' @@ -150,7 +190,7 @@ breakProc :: -- to create names of the new blocks with -> CmmInfo -- ^ Info table for the procedure -> CLabel -- ^ Name of the procedure - -> CmmFormals -- ^ Parameters of the procedure + -> CmmFormalsWithoutKinds -- ^ Parameters of the procedure -> [CmmBasicBlock] -- ^ Blocks of the procecure -- (First block is the entry block) -> [BrokenBlock] @@ -226,7 +266,7 @@ breakBlock gc_block_idents uniques (BasicBlock ident stmts) entry = -- Detect this special case to remain an inverse of -- 'cmmBlockFromBrokenBlock' - [CmmCall target results arguments (CmmSafe srt), + [CmmCall target results arguments (CmmSafe srt) ret, CmmBranch next_id] -> ([cont_info], [block]) where @@ -234,29 +274,33 @@ breakBlock gc_block_idents uniques (BasicBlock ident stmts) entry = ContFormat results srt (ident `elem` gc_block_idents)) block = do_call current_id entry accum_stmts exits next_id - target results arguments srt + target results arguments srt ret -- Break the block on safe calls (the main job of this function) - (CmmCall target results arguments (CmmSafe srt) : stmts) -> + (CmmCall target results arguments (CmmSafe srt) ret : stmts) -> (cont_info : cont_infos, block : blocks) where next_id = BlockId $ head uniques block = do_call current_id entry accum_stmts exits next_id - target results arguments srt - cont_info = (next_id, + target results arguments srt ret + + cont_info = (next_id, -- Entry convention for the + -- continuation of the call ContFormat results srt (ident `elem` gc_block_idents)) + + -- Break up the part after the call (cont_infos, blocks) = breakBlock' (tail uniques) next_id ControlEntry [] [] stmts -- Unsafe calls don't need a continuation -- but they do need to be expanded - (CmmCall target results arguments CmmUnsafe : stmts) -> + (CmmCall target results arguments CmmUnsafe ret : stmts) -> breakBlock' remaining_uniques current_id entry exits (accum_stmts ++ arg_stmts ++ caller_save ++ - [CmmCall target results new_args CmmUnsafe] ++ + [CmmCall target results new_args CmmUnsafe ret] ++ caller_load) stmts where @@ -273,9 +317,9 @@ breakBlock gc_block_idents uniques (BasicBlock ident stmts) entry = stmts do_call current_id entry accum_stmts exits next_id - target results arguments srt = + target results arguments srt ret = BrokenBlock current_id entry accum_stmts (next_id:exits) - (FinalCall next_id target results arguments srt + (FinalCall next_id target results arguments srt ret (current_id `elem` gc_block_idents)) cond_branch_target (CmmCondBranch _ target) = [target] @@ -304,7 +348,7 @@ makeContinuationEntries formats case lookup ident formats of Nothing -> block Just (ContFormat formals srt is_gc) -> - BrokenBlock ident (ContinuationEntry (map fst formals) srt is_gc) + BrokenBlock ident (ContinuationEntry (map kindlessCmm formals) srt is_gc) stmts targets exit adaptBlockToFormat :: [(BlockId, ContFormat)] @@ -314,7 +358,7 @@ adaptBlockToFormat :: [(BlockId, ContFormat)] adaptBlockToFormat formats unique block@(BrokenBlock ident entry stmts targets exit@(FinalCall next target formals - actuals srt is_gc)) = + actuals srt ret is_gc)) = if format_formals == formals && format_srt == srt && format_is_gc == is_gc @@ -331,14 +375,14 @@ adaptBlockToFormat formats unique revised_targets = adaptor_ident : delete next targets revised_exit = FinalCall adaptor_ident -- ^ The only part that changed - target formals actuals srt is_gc + target formals actuals srt ret is_gc adaptor_block = mk_adaptor_block adaptor_ident - (ContinuationEntry (map fst formals) srt is_gc) + (ContinuationEntry (map kindlessCmm formals) srt is_gc) next format_formals adaptor_ident = BlockId unique - mk_adaptor_block :: BlockId -> BlockEntryInfo -> BlockId -> CmmHintFormals -> BrokenBlock + mk_adaptor_block :: BlockId -> BlockEntryInfo -> BlockId -> CmmFormals -> BrokenBlock mk_adaptor_block ident entry next formals = BrokenBlock ident entry [] [next] exit where @@ -346,7 +390,8 @@ adaptBlockToFormat formats unique (CmmLit (CmmLabel (mkReturnPtLabel (getUnique next)))) (map formal_to_actual format_formals) - formal_to_actual (reg, hint) = ((CmmReg (CmmLocal reg)), hint) + formal_to_actual (CmmKinded reg hint) + = (CmmKinded (CmmReg (CmmLocal reg)) hint) -- TODO: Check if NoHint is right. We're -- jumping to a C-- function not a foreign one -- so it might always be right. @@ -365,8 +410,8 @@ cmmBlockFromBrokenBlock (BrokenBlock ident _ stmts _ exit) = FinalReturn arguments -> [CmmReturn arguments] FinalJump target arguments -> [CmmJump target arguments] FinalSwitch expr targets -> [CmmSwitch expr targets] - FinalCall branch_target call_target results arguments srt _ -> - [CmmCall call_target results arguments (CmmSafe srt), + FinalCall branch_target call_target results arguments srt ret _ -> + [CmmCall call_target results arguments (CmmSafe srt) ret, CmmBranch branch_target] -----------------------------------------------------------------------------