[project @ 2002-02-14 11:56:03 by njn]
[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 AbsCUtils        ( mkAbstractCs, mkAbsCStmts )
15 import CgTailCall       ( performReturn, mkStaticAlgReturnCode )
16 import ClosureInfo      ( layOutStaticConstr, layOutDynConstr, ClosureInfo )
17 import DataCon          ( DataCon, dataConName, dataConRepArgTys, isNullaryDataCon )
18 import Name             ( getOccName )
19 import OccName          ( occNameUserString )
20 import TyCon            ( tyConDataCons, isEnumerationTyCon, TyCon )
21 import Type             ( typePrimRep )
22 import CmdLineOpts
23 \end{code}
24
25 For every constructor we generate the following info tables:
26         A static info table, for static instances of the constructor,
27
28         Plus:
29
30 \begin{tabular}{lll}
31 Info tbls &      Macro  &            Kind of constructor \\
32 \hline
33 info & @CONST_INFO_TABLE@&    Zero arity (no info -- compiler uses static closure)\\
34 info & @CHARLIKE_INFO_TABLE@& Charlike   (no info -- compiler indexes fixed array)\\
35 info & @INTLIKE_INFO_TABLE@&  Intlike; the one macro generates both info tbls\\
36 info & @SPEC_INFO_TABLE@&     SPECish, and bigger than or equal to @MIN_UPD_SIZE@\\
37 info & @GEN_INFO_TABLE@&      GENish (hence bigger than or equal to @MIN_UPD_SIZE@)\\
38 \end{tabular}
39
40 Possible info tables for constructor con:
41
42 \begin{description}
43 \item[@_con_info@:]
44 Used for dynamically let(rec)-bound occurrences of
45 the constructor, and for updates.  For constructors
46 which are int-like, char-like or nullary, when GC occurs,
47 the closure tries to get rid of itself.
48
49 \item[@_static_info@:]
50 Static occurrences of the constructor
51 macro: @STATIC_INFO_TABLE@.
52 \end{description}
53
54
55 For zero-arity constructors, \tr{con}, we NO LONGER generate a static closure;
56 it's place is taken by the top level defn of the constructor.
57
58 For charlike and intlike closures there is a fixed array of static
59 closures predeclared.
60
61 \begin{code}
62 genStaticConBits :: CompilationInfo     -- global info about the compilation
63                  -> [TyCon]             -- tycons to generate
64                  -> AbstractC           -- output
65
66 genStaticConBits comp_info gen_tycons
67   = -- for each type constructor:
68     --   grab all its data constructors;
69     --      for each one, generate an info table
70     -- for each specialised type constructor
71     --   for each specialisation of the type constructor
72     --     grab data constructors, and generate info tables
73
74     -- ToDo: for tycons and specialisations which are not
75     --       declared in this module we must ensure that the
76     --       C labels are local to this module i.e. static
77     --       since they may be duplicated in other modules
78
79     mkAbstractCs [ gen_for_tycon tc `mkAbsCStmts` enum_closure_table tc
80                  | tc <- gen_tycons ]
81   where
82     gen_for_tycon :: TyCon -> AbstractC
83     gen_for_tycon tycon = mkAbstractCs [ genConInfo comp_info data_con 
84                                        | data_con <- tyConDataCons tycon ] 
85
86     enum_closure_table tycon
87         | isEnumerationTyCon tycon = CClosureTbl tycon
88         | otherwise                = AbsCNop
89                 -- Put the table after the data constructor decls, because the
90                 -- datatype closure table (for enumeration types)
91                 -- to (say) PrelBase_$wTrue_closure, which is defined in code_stuff
92 \end{code}
93
94
95 %************************************************************************
96 %*                                                                      *
97 \subsection[CgConTbls-info-tables]{Generating info tables for constructors}
98 %*                                                                      *
99 %************************************************************************
100
101 Generate the entry code, info tables, and (for niladic constructor) the
102 static closure, for a constructor.
103
104 \begin{code}
105 genConInfo :: CompilationInfo -> DataCon -> AbstractC
106
107 genConInfo comp_info data_con
108   =     -- Order of things is to reduce forward references
109     mkAbstractCs [if opt_EnsureSplittableC then CSplitMarker else AbsCNop,
110                   closure_code,
111                   static_code]
112   where
113     (closure_info, body_code) = mkConCodeAndInfo data_con
114
115     -- To allow the debuggers, interpreters, etc to cope with static
116     -- data structures (ie those built at compile time), we take care that
117     -- info-table contains the information we need.
118     (static_ci,_) = layOutStaticConstr con_name data_con typePrimRep arg_tys
119
120     static_body  = initC comp_info (
121                       profCtrC SLIT("TICK_ENT_STATIC_CON") [CReg node] `thenC`
122                       ldv_enter_and_body_code)
123
124     closure_body = initC comp_info (
125                       profCtrC SLIT("TICK_ENT_DYN_CON") [CReg node] `thenC`
126                       ldv_enter_and_body_code)
127
128     ldv_enter_and_body_code = ldvEnter `thenC` body_code
129
130     con_descr  = occNameUserString (getOccName data_con)
131
132     -- Don't need any dynamic closure code for zero-arity constructors
133     closure_code = if zero_arity_con then 
134                         AbsCNop 
135                    else 
136                         CClosureInfoAndCode closure_info closure_body Nothing con_descr
137
138     static_code  = CClosureInfoAndCode static_ci static_body Nothing con_descr
139
140     zero_arity_con   = isNullaryDataCon data_con
141         -- We used to check that all the arg-sizes were zero, but we don't
142         -- really have any constructors with only zero-size args, and it's
143         -- just one more thing to go wrong.
144
145     arg_tys         = dataConRepArgTys  data_con
146     con_name        = dataConName data_con
147 \end{code}
148
149 \begin{code}
150 mkConCodeAndInfo :: DataCon             -- Data constructor
151                  -> (ClosureInfo, Code) -- The info table
152
153 mkConCodeAndInfo con
154   = let
155         arg_tys = dataConRepArgTys con
156
157         (closure_info, arg_things)
158                 = layOutDynConstr (dataConName con) con typePrimRep arg_tys
159
160         body_code
161                 = -- NB: We don't set CC when entering data (WDP 94/06)
162                   profCtrC SLIT("TICK_RET_OLD") 
163                         [mkIntCLit (length arg_things)] `thenC`
164
165                   performReturn AbsCNop         -- Ptr to thing already in Node
166                                 (mkStaticAlgReturnCode con)
167         in
168         (closure_info, body_code)
169 \end{code}