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, coreExprCc,
12 substCoreExpr, substCoreBindings
16 , unTagBinders, unTagBindersAlts
20 , squashableDictishCcExpr
27 import CostCentre ( isDictCC, CostCentre, noCostCentre )
28 import Id ( idType, mkSysLocal, isBottomingId,
29 toplevelishId, mkIdWithNewUniq, applyTypeEnvToId,
31 addOneToIdEnv, growIdEnvList, lookupIdEnv,
32 isNullIdEnv, SYN_IE(IdEnv),
33 GenId{-instances-}, SYN_IE(Id)
35 import Literal ( literalType, isNoRepLit, Literal(..) )
36 import Maybes ( catMaybes, maybeToBool )
38 import Outputable ( PprStyle(..), Outputable(..) )
39 import PprType ( GenType{-instances-}, GenTyVar )
40 import Pretty ( vcat, text )
41 import PrimOp ( primOpType, PrimOp(..) )
42 import SrcLoc ( noSrcLoc )
43 import TyVar ( cloneTyVar,
44 isNullTyVarEnv, addOneToTyVarEnv, SYN_IE(TyVarEnv),
45 SYN_IE(TyVar), GenTyVar
47 import Type ( mkFunTy, mkForAllTy, mkForAllUsageTy, mkTyVarTy,
48 getFunTyExpandingDicts_maybe, applyTy, isPrimType,
49 splitSigmaTy, splitFunTy, eqTy, applyTypeEnvToTy,
52 import TysWiredIn ( trueDataCon, falseDataCon )
53 import Unique ( Unique )
54 import UniqSupply ( initUs, returnUs, thenUs,
55 mapUs, mapAndUnzipUs, getUnique,
56 SYN_IE(UniqSM), UniqSupply
58 import Usage ( SYN_IE(UVar) )
59 import Util ( zipEqual, panic, pprTrace, pprPanic, assertPanic )
62 type TypeEnv = TyVarEnv Type
63 applyUsage = panic "CoreUtils.applyUsage:ToDo"
66 %************************************************************************
68 \subsection{Find the type of a Core atom/expression}
70 %************************************************************************
73 coreExprType :: CoreExpr -> Type
75 coreExprType (Var var) = idType var
76 coreExprType (Lit lit) = literalType lit
78 coreExprType (Let _ body) = coreExprType body
79 coreExprType (SCC _ expr) = coreExprType expr
80 coreExprType (Case _ alts) = coreAltsType alts
82 coreExprType (Coerce _ ty _) = ty -- that's the whole point!
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) =
88 -- pprTrace "appTyArgs" (hsep [ppr PprDebug con, semi,
89 -- ppr PprDebug con_ty, semi,
90 -- ppr PprDebug args]) $
91 applyTypeToArgs con_ty args
93 con_ty = dataConRepType con
95 coreExprType (Prim op args) = applyTypeToArgs (primOpType op) args
97 coreExprType (Lam (ValBinder binder) expr)
98 = idType binder `mkFunTy` coreExprType expr
100 coreExprType (Lam (TyBinder tyvar) expr)
101 = mkForAllTy tyvar (coreExprType expr)
103 coreExprType (Lam (UsageBinder uvar) expr)
104 = mkForAllUsageTy uvar (panic "coreExprType:Lam UsageBinder") (coreExprType expr)
106 coreExprType (App expr (TyArg ty))
108 -- pprTrace "appTy1" (hsep [ppr PprDebug fun_ty, space, ppr PprDebug ty]) $
111 fun_ty = coreExprType expr
113 coreExprType (App expr (UsageArg use))
114 = applyUsage (coreExprType expr) use
116 coreExprType (App expr val_arg)
117 = ASSERT(isValArg val_arg)
119 fun_ty = coreExprType expr
121 case (getFunTyExpandingDicts_maybe False{-no peeking-} fun_ty) of
122 Just (_, result_ty) -> result_ty
124 Nothing -> pprPanic "coreExprType:\n"
125 (vcat [ppr PprDebug fun_ty,
126 ppr PprShowAll (App expr val_arg)])
131 coreAltsType :: CoreCaseAlts -> Type
133 coreAltsType (AlgAlts [] deflt) = default_ty deflt
134 coreAltsType (AlgAlts ((_,_,rhs1):_) _) = coreExprType rhs1
136 coreAltsType (PrimAlts [] deflt) = default_ty deflt
137 coreAltsType (PrimAlts ((_,rhs1):_) _) = coreExprType rhs1
139 default_ty NoDefault = panic "coreExprType:Case:default_ty"
140 default_ty (BindDefault _ rhs) = coreExprType rhs
144 applyTypeToArgs op_ty args = foldl applyTypeToArg op_ty args
146 applyTypeToArg op_ty (TyArg ty) = applyTy op_ty ty
147 applyTypeToArg op_ty (UsageArg _) = panic "applyTypeToArg: UsageArg"
148 applyTypeToArg op_ty val_or_lit_arg = case (getFunTyExpandingDicts_maybe False{-no peeking-} op_ty) of
149 Just (_, res_ty) -> res_ty
152 coreExprCc gets the cost centre enclosing an expression, if any.
153 It looks inside lambdas because (scc "foo" \x.e) = \x.scc "foo" e
156 coreExprCc :: GenCoreExpr val_bdr val_occ tyvar uvar -> CostCentre
157 coreExprCc (SCC cc e) = cc
158 coreExprCc (Lam _ e) = coreExprCc e
159 coreExprCc other = noCostCentre
162 %************************************************************************
164 \subsection{Routines to manufacture bits of @CoreExpr@}
166 %************************************************************************
169 mkCoreIfThenElse (Var bool) then_expr else_expr
170 | bool == trueDataCon = then_expr
171 | bool == falseDataCon = else_expr
173 mkCoreIfThenElse guard then_expr else_expr
175 (AlgAlts [ (trueDataCon, [], then_expr),
176 (falseDataCon, [], else_expr) ]
180 For making @Apps@ and @Lets@, we must take appropriate evasive
181 action if the thing being bound has unboxed type. @mkCoApp@ requires
182 a name supply to do its work.
184 @mkCoApps@, @mkCoCon@ and @mkCoPrim@ also handle the
185 arguments-must-be-atoms constraint.
192 mkCoApps :: CoreExpr -> [CoreArgOrExpr] -> UniqSM CoreExpr
193 mkCoCon :: Id -> [CoreArgOrExpr] -> UniqSM CoreExpr
194 mkCoPrim :: PrimOp -> [CoreArgOrExpr] -> UniqSM CoreExpr
196 mkCoApps fun args = co_thing (mkGenApp fun) args
197 mkCoCon con args = co_thing (Con con) args
198 mkCoPrim op args = co_thing (Prim op) args
200 co_thing :: ([CoreArg] -> CoreExpr)
204 co_thing thing arg_exprs
205 = mapAndUnzipUs expr_to_arg arg_exprs `thenUs` \ (args, maybe_binds) ->
206 returnUs (mkCoLetsUnboxedToCase (catMaybes maybe_binds) (thing args))
208 expr_to_arg :: CoreArgOrExpr
209 -> UniqSM (CoreArg, Maybe CoreBinding)
211 expr_to_arg (AnArg arg) = returnUs (arg, Nothing)
212 expr_to_arg (AnExpr (Var v)) = returnUs (VarArg v, Nothing)
213 expr_to_arg (AnExpr (Lit l)) = returnUs (LitArg l, Nothing)
214 expr_to_arg (AnExpr other_expr)
216 e_ty = coreExprType other_expr
218 getUnique `thenUs` \ uniq ->
220 new_var = mkSysLocal SLIT("a") uniq e_ty noSrcLoc
222 returnUs (VarArg new_var, Just (NonRec new_var other_expr))
227 GenCoreArg val_occ tyvar uvar -> GenCoreExpr val_bdr val_occ tyvar uvar
229 argToExpr (VarArg v) = Var v
230 argToExpr (LitArg lit) = Lit lit
233 All the following functions operate on binders, perform a uniform
234 transformation on them; ie. the function @(\ x -> (x,False))@
235 annotates all binders with False.
238 unTagBinders :: GenCoreExpr (Id,tag) bdee tv uv -> GenCoreExpr Id bdee tv uv
239 unTagBinders expr = bop_expr fst expr
241 unTagBindersAlts :: GenCoreCaseAlts (Id,tag) bdee tv uv -> GenCoreCaseAlts Id bdee tv uv
242 unTagBindersAlts alts = bop_alts fst alts
246 bop_expr :: (a -> b) -> GenCoreExpr a bdee tv uv -> GenCoreExpr b bdee tv uv
248 bop_expr f (Var b) = Var b
249 bop_expr f (Lit lit) = Lit lit
250 bop_expr f (Con con args) = Con con args
251 bop_expr f (Prim op args) = Prim op args
252 bop_expr f (Lam binder expr) = Lam (bop_binder f binder) (bop_expr f expr)
253 bop_expr f (App expr arg) = App (bop_expr f expr) arg
254 bop_expr f (SCC label expr) = SCC label (bop_expr f expr)
255 bop_expr f (Coerce c ty e) = Coerce c ty (bop_expr f e)
256 bop_expr f (Let bind expr) = Let (bop_bind f bind) (bop_expr f expr)
257 bop_expr f (Case expr alts) = Case (bop_expr f expr) (bop_alts f alts)
259 bop_binder f (ValBinder v) = ValBinder (f v)
260 bop_binder f (TyBinder t) = TyBinder t
261 bop_binder f (UsageBinder u) = UsageBinder u
263 bop_bind f (NonRec b e) = NonRec (f b) (bop_expr f e)
264 bop_bind f (Rec pairs) = Rec [(f b, bop_expr f e) | (b, e) <- pairs]
266 bop_alts f (AlgAlts alts deflt)
267 = AlgAlts [ (con, [f b | b <- binders], bop_expr f e)
268 | (con, binders, e) <- alts ]
271 bop_alts f (PrimAlts alts deflt)
272 = PrimAlts [ (lit, bop_expr f e) | (lit, e) <- alts ]
275 bop_deflt f (NoDefault) = NoDefault
276 bop_deflt f (BindDefault b expr) = BindDefault (f b) (bop_expr f expr)
279 OLD (but left here because of the nice example): @singleAlt@ checks
280 whether a bunch of case alternatives is actually just one alternative.
281 It specifically {\em ignores} alternatives which consist of just a
282 call to @error@, because they won't result in any code duplication.
286 case (case <something> of
288 False -> error "Foo") of
294 True -> case <rhs> of
296 False -> case error "Foo" of
302 True -> case <rhs> of
306 Notice that the \tr{<alts>} don't get duplicated.
309 nonErrorRHSs :: GenCoreCaseAlts a Id TyVar UVar -> [GenCoreExpr a Id TyVar UVar]
312 = filter not_error_app (find_rhss alts)
314 find_rhss (AlgAlts as deflt) = [rhs | (_,_,rhs) <- as] ++ deflt_rhs deflt
315 find_rhss (PrimAlts as deflt) = [rhs | (_,rhs) <- as] ++ deflt_rhs deflt
317 deflt_rhs NoDefault = []
318 deflt_rhs (BindDefault _ rhs) = [rhs]
321 = case (maybeErrorApp rhs Nothing) of
326 maybeErrorApp checks whether an expression is of the form
332 Just (error ty' args)
334 where ty' is supplied as an argument to maybeErrorApp.
336 Here's where it is useful:
338 case (error ty "Foo" e1 e2) of <alts>
342 where ty' is the type of any of the alternatives. You might think
343 this never occurs, but see the comments on the definition of
346 Note: we *avoid* the case where ty' might end up as a primitive type:
347 this is very uncool (totally wrong).
349 NOTICE: in the example above we threw away e1 and e2, but not the
350 string "Foo". How did we know to do that?
352 Answer: for now anyway, we only handle the case of a function whose
355 bottomingFn :: forall a. t1 -> ... -> tn -> a
356 ^---------------------^ NB!
358 Furthermore, we only count a bottomingApp if the function is applied
359 to more than n args. If so, we transform:
361 bottomingFn ty e1 ... en en+1 ... em
363 bottomingFn ty' e1 ... en
365 That is, we discard en+1 .. em
369 :: GenCoreExpr a Id TyVar UVar -- Expr to look at
370 -> Maybe Type -- Just ty => a result type *already cloned*;
371 -- Nothing => don't know result ty; we
372 -- *pretend* that the result ty won't be
373 -- primitive -- somebody later must
375 -> Maybe (GenCoreExpr b Id TyVar UVar)
377 maybeErrorApp expr result_ty_maybe
378 = case (collectArgs expr) of
379 (Var fun, [{-no usage???-}], [ty], other_args)
381 && maybeToBool result_ty_maybe -- we *know* the result type
382 -- (otherwise: live a fairy-tale existence...)
383 && not (isPrimType result_ty) ->
385 case (splitSigmaTy (idType fun)) of
386 ([tyvar], [], tau_ty) ->
387 case (splitFunTy tau_ty) of { (arg_tys, res_ty) ->
389 n_args_to_keep = length arg_tys
390 args_to_keep = take n_args_to_keep other_args
392 if (res_ty `eqTy` mkTyVarTy tyvar)
393 && n_args_to_keep <= length other_args
395 -- Phew! We're in business
396 Just (mkGenApp (Var fun) (TyArg result_ty : args_to_keep))
401 other -> Nothing -- Function type wrong shape
404 Just result_ty = result_ty_maybe
408 squashableDictishCcExpr :: CostCentre -> GenCoreExpr a b c d -> Bool
410 squashableDictishCcExpr cc expr
411 = if not (isDictCC cc) then
412 False -- that was easy...
414 squashable expr -- note: quite like the "atomic_rhs" stuff in simplifier
416 squashable (Var _) = True
417 squashable (Con _ _) = True -- I think so... WDP 94/09
418 squashable (Prim _ _) = True -- ditto
420 | notValArg a = squashable f
421 squashable other = False
424 %************************************************************************
426 \subsection{Core-renaming utils}
428 %************************************************************************
431 substCoreBindings :: ValEnv
432 -> TypeEnv -- TyVar=>Type
434 -> UniqSM [CoreBinding]
436 substCoreExpr :: ValEnv
437 -> TypeEnv -- TyVar=>Type
441 substCoreBindings venv tenv binds
442 -- if the envs are empty, then avoid doing anything
443 = if (isNullIdEnv venv && isNullTyVarEnv tenv) then
446 do_CoreBindings venv tenv binds
448 substCoreExpr venv tenv expr
449 = if (isNullIdEnv venv && isNullTyVarEnv tenv) then
452 do_CoreExpr venv tenv expr
455 The equiv code for @Types@ is in @TyUtils@.
457 Because binders aren't necessarily unique: we don't do @plusEnvs@
458 (which check for duplicates); rather, we use the shadowing version,
459 @growIdEnv@ (and shorthand @addOneToIdEnv@).
461 @do_CoreBindings@ takes into account the semantics of a list of
462 @CoreBindings@---things defined early in the list are visible later in
463 the list, but not vice versa.
466 type ValEnv = IdEnv CoreExpr
468 do_CoreBindings :: ValEnv
471 -> UniqSM [CoreBinding]
473 do_CoreBinding :: ValEnv
476 -> UniqSM (CoreBinding, ValEnv)
478 do_CoreBindings venv tenv [] = returnUs []
479 do_CoreBindings venv tenv (b:bs)
480 = do_CoreBinding venv tenv b `thenUs` \ (new_b, new_venv) ->
481 do_CoreBindings new_venv tenv bs `thenUs` \ new_bs ->
482 returnUs (new_b : new_bs)
484 do_CoreBinding venv tenv (NonRec binder rhs)
485 = do_CoreExpr venv tenv rhs `thenUs` \ new_rhs ->
487 dup_binder tenv binder `thenUs` \ (new_binder, (old, new)) ->
488 -- now plug new bindings into envs
489 let new_venv = addOneToIdEnv venv old new in
491 returnUs (NonRec new_binder new_rhs, new_venv)
493 do_CoreBinding venv tenv (Rec binds)
494 = -- for letrec, we plug in new bindings BEFORE cloning rhss
495 mapAndUnzipUs (dup_binder tenv) binders `thenUs` \ (new_binders, new_maps) ->
496 let new_venv = growIdEnvList venv new_maps in
498 mapUs (do_CoreExpr new_venv tenv) rhss `thenUs` \ new_rhss ->
499 returnUs (Rec (zipEqual "do_CoreBinding" new_binders new_rhss), new_venv)
501 (binders, rhss) = unzip binds
508 -> UniqSM CoreArgOrExpr
510 do_CoreArg venv tenv a@(VarArg v)
512 case (lookupIdEnv venv v) of
514 Just expr -> AnExpr expr
517 do_CoreArg venv tenv (TyArg ty)
518 = returnUs (AnArg (TyArg (applyTypeEnvToTy tenv ty)))
520 do_CoreArg venv tenv other_arg = returnUs (AnArg other_arg)
524 do_CoreExpr :: ValEnv
529 do_CoreExpr venv tenv orig_expr@(Var var)
531 case (lookupIdEnv venv var) of
532 Nothing -> --false:ASSERT(toplevelishId var) (SIGH)
537 do_CoreExpr venv tenv e@(Lit _) = returnUs e
539 do_CoreExpr venv tenv (Con con as)
540 = mapUs (do_CoreArg venv tenv) as `thenUs` \ new_as ->
543 do_CoreExpr venv tenv (Prim op as)
544 = mapUs (do_CoreArg venv tenv) as `thenUs` \ new_as ->
545 do_PrimOp op `thenUs` \ new_op ->
546 mkCoPrim new_op new_as
548 do_PrimOp (CCallOp label is_asm may_gc arg_tys result_ty)
550 new_arg_tys = map (applyTypeEnvToTy tenv) arg_tys
551 new_result_ty = applyTypeEnvToTy tenv result_ty
553 returnUs (CCallOp label is_asm may_gc new_arg_tys new_result_ty)
555 do_PrimOp other_op = returnUs other_op
557 do_CoreExpr venv tenv (Lam (ValBinder binder) expr)
558 = dup_binder tenv binder `thenUs` \(new_binder, (old,new)) ->
559 let new_venv = addOneToIdEnv venv old new in
560 do_CoreExpr new_venv tenv expr `thenUs` \ new_expr ->
561 returnUs (Lam (ValBinder new_binder) new_expr)
563 do_CoreExpr venv tenv (Lam (TyBinder tyvar) expr)
564 = dup_tyvar tyvar `thenUs` \ (new_tyvar, (old, new)) ->
566 new_tenv = addOneToTyVarEnv tenv old new
568 do_CoreExpr venv new_tenv expr `thenUs` \ new_expr ->
569 returnUs (Lam (TyBinder new_tyvar) new_expr)
571 do_CoreExpr venv tenv (Lam _ expr) = panic "CoreUtils.do_CoreExpr:Lam UsageBinder"
573 do_CoreExpr venv tenv (App expr arg)
574 = do_CoreExpr venv tenv expr `thenUs` \ new_expr ->
575 do_CoreArg venv tenv arg `thenUs` \ new_arg ->
576 mkCoApps new_expr [new_arg] -- ToDo: more efficiently?
578 do_CoreExpr venv tenv (Case expr alts)
579 = do_CoreExpr venv tenv expr `thenUs` \ new_expr ->
580 do_alts venv tenv alts `thenUs` \ new_alts ->
581 returnUs (Case new_expr new_alts)
583 do_alts venv tenv (AlgAlts alts deflt)
584 = mapUs (do_boxed_alt venv tenv) alts `thenUs` \ new_alts ->
585 do_default venv tenv deflt `thenUs` \ new_deflt ->
586 returnUs (AlgAlts new_alts new_deflt)
588 do_boxed_alt venv tenv (con, binders, expr)
589 = mapAndUnzipUs (dup_binder tenv) binders `thenUs` \ (new_binders, new_vmaps) ->
590 let new_venv = growIdEnvList venv new_vmaps in
591 do_CoreExpr new_venv tenv expr `thenUs` \ new_expr ->
592 returnUs (con, new_binders, new_expr)
595 do_alts venv tenv (PrimAlts alts deflt)
596 = mapUs (do_unboxed_alt venv tenv) alts `thenUs` \ new_alts ->
597 do_default venv tenv deflt `thenUs` \ new_deflt ->
598 returnUs (PrimAlts new_alts new_deflt)
600 do_unboxed_alt venv tenv (lit, expr)
601 = do_CoreExpr venv tenv expr `thenUs` \ new_expr ->
602 returnUs (lit, new_expr)
604 do_default venv tenv NoDefault = returnUs NoDefault
606 do_default venv tenv (BindDefault binder expr)
607 = dup_binder tenv binder `thenUs` \ (new_binder, (old, new)) ->
608 let new_venv = addOneToIdEnv venv old new in
609 do_CoreExpr new_venv tenv expr `thenUs` \ new_expr ->
610 returnUs (BindDefault new_binder new_expr)
612 do_CoreExpr venv tenv (Let core_bind expr)
613 = do_CoreBinding venv tenv core_bind `thenUs` \ (new_bind, new_venv) ->
614 -- and do the body of the let
615 do_CoreExpr new_venv tenv expr `thenUs` \ new_expr ->
616 returnUs (Let new_bind new_expr)
618 do_CoreExpr venv tenv (SCC label expr)
619 = do_CoreExpr venv tenv expr `thenUs` \ new_expr ->
620 returnUs (SCC label new_expr)
622 do_CoreExpr venv tenv (Coerce c ty expr)
623 = do_CoreExpr venv tenv expr `thenUs` \ new_expr ->
624 returnUs (Coerce c (applyTypeEnvToTy tenv ty) new_expr)
628 dup_tyvar :: TyVar -> UniqSM (TyVar, (TyVar, Type))
630 = getUnique `thenUs` \ uniq ->
631 let new_tyvar = cloneTyVar tyvar uniq in
632 returnUs (new_tyvar, (tyvar, mkTyVarTy new_tyvar))
634 -- same thing all over again --------------------
636 dup_binder :: TypeEnv -> Id -> UniqSM (Id, (Id, CoreExpr))
638 = if (toplevelishId b) then
639 -- binder is "top-level-ish"; -- it should *NOT* be renamed
640 -- ToDo: it's unsavoury that we return something to heave in env
641 returnUs (b, (b, Var b))
643 else -- otherwise, the full business
644 getUnique `thenUs` \ uniq ->
646 new_b1 = mkIdWithNewUniq b uniq
647 new_b2 = applyTypeEnvToId tenv new_b1
649 returnUs (new_b2, (b, Var new_b2))