[project @ 2000-05-23 11:35:36 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 CgMonad
13
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
20                         )
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 )
29 import Outputable       
30 \end{code}
31
32 For every constructor we generate the following info tables:
33         A static info table, for static instances of the constructor,
34
35         Plus:
36
37 \begin{tabular}{lll}
38 Info tbls &      Macro  &            Kind of constructor \\
39 \hline
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@)\\
45 \end{tabular}
46
47 Possible info tables for constructor con:
48
49 \begin{description}
50 \item[@_con_info@:]
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.
55
56 \item[@_static_info@:]
57 Static occurrences of the constructor
58 macro: @STATIC_INFO_TABLE@.
59 \end{description}
60
61
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.
64
65 For charlike and intlike closures there is a fixed array of static
66 closures predeclared.
67
68 \begin{code}
69 genStaticConBits :: CompilationInfo     -- global info about the compilation
70                  -> [TyCon]             -- tycons to generate
71                  -> AbstractC           -- output
72
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
80
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
85
86     mkAbstractCs [ gen_for_tycon tc | tc <- gen_tycons ]
87   where
88     gen_for_tycon :: TyCon -> AbstractC
89     gen_for_tycon tycon
90       = mkAbstractCs (map (genConInfo comp_info tycon) (tyConDataCons tycon)) 
91         `mkAbsCStmts` (
92           -- after the con decls, so we don't need to declare the constructor labels
93           if (isEnumerationTyCon tycon)
94             then CClosureTbl tycon
95             else AbsCNop
96         )
97 \end{code}
98
99 %************************************************************************
100 %*                                                                      *
101 \subsection[CgConTbls-info-tables]{Generating info tables for constructors}
102 %*                                                                      *
103 %************************************************************************
104
105 Generate the entry code, info tables, and (for niladic constructor) the
106 static closure, for a constructor.
107
108 \begin{code}
109 genConInfo :: CompilationInfo -> TyCon -> DataCon -> AbstractC
110
111 genConInfo comp_info tycon data_con
112   = mkAbstractCs [
113                   CSplitMarker,
114                   closure_code,
115                   static_code]
116         -- Order of things is to reduce forward references
117   where
118     (closure_info, body_code) = mkConCodeAndInfo data_con
119
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)
125
126     body       = (initC comp_info (
127                       profCtrC SLIT("TICK_ENT_CON") [CReg node] `thenC`
128                       body_code))
129
130     entry_addr = CLbl entry_label CodePtrRep
131     con_descr  = occNameUserString (getOccName data_con)
132
133     -- Don't need any dynamic closure code for zero-arity constructors
134     closure_code = if zero_arity_con then 
135                         AbsCNop 
136                    else 
137                         CClosureInfoAndCode closure_info body Nothing con_descr
138
139     static_code  = CClosureInfoAndCode static_ci body Nothing con_descr
140
141     cost_centre  = mkCCostCentreStack dontCareCCS -- not worried about static data costs
142
143     zero_size arg_ty = getPrimRepSize (typePrimRep arg_ty) == 0
144
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.
149
150     arg_tys         = dataConRepArgTys  data_con
151     entry_label     = mkConEntryLabel      con_name
152     con_name        = dataConName data_con
153 \end{code}
154
155 \begin{code}
156 mkConCodeAndInfo :: DataCon             -- Data constructor
157                  -> (ClosureInfo, Code) -- The info table
158
159 mkConCodeAndInfo con
160   = let
161         arg_tys = dataConRepArgTys con
162
163         (closure_info, arg_things)
164                 = layOutDynCon con typePrimRep arg_tys
165
166         body_code
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`
170
171                   performReturn AbsCNop         -- Ptr to thing already in Node
172                                 (mkStaticAlgReturnCode con)
173         in
174         (closure_info, body_code)
175 \end{code}