[project @ 1999-01-14 17:58:41 by sof]
[ghc-hetmet.git] / ghc / compiler / codeGen / CgExpr.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 % $Id: CgExpr.lhs,v 1.19 1999/01/14 17:58:46 sof Exp $
5 %
6 %********************************************************
7 %*                                                      *
8 \section[CgExpr]{Converting @StgExpr@s}
9 %*                                                      *
10 %********************************************************
11
12 \begin{code}
13 module CgExpr ( cgExpr ) where
14
15 #include "HsVersions.h"
16
17 import Constants        ( mAX_SPEC_SELECTEE_SIZE, mAX_SPEC_AP_SIZE )
18 import StgSyn
19 import CgMonad
20 import AbsCSyn
21 import AbsCUtils        ( mkAbstractCs )
22 import CLabel           ( mkClosureTblLabel )
23
24 import SMRep            ( fixedHdrSize )
25 import CgBindery        ( getArgAmodes, CgIdInfo, nukeDeadBindings )
26 import CgCase           ( cgCase, saveVolatileVarsAndRegs, 
27                           restoreCurrentCostCentre,
28                           splitTyConAppThroughNewTypes )
29 import CgClosure        ( cgRhsClosure, cgStdRhsClosure )
30 import CgCon            ( buildDynCon, cgReturnDataCon )
31 import CgLetNoEscape    ( cgLetNoEscapeClosure )
32 import CgRetConv        ( dataReturnConvPrim )
33 import CgTailCall       ( cgTailCall, performReturn, performPrimReturn,
34                           mkDynamicAlgReturnCode, mkPrimReturnCode,
35                           tailCallPrimOp, returnUnboxedTuple
36                         )
37 import ClosureInfo      ( mkClosureLFInfo, mkSelectorLFInfo,
38                           mkApLFInfo, layOutDynCon )
39 import CostCentre       ( sccAbleCostCentre, isDictCC, isSccCountCostCentre )
40 import Id               ( idPrimRep, idType, Id )
41 import VarSet
42 import DataCon          ( DataCon, dataConTyCon )
43 import Const            ( Con(..) )
44 import IdInfo           ( ArityInfo(..) )
45 import PrimOp           ( primOpOutOfLine, 
46                           getPrimOpResultInfo, PrimOp(..), PrimOpResultInfo(..)
47                         )
48 import PrimRep          ( getPrimRepSize, PrimRep(..), isFollowableRep )
49 import TyCon            ( maybeTyConSingleCon,
50                           isUnboxedTupleTyCon, isEnumerationTyCon )
51 import Type             ( Type, typePrimRep )
52 import Maybes           ( assocMaybe, maybeToBool )
53 import Unique           ( mkBuiltinUnique )
54 import BasicTypes       ( TopLevelFlag(..), RecFlag(..) )
55 import Outputable
56 \end{code}
57
58 This module provides the support code for @StgToAbstractC@ to deal
59 with STG {\em expressions}.  See also @CgClosure@, which deals
60 with closures, and @CgCon@, which deals with constructors.
61
62 \begin{code}
63 cgExpr  :: StgExpr              -- input
64         -> Code                 -- output
65 \end{code}
66
67 %********************************************************
68 %*                                                      *
69 %*              Tail calls                              *
70 %*                                                      *
71 %********************************************************
72
73 ``Applications'' mean {\em tail calls}, a service provided by module
74 @CgTailCall@.  This includes literals, which show up as
75 @(STGApp (StgLitArg 42) [])@.
76
77 \begin{code}
78 cgExpr (StgApp fun args) = cgTailCall fun args
79 \end{code}
80
81 %********************************************************
82 %*                                                      *
83 %*              STG ConApps  (for inline versions)      *
84 %*                                                      *
85 %********************************************************
86
87 \begin{code}
88 cgExpr (StgCon (DataCon con) args res_ty)
89   = getArgAmodes args `thenFC` \ amodes ->
90     cgReturnDataCon con amodes (all zero_size args)
91   where
92     zero_size atom = getPrimRepSize (getArgPrimRep atom) == 0
93 \end{code}
94
95 Literals are similar to constructors; they return by putting
96 themselves in an appropriate register and returning to the address on
97 top of the stack.
98
99 \begin{code}
100 cgExpr (StgCon (Literal lit) args res_ty)
101   = ASSERT( null args )
102     performPrimReturn (text "literal" <+> ppr lit) (CLit lit)
103 \end{code}
104
105
106 %********************************************************
107 %*                                                      *
108 %*              STG PrimApps  (unboxed primitive ops)   *
109 %*                                                      *
110 %********************************************************
111
112 Here is where we insert real live machine instructions.
113
114 NOTE about _ccall_GC_:
115
116 A _ccall_GC_ is treated as an out-of-line primop for the case
117 expression code, because we want a proper stack frame on the stack
118 when we perform it.  When we get here, however, we need to actually
119 perform the call, so we treat it an an inline primop.
120
121 \begin{code}
122 cgExpr (StgCon (PrimOp op@(CCallOp _ _ may_gc@True _)) args res_ty)
123   = primRetUnboxedTuple op args res_ty
124
125 cgExpr x@(StgCon (PrimOp op) args res_ty)
126   | primOpOutOfLine op = tailCallPrimOp op args
127   | otherwise
128   = ASSERT(op /= SeqOp) -- can't handle SeqOp
129
130     getArgAmodes args   `thenFC` \ arg_amodes ->
131
132     case (getPrimOpResultInfo op) of
133
134         ReturnsPrim kind ->
135             let result_amode = CReg (dataReturnConvPrim kind) in
136             performReturn 
137               (COpStmt [result_amode] op arg_amodes [{-no vol_regs-}])
138               (mkPrimReturnCode (text "primapp)" <+> ppr x))
139                           
140         -- otherwise, must be returning an enumerated type (eg. Bool).
141         -- we've only got the tag in R2, so we have to load the constructor
142         -- itself into R1.
143
144         ReturnsAlg tycon
145             | isUnboxedTupleTyCon tycon -> primRetUnboxedTuple op args res_ty
146
147
148             | isEnumerationTyCon  tycon ->
149                 performReturn
150                      (COpStmt [dyn_tag] op arg_amodes [{-no vol_regs-}])
151                           (\ sequel -> 
152                           absC (CAssign (CReg node) closure_lbl) `thenC`
153                           mkDynamicAlgReturnCode tycon dyn_tag sequel)
154
155             where
156                -- Pull a unique out of thin air to put the tag in.  
157                -- It shouldn't matter if this overlaps with anything - we're
158                -- about to return anyway.
159                dyn_tag = CTemp (mkBuiltinUnique 0) IntRep
160
161                closure_lbl = CTableEntry 
162                                (CLbl (mkClosureTblLabel tycon) PtrRep)
163                                dyn_tag PtrRep
164
165 \end{code}
166
167 %********************************************************
168 %*                                                      *
169 %*              Case expressions                        *
170 %*                                                      *
171 %********************************************************
172 Case-expression conversion is complicated enough to have its own
173 module, @CgCase@.
174 \begin{code}
175
176 cgExpr (StgCase expr live_vars save_vars bndr srt alts)
177   = cgCase expr live_vars save_vars bndr srt alts
178 \end{code}
179
180
181 %********************************************************
182 %*                                                      *
183 %*              Let and letrec                          *
184 %*                                                      *
185 %********************************************************
186 \subsection[let-and-letrec-codegen]{Converting @StgLet@ and @StgLetrec@}
187
188 \begin{code}
189 cgExpr (StgLet (StgNonRec name rhs) expr)
190   = cgRhs name rhs      `thenFC` \ (name, info) ->
191     addBindC name info  `thenC`
192     cgExpr expr
193
194 cgExpr (StgLet (StgRec pairs) expr)
195   = fixC (\ new_bindings -> addBindsC new_bindings `thenC`
196                             listFCs [ cgRhs b e | (b,e) <- pairs ]
197     ) `thenFC` \ new_bindings ->
198
199     addBindsC new_bindings `thenC`
200     cgExpr expr
201 \end{code}
202
203 \begin{code}
204 cgExpr (StgLetNoEscape live_in_whole_let live_in_rhss bindings body)
205   =     -- Figure out what volatile variables to save
206     nukeDeadBindings live_in_whole_let  `thenC`
207     saveVolatileVarsAndRegs live_in_rhss
208             `thenFC` \ (save_assts, rhs_eob_info, maybe_cc_slot) ->
209     -- ToDo: cost centre???
210     restoreCurrentCostCentre maybe_cc_slot `thenFC` \ restore_cc ->
211
212         -- Save those variables right now!
213     absC save_assts                             `thenC`
214
215         -- Produce code for the rhss
216         -- and add suitable bindings to the environment
217     cgLetNoEscapeBindings live_in_rhss rhs_eob_info maybe_cc_slot bindings `thenC`
218
219         -- Do the body
220     setEndOfBlockInfo rhs_eob_info (cgExpr body)
221 \end{code}
222
223
224 %********************************************************
225 %*                                                      *
226 %*              SCC Expressions                         *
227 %*                                                      *
228 %********************************************************
229
230 SCC expressions are treated specially. They set the current cost
231 centre.
232 \begin{code}
233 cgExpr (StgSCC cc expr)
234   = ASSERT(sccAbleCostCentre cc)
235     costCentresC
236         (if isDictCC cc then SLIT("SET_DICT_CCC") else SLIT("SET_CCC"))
237         [mkCCostCentre cc, mkIntCLit (if isSccCountCostCentre cc then 1 else 0)]
238     `thenC`
239     cgExpr expr
240 \end{code}
241
242 ToDo: counting of dict sccs ...
243
244 %********************************************************
245 %*                                                      *
246 %*              Non-top-level bindings                  *
247 %*                                                      *
248 %********************************************************
249 \subsection[non-top-level-bindings]{Converting non-top-level bindings}
250
251 We rely on the support code in @CgCon@ (to do constructors) and
252 in @CgClosure@ (to do closures).
253
254 \begin{code}
255 cgRhs :: Id -> StgRhs -> FCode (Id, CgIdInfo)
256         -- the Id is passed along so a binding can be set up
257
258 cgRhs name (StgRhsCon maybe_cc con args)
259   = getArgAmodes args           `thenFC` \ amodes ->
260     buildDynCon name maybe_cc con amodes (all zero_size args)
261                                 `thenFC` \ idinfo ->
262     returnFC (name, idinfo)
263   where
264     zero_size atom = getPrimRepSize (getArgPrimRep atom) == 0
265
266 cgRhs name (StgRhsClosure cc bi srt@(NoSRT) fvs upd_flag args body)
267   = mkRhsClosure name cc bi srt fvs upd_flag args body
268 cgRhs name (StgRhsClosure cc bi srt@(SRT _ _) fvs upd_flag args body)
269   = mkRhsClosure name cc bi srt fvs upd_flag args body
270 \end{code}
271
272 mkRhsClosure looks for two special forms of the right-hand side:
273         a) selector thunks.
274         b) AP thunks
275
276 If neither happens, it just calls mkClosureLFInfo.  You might think
277 that mkClosureLFInfo should do all this, but it seems wrong for the
278 latter to look at the structure of an expression
279
280 Selectors
281 ~~~~~~~~~
282 We look at the body of the closure to see if it's a selector---turgid,
283 but nothing deep.  We are looking for a closure of {\em exactly} the
284 form:
285
286 ...  = [the_fv] \ u [] ->
287          case the_fv of
288            con a_1 ... a_n -> a_i
289
290
291 \begin{code}
292 mkRhsClosure    bndr cc bi srt
293                 [the_fv]                -- Just one free var
294                 upd_flag                -- Updatable thunk
295                 []                      -- A thunk
296                 body@(StgCase (StgApp scrutinee [{-no args-}])
297                       _ _ _ _   -- ignore uniq, etc.
298                       (StgAlgAlts case_ty
299                          [(con, params, use_mask,
300                             (StgApp selectee [{-no args-}]))]
301                          StgNoDefault))
302   |  the_fv == scrutinee                        -- Scrutinee is the only free variable
303   && maybeToBool maybe_offset                   -- Selectee is a component of the tuple
304   && offset_into_int <= mAX_SPEC_SELECTEE_SIZE  -- Offset is small enough
305   = ASSERT(is_single_constructor)
306     cgStdRhsClosure bndr cc bi srt [the_fv] [] body lf_info [StgVarArg the_fv]
307   where
308     lf_info               = mkSelectorLFInfo (idType bndr) offset_into_int 
309                                 (isUpdatable upd_flag)
310     (_, params_w_offsets) = layOutDynCon con idPrimRep params
311     maybe_offset          = assocMaybe params_w_offsets selectee
312     Just the_offset       = maybe_offset
313     offset_into_int       = the_offset - fixedHdrSize
314     is_single_constructor = maybeToBool (maybeTyConSingleCon tycon)
315     tycon                 = dataConTyCon con
316 \end{code}
317
318
319 Ap thunks
320 ~~~~~~~~~
321
322 A more generic AP thunk of the form
323
324         x = [ x_1...x_n ] \.. [] -> x_1 ... x_n
325
326 A set of these is compiled statically into the RTS, so we just use
327 those.  We could extend the idea to thunks where some of the x_i are
328 global ids (and hence not free variables), but this would entail
329 generating a larger thunk.  It might be an option for non-optimising
330 compilation, though.
331
332 We only generate an Ap thunk if all the free variables are pointers,
333 for semi-obvious reasons.
334
335 \begin{code}
336 mkRhsClosure    bndr cc bi srt
337                 fvs
338                 upd_flag
339                 []                      -- No args; a thunk
340                 body@(StgApp fun_id args)
341
342   | length args + 1 == arity
343         && all isFollowableRep (map idPrimRep fvs) 
344         && isUpdatable upd_flag
345         && arity <= mAX_SPEC_AP_SIZE 
346
347                    -- Ha! an Ap thunk
348         = cgStdRhsClosure bndr cc bi srt fvs [] body lf_info payload
349
350    where
351         lf_info = mkApLFInfo (idType bndr) upd_flag arity
352         -- the payload has to be in the correct order, hence we can't
353         -- just use the fvs.
354         payload    = StgVarArg fun_id : args
355         arity      = length fvs
356 \end{code}
357
358 The default case
359 ~~~~~~~~~~~~~~~~
360 \begin{code}
361 mkRhsClosure bndr cc bi srt fvs upd_flag args body
362   = cgRhsClosure bndr cc bi srt fvs args body lf_info
363   where lf_info = mkClosureLFInfo bndr NotTopLevel fvs upd_flag args
364 \end{code}
365
366
367 %********************************************************
368 %*                                                      *
369 %*              Let-no-escape bindings
370 %*                                                      *
371 %********************************************************
372 \begin{code}
373 cgLetNoEscapeBindings live_in_rhss rhs_eob_info maybe_cc_slot (StgNonRec binder rhs)
374   = cgLetNoEscapeRhs live_in_rhss rhs_eob_info maybe_cc_slot    
375                         NonRecursive binder rhs 
376                                 `thenFC` \ (binder, info) ->
377     addBindC binder info
378
379 cgLetNoEscapeBindings live_in_rhss rhs_eob_info maybe_cc_slot (StgRec pairs)
380   = fixC (\ new_bindings ->
381                 addBindsC new_bindings  `thenC`
382                 listFCs [ cgLetNoEscapeRhs full_live_in_rhss 
383                                 rhs_eob_info maybe_cc_slot Recursive b e 
384                         | (b,e) <- pairs ]
385     ) `thenFC` \ new_bindings ->
386
387     addBindsC new_bindings
388   where
389     -- We add the binders to the live-in-rhss set so that we don't
390     -- delete the bindings for the binder from the environment!
391     full_live_in_rhss = live_in_rhss `unionVarSet` (mkVarSet [b | (b,r) <- pairs])
392
393 cgLetNoEscapeRhs
394     :: StgLiveVars      -- Live in rhss
395     -> EndOfBlockInfo
396     -> Maybe VirtualSpOffset
397     -> RecFlag
398     -> Id
399     -> StgRhs
400     -> FCode (Id, CgIdInfo)
401
402 cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec binder
403                  (StgRhsClosure cc bi srt _ upd_flag args body)
404   = -- We could check the update flag, but currently we don't switch it off
405     -- for let-no-escaped things, so we omit the check too!
406     -- case upd_flag of
407     --     Updatable -> panic "cgLetNoEscapeRhs"        -- Nothing to update!
408     --     other     -> cgLetNoEscapeClosure binder cc bi live_in_whole_let live_in_rhss args body
409     cgLetNoEscapeClosure binder cc bi srt full_live_in_rhss rhs_eob_info maybe_cc_slot rec args body
410
411 -- For a constructor RHS we want to generate a single chunk of code which
412 -- can be jumped to from many places, which will return the constructor.
413 -- It's easy; just behave as if it was an StgRhsClosure with a ConApp inside!
414 cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec binder
415                  (StgRhsCon cc con args)
416   = cgLetNoEscapeClosure binder cc stgArgOcc{-safe-} NoSRT full_live_in_rhss rhs_eob_info maybe_cc_slot rec
417         []      --No args; the binder is data structure, not a function
418         (StgCon (DataCon con) args (idType binder))
419 \end{code}
420
421 Little helper for primitives that return unboxed tuples.
422
423
424 \begin{code}
425 primRetUnboxedTuple :: PrimOp -> [StgArg] -> Type -> Code
426 primRetUnboxedTuple op args res_ty
427   = getArgAmodes args       `thenFC` \ arg_amodes ->
428     {-
429       put all the arguments in temporaries so they don't get stomped when
430       we push the return address.
431     -}
432     let
433       n_args              = length args
434       arg_uniqs           = map mkBuiltinUnique [0 .. n_args-1]
435       arg_reps            = map getArgPrimRep args
436       arg_temps           = zipWith CTemp arg_uniqs arg_reps
437     in
438     absC (mkAbstractCs (zipWith CAssign arg_temps arg_amodes)) `thenC`
439     {-
440       allocate some temporaries for the return values.
441     -}
442     let
443       (tc,ty_args)      = case splitTyConAppThroughNewTypes res_ty of
444                             Nothing -> pprPanic "primRetUnboxedTuple" (ppr res_ty)
445                             Just pr -> pr
446       prim_reps          = map typePrimRep ty_args
447       temp_uniqs         = map mkBuiltinUnique [ n_args .. n_args + length ty_args - 1]
448       temp_amodes        = zipWith CTemp temp_uniqs prim_reps
449     in
450     returnUnboxedTuple temp_amodes (absC (COpStmt temp_amodes op arg_temps []))
451
452 \end{code}