InCoercion, OutCoercion,
-- The simplifier mode
- setMode, getMode,
+ setMode, getMode, updMode,
-- Switch checker
SwitchChecker, SwitchResult(..), getSwitchChecker, getSimplIntSwitch,
setMode :: SimplifierMode -> SimplEnv -> SimplEnv
setMode mode env = env { seMode = mode }
+updMode :: (SimplifierMode -> SimplifierMode) -> SimplEnv -> SimplEnv
+updMode upd env = env { seMode = upd (seMode env) }
+
inGentleMode :: SimplEnv -> Bool
inGentleMode env = case seMode env of
SimplGently {} -> True
-- Inlining,
preInlineUnconditionally, postInlineUnconditionally,
activeInline, activeRule,
- simplEnvForGHCi, simplEnvForRules, simplGentlyForInlineRules,
+ simplEnvForGHCi, simplEnvForRules, updModeForInlineRules,
-- The continuation type
SimplCont(..), DupFlag(..), ArgInfo(..),
simplEnvForRules = mkSimplEnv allOffSwitchChecker $
SimplGently { sm_rules = True, sm_inline = False }
-simplGentlyForInlineRules :: SimplifierMode
-simplGentlyForInlineRules = SimplGently { sm_rules = True, sm_inline = True }
+updModeForInlineRules :: SimplifierMode -> SimplifierMode
+updModeForInlineRules mode
+ = case mode of
+ SimplGently {} -> mode -- Don't modify mode if we already gentle
+ SimplPhase {} -> SimplGently { sm_rules = True, sm_inline = True }
-- Simplify as much as possible, subject to the usual "gentle" rules
\end{code}
anything, because the byte-code interpreter might get confused about
unboxed tuples and suchlike.
+Note [RULEs enabled in SimplGently]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+RULES are enabled when doing "gentle" simplification. Two reasons:
+
+ * We really want the class-op cancellation to happen:
+ op (df d1 d2) --> $cop3 d1 d2
+ because this breaks the mutual recursion between 'op' and 'df'
+
+ * I wanted the RULE
+ lift String ===> ...
+ to work in Template Haskell when simplifying
+ splices, so we get simpler code for literal strings
+
Note [Simplifying gently inside InlineRules]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We don't do much simplification inside InlineRules (which come from
| otherwise
= case getMode env of
SimplGently { sm_rules = rules_on }
- | rules_on -> Just isEarlyActive
+ | rules_on -> Just isEarlyActive -- Note [RULEs enabled in SimplGently]
| otherwise -> Nothing
- -- Used to be Nothing (no rules in gentle mode)
- -- Main motivation for changing is that I wanted
- -- lift String ===> ...
- -- to work in Template Haskell when simplifying
- -- splices, so we get simpler code for literal strings
SimplPhase n _ -> Just (isActive n)
\end{code}
simplUnfolding env top_lvl _ _ _
(CoreUnfolding { uf_tmpl = expr, uf_arity = arity
, uf_guidance = guide@(InlineRule {}) })
- = do { expr' <- simplExpr (setMode simplGentlyForInlineRules env) expr
+ = do { expr' <- simplExpr (updMode updModeForInlineRules env) expr
-- See Note [Simplifying gently inside InlineRules] in SimplUtils
; let mb_wkr' = CoreSubst.substInlineRuleInfo (mkCoreSubst env) (ir_info guide)
; return (mkCoreUnfolding (isTopLevel top_lvl) expr' arity