diff options
author | Michael D. Adams <t-madams@microsoft.com> | 2007-06-27 15:09:03 +0000 |
---|---|---|
committer | Michael D. Adams <t-madams@microsoft.com> | 2007-06-27 15:09:03 +0000 |
commit | affbe8dae5d7eb350686b42ddbd4f3561b7bd0ec (patch) | |
tree | 7558970725c9e17e0017d6c825949d8e178d3445 /compiler/codeGen | |
parent | 207802589da0d23c3f16195f453b24a1e46e322d (diff) | |
download | haskell-affbe8dae5d7eb350686b42ddbd4f3561b7bd0ec.tar.gz |
Added an SRT to each CmmCall and added the current SRT to the CgMonad
Diffstat (limited to 'compiler/codeGen')
-rw-r--r-- | compiler/codeGen/CgCase.lhs | 30 | ||||
-rw-r--r-- | compiler/codeGen/CgClosure.lhs | 10 | ||||
-rw-r--r-- | compiler/codeGen/CgExpr.lhs | 20 | ||||
-rw-r--r-- | compiler/codeGen/CgForeignCall.hs | 19 | ||||
-rw-r--r-- | compiler/codeGen/CgHpc.hs | 2 | ||||
-rw-r--r-- | compiler/codeGen/CgInfoTbls.hs | 34 | ||||
-rw-r--r-- | compiler/codeGen/CgLetNoEscape.lhs | 5 | ||||
-rw-r--r-- | compiler/codeGen/CgMonad.lhs | 19 | ||||
-rw-r--r-- | compiler/codeGen/CgPrimOp.hs | 4 | ||||
-rw-r--r-- | compiler/codeGen/CgUtils.hs | 44 | ||||
-rw-r--r-- | compiler/codeGen/ClosureInfo.lhs | 4 | ||||
-rw-r--r-- | compiler/codeGen/CodeGen.lhs | 5 |
12 files changed, 117 insertions, 79 deletions
diff --git a/compiler/codeGen/CgCase.lhs b/compiler/codeGen/CgCase.lhs index a473e9158e..11a3c3e1d8 100644 --- a/compiler/codeGen/CgCase.lhs +++ b/compiler/codeGen/CgCase.lhs @@ -95,7 +95,6 @@ cgCase :: StgExpr -> StgLiveVars -> StgLiveVars -> Id - -> SRT -> AltType -> [StgAlt] -> Code @@ -104,7 +103,7 @@ cgCase :: StgExpr Special case #1: case of literal. \begin{code} -cgCase (StgLit lit) live_in_whole_case live_in_alts bndr srt +cgCase (StgLit lit) live_in_whole_case live_in_alts bndr alt_type@(PrimAlt tycon) alts = do { tmp_reg <- bindNewToTemp bndr ; cm_lit <- cgLit lit @@ -120,7 +119,7 @@ allocating more heap than strictly necessary, but it will sometimes eliminate a heap check altogether. \begin{code} -cgCase (StgApp v []) live_in_whole_case live_in_alts bndr srt +cgCase (StgApp v []) live_in_whole_case live_in_alts bndr alt_type@(PrimAlt tycon) alts = do { -- Careful! we can't just bind the default binder to the same thing -- as the scrutinee, since it might be a stack location, and having @@ -137,7 +136,7 @@ Special case #3: inline PrimOps and foreign calls. \begin{code} cgCase (StgOpApp op@(StgPrimOp primop) args _) - live_in_whole_case live_in_alts bndr srt alt_type alts + live_in_whole_case live_in_alts bndr alt_type alts | not (primOpOutOfLine primop) = cgInlinePrimOp primop args bndr alt_type live_in_alts alts \end{code} @@ -152,7 +151,7 @@ right here, just like an inline primop. \begin{code} cgCase (StgOpApp op@(StgFCallOp fcall _) args _) - live_in_whole_case live_in_alts bndr srt alt_type alts + live_in_whole_case live_in_alts bndr alt_type alts | unsafe_foreign_call = ASSERT( isSingleton alts ) do -- *must* be an unboxed tuple alt. @@ -177,7 +176,7 @@ we can reuse/trim the stack slot holding the variable (if it is in one). \begin{code} cgCase (StgApp fun args) - live_in_whole_case live_in_alts bndr srt alt_type alts + live_in_whole_case live_in_alts bndr alt_type alts = do { fun_info <- getCgIdInfo fun ; arg_amodes <- getArgAmodes args @@ -195,7 +194,7 @@ cgCase (StgApp fun args) <- forkEval alts_eob_info (allocStackTop retAddrSizeW >> nopC) (do { deAllocStackTop retAddrSizeW - ; cgEvalAlts maybe_cc_slot bndr srt alt_type alts }) + ; cgEvalAlts maybe_cc_slot bndr alt_type alts }) ; setEndOfBlockInfo scrut_eob_info (performTailCall fun_info arg_amodes save_assts) } @@ -215,7 +214,7 @@ deAllocStackTop call is doing above. Finally, here is the general case. \begin{code} -cgCase expr live_in_whole_case live_in_alts bndr srt alt_type alts +cgCase expr live_in_whole_case live_in_alts bndr alt_type alts = do { -- Figure out what volatile variables to save nukeDeadBindings live_in_whole_case @@ -232,7 +231,7 @@ cgCase expr live_in_whole_case live_in_alts bndr srt alt_type alts ; allocStackTop retAddrSizeW -- space for retn address ; nopC }) (do { deAllocStackTop retAddrSizeW - ; cgEvalAlts maybe_cc_slot bndr srt alt_type alts }) + ; cgEvalAlts maybe_cc_slot bndr alt_type alts }) ; setEndOfBlockInfo scrut_eob_info (cgExpr expr) } @@ -355,14 +354,13 @@ is some evaluation to be done. \begin{code} cgEvalAlts :: Maybe VirtualSpOffset -- Offset of cost-centre to be restored, if any -> Id - -> SRT -- SRT for the continuation -> AltType -> [StgAlt] -> FCode Sequel -- Any addr modes inside are guaranteed -- to be a label so that we can duplicate it -- without risk of duplicating code -cgEvalAlts cc_slot bndr srt alt_type@(PrimAlt tycon) alts +cgEvalAlts cc_slot bndr alt_type@(PrimAlt tycon) alts = do { let rep = tyConCgRep tycon reg = dataReturnConvPrim rep -- Bottom for voidRep @@ -374,10 +372,10 @@ cgEvalAlts cc_slot bndr srt alt_type@(PrimAlt tycon) alts ; restoreCurrentCostCentre cc_slot True ; cgPrimAlts GCMayHappen alt_type reg alts } - ; lbl <- emitReturnTarget (idName bndr) abs_c srt + ; lbl <- emitReturnTarget (idName bndr) abs_c ; returnFC (CaseAlts lbl Nothing bndr) } -cgEvalAlts cc_slot bndr srt (UbxTupAlt _) [(con,args,_,rhs)] +cgEvalAlts cc_slot bndr (UbxTupAlt _) [(con,args,_,rhs)] = -- Unboxed tuple case -- By now, the simplifier should have have turned it -- into case e of (# a,b #) -> e @@ -396,10 +394,10 @@ cgEvalAlts cc_slot bndr srt (UbxTupAlt _) [(con,args,_,rhs)] -- and finally the code for the alternative ; unbxTupleHeapCheck live_regs ptrs nptrs noStmts (cgExpr rhs) } - ; lbl <- emitReturnTarget (idName bndr) abs_c srt + ; lbl <- emitReturnTarget (idName bndr) abs_c ; returnFC (CaseAlts lbl Nothing bndr) } -cgEvalAlts cc_slot bndr srt alt_type alts +cgEvalAlts cc_slot bndr alt_type alts = -- Algebraic and polymorphic case do { -- Bind the default binder bindNewToReg bndr nodeReg (mkLFArgument bndr) @@ -416,7 +414,7 @@ cgEvalAlts cc_slot bndr srt alt_type alts ; (alts, mb_deflt) <- cgAlgAlts GCMayHappen cc_slot alt_type alts ; (lbl, branches) <- emitAlgReturnTarget (idName bndr) - alts mb_deflt srt fam_sz + alts mb_deflt fam_sz ; returnFC (CaseAlts lbl branches bndr) } where diff --git a/compiler/codeGen/CgClosure.lhs b/compiler/codeGen/CgClosure.lhs index fd851157d7..2c72860a29 100644 --- a/compiler/codeGen/CgClosure.lhs +++ b/compiler/codeGen/CgClosure.lhs @@ -61,17 +61,16 @@ They should have no free variables. cgTopRhsClosure :: Id -> CostCentreStack -- Optional cost centre annotation -> StgBinderInfo - -> SRT -> UpdateFlag -> [Id] -- Args -> StgExpr -> FCode (Id, CgIdInfo) -cgTopRhsClosure id ccs binder_info srt upd_flag args body = do +cgTopRhsClosure id ccs binder_info upd_flag args body = do { -- LAY OUT THE OBJECT let name = idName id ; lf_info <- mkClosureLFInfo id TopLevel [] upd_flag args - ; srt_info <- getSRTInfo name srt + ; srt_info <- getSRTInfo ; mod_name <- getModuleName ; let descr = closureDescription mod_name name closure_info = mkClosureInfo True id lf_info 0 0 srt_info descr @@ -136,14 +135,13 @@ Here's the general case. cgRhsClosure :: Id -> CostCentreStack -- Optional cost centre annotation -> StgBinderInfo - -> SRT -> [Id] -- Free vars -> UpdateFlag -> [Id] -- Args -> StgExpr -> FCode (Id, CgIdInfo) -cgRhsClosure bndr cc bndr_info srt fvs upd_flag args body = do +cgRhsClosure bndr cc bndr_info fvs upd_flag args body = do { -- LAY OUT THE OBJECT -- If the binder is itself a free variable, then don't store -- it in the closure. Instead, just bind it to Node on entry. @@ -161,7 +159,7 @@ cgRhsClosure bndr cc bndr_info srt fvs upd_flag args body = do ; lf_info <- mkClosureLFInfo bndr NotTopLevel fvs upd_flag args ; fv_infos <- mapFCs getCgIdInfo reduced_fvs - ; srt_info <- getSRTInfo name srt + ; srt_info <- getSRTInfo ; mod_name <- getModuleName ; let bind_details :: [(CgIdInfo, VirtualHpOffset)] (tot_wds, ptr_wds, bind_details) diff --git a/compiler/codeGen/CgExpr.lhs b/compiler/codeGen/CgExpr.lhs index 43f69906e6..a71493a28b 100644 --- a/compiler/codeGen/CgExpr.lhs +++ b/compiler/codeGen/CgExpr.lhs @@ -203,7 +203,7 @@ module, @CgCase@. \begin{code} cgExpr (StgCase expr live_vars save_vars bndr srt alt_type alts) - = cgCase expr live_vars save_vars bndr srt alt_type alts + = setSRT srt $ cgCase expr live_vars save_vars bndr alt_type alts \end{code} @@ -293,7 +293,7 @@ cgRhs name (StgRhsCon maybe_cc con args) cgRhs name (StgRhsClosure cc bi fvs upd_flag srt args body) = do this_pkg <- getThisPackage - mkRhsClosure this_pkg name cc bi srt fvs upd_flag args body + setSRT srt $ mkRhsClosure this_pkg name cc bi fvs upd_flag args body \end{code} mkRhsClosure looks for two special forms of the right-hand side: @@ -316,12 +316,12 @@ form: \begin{code} -mkRhsClosure this_pkg bndr cc bi srt +mkRhsClosure this_pkg bndr cc bi [the_fv] -- Just one free var upd_flag -- Updatable thunk [] -- A thunk body@(StgCase (StgApp scrutinee [{-no args-}]) - _ _ _ _ -- ignore uniq, etc. + _ _ _ srt -- ignore uniq, etc. (AlgAlt tycon) [(DataAlt con, params, use_mask, (StgApp selectee [{-no args-}]))]) @@ -334,7 +334,7 @@ mkRhsClosure this_pkg bndr cc bi srt -- other constructors in the datatype. It's still ok to make a selector -- thunk in this case, because we *know* which constructor the scrutinee -- will evaluate to. - cgStdRhsClosure bndr cc bi [the_fv] [] body lf_info [StgVarArg the_fv] + setSRT srt $ cgStdRhsClosure bndr cc bi [the_fv] [] body lf_info [StgVarArg the_fv] where lf_info = mkSelectorLFInfo bndr offset_into_int (isUpdatable upd_flag) @@ -362,7 +362,7 @@ We only generate an Ap thunk if all the free variables are pointers, for semi-obvious reasons. \begin{code} -mkRhsClosure this_pkg bndr cc bi srt +mkRhsClosure this_pkg bndr cc bi fvs upd_flag [] -- No args; a thunk @@ -387,8 +387,8 @@ mkRhsClosure this_pkg bndr cc bi srt The default case ~~~~~~~~~~~~~~~~ \begin{code} -mkRhsClosure this_pkg bndr cc bi srt fvs upd_flag args body - = cgRhsClosure bndr cc bi srt fvs upd_flag args body +mkRhsClosure this_pkg bndr cc bi fvs upd_flag args body + = cgRhsClosure bndr cc bi fvs upd_flag args body \end{code} @@ -434,7 +434,7 @@ cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec binder -- case upd_flag of -- Updatable -> panic "cgLetNoEscapeRhs" -- Nothing to update! -- other -> cgLetNoEscapeClosure binder cc bi live_in_whole_let live_in_rhss args body - cgLetNoEscapeClosure binder cc bi srt full_live_in_rhss rhs_eob_info + setSRT srt $ cgLetNoEscapeClosure binder cc bi full_live_in_rhss rhs_eob_info maybe_cc_slot rec args body -- For a constructor RHS we want to generate a single chunk of code which @@ -442,7 +442,7 @@ cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec binder -- It's easy; just behave as if it was an StgRhsClosure with a ConApp inside! cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec binder (StgRhsCon cc con args) - = cgLetNoEscapeClosure binder cc noBinderInfo{-safe-} NoSRT + = setSRT NoSRT $ cgLetNoEscapeClosure binder cc noBinderInfo{-safe-} full_live_in_rhss rhs_eob_info maybe_cc_slot rec [] --No args; the binder is data structure, not a function (StgConApp con args) diff --git a/compiler/codeGen/CgForeignCall.hs b/compiler/codeGen/CgForeignCall.hs index 48015fa45a..b2ca5b166a 100644 --- a/compiler/codeGen/CgForeignCall.hs +++ b/compiler/codeGen/CgForeignCall.hs @@ -32,6 +32,7 @@ import CmmUtils import MachOp import SMRep import ForeignCall +import ClosureInfo import Constants import StaticFlags import Outputable @@ -76,8 +77,9 @@ emitForeignCall emitForeignCall results (CCall (CCallSpec target cconv safety)) args live = do vols <- getVolatileRegs live + srt <- getSRTInfo emitForeignCall' safety results - (CmmForeignCall cmm_target cconv) call_args (Just vols) + (CmmForeignCall cmm_target cconv) call_args (Just vols) srt where (call_args, cmm_target) = case target of @@ -96,7 +98,7 @@ emitForeignCall results (CCall (CCallSpec target cconv safety)) args live -- ToDo: this might not be correct for 64-bit API arg_size rep = max (machRepByteWidth rep) wORD_SIZE -emitForeignCall results (DNCall _) args live +emitForeignCall _ (DNCall _) _ _ = panic "emitForeignCall: DNCall" @@ -107,13 +109,14 @@ emitForeignCall' -> CmmCallTarget -- the op -> [(CmmExpr,MachHint)] -- arguments -> Maybe [GlobalReg] -- live vars, in case we need to save them + -> C_SRT -- the SRT of the calls continuation -> Code -emitForeignCall' safety results target args vols +emitForeignCall' safety results target args vols srt | not (playSafe safety) = do temp_args <- load_args_into_temps args let (caller_save, caller_load) = callerSaveVolatileRegs vols stmtsC caller_save - stmtC (CmmCall target results temp_args) + stmtC (CmmCall target results temp_args srt) stmtsC caller_load | otherwise = do @@ -126,15 +129,17 @@ emitForeignCall' safety results target args vols let (caller_save, caller_load) = callerSaveVolatileRegs vols emitSaveThreadState stmtsC caller_save + -- Using the same SRT for each of these is a little bit conservative + -- but it should work for now. stmtC (CmmCall (CmmForeignCall suspendThread CCallConv) [ (id,PtrHint) ] [ (CmmReg (CmmGlobal BaseReg), PtrHint) ] - ) - stmtC (CmmCall temp_target results temp_args) + srt) + stmtC (CmmCall temp_target results temp_args srt) stmtC (CmmCall (CmmForeignCall resumeThread CCallConv) [ (new_base, PtrHint) ] [ (CmmReg (CmmLocal id), PtrHint) ] - ) + srt) -- Assign the result to BaseReg: we -- might now have a different Capability! stmtC (CmmAssign (CmmGlobal BaseReg) (CmmReg (CmmLocal new_base))) diff --git a/compiler/codeGen/CgHpc.hs b/compiler/codeGen/CgHpc.hs index e457e4c944..caf68cd154 100644 --- a/compiler/codeGen/CgHpc.hs +++ b/compiler/codeGen/CgHpc.hs @@ -17,6 +17,7 @@ import CgUtils import CgMonad import CgForeignCall import ForeignCall +import ClosureInfo import FastString import HscTypes import Char @@ -70,6 +71,7 @@ initHpc this_mod (HpcInfo tickCount hashNo) , (CmmLit $ CmmLabel $ mkHpcTicksLabel $ this_mod,PtrHint) ] (Just []) + C_SRT -- No SRT b/c we PlayRisky } where mod_alloc = mkFastString "hs_hpc_module" diff --git a/compiler/codeGen/CgInfoTbls.hs b/compiler/codeGen/CgInfoTbls.hs index d3b54a2f65..4220b47210 100644 --- a/compiler/codeGen/CgInfoTbls.hs +++ b/compiler/codeGen/CgInfoTbls.hs @@ -10,7 +10,6 @@ module CgInfoTbls ( emitClosureCodeAndInfoTable, emitInfoTableAndCode, dataConTagZ, - getSRTInfo, emitReturnTarget, emitAlgReturnTarget, emitReturnInstr, mkRetInfoTable, @@ -187,12 +186,11 @@ mkFunGenInfoExtraBits fun_type arity srt_label liveness slow_entry emitReturnTarget :: Name -> CgStmts -- The direct-return code (if any) - -> SRT -> FCode CLabel -emitReturnTarget name stmts srt +emitReturnTarget name stmts = do { live_slots <- getLiveStackSlots ; liveness <- buildContLiveness name live_slots - ; srt_info <- getSRTInfo name srt + ; srt_info <- getSRTInfo ; let cl_type | isBigLiveness liveness = rET_BIG @@ -231,15 +229,14 @@ emitAlgReturnTarget :: Name -- Just for its unique -> [(ConTagZ, CgStmts)] -- Tagged branches -> Maybe CgStmts -- Default branch (if any) - -> SRT -- Continuation's SRT -> Int -- family size -> FCode (CLabel, SemiTaggingStuff) -emitAlgReturnTarget name branches mb_deflt srt fam_sz +emitAlgReturnTarget name branches mb_deflt fam_sz = do { blks <- getCgStmts $ emitSwitch tag_expr branches mb_deflt 0 (fam_sz - 1) -- NB: tag_expr is zero-based - ; lbl <- emitReturnTarget name blks srt + ; lbl <- emitReturnTarget name blks ; return (lbl, Nothing) } -- Nothing: the internal branches in the switch don't have -- global labels, so we can't use them at the 'call site' @@ -425,29 +422,6 @@ emitInfoTableAndCode info_lbl std_info extra_bits args blocks -- ------------------------------------------------------------------------- --- There is just one SRT for each top level binding; all the nested --- bindings use sub-sections of this SRT. The label is passed down to --- the nested bindings via the monad. - -getSRTInfo :: Name -> SRT -> FCode C_SRT -getSRTInfo id NoSRT = return NoC_SRT -getSRTInfo id (SRT off len bmp) - | len > hALF_WORD_SIZE_IN_BITS || bmp == [fromIntegral srt_escape] - = do { srt_lbl <- getSRTLabel - ; let srt_desc_lbl = mkSRTDescLabel id - ; emitRODataLits srt_desc_lbl - ( cmmLabelOffW srt_lbl off - : mkWordCLit (fromIntegral len) - : map mkWordCLit bmp) - ; return (C_SRT srt_desc_lbl 0 srt_escape) } - - | otherwise - = do { srt_lbl <- getSRTLabel - ; return (C_SRT srt_lbl off (fromIntegral (head bmp))) } - -- The fromIntegral converts to StgHalfWord - -srt_escape = (-1) :: StgHalfWord - srtLabelAndLength :: C_SRT -> CLabel -> (CmmLit, StgHalfWord) srtLabelAndLength NoC_SRT _ = (zeroCLit, 0) diff --git a/compiler/codeGen/CgLetNoEscape.lhs b/compiler/codeGen/CgLetNoEscape.lhs index 99705f6de6..3913a99ef0 100644 --- a/compiler/codeGen/CgLetNoEscape.lhs +++ b/compiler/codeGen/CgLetNoEscape.lhs @@ -136,7 +136,6 @@ cgLetNoEscapeClosure :: Id -- binder -> CostCentreStack -- NB: *** NOT USED *** ToDo (WDP 94/06) -> StgBinderInfo -- NB: ditto - -> SRT -> StgLiveVars -- variables live in RHS, including the binders -- themselves in the case of a recursive group -> EndOfBlockInfo -- where are we going to? @@ -149,7 +148,7 @@ cgLetNoEscapeClosure -- ToDo: deal with the cost-centre issues cgLetNoEscapeClosure - bndr cc binder_info srt full_live_in_rhss + bndr cc binder_info full_live_in_rhss rhs_eob_info cc_slot rec args body = let arity = length args @@ -168,7 +167,7 @@ cgLetNoEscapeClosure -- Ignore the label that comes back from -- mkRetDirectTarget. It must be conjured up elswhere - ; emitReturnTarget (idName bndr) abs_c srt + ; emitReturnTarget (idName bndr) abs_c ; return () }) ; returnFC (bndr, letNoEscapeIdInfo bndr vSp lf_info) } diff --git a/compiler/codeGen/CgMonad.lhs b/compiler/codeGen/CgMonad.lhs index 61b358a6ba..ca08e06582 100644 --- a/compiler/codeGen/CgMonad.lhs +++ b/compiler/codeGen/CgMonad.lhs @@ -32,6 +32,7 @@ module CgMonad ( EndOfBlockInfo(..), setEndOfBlockInfo, getEndOfBlockInfo, + setSRT, getSRT, setSRTLabel, getSRTLabel, setTickyCtrLabel, getTickyCtrLabel, @@ -65,6 +66,7 @@ import PackageConfig import Cmm import CmmUtils import CLabel +import StgSyn (SRT) import SMRep import Module import Id @@ -98,7 +100,8 @@ data CgInfoDownwards -- information only passed *downwards* by the monad cgd_dflags :: DynFlags, cgd_mod :: Module, -- Module being compiled cgd_statics :: CgBindings, -- [Id -> info] : static environment - cgd_srt :: CLabel, -- label of the current SRT + cgd_srt_lbl :: CLabel, -- label of the current SRT + cgd_srt :: SRT, -- the current SRT cgd_ticky :: CLabel, -- current destination for ticky counts cgd_eob :: EndOfBlockInfo -- Info for stuff to do at end of basic block: } @@ -108,6 +111,7 @@ initCgInfoDown dflags mod = MkCgInfoDown { cgd_dflags = dflags, cgd_mod = mod, cgd_statics = emptyVarEnv, + cgd_srt_lbl = error "initC: srt_lbl", cgd_srt = error "initC: srt", cgd_ticky = mkTopTickyCtrLabel, cgd_eob = initEobInfo } @@ -828,12 +832,21 @@ getEndOfBlockInfo = do getSRTLabel :: FCode CLabel -- Used only by cgPanic getSRTLabel = do info <- getInfoDown - return (cgd_srt info) + return (cgd_srt_lbl info) setSRTLabel :: CLabel -> FCode a -> FCode a setSRTLabel srt_lbl code = do info <- getInfoDown - withInfoDown code (info { cgd_srt = srt_lbl}) + withInfoDown code (info { cgd_srt_lbl = srt_lbl}) + +getSRT :: FCode SRT +getSRT = do info <- getInfoDown + return (cgd_srt info) + +setSRT :: SRT -> FCode a -> FCode a +setSRT srt code + = do info <- getInfoDown + withInfoDown code (info { cgd_srt = srt}) -- ---------------------------------------------------------------------------- -- Get/set the current ticky counter label diff --git a/compiler/codeGen/CgPrimOp.hs b/compiler/codeGen/CgPrimOp.hs index 17ecfa0856..01279b453d 100644 --- a/compiler/codeGen/CgPrimOp.hs +++ b/compiler/codeGen/CgPrimOp.hs @@ -13,6 +13,7 @@ module CgPrimOp ( #include "HsVersions.h" import ForeignCall +import ClosureInfo import StgSyn import CgForeignCall import CgBindery @@ -122,6 +123,7 @@ emitPrimOp [res] ParOp [arg] live (CmmForeignCall newspark CCallConv) [(CmmReg (CmmGlobal BaseReg), PtrHint), (arg,PtrHint)] (Just vols) + NoC_SRT -- No SRT b/c we do PlayRisky where newspark = CmmLit (CmmLabel (mkRtsCodeLabel SLIT("newSpark"))) @@ -138,6 +140,7 @@ emitPrimOp [] WriteMutVarOp [mutv,var] live CCallConv) [(CmmReg (CmmGlobal BaseReg), PtrHint), (mutv,PtrHint)] (Just vols) + NoC_SRT -- No SRT b/c we do PlayRisky -- #define sizzeofByteArrayzh(r,a) \ -- r = (((StgArrWords *)(a))->words * sizeof(W_)) @@ -342,6 +345,7 @@ emitPrimOp [res] op args live (CmmPrim prim) [(a,NoHint) | a<-args] -- ToDo: hints? (Just vols) + NoC_SRT -- No SRT b/c we do PlayRisky | Just mop <- translateOp op = let stmt = CmmAssign (CmmLocal res) (CmmMachOp mop args) in diff --git a/compiler/codeGen/CgUtils.hs b/compiler/codeGen/CgUtils.hs index a4d2338e52..26857d386c 100644 --- a/compiler/codeGen/CgUtils.hs +++ b/compiler/codeGen/CgUtils.hs @@ -29,7 +29,9 @@ module CgUtils ( mkWordCLit, mkStringCLit, mkByteStringCLit, packHalfWordsCLit, - blankWord + blankWord, + + getSRTInfo ) where #include "HsVersions.h" @@ -45,6 +47,8 @@ import CLabel import CmmUtils import MachOp import ForeignCall +import ClosureInfo +import StgSyn (SRT(..)) import Literal import Digraph import ListSetOps @@ -284,8 +288,9 @@ emitRtsCall' -> Maybe [GlobalReg] -> Code emitRtsCall' res fun args vols = do + srt <- getSRTInfo stmtsC caller_save - stmtC (CmmCall target res args) + stmtC (CmmCall target res args srt) stmtsC caller_load where (caller_save, caller_load) = callerSaveVolatileRegs vols @@ -705,3 +710,38 @@ possiblySameLoc (CmmRegOff r1 start1) rep1 (CmmRegOff r2 start2) rep2 possiblySameLoc l1 rep1 (CmmLit _) rep2 = False possiblySameLoc l1 rep1 l2 rep2 = True -- Conservative + +------------------------------------------------------------------------- +-- +-- Static Reference Tables +-- +------------------------------------------------------------------------- + +-- There is just one SRT for each top level binding; all the nested +-- bindings use sub-sections of this SRT. The label is passed down to +-- the nested bindings via the monad. + +getSRTInfo :: FCode C_SRT +getSRTInfo = do + srt_lbl <- getSRTLabel + srt <- getSRT + case srt of + -- TODO: Should we panic in this case? + -- Someone obviously thinks there should be an SRT + NoSRT -> return NoC_SRT + SRT off len bmp + | len > hALF_WORD_SIZE_IN_BITS || bmp == [fromIntegral srt_escape] + -> do id <- newUnique + let srt_desc_lbl = mkLargeSRTLabel id + emitRODataLits srt_desc_lbl + ( cmmLabelOffW srt_lbl off + : mkWordCLit (fromIntegral len) + : map mkWordCLit bmp) + return (C_SRT srt_desc_lbl 0 srt_escape) + + SRT off len bmp + | otherwise + -> return (C_SRT srt_lbl off (fromIntegral (head bmp))) + -- The fromIntegral converts to StgHalfWord + +srt_escape = (-1) :: StgHalfWord diff --git a/compiler/codeGen/ClosureInfo.lhs b/compiler/codeGen/ClosureInfo.lhs index 27aed3a70e..ad26b2ec7c 100644 --- a/compiler/codeGen/ClosureInfo.lhs +++ b/compiler/codeGen/ClosureInfo.lhs @@ -127,6 +127,10 @@ data C_SRT = NoC_SRT needsSRT :: C_SRT -> Bool needsSRT NoC_SRT = False needsSRT (C_SRT _ _ _) = True + +instance Outputable C_SRT where + ppr (NoC_SRT) = ptext SLIT("_no_srt_") + ppr (C_SRT label off bitmap) = parens (ppr label <> comma <> ppr off <> comma <> text (show bitmap)) \end{code} %************************************************************************ diff --git a/compiler/codeGen/CodeGen.lhs b/compiler/codeGen/CodeGen.lhs index 13e9c4a59c..4c7f570ff4 100644 --- a/compiler/codeGen/CodeGen.lhs +++ b/compiler/codeGen/CodeGen.lhs @@ -323,8 +323,9 @@ cgTopRhs bndr (StgRhsCon cc con args) cgTopRhs bndr (StgRhsClosure cc bi fvs upd_flag srt args body) = ASSERT(null fvs) -- There should be no free variables - setSRTLabel (mkSRTLabel (idName bndr)) $ - forkStatics (cgTopRhsClosure bndr cc bi srt upd_flag args body) + setSRTLabel (mkSRTLabel (idName bndr)) $ + setSRT srt $ + forkStatics (cgTopRhsClosure bndr cc bi upd_flag args body) \end{code} |