2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[CoreUtils]{Utility functions on @Core@ syntax}
7 #include "HsVersions.h"
10 coreExprType, coreAltsType,
12 substCoreExpr, substCoreBindings
15 , escErrorMsg -- ToDo: kill
17 , unTagBinders, unTagBindersAlts
18 , manifestlyWHNF, manifestlyBottom
21 , squashableDictishCcExpr
22 {- exprSmallEnoughToDup,
29 import IdLoop -- for pananoia-checking purposes
33 import CostCentre ( isDictCC )
34 import Id ( idType, mkSysLocal, getIdArity, isBottomingId,
35 addOneToIdEnv, growIdEnvList, lookupIdEnv,
36 isNullIdEnv, IdEnv(..),
39 import IdInfo ( arityMaybe )
40 import Literal ( literalType, isNoRepLit, Literal(..) )
41 import Maybes ( catMaybes, maybeToBool )
42 import PprCore ( GenCoreExpr{-instances-}, GenCoreArg{-instances-} )
43 import PprStyle ( PprStyle(..) )
44 import PprType ( GenType{-instances-} )
45 import Pretty ( ppAboves )
46 import PrelInfo ( trueDataCon, falseDataCon,
49 import PrimOp ( primOpType, PrimOp(..) )
50 import SrcLoc ( mkUnknownSrcLoc )
51 import TyVar ( isNullTyVarEnv, TyVarEnv(..) )
52 import Type ( mkFunTys, mkForAllTy, mkForAllUsageTy, mkTyVarTy,
53 getFunTy_maybe, applyTy, isPrimType,
54 splitSigmaTy, splitFunTy, eqTy, applyTypeEnvToTy
56 import UniqSupply ( initUs, returnUs, thenUs,
58 UniqSM(..), UniqSupply
60 import Usage ( UVar(..) )
61 import Util ( zipEqual, panic, pprPanic, assertPanic )
63 type TypeEnv = TyVarEnv Type
64 applyUsage = panic "CoreUtils.applyUsage:ToDo"
65 dup_binder = panic "CoreUtils.dup_binder"
68 %************************************************************************
70 \subsection{Find the type of a Core atom/expression}
72 %************************************************************************
75 coreExprType :: CoreExpr -> Type
77 coreExprType (Var var) = idType var
78 coreExprType (Lit lit) = literalType lit
80 coreExprType (Let _ body) = coreExprType body
81 coreExprType (SCC _ expr) = coreExprType expr
82 coreExprType (Case _ alts) = coreAltsType alts
84 -- a Con is a fully-saturated application of a data constructor
85 -- a Prim is <ditto> of a PrimOp
87 coreExprType (Con con args) = applyTypeToArgs (idType con) args
88 coreExprType (Prim op args) = applyTypeToArgs (primOpType op) args
90 coreExprType (Lam (ValBinder binder) expr)
91 = mkFunTys [idType binder] (coreExprType expr)
93 coreExprType (Lam (TyBinder tyvar) expr)
94 = mkForAllTy tyvar (coreExprType expr)
96 coreExprType (Lam (UsageBinder uvar) expr)
97 = mkForAllUsageTy uvar (panic "coreExprType:Lam UsageBinder") (coreExprType expr)
99 coreExprType (App expr (TyArg ty))
100 = applyTy (coreExprType expr) ty
102 coreExprType (App expr (UsageArg use))
103 = applyUsage (coreExprType expr) use
105 coreExprType (App expr val_arg)
106 = ASSERT(isValArg val_arg)
108 fun_ty = coreExprType expr
110 case (getFunTy_maybe fun_ty) of
111 Just (_, result_ty) -> result_ty
113 Nothing -> pprPanic "coreExprType:\n"
114 (ppAboves [ppr PprDebug fun_ty,
115 ppr PprShowAll (App expr val_arg)])
120 coreAltsType :: CoreCaseAlts -> Type
122 coreAltsType (AlgAlts [] deflt) = default_ty deflt
123 coreAltsType (AlgAlts ((_,_,rhs1):_) _) = coreExprType rhs1
125 coreAltsType (PrimAlts [] deflt) = default_ty deflt
126 coreAltsType (PrimAlts ((_,rhs1):_) _) = coreExprType rhs1
128 default_ty NoDefault = panic "coreExprType:Case:default_ty"
129 default_ty (BindDefault _ rhs) = coreExprType rhs
133 applyTypeToArgs = panic "applyTypeToArgs"
136 %************************************************************************
138 \subsection{Routines to manufacture bits of @CoreExpr@}
140 %************************************************************************
143 mkCoreIfThenElse (Var bool) then_expr else_expr
144 | bool == trueDataCon = then_expr
145 | bool == falseDataCon = else_expr
147 mkCoreIfThenElse guard then_expr else_expr
149 (AlgAlts [ (trueDataCon, [], then_expr),
150 (falseDataCon, [], else_expr) ]
156 mkErrorApp :: Id -> Type -> Id -> String -> CoreExpr
158 mkErrorApp err_fun ty str_var error_msg
159 = Let (NonRec str_var (Lit (NoRepStr (_PK_ error_msg)))) (
160 mkApp (Var err_fun) [] [ty] [VarArg str_var])
163 escErrorMsg = panic "CoreUtils.escErrorMsg: To Die"
166 escErrorMsg ('%':xs) = '%' : '%' : escErrorMsg xs
167 escErrorMsg (x:xs) = x : escErrorMsg xs
171 For making @Apps@ and @Lets@, we must take appropriate evasive
172 action if the thing being bound has unboxed type. @mkCoApp@ requires
173 a name supply to do its work. Other-monad code will call @mkCoApp@
174 through its own interface function (e.g., the desugarer uses
177 @mkCoApp@, @mkCoCon@ and @mkCoPrim@ also handle the
178 arguments-must-be-atoms constraint.
182 --mkCoApp :: CoreExpr -> CoreExpr -> UniqSM CoreExpr
184 mkCoApp e1 (Var v) = returnUs (App e1 (VarArg v))
185 mkCoApp e1 (Lit l) = returnUs (App e1 (LitArg l))
188 e2_ty = coreExprType e2
190 panic "getUnique" `thenUs` \ uniq ->
192 new_var = mkSysLocal SLIT("a") uniq e2_ty mkUnknownSrcLoc
195 mkCoLetUnboxedToCase (NonRec new_var e2)
196 (App e1 (VarArg new_var))
203 mkCoCon :: Id -> [CoreExpr] -> UniqSM CoreExpr
204 mkCoPrim :: PrimOp -> [CoreExpr] -> UniqSM CoreExpr
206 mkCoCon con args = mkCoThing (Con con) args
207 mkCoPrim op args = mkCoThing (Prim op) args
209 mkCoThing thing arg_exprs
210 = mapAndUnzipUs expr_to_arg arg_exprs `thenUs` \ (args, maybe_binds) ->
211 returnUs (mkCoLetsUnboxedToCase (catMaybes maybe_binds) (thing args))
213 expr_to_arg :: CoreExpr
214 -> UniqSM (CoreArg, Maybe CoreBinding)
216 expr_to_arg (Var v) = returnUs (VarArg v, Nothing)
217 expr_to_arg (Lit l) = returnUs (LitArg l, Nothing)
218 expr_to_arg other_expr
220 e_ty = coreExprType other_expr
222 panic "getUnique" `thenUs` \ uniq ->
224 new_var = mkSysLocal SLIT("a") uniq e_ty mkUnknownSrcLoc
225 new_atom = VarArg new_var
227 returnUs (new_atom, Just (NonRec new_var other_expr))
233 GenCoreArg val_occ tyvar uvar -> GenCoreExpr val_bdr val_occ tyvar uvar
235 argToExpr (VarArg v) = Var v
236 argToExpr (LitArg lit) = Lit lit
242 -- GenCoreExpr val_bdr val_occ tyvar uvar ->
243 -- [GenCoreExpr val_bdr val_occ tyvar uvar] ->
244 -- UniqSM(GenCoreExpr val_bdr val_occ tyvar uvar)
246 mkCoApps fun [] = returnUs fun
247 mkCoApps fun (arg:args)
248 = mkCoApp fun arg `thenUs` \ new_fun ->
249 mkCoApps new_fun args
253 exprSmallEnoughToDup :: GenCoreExpr binder Id -> Bool
255 exprSmallEnoughToDup (Con _ _ _) = True -- Could check # of args
256 exprSmallEnoughToDup (Prim op _ _) = not (fragilePrimOp op) -- Could check # of args
257 exprSmallEnoughToDup (Lit lit) = not (isNoRepLit lit)
259 exprSmallEnoughToDup expr -- for now, just: <var> applied to <args>
260 = case (collectArgs expr) of { (fun, _, _, vargs) ->
262 Var v -> v /= buildId
264 && length vargs <= 6 -- or 10 or 1 or 4 or anything smallish.
269 Question (ADR): What is the above used for? Is a _ccall_ really small
272 @manifestlyWHNF@ looks at a Core expression and returns \tr{True} if
273 it is obviously in weak head normal form. It isn't a disaster if it
274 errs on the conservative side (returning \tr{False})---I've probably
275 left something out... [WDP]
278 manifestlyWHNF :: GenCoreExpr bndr Id tyvar uvar -> Bool
280 manifestlyWHNF (Var _) = True
281 manifestlyWHNF (Lit _) = True
282 manifestlyWHNF (Con _ _) = True
283 manifestlyWHNF (SCC _ e) = manifestlyWHNF e
284 manifestlyWHNF (Let _ e) = False
285 manifestlyWHNF (Case _ _) = False
287 manifestlyWHNF (Lam x e) = if isValBinder x then True else manifestlyWHNF e
289 manifestlyWHNF other_expr -- look for manifest partial application
290 = case (collectArgs other_expr) of { (fun, _, _, vargs) ->
293 num_val_args = length vargs
295 num_val_args == 0 -- Just a type application of
296 -- a variable (f t1 t2 t3);
299 case (arityMaybe (getIdArity f)) of
301 Just arity -> num_val_args < arity
307 @manifestlyBottom@ looks at a Core expression and returns \tr{True} if
308 it is obviously bottom, that is, it will certainly return bottom at
309 some point. It isn't a disaster if it errs on the conservative side
310 (returning \tr{False}).
313 manifestlyBottom :: GenCoreExpr bndr Id tyvar uvar -> Bool
315 manifestlyBottom (Var v) = isBottomingId v
316 manifestlyBottom (Lit _) = False
317 manifestlyBottom (Con _ _) = False
318 manifestlyBottom (Prim _ _) = False
319 manifestlyBottom (SCC _ e) = manifestlyBottom e
320 manifestlyBottom (Let _ e) = manifestlyBottom e
322 -- We do not assume \x.bottom == bottom:
323 manifestlyBottom (Lam x e) = if isValBinder x then False else manifestlyBottom e
325 manifestlyBottom (Case e a)
328 AlgAlts alts def -> all mbalg alts && mbdef def
329 PrimAlts alts def -> all mbprim alts && mbdef def
332 mbalg (_,_,e') = manifestlyBottom e'
334 mbprim (_,e') = manifestlyBottom e'
336 mbdef NoDefault = True
337 mbdef (BindDefault _ e') = manifestlyBottom e'
339 manifestlyBottom other_expr -- look for manifest partial application
340 = case (collectArgs other_expr) of { (fun, _, _, _) ->
342 Var f | isBottomingId f -> True
343 -- Application of a function which always gives
344 -- bottom; we treat this as a WHNF, because it
345 -- certainly doesn't need to be shared!
353 :: (Id -> Maybe (GenCoreExpr bndr Id))
354 -> GenCoreExpr bndr Id
356 coreExprArity f (Lam _ expr) = coreExprArity f expr + 1
357 coreExprArity f (CoTyLam _ expr) = coreExprArity f expr
358 coreExprArity f (App expr arg) = max (coreExprArity f expr - 1) 0
359 coreExprArity f (CoTyApp expr _) = coreExprArity f expr
360 coreExprArity f (Var v) = max further info
365 Just expr -> coreExprArity f expr
366 info = case (arityMaybe (getIdArity v)) of
369 coreExprArity f _ = 0
372 @isWrapperFor@: we want to see exactly:
374 /\ ... \ args -> case <arg> of ... -> case <arg> of ... -> wrkr <stuff>
377 Probably a little too HACKY [WDP].
380 isWrapperFor :: CoreExpr -> Id -> Bool
382 expr `isWrapperFor` var
383 = case (collectBinders expr) of { (_, _, args, body) -> -- lambdas off the front
384 unravel_casing args body
385 --NO, THANKS: && not (null args)
388 var's_worker = getWorkerId (getIdStrictness var)
390 is_elem = isIn "isWrapperFor"
393 unravel_casing case_ables (Case scrut alts)
394 = case (collectArgs scrut) of { (fun, _, _, vargs) ->
398 scrut_var /= var && all (doesn't_mention var) vargs
399 && scrut_var `is_elem` case_ables
400 && unravel_alts case_ables alts
407 unravel_casing case_ables other_expr
408 = case (collectArgs other_expr) of { (fun, _, _, vargs) ->
412 -- DOESN'T WORK: wrkr == var's_worker
415 && all (doesn't_mention var) vargs
416 && all (only_from case_ables) vargs
424 unravel_alts case_ables (AlgAlts [(_,params,rhs)] NoDefault)
425 = unravel_casing (params ++ case_ables) rhs
426 unravel_alts case_ables other = False
428 -------------------------
429 doesn't_mention var (ValArg (VarArg v)) = v /= var
430 doesn't_mention var other = True
432 -------------------------
433 only_from case_ables (ValArg (VarArg v)) = v `is_elem` case_ables
434 only_from case_ables other = True
438 All the following functions operate on binders, perform a uniform
439 transformation on them; ie. the function @(\ x -> (x,False))@
440 annotates all binders with False.
443 unTagBinders :: GenCoreExpr (Id,tag) bdee tv uv -> GenCoreExpr Id bdee tv uv
444 unTagBinders expr = bop_expr fst expr
446 unTagBindersAlts :: GenCoreCaseAlts (Id,tag) bdee tv uv -> GenCoreCaseAlts Id bdee tv uv
447 unTagBindersAlts alts = bop_alts fst alts
451 bop_expr :: (a -> b) -> GenCoreExpr a bdee tv uv -> GenCoreExpr b bdee tv uv
453 bop_expr f (Var b) = Var b
454 bop_expr f (Lit lit) = Lit lit
455 bop_expr f (Con con args) = Con con args
456 bop_expr f (Prim op args) = Prim op args
457 bop_expr f (Lam binder expr) = Lam (bop_binder f binder) (bop_expr f expr)
458 bop_expr f (App expr arg) = App (bop_expr f expr) arg
459 bop_expr f (SCC label expr) = SCC label (bop_expr f expr)
460 bop_expr f (Let bind expr) = Let (bop_bind f bind) (bop_expr f expr)
461 bop_expr f (Case expr alts) = Case (bop_expr f expr) (bop_alts f alts)
463 bop_binder f (ValBinder v) = ValBinder (f v)
464 bop_binder f (TyBinder t) = TyBinder t
465 bop_binder f (UsageBinder u) = UsageBinder u
467 bop_bind f (NonRec b e) = NonRec (f b) (bop_expr f e)
468 bop_bind f (Rec pairs) = Rec [(f b, bop_expr f e) | (b, e) <- pairs]
470 bop_alts f (AlgAlts alts deflt)
471 = AlgAlts [ (con, [f b | b <- binders], bop_expr f e)
472 | (con, binders, e) <- alts ]
475 bop_alts f (PrimAlts alts deflt)
476 = PrimAlts [ (lit, bop_expr f e) | (lit, e) <- alts ]
479 bop_deflt f (NoDefault) = NoDefault
480 bop_deflt f (BindDefault b expr) = BindDefault (f b) (bop_expr f expr)
483 OLD (but left here because of the nice example): @singleAlt@ checks
484 whether a bunch of case alternatives is actually just one alternative.
485 It specifically {\em ignores} alternatives which consist of just a
486 call to @error@, because they won't result in any code duplication.
490 case (case <something> of
492 False -> error "Foo") of
498 True -> case <rhs> of
500 False -> case error "Foo" of
506 True -> case <rhs> of
510 Notice that the \tr{<alts>} don't get duplicated.
513 nonErrorRHSs :: GenCoreCaseAlts a Id TyVar UVar -> [GenCoreExpr a Id TyVar UVar]
516 = filter not_error_app (find_rhss alts)
518 find_rhss (AlgAlts as deflt) = [rhs | (_,_,rhs) <- as] ++ deflt_rhs deflt
519 find_rhss (PrimAlts as deflt) = [rhs | (_,rhs) <- as] ++ deflt_rhs deflt
521 deflt_rhs NoDefault = []
522 deflt_rhs (BindDefault _ rhs) = [rhs]
525 = case (maybeErrorApp rhs Nothing) of
530 maybeErrorApp checks whether an expression is of the form
536 Just (error ty' args)
538 where ty' is supplied as an argument to maybeErrorApp.
540 Here's where it is useful:
542 case (error ty "Foo" e1 e2) of <alts>
546 where ty' is the type of any of the alternatives. You might think
547 this never occurs, but see the comments on the definition of
550 Note: we *avoid* the case where ty' might end up as a primitive type:
551 this is very uncool (totally wrong).
553 NOTICE: in the example above we threw away e1 and e2, but not the
554 string "Foo". How did we know to do that?
556 Answer: for now anyway, we only handle the case of a function whose
559 bottomingFn :: forall a. t1 -> ... -> tn -> a
560 ^---------------------^ NB!
562 Furthermore, we only count a bottomingApp if the function is applied
563 to more than n args. If so, we transform:
565 bottomingFn ty e1 ... en en+1 ... em
567 bottomingFn ty' e1 ... en
569 That is, we discard en+1 .. em
573 :: GenCoreExpr a Id TyVar UVar -- Expr to look at
574 -> Maybe Type -- Just ty => a result type *already cloned*;
575 -- Nothing => don't know result ty; we
576 -- *pretend* that the result ty won't be
577 -- primitive -- somebody later must
579 -> Maybe (GenCoreExpr a Id TyVar UVar)
581 maybeErrorApp expr result_ty_maybe
582 = case (collectArgs expr) of
583 (Var fun, [{-no usage???-}], [ty], other_args)
585 && maybeToBool result_ty_maybe -- we *know* the result type
586 -- (otherwise: live a fairy-tale existence...)
587 && not (isPrimType result_ty) ->
589 case (splitSigmaTy (idType fun)) of
590 ([tyvar], [], tau_ty) ->
591 case (splitFunTy tau_ty) of { (arg_tys, res_ty) ->
593 n_args_to_keep = length arg_tys
594 args_to_keep = take n_args_to_keep other_args
596 if (res_ty `eqTy` mkTyVarTy tyvar)
597 && n_args_to_keep <= length other_args
599 -- Phew! We're in business
600 Just (mkGenApp (Var fun) (TyArg result_ty : args_to_keep))
605 other -> Nothing -- Function type wrong shape
608 Just result_ty = result_ty_maybe
612 squashableDictishCcExpr :: CostCentre -> GenCoreExpr a b c d -> Bool
614 squashableDictishCcExpr cc expr
615 = if not (isDictCC cc) then
616 False -- that was easy...
618 squashable expr -- note: quite like the "atomic_rhs" stuff in simplifier
620 squashable (Var _) = True
621 squashable (Con _ _) = True -- I think so... WDP 94/09
622 squashable (Prim _ _) = True -- ditto
624 | notValArg a = squashable f
625 squashable other = False
628 %************************************************************************
630 \subsection{Core-renaming utils}
632 %************************************************************************
635 substCoreBindings :: ValEnv
636 -> TypeEnv -- TyVar=>Type
638 -> UniqSM [CoreBinding]
640 substCoreExpr :: ValEnv
641 -> TypeEnv -- TyVar=>Type
645 substCoreBindings venv tenv binds
646 -- if the envs are empty, then avoid doing anything
647 = if (isNullIdEnv venv && isNullTyVarEnv tenv) then
650 do_CoreBindings venv tenv binds
652 substCoreExpr venv tenv expr
653 = if (isNullIdEnv venv && isNullTyVarEnv tenv) then
656 do_CoreExpr venv tenv expr
659 The equiv code for @Types@ is in @TyUtils@.
661 Because binders aren't necessarily unique: we don't do @plusEnvs@
662 (which check for duplicates); rather, we use the shadowing version,
663 @growIdEnv@ (and shorthand @addOneToIdEnv@).
665 @do_CoreBindings@ takes into account the semantics of a list of
666 @CoreBindings@---things defined early in the list are visible later in
667 the list, but not vice versa.
670 type ValEnv = IdEnv CoreExpr
672 do_CoreBindings :: ValEnv
675 -> UniqSM [CoreBinding]
677 do_CoreBinding :: ValEnv
680 -> UniqSM (CoreBinding, ValEnv)
682 do_CoreBindings venv tenv [] = returnUs []
683 do_CoreBindings venv tenv (b:bs)
684 = do_CoreBinding venv tenv b `thenUs` \ (new_b, new_venv) ->
685 do_CoreBindings new_venv tenv bs `thenUs` \ new_bs ->
686 returnUs (new_b : new_bs)
688 do_CoreBinding venv tenv (NonRec binder rhs)
689 = do_CoreExpr venv tenv rhs `thenUs` \ new_rhs ->
691 dup_binder tenv binder `thenUs` \ (new_binder, (old, new)) ->
692 -- now plug new bindings into envs
693 let new_venv = addOneToIdEnv venv old new in
695 returnUs (NonRec new_binder new_rhs, new_venv)
697 do_CoreBinding venv tenv (Rec binds)
698 = -- for letrec, we plug in new bindings BEFORE cloning rhss
699 mapAndUnzipUs (dup_binder tenv) binders `thenUs` \ (new_binders, new_maps) ->
700 let new_venv = growIdEnvList venv new_maps in
702 mapUs (do_CoreExpr new_venv tenv) rhss `thenUs` \ new_rhss ->
703 returnUs (Rec (new_binders `zipEqual` new_rhss), new_venv)
705 (binders, rhss) = unzip binds
714 do_CoreArg venv tenv (LitArg lit) = returnUs (Lit lit)
715 do_CoreArg venv tenv (TyArg ty) = panic "do_CoreArg: TyArg"
716 do_CoreArg venv tenv (UsageArg usage) = panic "do_CoreArg: UsageArg"
717 do_CoreArg venv tenv (VarArg v)
719 case (lookupIdEnv venv v) of
720 Nothing -> --false:ASSERT(toplevelishId v)
727 do_CoreExpr :: ValEnv
732 do_CoreExpr venv tenv orig_expr@(Var var)
734 case (lookupIdEnv venv var) of
735 Nothing -> --false:ASSERT(toplevelishId var) (SIGH)
740 do_CoreExpr venv tenv e@(Lit _) = returnUs e
742 do_CoreExpr venv tenv (Con con as)
743 = panic "CoreUtils.do_CoreExpr:Con"
745 = mapUs (do_CoreArg venv tenv) as `thenUs` \ new_as ->
749 do_CoreExpr venv tenv (Prim op as)
750 = panic "CoreUtils.do_CoreExpr:Prim"
752 = mapUs (do_CoreArg venv tenv) as `thenUs` \ new_as ->
753 do_PrimOp op `thenUs` \ new_op ->
754 mkCoPrim new_op new_as
756 do_PrimOp (CCallOp label is_asm may_gc arg_tys result_ty)
758 new_arg_tys = map (applyTypeEnvToTy tenv) arg_tys
759 new_result_ty = applyTypeEnvToTy tenv result_ty
761 returnUs (CCallOp label is_asm may_gc new_arg_tys new_result_ty)
763 do_PrimOp other_op = returnUs other_op
766 do_CoreExpr venv tenv (Lam binder expr)
767 = dup_binder tenv binder `thenUs` \(new_binder, (old,new)) ->
768 let new_venv = addOneToIdEnv venv old new in
769 do_CoreExpr new_venv tenv expr `thenUs` \ new_expr ->
770 returnUs (Lam new_binder new_expr)
772 do_CoreExpr venv tenv (App expr arg)
773 = panic "CoreUtils.do_CoreExpr:App"
775 = do_CoreExpr venv tenv expr `thenUs` \ new_expr ->
776 do_CoreArg venv tenv arg `thenUs` \ new_arg ->
777 mkCoApp new_expr new_arg
780 do_CoreExpr venv tenv (Case expr alts)
781 = do_CoreExpr venv tenv expr `thenUs` \ new_expr ->
782 do_alts venv tenv alts `thenUs` \ new_alts ->
783 returnUs (Case new_expr new_alts)
785 do_alts venv tenv (AlgAlts alts deflt)
786 = mapUs (do_boxed_alt venv tenv) alts `thenUs` \ new_alts ->
787 do_default venv tenv deflt `thenUs` \ new_deflt ->
788 returnUs (AlgAlts new_alts new_deflt)
790 do_boxed_alt venv tenv (con, binders, expr)
791 = mapAndUnzipUs (dup_binder tenv) binders `thenUs` \ (new_binders, new_vmaps) ->
792 let new_venv = growIdEnvList venv new_vmaps in
793 do_CoreExpr new_venv tenv expr `thenUs` \ new_expr ->
794 returnUs (con, new_binders, new_expr)
797 do_alts venv tenv (PrimAlts alts deflt)
798 = mapUs (do_unboxed_alt venv tenv) alts `thenUs` \ new_alts ->
799 do_default venv tenv deflt `thenUs` \ new_deflt ->
800 returnUs (PrimAlts new_alts new_deflt)
802 do_unboxed_alt venv tenv (lit, expr)
803 = do_CoreExpr venv tenv expr `thenUs` \ new_expr ->
804 returnUs (lit, new_expr)
806 do_default venv tenv NoDefault = returnUs NoDefault
808 do_default venv tenv (BindDefault binder expr)
809 = dup_binder tenv binder `thenUs` \ (new_binder, (old, new)) ->
810 let new_venv = addOneToIdEnv venv old new in
811 do_CoreExpr new_venv tenv expr `thenUs` \ new_expr ->
812 returnUs (BindDefault new_binder new_expr)
814 do_CoreExpr venv tenv (Let core_bind expr)
815 = do_CoreBinding venv tenv core_bind `thenUs` \ (new_bind, new_venv) ->
816 -- and do the body of the let
817 do_CoreExpr new_venv tenv expr `thenUs` \ new_expr ->
818 returnUs (Let new_bind new_expr)
820 do_CoreExpr venv tenv (SCC label expr)
821 = do_CoreExpr venv tenv expr `thenUs` \ new_expr ->
822 returnUs (SCC label new_expr)