X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Fcmm%2FMkZipCfgCmm.hs;h=e623c302be6e2f3700b122e64d5ee45742d49fab;hp=890b37c3bc3727c781c74a77aa2bc50790d95ada;hb=0d80489c9b9f2421f65d8dd86c1e50c6bb429715;hpb=5b83f4b4e52ac3a49f5b45109c858b959aed04b2 diff --git a/compiler/cmm/MkZipCfgCmm.hs b/compiler/cmm/MkZipCfgCmm.hs index 890b37c..e623c30 100644 --- a/compiler/cmm/MkZipCfgCmm.hs +++ b/compiler/cmm/MkZipCfgCmm.hs @@ -7,9 +7,10 @@ module MkZipCfgCmm ( mkNop, mkAssign, mkStore, mkCall, mkCmmCall, mkUnsafeCall, mkFinalCall - , mkJump, mkCbranch, mkSwitch, mkReturn, mkComment, mkCmmIfThenElse - , mkCmmWhileDo, mkAddToContext - , (<*>), sequence, mkLabel, mkBranch + , mkJump, mkCbranch, mkSwitch, mkReturn, mkComment, copyIn, copyOut, mkEntry + , mkCmmIfThenElse, mkCmmIfThen, mkCmmWhileDo + , mkAddToContext + , (<*>), catAGraphs, mkLabel, mkBranch , emptyAGraph, withFreshLabel, withUnique, outOfLine , lgraphOfAGraph, graphOfAGraph, labelAGraph , CmmZ, CmmTopZ, CmmGraph, CmmBlock, CmmAGraph, Middle, Last, Convention(..) @@ -18,10 +19,13 @@ where #include "HsVersions.h" +import BlockId import CmmExpr import Cmm ( GenCmm(..), GenCmmTop(..), CmmStatic, CmmInfo - , CmmCallTarget(..), CmmActuals, CmmFormals + , CmmCallTarget(..), CmmActuals, CmmFormals, CmmFormalsWithoutKinds + , CmmKinded (..) ) +import MachOp (MachHint(..), wordRep) import ZipCfgCmmRep hiding (CmmGraph, CmmAGraph, CmmBlock, CmmZ, CmmTopZ) -- ^ to make this module more self-contained, these definitions are duplicated below import PprCmm() @@ -31,7 +35,6 @@ import FastString import ForeignCall import ZipCfg import MkZipCfg -import Prelude hiding( sequence ) type CmmGraph = LGraph Middle Last type CmmAGraph = AGraph Middle Last @@ -59,12 +62,14 @@ mkFinalCall :: CmmExpr -> CCallConv -> CmmActuals -> CmmAGraph mkAddToContext :: CmmExpr -> [CmmExpr] -> CmmAGraph ---------- Control transfer -mkJump :: CmmExpr -> CmmActuals -> CmmAGraph -mkCbranch :: CmmExpr -> BlockId -> BlockId -> CmmAGraph -mkSwitch :: CmmExpr -> [Maybe BlockId] -> CmmAGraph -mkReturn :: CmmActuals -> CmmAGraph +mkJump :: Area -> CmmExpr -> CmmActuals -> CmmAGraph +mkCbranch :: CmmExpr -> BlockId -> BlockId -> CmmAGraph +mkSwitch :: CmmExpr -> [Maybe BlockId] -> CmmAGraph +mkReturn :: Area -> CmmActuals -> CmmAGraph + mkCmmIfThenElse :: CmmExpr -> CmmAGraph -> CmmAGraph -> CmmAGraph -mkCmmWhileDo :: CmmExpr -> CmmAGraph -> CmmAGraph +mkCmmIfThen :: CmmExpr -> CmmAGraph -> CmmAGraph +mkCmmWhileDo :: CmmExpr -> CmmAGraph -> CmmAGraph -- Not to be forgotten, but exported by MkZipCfg: -- mkBranch :: BlockId -> CmmAGraph @@ -75,8 +80,16 @@ mkCmmWhileDo :: CmmExpr -> CmmAGraph -> CmmAGraph -------------------------------------------------------------------------- +mkCmmWhileDo e = mkWhileDo (mkCbranch e) mkCmmIfThenElse e = mkIfThenElse (mkCbranch e) -mkCmmWhileDo e = mkWhileDo (mkCbranch e) + +mkCmmIfThen e tbranch + = withFreshLabel "end of if" $ \endif -> + withFreshLabel "start of then" $ \tid -> + mkCbranch e tid endif <*> + mkLabel tid <*> tbranch <*> mkBranch endif <*> + mkLabel endif + -- ================ IMPLEMENTATION ================-- @@ -90,24 +103,61 @@ mkCbranch pred ifso ifnot = mkLast $ LastCondBranch pred ifso ifnot mkSwitch e tbl = mkLast $ LastSwitch e tbl mkUnsafeCall tgt results actuals = mkMiddle $ MidUnsafeCall tgt results actuals -mkAddToContext ra actuals = mkMiddle $ MidAddToContext ra actuals - -cmmArgConv, cmmResConv :: Convention -cmmArgConv = ConventionStandard CmmCallConv Arguments -cmmResConv = ConventionStandard CmmCallConv Arguments - -mkJump e actuals = mkMiddle (CopyOut cmmArgConv actuals) <*> mkLast (LastJump e) -mkReturn actuals = mkMiddle (CopyOut cmmResConv actuals) <*> mkLast LastReturn - -mkFinalCall f conv actuals = - mkMiddle (CopyOut (ConventionStandard conv Arguments) actuals) <*> - mkLast (LastCall f Nothing) +mkAddToContext ra actuals = mkMiddle $ MidAddToContext ra actuals + +cmmResConv :: Convention +cmmResConv = ConventionStandard CmmCallConv Results + +copyIn :: Convention -> Area -> CmmFormals -> [Middle] +copyIn _ area formals = reverse $ snd $ foldl ci (1, []) formals + where ci (n, ms) v = (n+1, MidAssign (CmmLocal $ kindlessCmm v) + (CmmLoad (CmmStackSlot area n) wordRep) : ms) + +copyOut :: Convention -> Area -> CmmActuals -> [Middle] +copyOut conv area actuals = moveSP conv $ snd $ foldl co (1, []) actuals + where moveSP (ConventionStandard _ Arguments) args = + MidAssign spReg (outgoingSlot area) : reverse args + moveSP _ args = reverse $ MidAssign spReg (outgoingSlot area) : args + co (n, ms) v = (n+1, MidStore (CmmStackSlot area n) (kindlessCmm v) : ms) +mkEntry :: Area -> Convention -> CmmFormalsWithoutKinds -> [Middle] +mkEntry area conv formals = copyIn conv area fs + where fs = map (\f -> CmmKinded f NoHint) formals + +-- I'm not sure how to get the calling conventions right yet, +-- and I suspect this should not be resolved until sometime after +-- Simon's patch is applied. +-- For now, I apply a bogus calling convention: all arguments go on the +-- stack, using the same amount of stack space. +lastWithArgs' :: BlockId -> Area -> Convention -> CmmActuals -> Maybe CmmFormals -> + (BlockId -> Last) -> CmmAGraph +lastWithArgs' k area conv actuals formals toLast = + (mkMiddles $ copyOut conv area actuals) <*> + -- adjust the sp + mkLast (toLast k) <*> + case formals of + Just formals -> mkLabel k <*> (mkMiddles $ copyIn conv area formals) + Nothing -> emptyAGraph +lastWithArgs :: Convention -> CmmActuals -> Maybe CmmFormals -> (BlockId -> Last) -> CmmAGraph +lastWithArgs c a f l = + withFreshLabel "call successor" $ \k -> lastWithArgs' k (mkCallArea k a f) c a f l + +always :: a -> b -> a +always x _ = x + +-- The area created for the jump and return arguments is the same area as the +-- procedure entry. +mkJump area e actuals = + lastWithArgs' (areaId area) area cmmResConv actuals Nothing $ always $ LastJump e +mkReturn area actuals = + lastWithArgs' (areaId area) area cmmResConv actuals Nothing $ always LastReturn + +mkFinalCall f conv actuals = + lastWithArgs (ConventionStandard conv Arguments) actuals Nothing + $ always $ LastCall f Nothing --mkFinalCall f conv actuals = mkCmmCall f results actuals srt = mkCall f CmmCallConv results actuals srt -mkCall f conv results actuals srt = - withFreshLabel "call successor" $ \k -> - mkMiddle (CopyOut (ConventionStandard conv Arguments) actuals) <*> - mkLast (LastCall f (Just k)) <*> - mkLabel k <*> - mkMiddle (CopyIn (ConventionStandard conv Results) results srt) +-- I'm dropping the SRT, but that should be okay: we plan to reconstruct it later. +mkCall f conv results actuals _ = + lastWithArgs (ConventionStandard conv Arguments) actuals (Just results) + $ \k -> LastCall f (Just k)