2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[CgConTbls]{Info tables and update bits for constructors}
7 module CgConTbls ( genStaticConBits ) where
9 #include "HsVersions.h"
15 import AbsCUtils ( mkAbstractCs, mkAbsCStmts )
16 import CostCentre ( noCCS )
17 import CgCon ( cgTopRhsCon )
18 import CgClosure ( cgTopRhsClosure )
19 import CgTailCall ( performReturn, mkStaticAlgReturnCode )
20 import ClosureInfo ( layOutStaticConstr, layOutDynConstr, mkClosureLFInfo, ClosureInfo )
21 import DataCon ( DataCon, dataConName, dataConRepArgTys, dataConId, isNullaryDataCon )
22 import Id ( mkTemplateLocals )
23 import Name ( getOccName )
24 import OccName ( occNameUserString )
25 import TyCon ( tyConDataCons, isEnumerationTyCon, TyCon )
26 import Type ( typePrimRep )
27 import BasicTypes ( TopLevelFlag(..) )
31 For every constructor we generate the following info tables:
32 A static info table, for static instances of the constructor,
37 Info tbls & Macro & Kind of constructor \\
39 info & @CONST_INFO_TABLE@& Zero arity (no info -- compiler uses static closure)\\
40 info & @CHARLIKE_INFO_TABLE@& Charlike (no info -- compiler indexes fixed array)\\
41 info & @INTLIKE_INFO_TABLE@& Intlike; the one macro generates both info tbls\\
42 info & @SPEC_INFO_TABLE@& SPECish, and bigger than or equal to @MIN_UPD_SIZE@\\
43 info & @GEN_INFO_TABLE@& GENish (hence bigger than or equal to @MIN_UPD_SIZE@)\\
46 Possible info tables for constructor con:
50 Used for dynamically let(rec)-bound occurrences of
51 the constructor, and for updates. For constructors
52 which are int-like, char-like or nullary, when GC occurs,
53 the closure tries to get rid of itself.
55 \item[@_static_info@:]
56 Static occurrences of the constructor
57 macro: @STATIC_INFO_TABLE@.
61 For zero-arity constructors, \tr{con}, we NO LONGER generate a static closure;
62 it's place is taken by the top level defn of the constructor.
64 For charlike and intlike closures there is a fixed array of static
68 genStaticConBits :: CompilationInfo -- global info about the compilation
69 -> [TyCon] -- tycons to generate
70 -> AbstractC -- output
72 genStaticConBits comp_info gen_tycons
73 = -- for each type constructor:
74 -- grab all its data constructors;
75 -- for each one, generate an info table
76 -- for each specialised type constructor
77 -- for each specialisation of the type constructor
78 -- grab data constructors, and generate info tables
80 -- ToDo: for tycons and specialisations which are not
81 -- declared in this module we must ensure that the
82 -- C labels are local to this module i.e. static
83 -- since they may be duplicated in other modules
85 mkAbstractCs [ gen_for_tycon tc `mkAbsCStmts` enum_closure_table tc
88 gen_for_tycon :: TyCon -> AbstractC
89 gen_for_tycon tycon = mkAbstractCs [ genConInfo comp_info data_con
90 | data_con <- tyConDataCons tycon ]
92 enum_closure_table tycon
93 | isEnumerationTyCon tycon = CClosureTbl tycon
95 -- Put the table after the data constructor decls, because the
96 -- datatype closure table (for enumeration types)
97 -- to (say) PrelBase_$wTrue_closure, which is defined in code_stuff
101 %************************************************************************
103 \subsection[CgConTbls-info-tables]{Generating info tables for constructors}
105 %************************************************************************
107 Generate the entry code, info tables, and (for niladic constructor) the
108 static closure, for a constructor.
111 genConInfo :: CompilationInfo -> DataCon -> AbstractC
113 genConInfo comp_info data_con
114 = -- Order of things is to reduce forward references
115 mkAbstractCs [CSplitMarker,
120 (closure_info, body_code) = mkConCodeAndInfo data_con
122 -- To allow the debuggers, interpreters, etc to cope with static
123 -- data structures (ie those built at compile time), we take care that
124 -- info-table contains the information we need.
125 (static_ci,_) = layOutStaticConstr con_name data_con typePrimRep arg_tys
127 body = initC comp_info (
128 profCtrC SLIT("TICK_ENT_CON") [CReg node] `thenC`
131 wrkr_code = initC comp_info (cgWorker data_con `thenFC` \ _ -> returnFC ())
132 con_descr = occNameUserString (getOccName data_con)
134 -- Don't need any dynamic closure code for zero-arity constructors
135 closure_code = if zero_arity_con then
138 CClosureInfoAndCode closure_info body Nothing con_descr
140 static_code = CClosureInfoAndCode static_ci body Nothing con_descr
142 zero_arity_con = isNullaryDataCon data_con
143 -- We used to check that all the arg-sizes were zero, but we don't
144 -- really have any constructors with only zero-size args, and it's
145 -- just one more thing to go wrong.
147 arg_tys = dataConRepArgTys data_con
148 con_name = dataConName data_con
152 mkConCodeAndInfo :: DataCon -- Data constructor
153 -> (ClosureInfo, Code) -- The info table
157 arg_tys = dataConRepArgTys con
159 (closure_info, arg_things)
160 = layOutDynConstr (dataConName con) con typePrimRep arg_tys
163 = -- NB: We don't set CC when entering data (WDP 94/06)
164 profCtrC SLIT("TICK_RET_OLD")
165 [mkIntCLit (length arg_things)] `thenC`
167 performReturn AbsCNop -- Ptr to thing already in Node
168 (mkStaticAlgReturnCode con)
170 (closure_info, body_code)
173 For a constructor C, make a binding
175 $wC = \x y -> $wC x y
177 i.e. a curried constructor that allocates. This means that we can treat
178 the worker for a constructor like any other function in the rest of the compiler.
182 | isNullaryDataCon data_con
183 = cgTopRhsCon work_id data_con []
186 = cgTopRhsClosure work_id
187 noCCS noBinderInfo NoSRT
191 work_id = dataConId data_con
192 arg_ids = mkTemplateLocals (dataConRepArgTys data_con)
193 rhs = StgConApp data_con [StgVarArg id | id <- arg_ids]
194 lf_info = mkClosureLFInfo work_id TopLevel [{-no fvs-}] ReEntrant arg_ids