diff options
Diffstat (limited to 'compiler/simplCore/Simplify.lhs')
-rw-r--r-- | compiler/simplCore/Simplify.lhs | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/compiler/simplCore/Simplify.lhs b/compiler/simplCore/Simplify.lhs index 4d1717f4ea..9ad7dc79cc 100644 --- a/compiler/simplCore/Simplify.lhs +++ b/compiler/simplCore/Simplify.lhs @@ -45,6 +45,7 @@ import TysPrim ( realWorldStatePrimTy ) import BasicTypes ( TopLevelFlag(..), isTopLevel, RecFlag(..) ) import MonadUtils ( foldlM, mapAccumLM ) import Maybes ( orElse, isNothing ) +import StaticFlags ( opt_AggressivePrimOps ) import Data.List ( mapAccumL ) import Outputable import FastString @@ -477,7 +478,7 @@ prepareRhs top_lvl env0 _ rhs0 go n_val_args env (Var fun) = return (is_exp, env, Var fun) where - is_exp = isExpandableApp fun n_val_args -- The fun a constructor or PAP + is_exp = isConLikeApp fun n_val_args -- The fun a constructor or PAP -- See Note [CONLIKE pragma] in BasicTypes -- The definition of is_exp should match that in -- OccurAnal.occAnalApp @@ -1657,7 +1658,7 @@ check that or (b) the scrutinee is a variable and 'x' is used strictly or - (c) 'x' is not used at all and e is ok-for-speculation + (c) 'x' is not used at all and e certainly terminates For the (c), consider case (case a ># b of { True -> (p,q); False -> (q,p) }) of @@ -1778,18 +1779,21 @@ rebuildCase env scrut case_bndr [(_, bndrs, rhs)] cont -- The case binder is going to be evaluated later, -- and the scrutinee is a simple variable - || (is_plain_seq && ok_for_spec) + || (is_plain_seq && expr_terminates) -- Note: not the same as exprIsHNF elim_unlifted - | is_plain_seq = exprOkForSideEffects scrut - -- The entire case is dead, so we can drop it, - -- _unless_ the scrutinee has side effects - | otherwise = exprOkForSpeculation scrut + | is_plain_seq + = if opt_AggressivePrimOps then expr_terminates + else exprOkForSideEffects scrut + -- The entire case is dead, so we can drop it + -- But if AggressivePrimOps isn't on, only drop it + -- if it has no side effects + | otherwise = exprOkForSpeculation scrut -- The case-binder is alive, but we may be able -- turn the case into a let, if the expression is ok-for-spec - ok_for_spec = exprOkForSpeculation scrut + expr_terminates = exprCertainlyTerminates scrut is_plain_seq = isDeadBinder case_bndr -- Evaluation *only* for effect strict_case_bndr = isStrictDmd (idDemandInfo case_bndr) |