b243e21eebe04cedd571d358f8adb6b0bced2469
[ghc-hetmet.git] / compiler / codeGen / CgExpr.lhs
1 %
2 % (c) The University of Glasgow 2006
3 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 %
5
6 \begin{code}
7 module CgExpr ( cgExpr ) where
8
9 #include "HsVersions.h"
10
11 import Constants
12 import StgSyn
13 import CgMonad
14
15 import SMRep
16 import CoreSyn
17 import CgProf
18 import CgHeapery
19 import CgBindery
20 import CgCase
21 import CgClosure
22 import CgCon
23 import CgLetNoEscape
24 import CgCallConv
25 import CgTailCall
26 import CgInfoTbls
27 import CgForeignCall
28 import CgPrimOp
29 import CgHpc
30 import CgUtils
31 import ClosureInfo
32 import Cmm
33 import MachOp
34 import VarSet
35 import Literal
36 import PrimOp
37 import Id
38 import TyCon
39 import Type
40 import Maybes
41 import ListSetOps
42 import BasicTypes
43 import Util
44 import Outputable
45 \end{code}
46
47 This module provides the support code for @StgToAbstractC@ to deal
48 with STG {\em expressions}.  See also @CgClosure@, which deals
49 with closures, and @CgCon@, which deals with constructors.
50
51 \begin{code}
52 cgExpr  :: StgExpr              -- input
53         -> Code                 -- output
54 \end{code}
55
56 %********************************************************
57 %*                                                      *
58 %*              Tail calls                              *
59 %*                                                      *
60 %********************************************************
61
62 ``Applications'' mean {\em tail calls}, a service provided by module
63 @CgTailCall@.  This includes literals, which show up as
64 @(STGApp (StgLitArg 42) [])@.
65
66 \begin{code}
67 cgExpr (StgApp fun args) = cgTailCall fun args
68 \end{code}
69
70 %********************************************************
71 %*                                                      *
72 %*              STG ConApps  (for inline versions)      *
73 %*                                                      *
74 %********************************************************
75
76 \begin{code}
77 cgExpr (StgConApp con args)
78   = do  { amodes <- getArgAmodes args
79         ; cgReturnDataCon con amodes }
80 \end{code}
81
82 Literals are similar to constructors; they return by putting
83 themselves in an appropriate register and returning to the address on
84 top of the stack.
85
86 \begin{code}
87 cgExpr (StgLit lit)
88   = do  { cmm_lit <- cgLit lit
89         ; performPrimReturn rep (CmmLit cmm_lit) }
90   where
91     rep = (typeCgRep) (literalType lit)
92 \end{code}
93
94
95 %********************************************************
96 %*                                                      *
97 %*      PrimOps and foreign calls.
98 %*                                                      *
99 %********************************************************
100
101 NOTE about "safe" foreign calls: a safe foreign call is never compiled
102 inline in a case expression.  When we see
103
104         case (ccall ...) of { ... }
105
106 We generate a proper return address for the alternatives and push the
107 stack frame before doing the call, so that in the event that the call
108 re-enters the RTS the stack is in a sane state.
109
110 \begin{code}
111 cgExpr (StgOpApp (StgFCallOp fcall _) stg_args res_ty) = do
112     {-
113         First, copy the args into temporaries.  We're going to push
114         a return address right before doing the call, so the args
115         must be out of the way.
116     -}
117     reps_n_amodes <- getArgAmodes stg_args
118     let 
119         -- Get the *non-void* args, and jiggle them with shimForeignCall
120         arg_exprs = [ (shimForeignCallArg stg_arg expr, stg_arg)
121                     | (stg_arg, (rep,expr)) <- stg_args `zip` reps_n_amodes, 
122                       nonVoidArg rep]
123
124     arg_tmps <- sequence [
125                  if isFollowableArg (typeCgRep (stgArgType stg_arg))
126                  then assignPtrTemp arg
127                  else assignNonPtrTemp arg
128                      | (arg, stg_arg) <- arg_exprs]
129     let arg_hints = zip arg_tmps (map (typeHint.stgArgType) stg_args)
130     {-
131         Now, allocate some result regs.
132     -}
133     (res_reps,res_regs,res_hints)  <- newUnboxedTupleRegs res_ty
134     ccallReturnUnboxedTuple (zip res_reps (map (CmmReg . CmmLocal) res_regs)) $
135         emitForeignCall (zip res_regs res_hints) fcall 
136            arg_hints emptyVarSet{-no live vars-}
137       
138 -- tagToEnum# is special: we need to pull the constructor out of the table,
139 -- and perform an appropriate return.
140
141 cgExpr (StgOpApp (StgPrimOp TagToEnumOp) [arg] res_ty) 
142   = ASSERT(isEnumerationTyCon tycon)
143     do  { (rep,amode) <- getArgAmode arg
144         ; amode' <- if isFollowableArg rep
145                     then assignPtrTemp amode
146                     else assignNonPtrTemp amode
147                                         -- We're going to use it twice,
148                                         -- so save in a temp if non-trivial
149         ; stmtC (CmmAssign nodeReg (tagToClosure tycon amode'))
150         ; performReturn emitReturnInstr }
151    where
152           -- If you're reading this code in the attempt to figure
153           -- out why the compiler panic'ed here, it is probably because
154           -- you used tagToEnum# in a non-monomorphic setting, e.g., 
155           --         intToTg :: Enum a => Int -> a ; intToTg (I# x#) = tagToEnum# x#
156           -- That won't work.
157         tycon = tyConAppTyCon res_ty
158
159
160 cgExpr x@(StgOpApp op@(StgPrimOp primop) args res_ty)
161   | primOpOutOfLine primop
162         = tailCallPrimOp primop args
163
164   | ReturnsPrim VoidRep <- result_info
165         = do cgPrimOp [] primop args emptyVarSet
166              performReturn emitReturnInstr
167
168   | ReturnsPrim rep <- result_info
169         = do res <- if isFollowableArg (typeCgRep res_ty)
170                         then newPtrTemp (argMachRep (typeCgRep res_ty))
171                         else newNonPtrTemp (argMachRep (typeCgRep res_ty))
172              cgPrimOp [res] primop args emptyVarSet
173              performPrimReturn (primRepToCgRep rep) (CmmReg (CmmLocal res))
174
175   | ReturnsAlg tycon <- result_info, isUnboxedTupleTyCon tycon
176         = do (reps, regs, _hints) <- newUnboxedTupleRegs res_ty
177              cgPrimOp regs primop args emptyVarSet{-no live vars-}
178              returnUnboxedTuple (zip reps (map (CmmReg . CmmLocal) regs))
179
180   | ReturnsAlg tycon <- result_info, isEnumerationTyCon tycon
181         -- c.f. cgExpr (...TagToEnumOp...)
182         = do tag_reg <- if isFollowableArg (typeCgRep res_ty)
183                         then newPtrTemp wordRep
184                         else newNonPtrTemp wordRep
185              cgPrimOp [tag_reg] primop args emptyVarSet
186              stmtC (CmmAssign nodeReg
187                     (tagToClosure tycon
188                      (CmmReg (CmmLocal tag_reg))))
189              performReturn emitReturnInstr
190   where
191         result_info = getPrimOpResultInfo primop
192 \end{code}
193
194 %********************************************************
195 %*                                                      *
196 %*              Case expressions                        *
197 %*                                                      *
198 %********************************************************
199 Case-expression conversion is complicated enough to have its own
200 module, @CgCase@.
201 \begin{code}
202
203 cgExpr (StgCase expr live_vars save_vars bndr srt alt_type alts)
204   = setSRT srt $ cgCase expr live_vars save_vars bndr alt_type alts
205 \end{code}
206
207
208 %********************************************************
209 %*                                                      *
210 %*              Let and letrec                          *
211 %*                                                      *
212 %********************************************************
213 \subsection[let-and-letrec-codegen]{Converting @StgLet@ and @StgLetrec@}
214
215 \begin{code}
216 cgExpr (StgLet (StgNonRec name rhs) expr)
217   = cgRhs name rhs      `thenFC` \ (name, info) ->
218     addBindC name info  `thenC`
219     cgExpr expr
220
221 cgExpr (StgLet (StgRec pairs) expr)
222   = fixC (\ new_bindings -> addBindsC new_bindings `thenC`
223                             listFCs [ cgRhs b e | (b,e) <- pairs ]
224     ) `thenFC` \ new_bindings ->
225
226     addBindsC new_bindings `thenC`
227     cgExpr expr
228 \end{code}
229
230 \begin{code}
231 cgExpr (StgLetNoEscape live_in_whole_let live_in_rhss bindings body)
232   = do  {       -- Figure out what volatile variables to save
233         ; nukeDeadBindings live_in_whole_let
234         ; (save_assts, rhs_eob_info, maybe_cc_slot) 
235                 <- saveVolatileVarsAndRegs live_in_rhss
236
237         -- Save those variables right now!
238         ; emitStmts save_assts
239
240         -- Produce code for the rhss
241         -- and add suitable bindings to the environment
242         ; cgLetNoEscapeBindings live_in_rhss rhs_eob_info 
243                                 maybe_cc_slot bindings
244
245         -- Do the body
246         ; setEndOfBlockInfo rhs_eob_info (cgExpr body) }
247 \end{code}
248
249
250 %********************************************************
251 %*                                                      *
252 %*              SCC Expressions                         *
253 %*                                                      *
254 %********************************************************
255
256 SCC expressions are treated specially. They set the current cost
257 centre.
258
259 \begin{code}
260 cgExpr (StgSCC cc expr) = do emitSetCCC cc; cgExpr expr
261 \end{code}
262
263 %********************************************************
264 %*                                                     *
265 %*             Hpc Tick Boxes                          *
266 %*                                                     *
267 %********************************************************
268
269 \begin{code}
270 cgExpr (StgTick m n expr) = do cgTickBox m n; cgExpr expr
271 \end{code}
272
273 %********************************************************
274 %*                                                      *
275 %*              Non-top-level bindings                  *
276 %*                                                      *
277 %********************************************************
278 \subsection[non-top-level-bindings]{Converting non-top-level bindings}
279
280 We rely on the support code in @CgCon@ (to do constructors) and
281 in @CgClosure@ (to do closures).
282
283 \begin{code}
284 cgRhs :: Id -> StgRhs -> FCode (Id, CgIdInfo)
285         -- the Id is passed along so a binding can be set up
286
287 cgRhs name (StgRhsCon maybe_cc con args)
288   = do  { amodes <- getArgAmodes args
289         ; idinfo <- buildDynCon name maybe_cc con amodes
290         ; returnFC (name, idinfo) }
291
292 cgRhs name (StgRhsClosure cc bi fvs upd_flag srt args body)
293   = setSRT srt $ mkRhsClosure name cc bi fvs upd_flag args body
294 \end{code}
295
296 mkRhsClosure looks for two special forms of the right-hand side:
297         a) selector thunks.
298         b) AP thunks
299
300 If neither happens, it just calls mkClosureLFInfo.  You might think
301 that mkClosureLFInfo should do all this, but it seems wrong for the
302 latter to look at the structure of an expression
303
304 Selectors
305 ~~~~~~~~~
306 We look at the body of the closure to see if it's a selector---turgid,
307 but nothing deep.  We are looking for a closure of {\em exactly} the
308 form:
309
310 ...  = [the_fv] \ u [] ->
311          case the_fv of
312            con a_1 ... a_n -> a_i
313
314
315 \begin{code}
316 mkRhsClosure    bndr cc bi
317                 [the_fv]                -- Just one free var
318                 upd_flag                -- Updatable thunk
319                 []                      -- A thunk
320                 body@(StgCase (StgApp scrutinee [{-no args-}])
321                       _ _ _ srt   -- ignore uniq, etc.
322                       (AlgAlt tycon)
323                       [(DataAlt con, params, use_mask,
324                             (StgApp selectee [{-no args-}]))])
325   |  the_fv == scrutinee                -- Scrutinee is the only free variable
326   && maybeToBool maybe_offset           -- Selectee is a component of the tuple
327   && offset_into_int <= mAX_SPEC_SELECTEE_SIZE  -- Offset is small enough
328   = -- NOT TRUE: ASSERT(is_single_constructor)
329     -- The simplifier may have statically determined that the single alternative
330     -- is the only possible case and eliminated the others, even if there are
331     -- other constructors in the datatype.  It's still ok to make a selector
332     -- thunk in this case, because we *know* which constructor the scrutinee
333     -- will evaluate to.
334     setSRT srt $ cgStdRhsClosure bndr cc bi [the_fv] [] body lf_info [StgVarArg the_fv]
335   where
336     lf_info               = mkSelectorLFInfo bndr offset_into_int
337                                  (isUpdatable upd_flag)
338     (_, params_w_offsets) = layOutDynConstr con (addIdReps params)
339                         -- Just want the layout
340     maybe_offset          = assocMaybe params_w_offsets selectee
341     Just the_offset       = maybe_offset
342     offset_into_int       = the_offset - fixedHdrSize
343 \end{code}
344
345 Ap thunks
346 ~~~~~~~~~
347
348 A more generic AP thunk of the form
349
350         x = [ x_1...x_n ] \.. [] -> x_1 ... x_n
351
352 A set of these is compiled statically into the RTS, so we just use
353 those.  We could extend the idea to thunks where some of the x_i are
354 global ids (and hence not free variables), but this would entail
355 generating a larger thunk.  It might be an option for non-optimising
356 compilation, though.
357
358 We only generate an Ap thunk if all the free variables are pointers,
359 for semi-obvious reasons.
360
361 \begin{code}
362 mkRhsClosure    bndr cc bi
363                 fvs
364                 upd_flag
365                 []                      -- No args; a thunk
366                 body@(StgApp fun_id args)
367
368   | args `lengthIs` (arity-1)
369         && all isFollowableArg (map idCgRep fvs) 
370         && isUpdatable upd_flag
371         && arity <= mAX_SPEC_AP_SIZE 
372
373                    -- Ha! an Ap thunk
374         = cgStdRhsClosure bndr cc bi fvs [] body lf_info payload
375
376    where
377         lf_info = mkApLFInfo bndr upd_flag arity
378         -- the payload has to be in the correct order, hence we can't
379         -- just use the fvs.
380         payload = StgVarArg fun_id : args
381         arity   = length fvs
382 \end{code}
383
384 The default case
385 ~~~~~~~~~~~~~~~~
386 \begin{code}
387 mkRhsClosure bndr cc bi fvs upd_flag args body
388   = cgRhsClosure bndr cc bi fvs upd_flag args body
389 \end{code}
390
391
392 %********************************************************
393 %*                                                      *
394 %*              Let-no-escape bindings
395 %*                                                      *
396 %********************************************************
397 \begin{code}
398 cgLetNoEscapeBindings live_in_rhss rhs_eob_info maybe_cc_slot 
399         (StgNonRec binder rhs)
400   = do  { (binder,info) <- cgLetNoEscapeRhs live_in_rhss rhs_eob_info 
401                                             maybe_cc_slot       
402                                             NonRecursive binder rhs 
403         ; addBindC binder info }
404
405 cgLetNoEscapeBindings live_in_rhss rhs_eob_info maybe_cc_slot (StgRec pairs)
406   = do  { new_bindings <- fixC (\ new_bindings -> do
407                 { addBindsC new_bindings
408                 ; listFCs [ cgLetNoEscapeRhs full_live_in_rhss 
409                                 rhs_eob_info maybe_cc_slot Recursive b e 
410                           | (b,e) <- pairs ] })
411
412         ; addBindsC new_bindings }
413   where
414     -- We add the binders to the live-in-rhss set so that we don't
415     -- delete the bindings for the binder from the environment!
416     full_live_in_rhss = live_in_rhss `unionVarSet` (mkVarSet [b | (b,r) <- pairs])
417
418 cgLetNoEscapeRhs
419     :: StgLiveVars      -- Live in rhss
420     -> EndOfBlockInfo
421     -> Maybe VirtualSpOffset
422     -> RecFlag
423     -> Id
424     -> StgRhs
425     -> FCode (Id, CgIdInfo)
426
427 cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec binder
428                  (StgRhsClosure cc bi _ upd_flag srt args body)
429   = -- We could check the update flag, but currently we don't switch it off
430     -- for let-no-escaped things, so we omit the check too!
431     -- case upd_flag of
432     --     Updatable -> panic "cgLetNoEscapeRhs"        -- Nothing to update!
433     --     other     -> cgLetNoEscapeClosure binder cc bi live_in_whole_let live_in_rhss args body
434     setSRT srt $ cgLetNoEscapeClosure binder cc bi full_live_in_rhss rhs_eob_info
435         maybe_cc_slot rec args body
436
437 -- For a constructor RHS we want to generate a single chunk of code which
438 -- can be jumped to from many places, which will return the constructor.
439 -- It's easy; just behave as if it was an StgRhsClosure with a ConApp inside!
440 cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec binder
441                  (StgRhsCon cc con args)
442   = setSRT NoSRT $ cgLetNoEscapeClosure binder cc noBinderInfo{-safe-}
443                          full_live_in_rhss rhs_eob_info maybe_cc_slot rec
444         []      --No args; the binder is data structure, not a function
445         (StgConApp con args)
446 \end{code}
447
448 Little helper for primitives that return unboxed tuples.
449
450 \begin{code}
451 newUnboxedTupleRegs :: Type -> FCode ([CgRep], [LocalReg], [MachHint])
452 newUnboxedTupleRegs res_ty =
453    let
454         ty_args = tyConAppArgs (repType res_ty)
455         (reps,hints) = unzip [ (rep, typeHint ty) | ty <- ty_args,
456                                                     let rep = typeCgRep ty,
457                                                     nonVoidArg rep ]
458         make_new_temp rep = if isFollowableArg rep
459                             then newPtrTemp (argMachRep rep)
460                             else newNonPtrTemp (argMachRep rep)
461    in do
462    regs <- mapM make_new_temp reps
463    return (reps,regs,hints)
464 \end{code}