[project @ 2001-10-03 13:58:13 by simonpj]
[ghc-hetmet.git] / ghc / compiler / codeGen / CgConTbls.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[CgConTbls]{Info tables and update bits for constructors}
5
6 \begin{code}
7 module CgConTbls ( genStaticConBits ) where
8
9 #include "HsVersions.h"
10
11 import AbsCSyn
12 import StgSyn
13 import CgMonad
14
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(..) )
28 import Outputable
29 \end{code}
30
31 For every constructor we generate the following info tables:
32         A static info table, for static instances of the constructor,
33
34         Plus:
35
36 \begin{tabular}{lll}
37 Info tbls &      Macro  &            Kind of constructor \\
38 \hline
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@)\\
44 \end{tabular}
45
46 Possible info tables for constructor con:
47
48 \begin{description}
49 \item[@_con_info@:]
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.
54
55 \item[@_static_info@:]
56 Static occurrences of the constructor
57 macro: @STATIC_INFO_TABLE@.
58 \end{description}
59
60
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.
63
64 For charlike and intlike closures there is a fixed array of static
65 closures predeclared.
66
67 \begin{code}
68 genStaticConBits :: CompilationInfo     -- global info about the compilation
69                  -> [TyCon]             -- tycons to generate
70                  -> AbstractC           -- output
71
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
79
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
84
85     mkAbstractCs [ gen_for_tycon tc `mkAbsCStmts` enum_closure_table tc
86                  | tc <- gen_tycons ]
87   where
88     gen_for_tycon :: TyCon -> AbstractC
89     gen_for_tycon tycon = mkAbstractCs [ genConInfo comp_info data_con 
90                                        | data_con <- tyConDataCons tycon ] 
91
92     enum_closure_table tycon
93         | isEnumerationTyCon tycon = CClosureTbl tycon
94         | otherwise                = AbsCNop
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
98 \end{code}
99
100
101 %************************************************************************
102 %*                                                                      *
103 \subsection[CgConTbls-info-tables]{Generating info tables for constructors}
104 %*                                                                      *
105 %************************************************************************
106
107 Generate the entry code, info tables, and (for niladic constructor) the
108 static closure, for a constructor.
109
110 \begin{code}
111 genConInfo :: CompilationInfo -> DataCon -> AbstractC
112
113 genConInfo comp_info data_con
114   =     -- Order of things is to reduce forward references
115     mkAbstractCs [CSplitMarker,
116                   closure_code,
117                   static_code,
118                   wrkr_code]
119   where
120     (closure_info, body_code) = mkConCodeAndInfo data_con
121
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
126
127     body       = initC comp_info (
128                       profCtrC SLIT("TICK_ENT_CON") [CReg node] `thenC`
129                       body_code)
130
131     wrkr_code  = initC comp_info (cgWorker data_con `thenFC` \ _ -> returnFC ())
132     con_descr  = occNameUserString (getOccName data_con)
133
134     -- Don't need any dynamic closure code for zero-arity constructors
135     closure_code = if zero_arity_con then 
136                         AbsCNop 
137                    else 
138                         CClosureInfoAndCode closure_info body Nothing con_descr
139
140     static_code  = CClosureInfoAndCode static_ci body Nothing con_descr
141
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.
146
147     arg_tys         = dataConRepArgTys  data_con
148     con_name        = dataConName data_con
149 \end{code}
150
151 \begin{code}
152 mkConCodeAndInfo :: DataCon             -- Data constructor
153                  -> (ClosureInfo, Code) -- The info table
154
155 mkConCodeAndInfo con
156   = let
157         arg_tys = dataConRepArgTys con
158
159         (closure_info, arg_things)
160                 = layOutDynConstr (dataConName con) con typePrimRep arg_tys
161
162         body_code
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`
166
167                   performReturn AbsCNop         -- Ptr to thing already in Node
168                                 (mkStaticAlgReturnCode con)
169         in
170         (closure_info, body_code)
171 \end{code}
172
173 For a constructor C, make a binding
174
175         $wC = \x y -> $wC x y
176
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.
179
180 \begin{code}
181 cgWorker data_con
182   | isNullaryDataCon data_con
183   = cgTopRhsCon work_id data_con []
184
185   | otherwise
186   = cgTopRhsClosure work_id
187             noCCS noBinderInfo NoSRT
188             arg_ids rhs
189             lf_info
190   where
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
195 \end{code}