summaryrefslogtreecommitdiff
path: root/compiler/simplCore
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/simplCore')
-rw-r--r--compiler/simplCore/OccurAnal.hs2
-rw-r--r--compiler/simplCore/SetLevels.hs2
-rw-r--r--compiler/simplCore/SimplCore.hs12
-rw-r--r--compiler/simplCore/SimplUtils.hs66
-rw-r--r--compiler/simplCore/Simplify.hs18
5 files changed, 56 insertions, 44 deletions
diff --git a/compiler/simplCore/OccurAnal.hs b/compiler/simplCore/OccurAnal.hs
index 1e086027ba..1e485aee1e 100644
--- a/compiler/simplCore/OccurAnal.hs
+++ b/compiler/simplCore/OccurAnal.hs
@@ -253,7 +253,7 @@ always in scope.
* Note [Rule dependency info]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The VarSet in a SpecInfo is used for dependency analysis in the
+ The VarSet in a RuleInfo is used for dependency analysis in the
occurrence analyser. We must track free vars in *both* lhs and rhs.
Hence use of idRuleVars, rather than idRuleRhsVars in occAnalBind.
Why both? Consider
diff --git a/compiler/simplCore/SetLevels.hs b/compiler/simplCore/SetLevels.hs
index de02e27c2b..d873cc5e15 100644
--- a/compiler/simplCore/SetLevels.hs
+++ b/compiler/simplCore/SetLevels.hs
@@ -1015,7 +1015,7 @@ abstractVars dest_lvl (LE { le_subst = subst, le_lvl_env = lvl_env }) in_fvs
-- We are going to lambda-abstract, so nuke any IdInfo,
-- and add the tyvars of the Id (if necessary)
zap v | isId v = WARN( isStableUnfolding (idUnfolding v) ||
- not (isEmptySpecInfo (idSpecialisation v)),
+ not (isEmptyRuleInfo (idSpecialisation v)),
text "absVarsOf: discarding info on" <+> ppr v )
setIdInfo v vanillaIdInfo
| otherwise = v
diff --git a/compiler/simplCore/SimplCore.hs b/compiler/simplCore/SimplCore.hs
index 90233d608a..dddb24d335 100644
--- a/compiler/simplCore/SimplCore.hs
+++ b/compiler/simplCore/SimplCore.hs
@@ -15,7 +15,7 @@ import CoreSyn
import HscTypes
import CSE ( cseProgram )
import Rules ( mkRuleBase, unionRuleBase,
- extendRuleBaseList, ruleCheckProgram, addSpecInfo, )
+ extendRuleBaseList, ruleCheckProgram, addRuleInfo, )
import PprCore ( pprCoreBindings, pprCoreExpr )
import OccurAnal ( occurAnalysePgm, occurAnalyseExpr )
import IdInfo
@@ -871,7 +871,7 @@ shortOutIndirections binds
-- These exported Ids are the subjects of the indirection-elimination
exp_ids = map fst $ varEnvElts ind_env
exp_id_set = mkVarSet exp_ids
- no_need_to_flatten = all (null . specInfoRules . idSpecialisation) exp_ids
+ no_need_to_flatten = all (null . ruleInfoRules . idSpecialisation) exp_ids
binds' = concatMap zap binds
zap (NonRec bndr rhs) = [NonRec b r | (b,r) <- zapPair (bndr,rhs)]
@@ -929,7 +929,7 @@ hasShortableIdInfo :: Id -> Bool
-- so we can safely discard it
-- See Note [Messing up the exported Id's IdInfo]
hasShortableIdInfo id
- = isEmptySpecInfo (specInfo info)
+ = isEmptyRuleInfo (ruleInfo info)
&& isDefaultInlinePragma (inlinePragInfo info)
&& not (isStableUnfolding (unfoldingInfo info))
where
@@ -951,8 +951,8 @@ transferIdInfo exported_id local_id
transfer exp_info = exp_info `setStrictnessInfo` strictnessInfo local_info
`setUnfoldingInfo` unfoldingInfo local_info
`setInlinePragInfo` inlinePragInfo local_info
- `setSpecInfo` addSpecInfo (specInfo exp_info) new_info
- new_info = setSpecInfoHead (idName exported_id)
- (specInfo local_info)
+ `setRuleInfo` addRuleInfo (ruleInfo exp_info) new_info
+ new_info = setRuleInfoHead (idName exported_id)
+ (ruleInfo local_info)
-- Remember to set the function-name field of the
-- rules as we transfer them from one function to another
diff --git a/compiler/simplCore/SimplUtils.hs b/compiler/simplCore/SimplUtils.hs
index effd2121e9..1577efda37 100644
--- a/compiler/simplCore/SimplUtils.hs
+++ b/compiler/simplCore/SimplUtils.hs
@@ -14,7 +14,7 @@ module SimplUtils (
preInlineUnconditionally, postInlineUnconditionally,
activeUnfolding, activeRule,
getUnfoldingInRuleMatch,
- simplEnvForGHCi, updModeForStableUnfoldings, updModeForRuleLHS,
+ simplEnvForGHCi, updModeForStableUnfoldings, updModeForRules,
-- The continuation type
SimplCont(..), DupFlag(..),
@@ -701,24 +701,25 @@ updModeForStableUnfoldings inline_rule_act current_mode
phaseFromActivation (ActiveAfter n) = Phase n
phaseFromActivation _ = InitialPhase
-updModeForRuleLHS :: SimplifierMode -> SimplifierMode
--- See Note [Simplifying rule LHSs]
-updModeForRuleLHS current_mode
+updModeForRules :: SimplifierMode -> SimplifierMode
+-- See Note [Simplifying rules]
+updModeForRules current_mode
= current_mode { sm_phase = InitialPhase
, sm_inline = False
, sm_rules = False
, sm_eta_expand = False }
-{- Note [Simplifying rule LHSs]
+{- Note [Simplifying rules]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When simplifying on the LHS of a rule, refrain from all inlining and
-all RULES. Doing anything to the LHS is plain confusing, because it
-means that what the rule matches is not what the user wrote.
-c.f. Trac #10595, and #10528.
+When simplifying a rule, refrain from any inlining or applying of other RULES.
+Doing anything to the LHS is plain confusing, because it means that what the
+rule matches is not what the user wrote. c.f. Trac #10595, and #10528.
Moreover, inlining (or applying rules) on rule LHSs risks introducing
Ticks into the LHS, which makes matching trickier. Trac #10665, #10745.
+Doing this to either side confounds tools like HERMIT, which seek to reason
+about and apply the RULES as originally written. See Trac #10829.
Note [Inlining in gentle mode]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1522,6 +1523,30 @@ as we would normally do.
That's why the whole transformation is part of the same process that
floats let-bindings and constructor arguments out of RHSs. In particular,
it is guarded by the doFloatFromRhs call in simplLazyBind.
+
+Note [Which type variables to abstract over]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Abstract only over the type variables free in the rhs wrt which the
+new binding is abstracted. Note that
+
+ * The naive approach of abstracting wrt the
+ tyvars free in the Id's /type/ fails. Consider:
+ /\ a b -> let t :: (a,b) = (e1, e2)
+ x :: a = fst t
+ in ...
+ Here, b isn't free in x's type, but we must nevertheless
+ abstract wrt b as well, because t's type mentions b.
+ Since t is floated too, we'd end up with the bogus:
+ poly_t = /\ a b -> (e1, e2)
+ poly_x = /\ a -> fst (poly_t a *b*)
+
+ * We must do closeOverKinds. Example (Trac #10934):
+ f = /\k (f:k->*) (a:k). let t = AccFailure @ (f a) in ...
+ Here we want to float 't', but we must remember to abstract over
+ 'k' as well, even though it is not explicitly mentioned in the RHS,
+ otherwise we get
+ t = /\ (f:k->*) (a:k). AccFailure @ (f a)
+ which is obviously bogus.
-}
abstractFloats :: [OutTyVar] -> SimplEnv -> OutExpr -> SimplM ([OutBind], OutExpr)
@@ -1542,23 +1567,12 @@ abstractFloats main_tvs body_env body
; return (subst', (NonRec poly_id poly_rhs)) }
where
rhs' = CoreSubst.substExpr (text "abstract_floats2") subst rhs
- tvs_here = varSetElemsKvsFirst (main_tv_set `intersectVarSet` exprSomeFreeVars isTyVar rhs')
-
- -- Abstract only over the type variables free in the rhs
- -- wrt which the new binding is abstracted. But the naive
- -- approach of abstract wrt the tyvars free in the Id's type
- -- fails. Consider:
- -- /\ a b -> let t :: (a,b) = (e1, e2)
- -- x :: a = fst t
- -- in ...
- -- Here, b isn't free in x's type, but we must nevertheless
- -- abstract wrt b as well, because t's type mentions b.
- -- Since t is floated too, we'd end up with the bogus:
- -- poly_t = /\ a b -> (e1, e2)
- -- poly_x = /\ a -> fst (poly_t a *b*)
- -- So for now we adopt the even more naive approach of
- -- abstracting wrt *all* the tyvars. We'll see if that
- -- gives rise to problems. SLPJ June 98
+
+ -- tvs_here: see Note [Which type variables to abstract over]
+ tvs_here = varSetElemsKvsFirst $
+ intersectVarSet main_tv_set $
+ closeOverKinds $
+ exprSomeFreeVars isTyVar rhs'
abstract subst (Rec prs)
= do { (poly_ids, poly_apps) <- mapAndUnzipM (mk_poly tvs_here) ids
diff --git a/compiler/simplCore/Simplify.hs b/compiler/simplCore/Simplify.hs
index 07bc0041a1..2c73f8e119 100644
--- a/compiler/simplCore/Simplify.hs
+++ b/compiler/simplCore/Simplify.hs
@@ -36,7 +36,7 @@ import CoreUnfold
import CoreUtils
import CoreArity
--import PrimOp ( tagToEnumKey ) -- temporalily commented out. See #8326
-import Rules ( mkSpecInfo, lookupRule, getRules )
+import Rules ( mkRuleInfo, lookupRule, getRules )
import TysPrim ( voidPrimTy ) --, intPrimTy ) -- temporalily commented out. See #8326
import BasicTypes ( TopLevelFlag(..), isTopLevel, RecFlag(..) )
import MonadUtils ( foldlM, mapAccumLM, liftIO )
@@ -2957,10 +2957,10 @@ addBndrRules env in_id out_id
= return (env, out_id)
| otherwise
= do { new_rules <- simplRules env (Just (idName out_id)) old_rules
- ; let final_id = out_id `setIdSpecialisation` mkSpecInfo new_rules
+ ; let final_id = out_id `setIdSpecialisation` mkRuleInfo new_rules
; return (modifyInScope env final_id, final_id) }
where
- old_rules = specInfoRules (idSpecialisation in_id)
+ old_rules = ruleInfoRules (idSpecialisation in_id)
simplRules :: SimplEnv -> Maybe Name -> [CoreRule] -> SimplM [CoreRule]
simplRules env mb_new_nm rules
@@ -2970,13 +2970,11 @@ simplRules env mb_new_nm rules
= return rule
simpl_rule rule@(Rule { ru_bndrs = bndrs, ru_args = args
- , ru_fn = fn_name, ru_rhs = rhs
- , ru_act = act })
- = do { (env, bndrs') <- simplBinders env bndrs
- ; let lhs_env = updMode updModeForRuleLHS env
- rhs_env = updMode (updModeForStableUnfoldings act) env
- ; args' <- mapM (simplExpr lhs_env) args
- ; rhs' <- simplExpr rhs_env rhs
+ , ru_fn = fn_name, ru_rhs = rhs })
+ = do { (env', bndrs') <- simplBinders env bndrs
+ ; let rule_env = updMode updModeForRules env'
+ ; args' <- mapM (simplExpr rule_env) args
+ ; rhs' <- simplExpr rule_env rhs
; return (rule { ru_bndrs = bndrs'
, ru_fn = mb_new_nm `orElse` fn_name
, ru_args = args'