a6e44d3fb4d7e784bcbd309d919bea2c1a46bf35
[ghc-hetmet.git] / ghc / compiler / simplCore / Simplify.lhs
1 %
2 % (c) The AQUA Project, Glasgow University, 1993-1996
3 %
4 \section[Simplify]{The main module of the simplifier}
5
6 \begin{code}
7 #include "HsVersions.h"
8
9 module Simplify ( simplTopBinds, simplExpr, simplBind ) where
10
11 IMP_Ubiq(){-uitous-}
12 IMPORT_DELOOPER(SmplLoop)               -- paranoia checking
13 IMPORT_1_3(List(partition))
14
15 import BinderInfo
16 import CmdLineOpts      ( SimplifierSwitch(..) )
17 import ConFold          ( completePrim )
18 import CostCentre       ( isSccCountCostCentre, cmpCostCentre )
19 import CoreSyn
20 import CoreUtils        ( coreExprType, nonErrorRHSs, maybeErrorApp,
21                           unTagBinders, squashableDictishCcExpr,
22                           manifestlyWHNF
23                         )
24 import Id               ( idType, idWantsToBeINLINEd,
25                           getIdDemandInfo, addIdDemandInfo,
26                           GenId{-instance NamedThing-}
27                         )
28 import IdInfo           ( willBeDemanded, DemandInfo )
29 import Literal          ( isNoRepLit )
30 import Maybes           ( maybeToBool )
31 import Name             ( isLocallyDefined )
32 import PprStyle         ( PprStyle(..) )
33 import PprType          ( GenType{-instance Outputable-} )
34 import Pretty           ( ppAbove )
35 import PrimOp           ( primOpOkForSpeculation, PrimOp(..) )
36 import SimplCase        ( simplCase, bindLargeRhs )
37 import SimplEnv
38 import SimplMonad
39 import SimplVar         ( completeVar )
40 import SimplUtils
41 import Type             ( mkTyVarTy, mkTyVarTys, mkAppTy,
42                           splitFunTy, getFunTy_maybe, eqTy
43                         )
44 import TysWiredIn       ( realWorldStateTy )
45 import Util             ( isSingleton, zipEqual, panic, pprPanic, assertPanic )
46 \end{code}
47
48 The controlling flags, and what they do
49 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50
51 passes:
52 ------
53 -fsimplify              = run the simplifier
54 -ffloat-inwards         = runs the float lets inwards pass
55 -ffloat                 = runs the full laziness pass
56                           (ToDo: rename to -ffull-laziness)
57 -fupdate-analysis       = runs update analyser
58 -fstrictness            = runs strictness analyser
59 -fsaturate-apps         = saturates applications (eta expansion)
60
61 options:
62 -------
63 -ffloat-past-lambda     = OK to do full laziness.
64                           (ToDo: remove, as the full laziness pass is
65                                  useless without this flag, therefore
66                                  it is unnecessary. Just -ffull-laziness
67                                  should be kept.)
68
69 -ffloat-lets-ok         = OK to float lets out of lets if the enclosing
70                           let is strict or if the floating will expose
71                           a WHNF [simplifier].
72
73 -ffloat-primops-ok      = OK to float out of lets cases whose scrutinee
74                           is a primop that cannot fail [simplifier].
75
76 -fcode-duplication-ok   = allows the previous option to work on cases with
77                           multiple branches [simplifier].
78
79 -flet-to-case           = does let-to-case transformation [simplifier].
80
81 -fcase-of-case          = does case of case transformation [simplifier].
82
83 -fpedantic-bottoms      = does not allow:
84                              case x of y -> e  ===>  e[x/y]
85                           (which may turn bottom into non-bottom)
86
87
88                         NOTES ON INLINING
89                         ~~~~~~~~~~~~~~~~~
90
91 Inlining is one of the delicate aspects of the simplifier.  By
92 ``inlining'' we mean replacing an occurrence of a variable ``x'' by
93 the RHS of x's definition.  Thus
94
95         let x = e in ...x...    ===>   let x = e in ...e...
96
97 We have two mechanisms for inlining:
98
99 1.  Unconditional.  The occurrence analyser has pinned an (OneOcc
100 FunOcc NoDupDanger NotInsideSCC n) flag on the variable, saying ``it's
101 certainly safe to inline this variable, and to drop its binding''.
102 (...Umm... if n <= 1; if n > 1, it is still safe, provided you are
103 happy to be duplicating code...) When it encounters such a beast, the
104 simplifer binds the variable to its RHS (in the id_env) and continues.
105 It doesn't even look at the RHS at that stage.  It also drops the
106 binding altogether.
107
108 2.  Conditional.  In all other situations, the simplifer simplifies
109 the RHS anyway, and keeps the new binding.  It also binds the new
110 (cloned) variable to a ``suitable'' UnfoldingDetails in the UnfoldEnv.
111
112 Here, ``suitable'' might mean NoUnfoldingDetails (if the occurrence
113 info is ManyOcc and the RHS is not a manifest HNF, or UnfoldAlways (if
114 the variable has an INLINE pragma on it).  The idea is that anything
115 in the UnfoldEnv is safe to use, but also has an enclosing binding if
116 you decide not to use it.
117
118 Head normal forms
119 ~~~~~~~~~~~~~~~~~
120 We *never* put a non-HNF unfolding in the UnfoldEnv except in the
121 INLINE-pragma case.
122
123 At one time I thought it would be OK to put non-HNF unfoldings in for
124 variables which occur only once [if they got inlined at that
125 occurrence the RHS of the binding would become dead, so no duplication
126 would occur].   But consider:
127 @
128         let x = <expensive>
129             f = \y -> ...y...y...y...
130         in f x
131 @
132 Now, it seems that @x@ appears only once, but even so it is NOT safe
133 to put @x@ in the UnfoldEnv, because @f@ will be inlined, and will
134 duplicate the references to @x@.
135
136 Because of this, the "unconditional-inline" mechanism above is the
137 only way in which non-HNFs can get inlined.
138
139 INLINE pragmas
140 ~~~~~~~~~~~~~~
141
142 When a variable has an INLINE pragma on it --- which includes wrappers
143 produced by the strictness analyser --- we treat it rather carefully.
144
145 For a start, we are careful not to substitute into its RHS, because
146 that might make it BIG, and the user said "inline exactly this", not
147 "inline whatever you get after inlining other stuff inside me".  For
148 example
149
150         let f = BIG
151         in {-# INLINE y #-} y = f 3
152         in ...y...y...
153
154 Here we don't want to substitute BIG for the (single) occurrence of f,
155 because then we'd duplicate BIG when we inline'd y.  (Exception:
156 things in the UnfoldEnv with UnfoldAlways flags, which originated in
157 other INLINE pragmas.)
158
159 So, we clean out the UnfoldEnv of all GenForm inlinings before
160 going into such an RHS.
161
162 What about imports?  They don't really matter much because we only
163 inline relatively small things via imports.
164
165 We augment the the UnfoldEnv with UnfoldAlways guidance if there's an
166 INLINE pragma.  We also do this for the RHSs of recursive decls,
167 before looking at the recursive decls. That way we achieve the effect
168 of inlining a wrapper in the body of its worker, in the case of a
169 mutually-recursive worker/wrapper split.
170
171
172 %************************************************************************
173 %*                                                                      *
174 \subsection[Simplify-simplExpr]{The main function: simplExpr}
175 %*                                                                      *
176 %************************************************************************
177
178 At the top level things are a little different.
179
180   * No cloning (not allowed for exported Ids, unnecessary for the others)
181
182   * No floating.   Case floating is obviously out.  Let floating is
183         theoretically OK, but dangerous because of space leaks.
184         The long-distance let-floater lifts these lets.
185
186 \begin{code}
187 simplTopBinds :: SimplEnv -> [InBinding] -> SmplM [OutBinding]
188
189 simplTopBinds env [] = returnSmpl []
190
191 -- Dead code is now discarded by the occurrence analyser,
192
193 simplTopBinds env (NonRec binder@(in_id, occ_info) rhs : binds)
194   | inlineUnconditionally ok_to_dup_code occ_info
195   = let
196         new_env = extendIdEnvWithInlining env env binder rhs
197     in
198     simplTopBinds new_env binds
199   where
200     ok_to_dup_code = switchIsSet env SimplOkToDupCode
201
202 simplTopBinds env (NonRec binder@(in_id,occ_info) rhs : binds)
203   =     -- No cloning necessary at top level
204         -- Process the binding
205     simplRhsExpr env binder rhs         `thenSmpl` \ rhs' ->
206     let
207        new_env = case rhs' of
208          Var v                      -> extendIdEnvWithAtom env binder (VarArg v)
209          Lit i | not (isNoRepLit i) -> extendIdEnvWithAtom env binder (LitArg i)
210          other                      -> extendUnfoldEnvGivenRhs env binder in_id rhs'
211     in
212         -- Process the other bindings
213     simplTopBinds new_env binds `thenSmpl` \ binds' ->
214
215         -- Glue together and return ...
216         -- We leave it to susequent occurrence analysis to throw away
217         -- an unused atom binding. This localises the decision about
218         -- discarding top-level bindings.
219     returnSmpl (NonRec in_id rhs' : binds')
220
221 simplTopBinds env (Rec pairs : binds)
222   = simplRecursiveGroup env triples     `thenSmpl` \ (bind', new_env) ->
223
224         -- Process the other bindings
225     simplTopBinds new_env binds         `thenSmpl` \ binds' ->
226
227         -- Glue together and return
228     returnSmpl (bind' : binds')
229   where
230     triples = [(id, (binder, rhs)) | (binder@(id,_), rhs) <- pairs]
231                 -- No cloning necessary at top level
232 \end{code}
233
234 %************************************************************************
235 %*                                                                      *
236 \subsection[Simplify-simplExpr]{The main function: simplExpr}
237 %*                                                                      *
238 %************************************************************************
239
240
241 \begin{code}
242 simplExpr :: SimplEnv
243           -> InExpr -> [OutArg]
244           -> SmplM OutExpr
245 \end{code}
246
247 The expression returned has the same meaning as the input expression
248 applied to the specified arguments.
249
250
251 Variables
252 ~~~~~~~~~
253 Check if there's a macro-expansion, and if so rattle on.  Otherwise do
254 the more sophisticated stuff.
255
256 \begin{code}
257 simplExpr env (Var v) args
258   = case (lookupId env v) of
259       Nothing -> let
260                     new_v = simplTyInId env v
261                  in
262                  completeVar env new_v args
263
264       Just info ->
265         case info of
266           ItsAnAtom (LitArg lit)        -- A boring old literal
267                         -- Paranoia check for args empty
268             ->  case args of
269                   []    -> returnSmpl (Lit lit)
270                   other -> panic "simplExpr:coVar"
271
272           ItsAnAtom (VarArg var)        -- More interesting!  An id!
273                                         -- No need to substitute the type env here,
274                                         -- because we already have!
275             -> completeVar env var args
276
277           InlineIt id_env ty_env in_expr        -- A macro-expansion
278             -> simplExpr (replaceInEnvs env (ty_env, id_env)) in_expr args
279 \end{code}
280
281 Literals
282 ~~~~~~~~
283
284 \begin{code}
285 simplExpr env (Lit l) [] = returnSmpl (Lit l)
286 #ifdef DEBUG
287 simplExpr env (Lit l) _  = panic "simplExpr:Lit with argument"
288 #endif
289 \end{code}
290
291 Primitive applications are simple.
292 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
293
294 NB: Prim expects an empty argument list! (Because it should be
295 saturated and not higher-order. ADR)
296
297 \begin{code}
298 simplExpr env (Prim op prim_args) args
299   = ASSERT (null args)
300     let
301         prim_args' = [simplArg env prim_arg | prim_arg <- prim_args]
302         op'        = simpl_op op
303     in
304     completePrim env op' prim_args'
305   where
306     -- PrimOps just need any types in them renamed.
307
308     simpl_op (CCallOp label is_asm may_gc arg_tys result_ty)
309       = let
310             arg_tys'    = map (simplTy env) arg_tys
311             result_ty'  = simplTy env result_ty
312         in
313         CCallOp label is_asm may_gc arg_tys' result_ty'
314
315     simpl_op other_op = other_op
316 \end{code}
317
318 Constructor applications
319 ~~~~~~~~~~~~~~~~~~~~~~~~
320 Nothing to try here.  We only reuse constructors when they appear as the
321 rhs of a let binding (see completeLetBinding).
322
323 \begin{code}
324 simplExpr env (Con con con_args) args
325   = ASSERT( null args )
326     returnSmpl (Con con [simplArg env con_arg | con_arg <- con_args])
327 \end{code}
328
329
330 Applications are easy too:
331 ~~~~~~~~~~~~~~~~~~~~~~~~~~
332 Just stuff 'em in the arg stack
333
334 \begin{code}
335 simplExpr env (App fun arg) args
336   = simplExpr env fun (simplArg env arg : args)
337 \end{code}
338
339 Type lambdas
340 ~~~~~~~~~~~~
341
342 We only eta-reduce a type lambda if all type arguments in the body can
343 be eta-reduced. This requires us to collect up all tyvar parameters so
344 we can pass them all to @mkTyLamTryingEta@.
345
346 \begin{code}
347 simplExpr env (Lam (TyBinder tyvar) body) (TyArg ty : args)
348   = -- ASSERT(not (isPrimType ty))
349     let
350         new_env = extendTyEnv env tyvar ty
351     in
352     tick TyBetaReduction        `thenSmpl_`
353     simplExpr new_env body args
354
355 simplExpr env tylam@(Lam (TyBinder tyvar) body) []
356   = do_tylambdas env [] tylam
357   where
358     do_tylambdas env tyvars' (Lam (TyBinder tyvar) body)
359       =   -- Clone the type variable
360         cloneTyVarSmpl tyvar            `thenSmpl` \ tyvar' ->
361         let
362             new_env = extendTyEnv env tyvar (mkTyVarTy tyvar')
363         in
364         do_tylambdas new_env (tyvar':tyvars') body
365
366     do_tylambdas env tyvars' body
367       = simplExpr env body []           `thenSmpl` \ body' ->
368         returnSmpl (
369            (if switchIsSet env SimplDoEtaReduction
370            then mkTyLamTryingEta
371            else mkTyLam) (reverse tyvars')  body'
372         )
373
374 #ifdef DEBUG
375 simplExpr env (Lam (TyBinder _) _) (_ : _)
376   = panic "simplExpr:TyLam with non-TyArg"
377 #endif
378 \end{code}
379
380
381 Ordinary lambdas
382 ~~~~~~~~~~~~~~~~
383
384 \begin{code}
385 simplExpr env (Lam (ValBinder binder) body) args
386   | null leftover_binders
387   =     -- The lambda is saturated (or over-saturated)
388     tick BetaReduction  `thenSmpl_`
389     simplExpr env_for_enough_args body leftover_args
390
391   | otherwise
392   =     -- Too few args to saturate the lambda
393     ASSERT( null leftover_args )
394
395     (if not (null args) -- ah, we must've gotten rid of some...
396      then tick BetaReduction
397      else returnSmpl (panic "BetaReduction")
398     ) `thenSmpl_`
399
400     simplLam env_for_too_few_args leftover_binders body
401              0 {- Guaranteed applied to at least 0 args! -}
402
403   where
404     (binder_args_pairs, leftover_binders, leftover_args) = collect_val_args binder args
405
406     env_for_enough_args  = extendIdEnvWithAtomList env binder_args_pairs
407
408     env_for_too_few_args = extendIdEnvWithAtomList env zapped_binder_args_pairs
409
410         -- Since there aren't enough args the binders we are cancelling with
411         -- the args supplied are, in effect, ocurring inside a lambda.
412         -- So we modify their occurrence info to reflect this fact.
413         -- Example:     (\ x y z -> e) p q
414         --          ==> (\z -> e[p/x, q/y])
415         --      but we should behave as if x and y are marked "inside lambda".
416         -- The occurrence analyser does not mark them so itself because then we
417         -- do badly on the very common case of saturated lambdas applications:
418         --              (\ x y z -> e) p q r
419         --          ==> e[p/x, q/y, r/z]
420         --
421     zapped_binder_args_pairs = [ ((id, markDangerousToDup occ_info), arg)
422                                | ((id, occ_info), arg) <- binder_args_pairs ]
423
424     collect_val_args :: InBinder                -- Binder
425                      -> [OutArg]                -- Arguments
426                      -> ([(InBinder,OutArg)],   -- Binder,arg pairs (ToDo: a maybe?)
427                          [InBinder],            -- Leftover binders (ToDo: a maybe)
428                          [OutArg])              -- Leftover args
429
430         -- collect_val_args strips off the leading ValArgs from
431         -- the current arg list, returning them along with the
432         -- depleted list
433     collect_val_args binder []   = ([], [binder], [])
434     collect_val_args binder (arg : args) | isValArg arg
435         = ([(binder,arg)], [], args)
436
437 #ifdef DEBUG
438     collect_val_args _ (other_val_arg : _) = panic "collect_val_args"
439                 -- TyArg should never meet a Lam
440 #endif
441 \end{code}
442
443
444 Let expressions
445 ~~~~~~~~~~~~~~~
446
447 \begin{code}
448 simplExpr env (Let bind body) args
449
450 {- OMIT this; it's a pain to do at the other sites wehre simplBind is called,
451    and it doesn't seem worth retaining the ability to not float applications
452    into let/case 
453
454   | switchIsSet env SimplNoLetFromApp
455   = simplBind env bind (\env -> simplExpr env body [])
456                        (computeResultType env body [])  `thenSmpl` \ let_expr' ->
457     returnSmpl (mkGenApp let_expr' args)
458
459   | otherwise           -- No float from application
460 -}
461
462   = simplBind env bind (\env -> simplExpr env body args)
463                        (computeResultType env body args)
464 \end{code}
465
466 Case expressions
467 ~~~~~~~~~~~~~~~~
468
469 \begin{code}
470 simplExpr env expr@(Case scrut alts) args
471   = simplCase env scrut alts (\env rhs -> simplExpr env rhs args)
472                              (computeResultType env expr args)
473 \end{code}
474
475
476 Coercions
477 ~~~~~~~~~
478 \begin{code}
479 simplExpr env (Coerce coercion ty body) args
480   = simplCoerce env coercion ty body args 
481 \end{code}
482
483
484 Set-cost-centre
485 ~~~~~~~~~~~~~~~
486
487 1) Eliminating nested sccs ...
488 We must be careful to maintain the scc counts ...
489
490 \begin{code}
491 simplExpr env (SCC cc1 (SCC cc2 expr)) args
492   | not (isSccCountCostCentre cc2) && case cmpCostCentre cc1 cc2 of { EQ_ -> True; _ -> False }
493         -- eliminate inner scc if no call counts and same cc as outer
494   = simplExpr env (SCC cc1 expr) args
495
496   | not (isSccCountCostCentre cc2) && not (isSccCountCostCentre cc1)
497         -- eliminate outer scc if no call counts associated with either ccs
498   = simplExpr env (SCC cc2 expr) args
499 \end{code}
500
501 2) Moving sccs inside lambdas ...
502   
503 \begin{code}
504 simplExpr env (SCC cc (Lam binder@(ValBinder _) body)) args
505   | not (isSccCountCostCentre cc)
506         -- move scc inside lambda only if no call counts
507   = simplExpr env (Lam binder (SCC cc body)) args
508
509 simplExpr env (SCC cc (Lam binder body)) args
510         -- always ok to move scc inside type/usage lambda
511   = simplExpr env (Lam binder (SCC cc body)) args
512 \end{code}
513
514 3) Eliminating dict sccs ...
515
516 \begin{code}
517 simplExpr env (SCC cc expr) args
518   | squashableDictishCcExpr cc expr
519         -- eliminate dict cc if trivial dict expression
520   = simplExpr env expr args
521 \end{code}
522
523 4) Moving arguments inside the body of an scc ...
524 This moves the cost of doing the application inside the scc
525 (which may include the cost of extracting methods etc)
526
527 \begin{code}
528 simplExpr env (SCC cost_centre body) args
529   = let
530         new_env = setEnclosingCC env (EnclosingCC cost_centre)
531     in
532     simplExpr new_env body args         `thenSmpl` \ body' ->
533     returnSmpl (SCC cost_centre body')
534 \end{code}
535
536 %************************************************************************
537 %*                                                                      *
538 \subsection{Simplify RHS of a Let/Letrec}
539 %*                                                                      *
540 %************************************************************************
541
542 simplRhsExpr does arity-expansion.  That is, given:
543
544         * a right hand side /\ tyvars -> \a1 ... an -> e
545         * the information (stored in BinderInfo) that the function will always
546           be applied to at least k arguments
547
548 it transforms the rhs to
549
550         /\tyvars -> \a1 ... an b(n+1) ... bk -> (e b(n+1) ... bk)
551
552 This is a Very Good Thing!
553
554 \begin{code}
555 simplRhsExpr
556         :: SimplEnv
557         -> InBinder
558         -> InExpr
559         -> SmplM OutExpr
560
561 simplRhsExpr env binder@(id,occ_info) rhs
562   | dont_eta_expand rhs
563   = simplExpr rhs_env rhs []
564
565   | otherwise   -- Have a go at eta expansion
566   =     -- Deal with the big lambda part
567     mapSmpl cloneTyVarSmpl tyvars                       `thenSmpl` \ tyvars' ->
568     let
569         lam_env  = extendTyEnvList rhs_env (zipEqual "simplRhsExpr" tyvars (mkTyVarTys tyvars'))
570     in
571         -- Deal with the little lambda part
572         -- Note that we call simplLam even if there are no binders, in case
573         -- it can do arity expansion.
574     simplLam lam_env binders body min_no_of_args        `thenSmpl` \ lambda' ->
575
576         -- Put it back together
577     returnSmpl (
578        (if switchIsSet env SimplDoEtaReduction
579        then mkTyLamTryingEta
580        else mkTyLam) tyvars' lambda'
581     )
582   where
583         -- Note from ANDY:
584         -- If you say {-# INLINE #-} then you get what's coming to you;
585         -- you are saying inline the rhs, please.
586         -- we might want a {-# INLINE UNSIMPLIFIED #-} option.
587     rhs_env | simplIdWantsToBeINLINEd id env = filterUnfoldEnvForInlines env
588             | otherwise                      = env
589
590     (uvars, tyvars, binders, body) = collectBinders rhs
591
592     min_no_of_args | not (null binders)                 &&      -- It's not a thunk
593                      switchIsSet env SimplDoArityExpand         -- Arity expansion on
594                    = getBinderInfoArity occ_info - length binders
595
596                    | otherwise  -- Not a thunk
597                    = 0          -- Play safe!
598
599         -- dont_eta_expand prevents eta expansion in silly situations.
600         -- For example, consider the defn
601         --      x = y
602         -- It would be silly to eta expand the "y", because it would just
603         -- get eta-reduced back to y.  Furthermore, if this was a top level defn,
604         -- and x was exported, then the defn won't be eliminated, so this
605         -- silly expand/reduce cycle will happen every time, which makes the
606         -- simplifier loop!.
607         -- The solution is to not even try eta expansion unless the rhs looks
608         -- non-trivial.
609     dont_eta_expand (Lit _)     = True
610     dont_eta_expand (Var _)     = True
611     dont_eta_expand (Con _ _)   = True
612     dont_eta_expand (App f a)
613       | notValArg    a          = dont_eta_expand f
614     dont_eta_expand (Lam x b)
615       | notValBinder x          = dont_eta_expand b
616     dont_eta_expand _           = False
617 \end{code}
618
619
620 %************************************************************************
621 %*                                                                      *
622 \subsection{Simplify a lambda abstraction}
623 %*                                                                      *
624 %************************************************************************
625
626 Simplify (\binders -> body) trying eta expansion and reduction, given that
627 the abstraction will always be applied to at least min_no_of_args.
628
629 \begin{code}
630 simplLam env binders body min_no_of_args
631   | not (switchIsSet env SimplDoLambdaEtaExpansion) ||  -- Bale out if eta expansion off
632     null potential_extra_binder_tys                 ||  -- or ain't a function
633     no_of_extra_binders == 0                            -- or no extra binders needed
634   = cloneIds env binders                `thenSmpl` \ binders' ->
635     let
636         new_env = extendIdEnvWithClones env binders binders'
637     in
638     simplExpr new_env body []           `thenSmpl` \ body' ->
639     returnSmpl (
640       (if switchIsSet new_env SimplDoEtaReduction
641        then mkValLamTryingEta
642        else mkValLam) binders' body'
643     )
644
645   | otherwise                           -- Eta expansion possible
646   = tick EtaExpansion                   `thenSmpl_`
647     cloneIds env binders                `thenSmpl` \ binders' ->
648     let
649         new_env = extendIdEnvWithClones env binders binders'
650     in
651     newIds extra_binder_tys                             `thenSmpl` \ extra_binders' ->
652     simplExpr new_env body (map VarArg extra_binders')  `thenSmpl` \ body' ->
653     returnSmpl (
654       (if switchIsSet new_env SimplDoEtaReduction
655        then mkValLamTryingEta
656        else mkValLam) (binders' ++ extra_binders') body'
657     )
658
659   where
660     (potential_extra_binder_tys, res_ty)
661         = splitFunTy (simplTy env (coreExprType (unTagBinders body)))
662         -- Note: it's possible that simplLam will be applied to something
663         -- with a forall type.  Eg when being applied to the rhs of
664         --              let x = wurble
665         -- where wurble has a forall-type, but no big lambdas at the top.
666         -- We could be clever an insert new big lambdas, but we don't bother.
667
668     extra_binder_tys = take no_of_extra_binders potential_extra_binder_tys
669
670     no_of_extra_binders =       -- First, use the info about how many args it's
671                                 -- always applied to in its scope
672                            min_no_of_args
673
674                                 -- Next, try seeing if there's a lambda hidden inside
675                                 -- something cheap
676                            `max`
677                            etaExpandCount body
678
679                                 -- Finally, see if it's a state transformer, in which
680                                 -- case we eta-expand on principle! This can waste work,
681                                 -- but usually doesn't
682                            `max`
683                            case potential_extra_binder_tys of
684                                 [ty] | ty `eqTy` realWorldStateTy -> 1
685                                 other                             -> 0
686
687 \end{code}
688
689
690
691 %************************************************************************
692 %*                                                                      *
693 \subsection[Simplify-coerce]{Coerce expressions}
694 %*                                                                      *
695 %************************************************************************
696
697 \begin{code}
698 -- (coerce (case s of p -> r)) args ==> case s of p -> (coerce r) args
699 simplCoerce env coercion ty expr@(Case scrut alts) args
700   = simplCase env scrut alts (\env rhs -> simplCoerce env coercion ty rhs args)
701                              (computeResultType env expr args)
702
703 -- (coerce (let defns in b)) args  ==> let defns' in (coerce b) args
704 simplCoerce env coercion ty (Let bind body) args
705   = simplBind env bind (\env -> simplCoerce env coercion ty body args)
706                        (computeResultType env body args)
707
708 -- Default case
709 simplCoerce env coercion ty expr args
710   = simplExpr env expr []       `thenSmpl` \ expr' ->
711     returnSmpl (mkGenApp (mkCoerce coercion (simplTy env ty) expr') args)
712   where
713
714         -- Try cancellation; we do this "on the way up" because
715         -- I think that's where it'll bite best
716     mkCoerce (CoerceIn  con1) ty1 (Coerce (CoerceOut con2) ty2 body) | con1 == con2 = body
717     mkCoerce (CoerceOut con1) ty1 (Coerce (CoerceIn  con2) ty2 body) | con1 == con2 = body
718     mkCoerce coercion ty  body = Coerce coercion ty body
719 \end{code}
720
721
722 %************************************************************************
723 %*                                                                      *
724 \subsection[Simplify-let]{Let-expressions}
725 %*                                                                      *
726 %************************************************************************
727
728 \begin{code}
729 simplBind :: SimplEnv
730           -> InBinding
731           -> (SimplEnv -> SmplM OutExpr)
732           -> OutType
733           -> SmplM OutExpr
734 \end{code}
735
736 When floating cases out of lets, remember this:
737
738         let x* = case e of alts
739         in <small expr>
740
741 where x* is sure to be demanded or e is a cheap operation that cannot
742 fail, e.g. unboxed addition.  Here we should be prepared to duplicate
743 <small expr>.  A good example:
744
745         let x* = case y of
746                    p1 -> build e1
747                    p2 -> build e2
748         in
749         foldr c n x*
750 ==>
751         case y of
752           p1 -> foldr c n (build e1)
753           p2 -> foldr c n (build e2)
754
755 NEW: We use the same machinery that we use for case-of-case to
756 *always* do case floating from let, that is we let bind and abstract
757 the original let body, and let the occurrence analyser later decide
758 whether the new let should be inlined or not. The example above
759 becomes:
760
761 ==>
762       let join_body x' = foldr c n x'
763         in case y of
764         p1 -> let x* = build e1
765                 in join_body x*
766         p2 -> let x* = build e2
767                 in join_body x*
768
769 note that join_body is a let-no-escape.
770 In this particular example join_body will later be inlined,
771 achieving the same effect.
772 ToDo: check this is OK with andy
773
774
775
776 \begin{code}
777 -- Dead code is now discarded by the occurrence analyser,
778
779 simplBind env (NonRec binder@(id,occ_info) rhs) body_c body_ty
780   |  inlineUnconditionally ok_to_dup occ_info
781   = body_c (extendIdEnvWithInlining env env binder rhs)
782
783 -- Try let-to-case
784 -- It's important to try let-to-case before floating. Consider
785 --
786 --      let a*::Int = case v of {p1->e1; p2->e2}
787 --      in b
788 --
789 -- (The * means that a is sure to be demanded.)
790 -- If we do case-floating first we get this:
791 --
792 --      let k = \a* -> b
793 --      in case v of
794 --              p1-> let a*=e1 in k a
795 --              p2-> let a*=e2 in k a
796 --
797 -- Now watch what happens if we do let-to-case first:
798 --
799 --      case (case v of {p1->e1; p2->e2}) of
800 --        Int a# -> let a*=I# a# in b
801 -- ===>
802 --      let k = \a# -> let a*=I# a# in b
803 --      in case v of
804 --              p1 -> case e1 of I# a# -> k a#
805 --              p1 -> case e1 of I# a# -> k a#
806 --
807 -- The latter is clearly better.  (Remember the reboxing let-decl
808 -- for a is likely to go away, because after all b is strict in a.)
809
810   | will_be_demanded &&
811     try_let_to_case &&
812     type_ok_for_let_to_case rhs_ty &&
813     not (manifestlyWHNF rhs)
814         -- note: no "manifestlyBottom rhs" in there... (comment below)
815     = tick Let2Case                             `thenSmpl_`
816       mkIdentityAlts rhs_ty                     `thenSmpl` \ id_alts ->
817       simplCase env rhs id_alts (\env rhs -> done_float env rhs body_c) body_ty
818         {-
819         We do not do let to case for WHNFs, e.g.
820
821           let x = a:b in ...
822           =/=>
823           case a:b of x in ...
824
825           as this is less efficient.
826           but we don't mind doing let-to-case for "bottom", as that
827           will
828           allow us to remove more dead code, if anything:
829           let x = error in ...
830           ===>
831           case error  of x -> ...
832           ===>
833           error
834
835           Notice that let to case occurs only if x is used strictly in
836           its body (obviously).
837         -}
838
839   | (will_be_demanded && not no_float) ||
840     always_float_let_from_let ||
841     floatExposesHNF float_lets float_primops ok_to_dup rhs
842   = try_float env rhs body_c
843
844   | otherwise
845   = done_float env rhs body_c
846
847   where
848     will_be_demanded = willBeDemanded (getIdDemandInfo id)
849     rhs_ty           = idType id
850
851     float_lets                = switchIsSet env SimplFloatLetsExposingWHNF
852     float_primops             = switchIsSet env SimplOkToFloatPrimOps
853     ok_to_dup                 = switchIsSet env SimplOkToDupCode
854     always_float_let_from_let = switchIsSet env SimplAlwaysFloatLetsFromLets
855     try_let_to_case           = switchIsSet env SimplLetToCase
856     no_float                  = switchIsSet env SimplNoLetFromStrictLet
857
858     -------------------------------------------
859     done_float env rhs body_c
860         = simplRhsExpr env binder rhs   `thenSmpl` \ rhs' ->
861           completeLet env binder rhs' body_c body_ty
862
863     ---------------------------------------
864     try_float env (Let bind rhs) body_c
865       = tick LetFloatFromLet                    `thenSmpl_`
866         simplBind env (fix_up_demandedness will_be_demanded bind)
867                       (\env -> try_float env rhs body_c) body_ty
868
869     try_float env (Case scrut alts) body_c
870       | will_be_demanded || (float_primops && is_cheap_prim_app scrut)
871       = tick CaseFloatFromLet                           `thenSmpl_`
872
873         -- First, bind large let-body if necessary
874         if no_need_to_bind_large_body then
875             simplCase env scrut alts (\env rhs -> try_float env rhs body_c) body_ty
876         else
877             bindLargeRhs env [binder] body_ty body_c    `thenSmpl` \ (extra_binding, new_body) ->
878             let
879                 body_c' = \env -> simplExpr env new_body []
880             in
881             simplCase env scrut alts
882                       (\env rhs -> try_float env rhs body_c')
883                       body_ty                           `thenSmpl` \ case_expr ->
884
885             returnSmpl (Let extra_binding case_expr)
886       where
887         no_need_to_bind_large_body
888           = ok_to_dup || isSingleton (nonErrorRHSs alts)
889
890     try_float env other_rhs body_c = done_float env other_rhs body_c
891 \end{code}
892
893 Letrec expressions
894 ~~~~~~~~~~~~~~~~~~
895
896 Simplify each RHS, float any let(recs) from the RHSs (if let-floating is
897 on and it'll expose a HNF), and bang the whole resulting mess together
898 into a huge letrec.
899
900 1. Any "macros" should be expanded.  The main application of this
901 macro-expansion is:
902
903         letrec
904                 f = ....g...
905                 g = ....f...
906         in
907         ....f...
908
909 Here we would like the single call to g to be inlined.
910
911 We can spot this easily, because g will be tagged as having just one
912 occurrence.  The "inlineUnconditionally" predicate is just what we want.
913
914 A worry: could this lead to non-termination?  For example:
915
916         letrec
917                 f = ...g...
918                 g = ...f...
919                 h = ...h...
920         in
921         ..h..
922
923 Here, f and g call each other (just once) and neither is used elsewhere.
924 But it's OK:
925
926 * the occurrence analyser will drop any (sub)-group that isn't used at
927   all.
928
929 * If the group is used outside itself (ie in the "in" part), then there
930   can't be a cyle.
931
932 ** IMPORTANT: check that NewOccAnal has the property that a group of
933    bindings like the above has f&g dropped.! ***
934
935
936 2. We'd also like to pull out any top-level let(rec)s from the
937 rhs of the defns:
938
939         letrec
940                 f = let h = ... in \x -> ....h...f...h...
941         in
942         ...f...
943 ====>
944         letrec
945                 h = ...
946                 f = \x -> ....h...f...h...
947         in
948         ...f...
949
950 But floating cases is less easy?  (Don't for now; ToDo?)
951
952
953 3.  We'd like to arrange that the RHSs "know" about members of the
954 group that are bound to constructors.  For example:
955
956     let rec
957        d.Eq      = (==,/=)
958        f a b c d = case d.Eq of (h,_) -> let x = (a,b); y = (c,d) in not (h x y)
959        /= a b    = unpack tuple a, unpack tuple b, call f
960     in d.Eq
961
962 here, by knowing about d.Eq in f's rhs, one could get rid of
963 the case (and break out the recursion completely).
964 [This occurred with more aggressive inlining threshold (4),
965 nofib/spectral/knights]
966
967 How to do it?
968         1: we simplify constructor rhss first.
969         2: we record the "known constructors" in the environment
970         3: we simplify the other rhss, with the knowledge about the constructors
971
972
973
974 \begin{code}
975 simplBind env (Rec pairs) body_c body_ty
976   =     -- Do floating, if necessary
977     (if float_lets || always_float_let_from_let
978      then
979         mapSmpl float pairs     `thenSmpl` \ floated_pairs_s ->
980         returnSmpl (concat floated_pairs_s)
981      else
982         returnSmpl pairs
983     )                                   `thenSmpl` \ floated_pairs ->
984     let
985         binders = map fst floated_pairs
986     in
987     cloneIds env binders                `thenSmpl` \ ids' ->
988     let
989         env_w_clones = extendIdEnvWithClones env binders ids'
990         triples      = zipEqual "simplBind" ids' floated_pairs
991     in
992
993     simplRecursiveGroup env_w_clones triples    `thenSmpl` \ (binding, new_env) ->
994
995     body_c new_env                              `thenSmpl` \ body' ->
996
997     returnSmpl (Let binding body')
998
999   where
1000     ------------ Floating stuff -------------------
1001
1002     float_lets                = switchIsSet env SimplFloatLetsExposingWHNF
1003     always_float_let_from_let = switchIsSet env SimplAlwaysFloatLetsFromLets
1004
1005     float (binder,rhs)
1006       = let
1007             pairs_s = float_pair (binder,rhs)
1008         in
1009         case pairs_s of
1010           [_] -> returnSmpl pairs_s
1011           more_than_one
1012             -> tickN LetFloatFromLet (length pairs_s - 1) `thenSmpl_`
1013                 -- It's important to increment the tick counts if we
1014                 -- do any floating.  A situation where this turns out
1015                 -- to be important is this:
1016                 -- Float in produces:
1017                 --      letrec  x = let y = Ey in Ex
1018                 --      in B
1019                 -- Now floating gives this:
1020                 --      letrec x = Ex
1021                 --             y = Ey
1022                 --      in B
1023                 --- We now want to iterate once more in case Ey doesn't
1024                 -- mention x, in which case the y binding can be pulled
1025                 -- out as an enclosing let(rec), which in turn gives
1026                 -- the strictness analyser more chance.
1027                 returnSmpl pairs_s
1028
1029     float_pairs pairs = concat (map float_pair pairs)
1030
1031     float_pair (binder, rhs)
1032         | always_float_let_from_let ||
1033           floatExposesHNF True False False rhs
1034         = (binder,rhs') : pairs'
1035
1036         | otherwise
1037         = [(binder,rhs)]
1038         where
1039           (pairs', rhs') = do_float rhs
1040
1041         -- Float just pulls out any top-level let(rec) bindings
1042     do_float :: InExpr -> ([(InBinder,InExpr)], InExpr)
1043     do_float (Let (Rec pairs) body)     = (float_pairs pairs    ++ pairs', body')
1044                                             where
1045                                               (pairs', body') = do_float body
1046     do_float (Let (NonRec id rhs) body) = (float_pair (id,rhs) ++ pairs', body')
1047                                             where
1048                                               (pairs', body') = do_float body
1049     do_float other                          = ([], other)
1050
1051 simplRecursiveGroup env triples
1052   =     -- Toss out all the dead pairs?  No, there shouldn't be any!
1053         -- Dead code is discarded by the occurrence analyser
1054     let
1055             -- Separate the live triples into "inline"able and
1056             -- "ordinary" We're paranoid about duplication!
1057         (inline_triples, ordinary_triples)
1058           = partition is_inline_triple triples
1059
1060         is_inline_triple (_, ((_,occ_info),_))
1061           = inlineUnconditionally False {-not ok_to_dup-} occ_info
1062
1063             -- Now add in the inline_pairs info (using "env_w_clones"),
1064             -- so that we will save away suitably-clone-laden envs
1065             -- inside the InlineIts...).
1066
1067             -- NOTE ALSO that we tie a knot here, because the
1068             -- saved-away envs must also include these very inlinings
1069             -- (they aren't stored anywhere else, and a late one might
1070             -- be used in an early one).
1071
1072         env_w_inlinings = foldl add_inline env inline_triples
1073
1074         add_inline env (id', (binder,rhs))
1075           = extendIdEnvWithInlining env env_w_inlinings binder rhs
1076
1077             -- Separate the remaining bindings into the ones which
1078             -- need to be dealt with first (the "early" ones)
1079             -- and the others (the "late" ones)
1080         (early_triples, late_triples)
1081           = partition is_early_triple ordinary_triples
1082
1083         is_early_triple (_, (_, Con _ _)) = True
1084         is_early_triple (i, _           ) = idWantsToBeINLINEd i
1085     in
1086         -- Process the early bindings first
1087     mapSmpl (do_one_binding env_w_inlinings) early_triples      `thenSmpl` \ early_triples' ->
1088
1089         -- Now further extend the environment to record our knowledge
1090         -- about the form of the binders bound in the constructor bindings
1091     let
1092         env_w_early_info = foldr add_early_info env_w_inlinings early_triples'
1093         add_early_info (binder, (id', rhs')) env = extendUnfoldEnvGivenRhs env binder id' rhs'
1094     in
1095         -- Now process the non-constructor bindings
1096     mapSmpl (do_one_binding env_w_early_info) late_triples      `thenSmpl` \ late_triples' ->
1097
1098         -- Phew! We're done
1099     let
1100         binding = Rec (map snd early_triples' ++ map snd late_triples')
1101     in
1102     returnSmpl (binding, env_w_early_info)
1103   where
1104
1105     do_one_binding env (id', (binder,rhs))
1106       = simplRhsExpr env binder rhs `thenSmpl` \ rhs' ->
1107         returnSmpl (binder, (id', rhs'))
1108 \end{code}
1109
1110
1111 @completeLet@ looks at the simplified post-floating RHS of the
1112 let-expression, and decides what to do.  There's one interesting
1113 aspect to this, namely constructor reuse.  Consider
1114 @
1115         f = \x -> case x of
1116                     (y:ys) -> y:ys
1117                     []     -> ...
1118 @
1119 Is it a good idea to replace the rhs @y:ys@ with @x@?  This depends a
1120 bit on the compiler technology, but in general I believe not. For
1121 example, here's some code from a real program:
1122 @
1123 const.Int.max.wrk{-s2516-} =
1124     \ upk.s3297#  upk.s3298# ->
1125         let {
1126           a.s3299 :: Int
1127           _N_ {-# U(P) #-}
1128           a.s3299 = I#! upk.s3297#
1129         } in
1130           case (const.Int._tagCmp.wrk{-s2513-} upk.s3297# upk.s3298#) of {
1131             _LT -> I#! upk.s3298#
1132             _EQ -> a.s3299
1133             _GT -> a.s3299
1134           }
1135 @
1136 The a.s3299 really isn't doing much good.  We'd be better off inlining
1137 it.  (Actually, let-no-escapery means it isn't as bad as it looks.)
1138
1139 So the current strategy is to inline all known-form constructors, and
1140 only do the reverse (turn a constructor application back into a
1141 variable) when we find a let-expression:
1142 @
1143         let x = C a1 .. an
1144         in
1145         ... (let y = C a1 .. an in ...) ...
1146 @
1147 where it is always good to ditch the binding for y, and replace y by
1148 x.  That's just what completeLetBinding does.
1149
1150 \begin{code}
1151 completeLet
1152         :: SimplEnv
1153         -> InBinder
1154         -> OutExpr              -- The simplified RHS
1155         -> (SimplEnv -> SmplM OutExpr)          -- Body handler
1156         -> OutType              -- Type of body
1157         -> SmplM OutExpr
1158
1159 completeLet env binder new_rhs body_c body_ty
1160   -- See if RHS is an atom, or a reusable constructor
1161   | maybeToBool maybe_atomic_rhs
1162   = let
1163         new_env = extendIdEnvWithAtom env binder rhs_atom
1164     in
1165     tick atom_tick_type                 `thenSmpl_`
1166     body_c new_env
1167   where
1168     maybe_atomic_rhs :: Maybe (OutArg, TickType)
1169     maybe_atomic_rhs = exprToAtom env new_rhs
1170         -- If the RHS is atomic, we return Just (atom, tick type)
1171         -- otherwise Nothing
1172     Just (rhs_atom, atom_tick_type) = maybe_atomic_rhs
1173
1174 completeLet env binder@(id,_) new_rhs body_c body_ty
1175   -- Maybe the rhs is an application of error, and sure to be demanded
1176   | will_be_demanded &&
1177     maybeToBool maybe_error_app
1178   = tick CaseOfError                    `thenSmpl_`
1179     returnSmpl retyped_error_app
1180   where
1181     will_be_demanded       = willBeDemanded (getIdDemandInfo id)
1182     maybe_error_app        = maybeErrorApp new_rhs (Just body_ty)
1183     Just retyped_error_app = maybe_error_app
1184
1185 {-
1186 completeLet env binder (Coerce coercion ty rhs) body_c body_ty
1187    -- Rhs is a coercion
1188    | maybeToBool maybe_atomic_coerce_rhs
1189    = tick tick_type             `thenSmpl_`
1190      complete_coerce env rhs_atom rhs
1191    where
1192      maybe_atomic_coerce_rhs    = exprToAtom env rhs
1193      Just (rhs_atom, tick_type) = maybe_atomic_coerce_rhs
1194
1195           returnSmpl (CoerceForm coercion rhs_atom, env)
1196         Nothing
1197           newId (coreExprType rhs)      `thenSmpl` \ inner_id ->
1198           
1199      complete_coerce env atom rhs
1200        = cloneId env binder                     `thenSmpl` \ id' ->
1201          let
1202             env1    = extendIdEnvWithClone env binder id'
1203             new_env = extendUnfoldEnvGivenFormDetails env1 id' (CoerceForm coercion rhs_atom)
1204          in
1205          body_c new_env                 `thenSmpl` \ body' ->
1206          returnSmpl (Let (NonRec id' (Coerce coercion ty rhs) body')
1207 -}   
1208
1209 completeLet env binder new_rhs body_c body_ty
1210   -- The general case
1211   = cloneId env binder                  `thenSmpl` \ id' ->
1212     let
1213         env1    = extendIdEnvWithClone env binder id'
1214         new_env = extendUnfoldEnvGivenRhs env1 binder id' new_rhs
1215     in
1216     body_c new_env                      `thenSmpl` \ body' ->
1217     returnSmpl (Let (NonRec id' new_rhs) body')
1218 \end{code}
1219
1220 %************************************************************************
1221 %*                                                                      *
1222 \subsection[Simplify-atoms]{Simplifying atoms}
1223 %*                                                                      *
1224 %************************************************************************
1225
1226 \begin{code}
1227 simplArg :: SimplEnv -> InArg -> OutArg
1228
1229 simplArg env (LitArg lit) = LitArg lit
1230 simplArg env (TyArg  ty)  = TyArg  (simplTy env ty)
1231
1232 simplArg env (VarArg id)
1233   | isLocallyDefined id
1234   = case lookupId env id of
1235         Just (ItsAnAtom atom) -> atom
1236         Just (InlineIt _ _ _) -> pprPanic "simplArg InLineIt:" (ppAbove (ppr PprDebug id) (pprSimplEnv env))
1237         Nothing               -> VarArg id      -- Must be an uncloned thing
1238
1239   | otherwise
1240   =     -- Not locally defined, so no change
1241     VarArg id
1242 \end{code}
1243
1244
1245 \begin{code}
1246 exprToAtom env (Var var) 
1247   = Just (VarArg var, AtomicRhs)
1248
1249 exprToAtom env (Lit lit) 
1250   | not (isNoRepLit lit)
1251   = Just (LitArg lit, AtomicRhs)
1252
1253 exprToAtom env (Con con con_args)
1254   | switchIsSet env SimplReuseCon
1255   -- Look out for
1256   --    let v = C args
1257   --    in
1258   --- ...(let w = C same-args in ...)...
1259   -- Then use v instead of w.    This may save
1260   -- re-constructing an existing constructor.
1261   = case (lookForConstructor env con con_args) of
1262                   Nothing  -> Nothing
1263                   Just var -> Just (VarArg var, ConReused)
1264
1265 exprToAtom env other
1266   = Nothing
1267 \end{code}
1268
1269 %************************************************************************
1270 %*                                                                      *
1271 \subsection[Simplify-quickies]{Some local help functions}
1272 %*                                                                      *
1273 %************************************************************************
1274
1275
1276 \begin{code}
1277 -- fix_up_demandedness switches off the willBeDemanded Info field
1278 -- for bindings floated out of a non-demanded let
1279 fix_up_demandedness True {- Will be demanded -} bind
1280    = bind       -- Simple; no change to demand info needed
1281 fix_up_demandedness False {- May not be demanded -} (NonRec binder rhs)
1282    = NonRec (un_demandify binder) rhs
1283 fix_up_demandedness False {- May not be demanded -} (Rec pairs)
1284    = Rec [(un_demandify binder, rhs) | (binder,rhs) <- pairs]
1285
1286 un_demandify (id, occ_info) = (id `addIdDemandInfo` noInfo, occ_info)
1287
1288 is_cheap_prim_app (Prim op _) = primOpOkForSpeculation op
1289 is_cheap_prim_app other       = False
1290
1291 computeResultType :: SimplEnv -> InExpr -> [OutArg] -> OutType
1292 computeResultType env expr args
1293   = go expr_ty' args
1294   where
1295     expr_ty  = coreExprType (unTagBinders expr)
1296     expr_ty' = simplTy env expr_ty
1297
1298     go ty [] = ty
1299     go ty (TyArg ty_arg : args) = go (mkAppTy ty ty_arg) args
1300     go ty (a:args) | isValArg a = case (getFunTy_maybe ty) of
1301                                     Just (_, res_ty) -> go res_ty args
1302                                     Nothing          -> panic "computeResultType"
1303 \end{code}
1304