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"
14 import StgSyn ( SRT(..) )
15 import AbsCUtils ( mkAbstractCs, mkAbsCStmts )
16 import CgTailCall ( performReturn, mkStaticAlgReturnCode )
17 import CLabel ( mkConEntryLabel )
18 import ClosureInfo ( layOutStaticClosure, layOutDynCon,
19 mkConLFInfo, ClosureInfo
21 import CostCentre ( dontCareCCS )
22 import FiniteMap ( fmToList, FiniteMap )
23 import DataCon ( DataCon, dataConName, dataConRepArgTys, isNullaryDataCon )
24 import Name ( getOccName )
25 import OccName ( occNameUserString )
26 import PrimRep ( getPrimRepSize, PrimRep(..) )
27 import TyCon ( tyConDataCons, isEnumerationTyCon, TyCon )
28 import Type ( typePrimRep, Type )
32 For every constructor we generate the following info tables:
33 A static info table, for static instances of the constructor,
38 Info tbls & Macro & Kind of constructor \\
40 info & @CONST_INFO_TABLE@& Zero arity (no info -- compiler uses static closure)\\
41 info & @CHARLIKE_INFO_TABLE@& Charlike (no info -- compiler indexes fixed array)\\
42 info & @INTLIKE_INFO_TABLE@& Intlike; the one macro generates both info tbls\\
43 info & @SPEC_INFO_TABLE@& SPECish, and bigger than or equal to @MIN_UPD_SIZE@\\
44 info & @GEN_INFO_TABLE@& GENish (hence bigger than or equal to @MIN_UPD_SIZE@)\\
47 Possible info tables for constructor con:
51 Used for dynamically let(rec)-bound occurrences of
52 the constructor, and for updates. For constructors
53 which are int-like, char-like or nullary, when GC occurs,
54 the closure tries to get rid of itself.
56 \item[@_static_info@:]
57 Static occurrences of the constructor
58 macro: @STATIC_INFO_TABLE@.
62 For zero-arity constructors, \tr{con}, we NO LONGER generate a static closure;
63 it's place is taken by the top level defn of the constructor.
65 For charlike and intlike closures there is a fixed array of static
69 genStaticConBits :: CompilationInfo -- global info about the compilation
70 -> [TyCon] -- tycons to generate
71 -> AbstractC -- output
73 genStaticConBits comp_info gen_tycons
74 = -- for each type constructor:
75 -- grab all its data constructors;
76 -- for each one, generate an info table
77 -- for each specialised type constructor
78 -- for each specialisation of the type constructor
79 -- grab data constructors, and generate info tables
81 -- ToDo: for tycons and specialisations which are not
82 -- declared in this module we must ensure that the
83 -- C labels are local to this module i.e. static
84 -- since they may be duplicated in other modules
86 mkAbstractCs [ gen_for_tycon tc | tc <- gen_tycons ]
88 gen_for_tycon :: TyCon -> AbstractC
90 = mkAbstractCs (map (genConInfo comp_info tycon) (tyConDataCons tycon))
92 -- after the con decls, so we don't need to declare the constructor labels
93 if (isEnumerationTyCon tycon)
94 then CClosureTbl tycon
99 %************************************************************************
101 \subsection[CgConTbls-info-tables]{Generating info tables for constructors}
103 %************************************************************************
105 Generate the entry code, info tables, and (for niladic constructor) the
106 static closure, for a constructor.
109 genConInfo :: CompilationInfo -> TyCon -> DataCon -> AbstractC
111 genConInfo comp_info tycon data_con
116 -- Order of things is to reduce forward references
118 (closure_info, body_code) = mkConCodeAndInfo data_con
120 -- To allow the debuggers, interpreters, etc to cope with static
121 -- data structures (ie those built at compile time), we take care that
122 -- info-table contains the information we need.
123 (static_ci,_) = layOutStaticClosure con_name typePrimRep arg_tys
124 (mkConLFInfo data_con)
126 body = (initC comp_info (
127 profCtrC SLIT("TICK_ENT_CON") [CReg node] `thenC`
130 entry_addr = CLbl entry_label CodePtrRep
131 con_descr = occNameUserString (getOccName data_con)
133 -- Don't need any dynamic closure code for zero-arity constructors
134 closure_code = if zero_arity_con then
137 CClosureInfoAndCode closure_info body Nothing con_descr
139 static_code = CClosureInfoAndCode static_ci body Nothing con_descr
141 cost_centre = mkCCostCentreStack dontCareCCS -- not worried about static data costs
143 zero_size arg_ty = getPrimRepSize (typePrimRep arg_ty) == 0
145 zero_arity_con = isNullaryDataCon data_con
146 -- We used to check that all the arg-sizes were zero, but we don't
147 -- really have any constructors with only zero-size args, and it's
148 -- just one more thing to go wrong.
150 arg_tys = dataConRepArgTys data_con
151 entry_label = mkConEntryLabel con_name
152 con_name = dataConName data_con
156 mkConCodeAndInfo :: DataCon -- Data constructor
157 -> (ClosureInfo, Code) -- The info table
161 arg_tys = dataConRepArgTys con
163 (closure_info, arg_things)
164 = layOutDynCon con typePrimRep arg_tys
167 = -- NB: We don't set CC when entering data (WDP 94/06)
168 profCtrC SLIT("TICK_RET_OLD")
169 [mkIntCLit (length arg_things)] `thenC`
171 performReturn AbsCNop -- Ptr to thing already in Node
172 (mkStaticAlgReturnCode con)
174 (closure_info, body_code)