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