import TyCon
import DataCon
import Id
+import IdInfo
import Type
import PrelInfo
import Outputable
import ListSetOps
-#ifdef DEBUG
-import Util ( lengthIs )
-#endif
+import Util
+import Module
+import FastString
+import StaticFlags
\end{code}
-> FCode (Id, CgIdInfo)
cgTopRhsCon id con args
= do {
- ; this_pkg <- getThisPackage
#if mingw32_TARGET_OS
-- Windows DLLs have a problem with static cross-DLL refs.
+ ; this_pkg <- getThisPackage
; ASSERT( not (isDllConApp this_pkg con args) ) return ()
#endif
; ASSERT( args `lengthIs` dataConRepArity con ) return ()
; let
name = idName id
lf_info = mkConLFInfo con
- closure_label = mkClosureLabel this_pkg name
+ closure_label = mkClosureLabel name $ idCafInfo id
caffy = any stgArgHasCafRefs args
- (closure_info, amodes_w_offsets) = layOutStaticConstr this_pkg con amodes
+ (closure_info, amodes_w_offsets) = layOutStaticConstr con amodes
closure_rep = mkStaticClosureFields
closure_info
dontCareCCS -- Because it's static data
at all.
\begin{code}
-buildDynCon binder cc con []
- = do this_pkg <- getThisPackage
- returnFC (taggedStableIdInfo binder
- (mkLblExpr (mkClosureLabel this_pkg (dataConName con)))
+buildDynCon binder _ con []
+ = returnFC (taggedStableIdInfo binder
+ (mkLblExpr (mkClosureLabel (dataConName con)
+ (idCafInfo binder)))
(mkConLFInfo con)
con)
\end{code}
Because of this, we use can safely return an addressing mode.
+We don't support this optimisation when compiling into Windows DLLs yet
+because they don't support cross package data references well.
+
\begin{code}
-buildDynCon binder cc con [arg_amode]
+
+
+buildDynCon binder _ con [arg_amode]
| maybeIntLikeCon con
+#if defined(mingw32_TARGET_OS)
+ , not opt_PIC
+#endif
, (_, CmmLit (CmmInt val _)) <- arg_amode
, let val_int = (fromIntegral val) :: Int
, val_int <= mAX_INTLIKE && val_int >= mIN_INTLIKE
- = do { let intlike_lbl = mkRtsDataLabel SLIT("stg_INTLIKE_closure")
+ = do { let intlike_lbl = mkCmmGcPtrLabel rtsPackageId (fsLit "stg_INTLIKE_closure")
offsetW = (val_int - mIN_INTLIKE) * (fixedHdrSize + 1)
-- INTLIKE closures consist of a header and one word payload
intlike_amode = CmmLit (cmmLabelOffW intlike_lbl offsetW)
; returnFC (taggedStableIdInfo binder intlike_amode (mkConLFInfo con) con) }
-buildDynCon binder cc con [arg_amode]
+buildDynCon binder _ con [arg_amode]
| maybeCharLikeCon con
+#if defined(mingw32_TARGET_OS)
+ , not opt_PIC
+#endif
, (_, CmmLit (CmmInt val _)) <- arg_amode
, let val_int = (fromIntegral val) :: Int
, val_int <= mAX_CHARLIKE && val_int >= mIN_CHARLIKE
- = do { let charlike_lbl = mkRtsDataLabel SLIT("stg_CHARLIKE_closure")
+ = do { let charlike_lbl = mkCmmGcPtrLabel rtsPackageId (fsLit "stg_CHARLIKE_closure")
offsetW = (val_int - mIN_CHARLIKE) * (fixedHdrSize + 1)
-- CHARLIKE closures consist of a header and one word payload
charlike_amode = CmmLit (cmmLabelOffW charlike_lbl offsetW)
; returnFC (taggedStableIdInfo binder charlike_amode (mkConLFInfo con) con) }
+
\end{code}
Now the general case.
\begin{code}
buildDynCon binder ccs con args
= do {
- ; this_pkg <- getThisPackage
; let
- (closure_info, amodes_w_offsets) = layOutDynConstr this_pkg con args
+ (closure_info, amodes_w_offsets) = layOutDynConstr con args
; hp_off <- allocDynClosure closure_info use_cc blame_cc amodes_w_offsets
; returnFC (taggedHeapIdInfo binder hp_off lf_info con) }
\begin{code}
bindConArgs :: DataCon -> [Id] -> Code
bindConArgs con args
- = do this_pkg <- getThisPackage
+ = do
let
-- The binding below forces the masking out of the tag bits
-- when accessing the constructor field.
bind_arg (arg, offset) = bindNewToUntagNode arg offset (mkLFArgument arg) (tagForCon con)
- (_, args_w_offsets) = layOutDynConstr this_pkg con (addIdReps args)
+ (_, args_w_offsets) = layOutDynConstr con (addIdReps args)
--
ASSERT(not (isUnboxedTupleCon con)) return ()
mapCs bind_arg args_w_offsets
cgReturnDataCon :: DataCon -> [(CgRep, CmmExpr)] -> Code
cgReturnDataCon con amodes
+ | isUnboxedTupleCon con = returnUnboxedTuple amodes
+ -- when profiling we can't shortcut here, we have to enter the closure
+ -- for it to be marked as "used" for LDV profiling.
+ | opt_SccProfilingOn = build_it_then enter_it
+ | otherwise
= ASSERT( amodes `lengthIs` dataConRepArity con )
do { EndOfBlockInfo _ sequel <- getEndOfBlockInfo
; case sequel of
| isDeadBinder bndr -> performReturn (jump_to deflt_lbl)
| otherwise -> build_it_then (jump_to deflt_lbl) }
- other_sequel -- The usual case
- | isUnboxedTupleCon con -> returnUnboxedTuple amodes
- | otherwise -> build_it_then emitReturnInstr
+ _otherwise -- The usual case
+ -> build_it_then emitReturnInstr
}
where
+ enter_it = stmtsC [ CmmAssign nodeReg (cmmUntag (CmmReg nodeReg)),
+ CmmJump (entryCode (closureInfoPtr (CmmReg nodeReg))) [] ]
jump_to lbl = stmtC (CmmJump (CmmLit lbl) [])
build_it_then return_code
= do { -- BUILD THE OBJECT IN THE HEAP
-- datatype closure table (for enumeration types)
-- to (say) PrelBase_$wTrue_closure, which is defined in code_stuff
-- Note that the closure pointers are tagged.
+
+ -- XXX comment says to put table after constructor decls, but
+ -- code appears to put it before --- NR 16 Aug 2007
; extra <-
if isEnumerationTyCon tycon then do
- tbl <- getCmm (emitRODataLits (mkLocalClosureTableLabel
- (tyConName tycon))
- [ CmmLabelOff (mkLocalClosureLabel (dataConName con)) (tagForCon con)
+ tbl <- getCmm (emitRODataLits "cgTyCon" (mkLocalClosureTableLabel (tyConName tycon) NoCafRefs)
+ [ CmmLabelOff (mkLocalClosureLabel (dataConName con) NoCafRefs) (tagForCon con)
| con <- tyConDataCons tycon])
return [tbl]
else
cgDataCon :: DataCon -> Code
cgDataCon data_con
= do { -- Don't need any dynamic closure code for zero-arity constructors
- this_pkg <- getThisPackage
; let
-- To allow the debuggers, interpreters, etc to cope with
-- time), we take care that info-table contains the
-- information we need.
(static_cl_info, _) =
- layOutStaticConstr this_pkg data_con arg_reps
+ layOutStaticConstr data_con arg_reps
(dyn_cl_info, arg_things) =
- layOutDynConstr this_pkg data_con arg_reps
+ layOutDynConstr data_con arg_reps
emit_info cl_info ticky_code
= do { code_blks <- getCgStmts the_code
; emitClosureCodeAndInfoTable cl_info [] code_blks }
where
- the_code = do { ticky_code
+ the_code = do { _ <- ticky_code
; ldvEnter (CmmReg nodeReg)
; body_code }