-`%
+%
% (c) The AQUA Project, Glasgow University, 1994-1996
%
\section[SimplCase]{Simplification of `case' expression}
import TysPrim ( voidTy )
import Util ( Eager, runEager, appEager,
isIn, isSingleton, zipEqual, panic, assertPanic )
+import Outputable
\end{code}
Float let out of case.
\begin{code}
simplCase :: SimplEnv
- -> InExpr -- Scrutinee
- -> InAlts -- Alternatives
+ -> InExpr -- Scrutinee
+ -> (SubstEnvs, InAlts) -- Alternatives, and their static environment
-> (SimplEnv -> InExpr -> SmplM OutExpr) -- Rhs handler
-> OutType -- Type of result expression
-> SmplM OutExpr
\begin{code}
-simplCase env (Case inner_scrut inner_alts) outer_alts rhs_c result_ty
+simplCase env (Case inner_scrut inner_alts) (subst_envs, outer_alts) rhs_c result_ty
| switchIsSet env SimplCaseOfCase
= -- Ha! Do case-of-case
tick CaseOfCase `thenSmpl_`
if no_need_to_bind_large_alts
then
- simplCase env inner_scrut inner_alts
- (\env rhs -> simplCase env rhs outer_alts rhs_c result_ty) result_ty
+ simplCase env inner_scrut (getSubstEnvs env, inner_alts)
+ (\env' rhs -> simplCase env' rhs (subst_envs, outer_alts) rhs_c result_ty)
+ result_ty
else
- bindLargeAlts env outer_alts rhs_c result_ty `thenSmpl` \ (extra_bindings, outer_alts') ->
+ bindLargeAlts env_alts outer_alts rhs_c result_ty `thenSmpl` \ (extra_bindings, outer_alts') ->
let
rhs_c' = \env rhs -> simplExpr env rhs [] result_ty
in
- simplCase env inner_scrut inner_alts
- (\env rhs -> simplCase env rhs outer_alts' rhs_c' result_ty)
+ simplCase env inner_scrut (getSubstEnvs env, inner_alts)
+ (\env rhs -> simplCase env rhs (emptySubstEnvs, outer_alts') rhs_c' result_ty)
result_ty
`thenSmpl` \ case_expr ->
returnSmpl (mkCoLetsNoUnboxed extra_bindings case_expr)
where
+ env_alts = setSubstEnvs env subst_envs
+
no_need_to_bind_large_alts = switchIsSet env SimplOkToDupCode ||
isSingleton (nonErrorRHSs inner_alts)
\end{code}
Finally the default case
\begin{code}
-simplCase env other_scrut alts rhs_c result_ty
- = simplTy env scrut_ty `appEager` \ scrut_ty' ->
- simplExpr env' other_scrut [] scrut_ty `thenSmpl` \ scrut' ->
- completeCase env scrut' alts rhs_c
+simplCase env other_scrut (subst_envs, alts) rhs_c result_ty
+ = simplTy env scrut_ty `appEager` \ scrut_ty' ->
+ simplExpr env_scrut other_scrut [] scrut_ty' `thenSmpl` \ scrut' ->
+ completeCase env_alts scrut' alts rhs_c
where
-- When simplifying the scrutinee of a complete case that
-- has no default alternative
- env' = case alts of
+ env_scrut = case alts of
AlgAlts _ NoDefault -> setCaseScrutinee env
PrimAlts _ NoDefault -> setCaseScrutinee env
other -> env
+ env_alts = setSubstEnvs env subst_envs
+
scrut_ty = coreExprType (unTagBinders other_scrut)
\end{code}
info_from_this_case rhs_c
= simplBinder env binder `thenSmpl` \ (env1, binder') ->
let
- env2 = extendEnvGivenUnfolding env1 binder' occ_info info_from_this_case
+ env2 = extendEnvGivenNewRhs env1 scrut_var (Var binder')
-- Add form details for the default binder
- scrut_info = lookupUnfolding env scrut_var
- env3 = extendEnvGivenUnfolding env2 binder' occ_info scrut_info
- new_env = extendEnvGivenNewRhs env3 scrut_var (Var binder')
+ scrut_unf = lookupUnfolding env scrut_var
+ new_env = extendEnvGivenUnfolding env2 binder' noBinderInfo scrut_unf
+ -- Use noBinderInfo rather than occ_info because we've
+ -- added more occurrences by binding the scrut_var to it
in
rhs_c new_env rhs `thenSmpl` \ rhs' ->
returnSmpl (BindDefault binder' rhs')
-> (SimplEnv -> InExpr -> SmplM OutExpr) -- Rhs handler
-> SmplM OutExpr
-completeAlgCaseWithKnownCon env con con_args (AlgAlts alts deflt) rhs_c
+completeAlgCaseWithKnownCon env con con_args a@(AlgAlts alts deflt) rhs_c
= ASSERT(isDataCon con)
search_alts alts
where
= -- No matching alternative
case deflt of
NoDefault -> -- Blargh!
- panic "completeAlgCaseWithKnownCon: No matching alternative and no default"
+ pprPanic "completeAlgCaseWithKnownCon: No matching alternative and no default"
+ (ppr con <+> ppr con_args $$ ppr a)
BindDefault binder@(_,occ_info) rhs -> -- OK, there's a default case
-- let-bind the binder to the constructor