summaryrefslogtreecommitdiff
path: root/compiler/codeGen
diff options
context:
space:
mode:
authorMichael D. Adams <t-madams@microsoft.com>2007-06-27 15:09:03 +0000
committerMichael D. Adams <t-madams@microsoft.com>2007-06-27 15:09:03 +0000
commitaffbe8dae5d7eb350686b42ddbd4f3561b7bd0ec (patch)
tree7558970725c9e17e0017d6c825949d8e178d3445 /compiler/codeGen
parent207802589da0d23c3f16195f453b24a1e46e322d (diff)
downloadhaskell-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.lhs30
-rw-r--r--compiler/codeGen/CgClosure.lhs10
-rw-r--r--compiler/codeGen/CgExpr.lhs20
-rw-r--r--compiler/codeGen/CgForeignCall.hs19
-rw-r--r--compiler/codeGen/CgHpc.hs2
-rw-r--r--compiler/codeGen/CgInfoTbls.hs34
-rw-r--r--compiler/codeGen/CgLetNoEscape.lhs5
-rw-r--r--compiler/codeGen/CgMonad.lhs19
-rw-r--r--compiler/codeGen/CgPrimOp.hs4
-rw-r--r--compiler/codeGen/CgUtils.hs44
-rw-r--r--compiler/codeGen/ClosureInfo.lhs4
-rw-r--r--compiler/codeGen/CodeGen.lhs5
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}