-Special Case:
-Constructors some of whose arguments are of \tr{Float#} or
-\tr{Double#} type, {\em or} which are ``lit lits'' (which are given
-\tr{Addr#} type).
-
-These ones have to be compiled as re-entrant thunks rather than closures,
-because we can't figure out a way to persuade C to allow us to initialise a
-static closure with Floats and Doubles!
-Thus, for \tr{x = 2.0} (defaults to Double), we get:
-
-\begin{verbatim}
--- The STG syntax:
- Main.x = MkDouble [2.0##]
-
--- C Code:
-
--- closure:
- SET_STATIC_HDR(Main_x_closure,Main_x_static,CC_DATA,,EXTDATA_RO)
- };
--- its *own* info table:
- STATIC_INFO_TABLE(Main_x,Main_x_entry,,,,EXTFUN,???,":MkDouble","Double");
--- with its *own* entry code:
- STGFUN(Main_x_entry) {
- P_ u1701;
- RetDouble1=2.0;
- u1701=(P_)*SpB;
- SpB=SpB-1;
- JMP_(u1701[0]);
- }
-\end{verbatim}
-
-The above has the down side that each floating-point constant will end
-up with its own info table (rather than sharing the MkFloat/MkDouble
-ones). On the plus side, however, it does return a value (\tr{2.0})
-{\em straight away}.
-
-Here, then is the implementation: just pretend it's a non-updatable
-thunk. That is, instead of
-
- x = F# 3.455#
-
-pretend we've seen
-
- x = [] \n [] -> F# 3.455#
-
-\begin{code}
-top_cc = dontCareCostCentre -- out here to avoid a cgTopRhsCon CAF (sigh)
-top_ccc = mkCCostCentre dontCareCostCentre -- because it's static data
-
-cgTopRhsCon name con args all_zero_size_args
- | any (isFloatingKind . getAtomKind) args
- || any isLitLitStgAtom args
- = cgTopRhsClosure name top_cc NoStgBinderInfo [] body lf_info
- where
- body = StgConApp con args emptyUniqSet{-emptyLiveVarSet-}
- lf_info = mkClosureLFInfo True {- Top level -} [] ReEntrant [] body
-\end{code}
-
-OK, so now we have the general case.
-
-\begin{code}
-cgTopRhsCon name con args all_zero_size_args
- = (
- ASSERT(isDataCon con)
-
- -- LAY IT OUT
- getAtomAmodes args `thenFC` \ amodes ->
-
- let
- (closure_info, amodes_w_offsets)
- = layOutStaticClosure name getAmodeKind amodes lf_info
- in
- -- HWL: In 0.22 there was a heap check in here that had to be changed.
- -- CHECK if having no heap check is ok for GrAnSim here!!!
-
- -- BUILD THE OBJECT
- absC (CStaticClosure
- closure_label -- Labelled with the name on lhs of defn
- closure_info -- Closure is static
- top_ccc
- (map fst amodes_w_offsets)) -- Sorted into ptrs first, then nonptrs
-
- ) `thenC`
-
- -- RETURN
- returnFC (name, stableAmodeIdInfo name (CLbl closure_label PtrKind) lf_info)
- where
- con_tycon = getDataConTyCon con
- lf_info = mkConLFInfo con
-
- closure_label = mkClosureLabel name
- info_label = mkInfoTableLabel con
- con_entry_label = mkConEntryLabel con
- entry_label = mkStdEntryLabel name
-\end{code}
-
-The general case is:
-\begin{verbatim}
--- code:
- data Foo = MkFoo
- x = MkFoo
-
--- STG code:
-STG syntax:
- Main.x = Main.MkFoo []
-
--- interesting parts of the C Code:
-
--- closure for "x":
- SET_STATIC_HDR(Main_x_closure,Main_MkFoo_static,CC_DATA,,EXTDATA_RO)
- };
--- entry code for "x":
- STGFUN(Main_x_entry) {
- Node=(W_)(Main_x_closure);
- STGJUMP(Main_MkFoo_entry);
- }
-\end{verbatim}
-
-Observe: (1)~We create a static closure for \tr{x}, {\em reusing} the
-regular \tr{MkFoo} info-table and entry code. (2)~However: the
-\tr{MkFoo} code expects Node to be set, but the caller of \tr{x_entry}
-will not have set it. Therefore, the whole point of \tr{x_entry} is
-to set node (and then call the shared \tr{MkFoo} entry code).
-
-
-
-Special Case:
-For top-level Int/Char constants. We get entry-code fragments of the form:
-
-\begin{verbatim}
--- code:
- y = 1
-
--- entry code for "y":
- STGFUN(Main_y_entry) {
- Node=(W_)(Main_y_closure);
- STGJUMP(I#_entry);
- }
-\end{verbatim}
-
-This is pretty tiresome: we {\em know} what the constant is---we'd
-rather just return it. We end up with something that's a hybrid
-between the Float/Double and general cases: (a)~like Floats/Doubles,
-the entry-code returns the value immediately; (b)~like the general
-case, we share the data-constructor's std info table. So, what we
-want is:
-\begin{verbatim}
--- code:
- z = 1
-
--- STG code:
-STG syntax:
- Main.z = I# [1#]
-
--- interesting parts of the C Code:
-
--- closure for "z" (shares I# info table):
- SET_STATIC_HDR(Main_z_closure,I#_static,CC_DATA,,EXTDATA_RO)
- };
--- entry code for "z" (do the business directly):
- STGFUN(Main_z_entry) {
- P_ u1702;
- Ret1=1;
- u1702=(P_)*SpB;
- SpB=SpB-1;
- JMP_(u1702[0]);
- }
-\end{verbatim}
-
-This blob used to be in cgTopRhsCon, but I don't see how we can
-jump direct to the named code for a constructor; any external entries
-will be via Node. Generating all this extra code is a real waste
-for big static data structures. So I've nuked it. SLPJ Sept 94
-
-
-Further discourse on these entry-code fragments (NB this isn't done
-yet [ToDo]): They're really pretty pointless, except for {\em
-exported} top-level constants (the rare case). Consider:
-\begin{verbatim}
-y = p : ps -- y is not exported
-f a b = y
-g c = (y, c)
-\end{verbatim}
-Why have a \tr{y_entry} fragment at all? The code generator should
-``know enough'' about \tr{y} not to need it. For the first case
-above, with \tr{y} in ``head position,'' it should generate code just
-as for an \tr{StgRhsCon} (possibly because the STG simplification
-actually did the unfolding to make it so). At the least, it should
-load up \tr{Node} and call \tr{Cons}'s entry code---not some special
-\tr{y_entry} code.
-
-\begin{pseudocode}
- -- WE NEED AN ENTRY PT, IN CASE SOMEONE JUMPS DIRECT TO name
- -- FROM OUTSIDE. NB: this CCodeBlock precedes the
- -- CStaticClosure for the same reason (fewer forward refs) as
- -- we did in CgClosure.
-
- -- we either have ``in-line'' returning code (special case)
- -- or we set Node and jump to the constructor's entry code
-
- (if maybeToBool (maybeCharLikeTyCon con_tycon)
- || maybeToBool (maybeIntLikeTyCon con_tycon)
- then -- special case
- getAbsC (-- OLD: No, we don't fiddle cost-centres on
- -- entry to data values any more (WDP 94/06)
- -- lexCostCentreC "ENTER_CC_D" [top_ccc]
- -- `thenC`
- cgReturnDataCon con amodes all_zero_size_args emptyUniqSet{-no live vars-})
- else -- boring case
- returnFC (
- mkAbstractCs [
- -- Node := this_closure
- CAssign (CReg node) (CLbl closure_label PtrKind),
- -- InfoPtr := info table for this_closure
- CAssign (CReg infoptr) (CLbl info_label DataPtrKind),
- -- Jump to std code for this constructor
- CJump (CLbl con_entry_label CodePtrKind)
- ])
- ) `thenFC` \ ret_absC ->
-
- absC (CCodeBlock entry_label ret_absC) `thenC`
-\end{pseudocode}
-
-=========================== END OF OLD STUFF ==============================
-
-