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