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
24 IMPORT_DELOOPER(IdLoop) -- for pananoia-checking purposes
28 import CostCentre ( isDictCC, CostCentre, noCostCentre )
29 import Id ( idType, mkSysLocal, isBottomingId,
30 toplevelishId, mkIdWithNewUniq, applyTypeEnvToId,
32 addOneToIdEnv, growIdEnvList, lookupIdEnv,
33 isNullIdEnv, SYN_IE(IdEnv),
36 import Literal ( literalType, isNoRepLit, Literal(..) )
37 import Maybes ( catMaybes, maybeToBool )
39 import PprStyle ( PprStyle(..) )
40 import PprType ( GenType{-instances-} )
41 import Pretty ( vcat, text )
42 import PrimOp ( primOpType, PrimOp(..) )
43 import SrcLoc ( noSrcLoc )
44 import TyVar ( cloneTyVar,
45 isNullTyVarEnv, addOneToTyVarEnv, SYN_IE(TyVarEnv),
48 import Type ( mkFunTy, mkForAllTy, mkForAllUsageTy, mkTyVarTy,
49 getFunTyExpandingDicts_maybe, applyTy, isPrimType,
50 splitSigmaTy, splitFunTy, eqTy, applyTypeEnvToTy,
53 import TysWiredIn ( trueDataCon, falseDataCon )
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 )
61 import Outputable ( Outputable(..) )
63 type TypeEnv = TyVarEnv Type
64 applyUsage = panic "CoreUtils.applyUsage:ToDo"
67 %************************************************************************
69 \subsection{Find the type of a Core atom/expression}
71 %************************************************************************
74 coreExprType :: CoreExpr -> Type
76 coreExprType (Var var) = idType var
77 coreExprType (Lit lit) = literalType lit
79 coreExprType (Let _ body) = coreExprType body
80 coreExprType (SCC _ expr) = coreExprType expr
81 coreExprType (Case _ alts) = coreAltsType alts
83 coreExprType (Coerce _ ty _) = ty -- that's the whole point!
85 -- a Con is a fully-saturated application of a data constructor
86 -- a Prim is <ditto> of a PrimOp
88 coreExprType (Con con args) =
89 -- pprTrace "appTyArgs" (hsep [ppr PprDebug con, semi,
90 -- ppr PprDebug con_ty, semi,
91 -- ppr PprDebug args]) $
92 applyTypeToArgs con_ty args
94 con_ty = dataConRepType con
96 coreExprType (Prim op args) = applyTypeToArgs (primOpType op) args
98 coreExprType (Lam (ValBinder binder) expr)
99 = idType binder `mkFunTy` coreExprType expr
101 coreExprType (Lam (TyBinder tyvar) expr)
102 = mkForAllTy tyvar (coreExprType expr)
104 coreExprType (Lam (UsageBinder uvar) expr)
105 = mkForAllUsageTy uvar (panic "coreExprType:Lam UsageBinder") (coreExprType expr)
107 coreExprType (App expr (TyArg ty))
109 -- pprTrace "appTy1" (hsep [ppr PprDebug fun_ty, space, ppr PprDebug ty]) $
112 fun_ty = coreExprType expr
114 coreExprType (App expr (UsageArg use))
115 = applyUsage (coreExprType expr) use
117 coreExprType (App expr val_arg)
118 = ASSERT(isValArg val_arg)
120 fun_ty = coreExprType expr
122 case (getFunTyExpandingDicts_maybe False{-no peeking-} fun_ty) of
123 Just (_, result_ty) -> result_ty
125 Nothing -> pprPanic "coreExprType:\n"
126 (vcat [ppr PprDebug fun_ty,
127 ppr PprShowAll (App expr val_arg)])
132 coreAltsType :: CoreCaseAlts -> Type
134 coreAltsType (AlgAlts [] deflt) = default_ty deflt
135 coreAltsType (AlgAlts ((_,_,rhs1):_) _) = coreExprType rhs1
137 coreAltsType (PrimAlts [] deflt) = default_ty deflt
138 coreAltsType (PrimAlts ((_,rhs1):_) _) = coreExprType rhs1
140 default_ty NoDefault = panic "coreExprType:Case:default_ty"
141 default_ty (BindDefault _ rhs) = coreExprType rhs
145 applyTypeToArgs op_ty args = foldl applyTypeToArg op_ty args
147 applyTypeToArg op_ty (TyArg ty) = applyTy op_ty ty
148 applyTypeToArg op_ty (UsageArg _) = panic "applyTypeToArg: UsageArg"
149 applyTypeToArg op_ty val_or_lit_arg = case (getFunTyExpandingDicts_maybe False{-no peeking-} op_ty) of
150 Just (_, res_ty) -> res_ty
153 coreExprCc gets the cost centre enclosing an expression, if any.
154 It looks inside lambdas because (scc "foo" \x.e) = \x.scc "foo" e
157 coreExprCc :: GenCoreExpr val_bdr val_occ tyvar uvar -> CostCentre
158 coreExprCc (SCC cc e) = cc
159 coreExprCc (Lam _ e) = coreExprCc e
160 coreExprCc other = noCostCentre
163 %************************************************************************
165 \subsection{Routines to manufacture bits of @CoreExpr@}
167 %************************************************************************
170 mkCoreIfThenElse (Var bool) then_expr else_expr
171 | bool == trueDataCon = then_expr
172 | bool == falseDataCon = else_expr
174 mkCoreIfThenElse guard then_expr else_expr
176 (AlgAlts [ (trueDataCon, [], then_expr),
177 (falseDataCon, [], else_expr) ]
181 For making @Apps@ and @Lets@, we must take appropriate evasive
182 action if the thing being bound has unboxed type. @mkCoApp@ requires
183 a name supply to do its work.
185 @mkCoApps@, @mkCoCon@ and @mkCoPrim@ also handle the
186 arguments-must-be-atoms constraint.
193 mkCoApps :: CoreExpr -> [CoreArgOrExpr] -> UniqSM CoreExpr
194 mkCoCon :: Id -> [CoreArgOrExpr] -> UniqSM CoreExpr
195 mkCoPrim :: PrimOp -> [CoreArgOrExpr] -> UniqSM CoreExpr
197 mkCoApps fun args = co_thing (mkGenApp fun) args
198 mkCoCon con args = co_thing (Con con) args
199 mkCoPrim op args = co_thing (Prim op) args
201 co_thing :: ([CoreArg] -> CoreExpr)
205 co_thing thing arg_exprs
206 = mapAndUnzipUs expr_to_arg arg_exprs `thenUs` \ (args, maybe_binds) ->
207 returnUs (mkCoLetsUnboxedToCase (catMaybes maybe_binds) (thing args))
209 expr_to_arg :: CoreArgOrExpr
210 -> UniqSM (CoreArg, Maybe CoreBinding)
212 expr_to_arg (AnArg arg) = returnUs (arg, Nothing)
213 expr_to_arg (AnExpr (Var v)) = returnUs (VarArg v, Nothing)
214 expr_to_arg (AnExpr (Lit l)) = returnUs (LitArg l, Nothing)
215 expr_to_arg (AnExpr other_expr)
217 e_ty = coreExprType other_expr
219 getUnique `thenUs` \ uniq ->
221 new_var = mkSysLocal SLIT("a") uniq e_ty noSrcLoc
223 returnUs (VarArg new_var, Just (NonRec new_var other_expr))
228 GenCoreArg val_occ tyvar uvar -> GenCoreExpr val_bdr val_occ tyvar uvar
230 argToExpr (VarArg v) = Var v
231 argToExpr (LitArg lit) = Lit lit
234 All the following functions operate on binders, perform a uniform
235 transformation on them; ie. the function @(\ x -> (x,False))@
236 annotates all binders with False.
239 unTagBinders :: GenCoreExpr (Id,tag) bdee tv uv -> GenCoreExpr Id bdee tv uv
240 unTagBinders expr = bop_expr fst expr
242 unTagBindersAlts :: GenCoreCaseAlts (Id,tag) bdee tv uv -> GenCoreCaseAlts Id bdee tv uv
243 unTagBindersAlts alts = bop_alts fst alts
247 bop_expr :: (a -> b) -> GenCoreExpr a bdee tv uv -> GenCoreExpr b bdee tv uv
249 bop_expr f (Var b) = Var b
250 bop_expr f (Lit lit) = Lit lit
251 bop_expr f (Con con args) = Con con args
252 bop_expr f (Prim op args) = Prim op args
253 bop_expr f (Lam binder expr) = Lam (bop_binder f binder) (bop_expr f expr)
254 bop_expr f (App expr arg) = App (bop_expr f expr) arg
255 bop_expr f (SCC label expr) = SCC label (bop_expr f expr)
256 bop_expr f (Coerce c ty e) = Coerce c ty (bop_expr f e)
257 bop_expr f (Let bind expr) = Let (bop_bind f bind) (bop_expr f expr)
258 bop_expr f (Case expr alts) = Case (bop_expr f expr) (bop_alts f alts)
260 bop_binder f (ValBinder v) = ValBinder (f v)
261 bop_binder f (TyBinder t) = TyBinder t
262 bop_binder f (UsageBinder u) = UsageBinder u
264 bop_bind f (NonRec b e) = NonRec (f b) (bop_expr f e)
265 bop_bind f (Rec pairs) = Rec [(f b, bop_expr f e) | (b, e) <- pairs]
267 bop_alts f (AlgAlts alts deflt)
268 = AlgAlts [ (con, [f b | b <- binders], bop_expr f e)
269 | (con, binders, e) <- alts ]
272 bop_alts f (PrimAlts alts deflt)
273 = PrimAlts [ (lit, bop_expr f e) | (lit, e) <- alts ]
276 bop_deflt f (NoDefault) = NoDefault
277 bop_deflt f (BindDefault b expr) = BindDefault (f b) (bop_expr f expr)
280 OLD (but left here because of the nice example): @singleAlt@ checks
281 whether a bunch of case alternatives is actually just one alternative.
282 It specifically {\em ignores} alternatives which consist of just a
283 call to @error@, because they won't result in any code duplication.
287 case (case <something> of
289 False -> error "Foo") of
295 True -> case <rhs> of
297 False -> case error "Foo" of
303 True -> case <rhs> of
307 Notice that the \tr{<alts>} don't get duplicated.
310 nonErrorRHSs :: GenCoreCaseAlts a Id TyVar UVar -> [GenCoreExpr a Id TyVar UVar]
313 = filter not_error_app (find_rhss alts)
315 find_rhss (AlgAlts as deflt) = [rhs | (_,_,rhs) <- as] ++ deflt_rhs deflt
316 find_rhss (PrimAlts as deflt) = [rhs | (_,rhs) <- as] ++ deflt_rhs deflt
318 deflt_rhs NoDefault = []
319 deflt_rhs (BindDefault _ rhs) = [rhs]
322 = case (maybeErrorApp rhs Nothing) of
327 maybeErrorApp checks whether an expression is of the form
333 Just (error ty' args)
335 where ty' is supplied as an argument to maybeErrorApp.
337 Here's where it is useful:
339 case (error ty "Foo" e1 e2) of <alts>
343 where ty' is the type of any of the alternatives. You might think
344 this never occurs, but see the comments on the definition of
347 Note: we *avoid* the case where ty' might end up as a primitive type:
348 this is very uncool (totally wrong).
350 NOTICE: in the example above we threw away e1 and e2, but not the
351 string "Foo". How did we know to do that?
353 Answer: for now anyway, we only handle the case of a function whose
356 bottomingFn :: forall a. t1 -> ... -> tn -> a
357 ^---------------------^ NB!
359 Furthermore, we only count a bottomingApp if the function is applied
360 to more than n args. If so, we transform:
362 bottomingFn ty e1 ... en en+1 ... em
364 bottomingFn ty' e1 ... en
366 That is, we discard en+1 .. em
370 :: GenCoreExpr a Id TyVar UVar -- Expr to look at
371 -> Maybe Type -- Just ty => a result type *already cloned*;
372 -- Nothing => don't know result ty; we
373 -- *pretend* that the result ty won't be
374 -- primitive -- somebody later must
376 -> Maybe (GenCoreExpr b Id TyVar UVar)
378 maybeErrorApp expr result_ty_maybe
379 = case (collectArgs expr) of
380 (Var fun, [{-no usage???-}], [ty], other_args)
382 && maybeToBool result_ty_maybe -- we *know* the result type
383 -- (otherwise: live a fairy-tale existence...)
384 && not (isPrimType result_ty) ->
386 case (splitSigmaTy (idType fun)) of
387 ([tyvar], [], tau_ty) ->
388 case (splitFunTy tau_ty) of { (arg_tys, res_ty) ->
390 n_args_to_keep = length arg_tys
391 args_to_keep = take n_args_to_keep other_args
393 if (res_ty `eqTy` mkTyVarTy tyvar)
394 && n_args_to_keep <= length other_args
396 -- Phew! We're in business
397 Just (mkGenApp (Var fun) (TyArg result_ty : args_to_keep))
402 other -> Nothing -- Function type wrong shape
405 Just result_ty = result_ty_maybe
409 squashableDictishCcExpr :: CostCentre -> GenCoreExpr a b c d -> Bool
411 squashableDictishCcExpr cc expr
412 = if not (isDictCC cc) then
413 False -- that was easy...
415 squashable expr -- note: quite like the "atomic_rhs" stuff in simplifier
417 squashable (Var _) = True
418 squashable (Con _ _) = True -- I think so... WDP 94/09
419 squashable (Prim _ _) = True -- ditto
421 | notValArg a = squashable f
422 squashable other = False
425 %************************************************************************
427 \subsection{Core-renaming utils}
429 %************************************************************************
432 substCoreBindings :: ValEnv
433 -> TypeEnv -- TyVar=>Type
435 -> UniqSM [CoreBinding]
437 substCoreExpr :: ValEnv
438 -> TypeEnv -- TyVar=>Type
442 substCoreBindings venv tenv binds
443 -- if the envs are empty, then avoid doing anything
444 = if (isNullIdEnv venv && isNullTyVarEnv tenv) then
447 do_CoreBindings venv tenv binds
449 substCoreExpr venv tenv expr
450 = if (isNullIdEnv venv && isNullTyVarEnv tenv) then
453 do_CoreExpr venv tenv expr
456 The equiv code for @Types@ is in @TyUtils@.
458 Because binders aren't necessarily unique: we don't do @plusEnvs@
459 (which check for duplicates); rather, we use the shadowing version,
460 @growIdEnv@ (and shorthand @addOneToIdEnv@).
462 @do_CoreBindings@ takes into account the semantics of a list of
463 @CoreBindings@---things defined early in the list are visible later in
464 the list, but not vice versa.
467 type ValEnv = IdEnv CoreExpr
469 do_CoreBindings :: ValEnv
472 -> UniqSM [CoreBinding]
474 do_CoreBinding :: ValEnv
477 -> UniqSM (CoreBinding, ValEnv)
479 do_CoreBindings venv tenv [] = returnUs []
480 do_CoreBindings venv tenv (b:bs)
481 = do_CoreBinding venv tenv b `thenUs` \ (new_b, new_venv) ->
482 do_CoreBindings new_venv tenv bs `thenUs` \ new_bs ->
483 returnUs (new_b : new_bs)
485 do_CoreBinding venv tenv (NonRec binder rhs)
486 = do_CoreExpr venv tenv rhs `thenUs` \ new_rhs ->
488 dup_binder tenv binder `thenUs` \ (new_binder, (old, new)) ->
489 -- now plug new bindings into envs
490 let new_venv = addOneToIdEnv venv old new in
492 returnUs (NonRec new_binder new_rhs, new_venv)
494 do_CoreBinding venv tenv (Rec binds)
495 = -- for letrec, we plug in new bindings BEFORE cloning rhss
496 mapAndUnzipUs (dup_binder tenv) binders `thenUs` \ (new_binders, new_maps) ->
497 let new_venv = growIdEnvList venv new_maps in
499 mapUs (do_CoreExpr new_venv tenv) rhss `thenUs` \ new_rhss ->
500 returnUs (Rec (zipEqual "do_CoreBinding" new_binders new_rhss), new_venv)
502 (binders, rhss) = unzip binds
509 -> UniqSM CoreArgOrExpr
511 do_CoreArg venv tenv a@(VarArg v)
513 case (lookupIdEnv venv v) of
515 Just expr -> AnExpr expr
518 do_CoreArg venv tenv (TyArg ty)
519 = returnUs (AnArg (TyArg (applyTypeEnvToTy tenv ty)))
521 do_CoreArg venv tenv other_arg = returnUs (AnArg other_arg)
525 do_CoreExpr :: ValEnv
530 do_CoreExpr venv tenv orig_expr@(Var var)
532 case (lookupIdEnv venv var) of
533 Nothing -> --false:ASSERT(toplevelishId var) (SIGH)
538 do_CoreExpr venv tenv e@(Lit _) = returnUs e
540 do_CoreExpr venv tenv (Con con as)
541 = mapUs (do_CoreArg venv tenv) as `thenUs` \ new_as ->
544 do_CoreExpr venv tenv (Prim op as)
545 = mapUs (do_CoreArg venv tenv) as `thenUs` \ new_as ->
546 do_PrimOp op `thenUs` \ new_op ->
547 mkCoPrim new_op new_as
549 do_PrimOp (CCallOp label is_asm may_gc arg_tys result_ty)
551 new_arg_tys = map (applyTypeEnvToTy tenv) arg_tys
552 new_result_ty = applyTypeEnvToTy tenv result_ty
554 returnUs (CCallOp label is_asm may_gc new_arg_tys new_result_ty)
556 do_PrimOp other_op = returnUs other_op
558 do_CoreExpr venv tenv (Lam (ValBinder binder) expr)
559 = dup_binder tenv binder `thenUs` \(new_binder, (old,new)) ->
560 let new_venv = addOneToIdEnv venv old new in
561 do_CoreExpr new_venv tenv expr `thenUs` \ new_expr ->
562 returnUs (Lam (ValBinder new_binder) new_expr)
564 do_CoreExpr venv tenv (Lam (TyBinder tyvar) expr)
565 = dup_tyvar tyvar `thenUs` \ (new_tyvar, (old, new)) ->
567 new_tenv = addOneToTyVarEnv tenv old new
569 do_CoreExpr venv new_tenv expr `thenUs` \ new_expr ->
570 returnUs (Lam (TyBinder new_tyvar) new_expr)
572 do_CoreExpr venv tenv (Lam _ expr) = panic "CoreUtils.do_CoreExpr:Lam UsageBinder"
574 do_CoreExpr venv tenv (App expr arg)
575 = do_CoreExpr venv tenv expr `thenUs` \ new_expr ->
576 do_CoreArg venv tenv arg `thenUs` \ new_arg ->
577 mkCoApps new_expr [new_arg] -- ToDo: more efficiently?
579 do_CoreExpr venv tenv (Case expr alts)
580 = do_CoreExpr venv tenv expr `thenUs` \ new_expr ->
581 do_alts venv tenv alts `thenUs` \ new_alts ->
582 returnUs (Case new_expr new_alts)
584 do_alts venv tenv (AlgAlts alts deflt)
585 = mapUs (do_boxed_alt venv tenv) alts `thenUs` \ new_alts ->
586 do_default venv tenv deflt `thenUs` \ new_deflt ->
587 returnUs (AlgAlts new_alts new_deflt)
589 do_boxed_alt venv tenv (con, binders, expr)
590 = mapAndUnzipUs (dup_binder tenv) binders `thenUs` \ (new_binders, new_vmaps) ->
591 let new_venv = growIdEnvList venv new_vmaps in
592 do_CoreExpr new_venv tenv expr `thenUs` \ new_expr ->
593 returnUs (con, new_binders, new_expr)
596 do_alts venv tenv (PrimAlts alts deflt)
597 = mapUs (do_unboxed_alt venv tenv) alts `thenUs` \ new_alts ->
598 do_default venv tenv deflt `thenUs` \ new_deflt ->
599 returnUs (PrimAlts new_alts new_deflt)
601 do_unboxed_alt venv tenv (lit, expr)
602 = do_CoreExpr venv tenv expr `thenUs` \ new_expr ->
603 returnUs (lit, new_expr)
605 do_default venv tenv NoDefault = returnUs NoDefault
607 do_default venv tenv (BindDefault binder expr)
608 = dup_binder tenv binder `thenUs` \ (new_binder, (old, new)) ->
609 let new_venv = addOneToIdEnv venv old new in
610 do_CoreExpr new_venv tenv expr `thenUs` \ new_expr ->
611 returnUs (BindDefault new_binder new_expr)
613 do_CoreExpr venv tenv (Let core_bind expr)
614 = do_CoreBinding venv tenv core_bind `thenUs` \ (new_bind, new_venv) ->
615 -- and do the body of the let
616 do_CoreExpr new_venv tenv expr `thenUs` \ new_expr ->
617 returnUs (Let new_bind new_expr)
619 do_CoreExpr venv tenv (SCC label expr)
620 = do_CoreExpr venv tenv expr `thenUs` \ new_expr ->
621 returnUs (SCC label new_expr)
623 do_CoreExpr venv tenv (Coerce c ty expr)
624 = do_CoreExpr venv tenv expr `thenUs` \ new_expr ->
625 returnUs (Coerce c (applyTypeEnvToTy tenv ty) new_expr)
629 dup_tyvar :: TyVar -> UniqSM (TyVar, (TyVar, Type))
631 = getUnique `thenUs` \ uniq ->
632 let new_tyvar = cloneTyVar tyvar uniq in
633 returnUs (new_tyvar, (tyvar, mkTyVarTy new_tyvar))
635 -- same thing all over again --------------------
637 dup_binder :: TypeEnv -> Id -> UniqSM (Id, (Id, CoreExpr))
639 = if (toplevelishId b) then
640 -- binder is "top-level-ish"; -- it should *NOT* be renamed
641 -- ToDo: it's unsavoury that we return something to heave in env
642 returnUs (b, (b, Var b))
644 else -- otherwise, the full business
645 getUnique `thenUs` \ uniq ->
647 new_b1 = mkIdWithNewUniq b uniq
648 new_b2 = applyTypeEnvToId tenv new_b1
650 returnUs (new_b2, (b, Var new_b2))