diff options
| author | Ben Gamari <bgamari.foss@gmail.com> | 2018-06-07 13:20:30 -0400 |
|---|---|---|
| committer | Ben Gamari <ben@smart-cactus.org> | 2018-06-07 18:06:29 -0400 |
| commit | 64c71ce956af3af593a46ef0d615c7f6fe6ecece (patch) | |
| tree | 79d2b226b8ad0f500028b12e0d4c38464050eaa2 | |
| parent | f7417118732d6c8431b3f281c3d34455c7443550 (diff) | |
| download | haskell-64c71ce956af3af593a46ef0d615c7f6fe6ecece.tar.gz | |
Don't use unsafeGlobalDynFlags in optCoercion
This plumbs DynFlags through CoreOpt so optCoercion can finally
eliminate its usage of `unsafeGlobalDynFlags`.
Note that this doesn't completely eliminate `unsafeGlobalDynFlags`
usage from this bit of the compiler. A few uses are introduced in
call-sites where we don't (yet) have ready access to `DynFlags`.
Test Plan: Validate
Reviewers: goldfire
Subscribers: rwbarton, thomie, carter
Differential Revision: https://phabricator.haskell.org/D4774
| -rw-r--r-- | compiler/coreSyn/CoreOpt.hs | 43 | ||||
| -rw-r--r-- | compiler/coreSyn/CoreUnfold.hs | 27 | ||||
| -rw-r--r-- | compiler/deSugar/Desugar.hs | 6 | ||||
| -rw-r--r-- | compiler/deSugar/DsBinds.hs | 4 | ||||
| -rw-r--r-- | compiler/simplCore/Simplify.hs | 5 | ||||
| -rw-r--r-- | compiler/specialise/Specialise.hs | 2 | ||||
| -rw-r--r-- | compiler/types/OptCoercion.hs | 12 |
7 files changed, 55 insertions, 44 deletions
diff --git a/compiler/coreSyn/CoreOpt.hs b/compiler/coreSyn/CoreOpt.hs index de0dd04656..0353ab6a75 100644 --- a/compiler/coreSyn/CoreOpt.hs +++ b/compiler/coreSyn/CoreOpt.hs @@ -86,7 +86,7 @@ little dance in action; the full Simplifier is a lot more complicated. -} -simpleOptExpr :: CoreExpr -> CoreExpr +simpleOptExpr :: DynFlags -> CoreExpr -> CoreExpr -- See Note [The simple optimiser] -- Do simple optimisation on an expression -- The optimisation is very straightforward: just @@ -103,9 +103,9 @@ simpleOptExpr :: CoreExpr -> CoreExpr -- in (let x = y in ....) we substitute for x; so y's occ-info -- may change radically -simpleOptExpr expr +simpleOptExpr dflags expr = -- pprTrace "simpleOptExpr" (ppr init_subst $$ ppr expr) - simpleOptExprWith init_subst expr + simpleOptExprWith dflags init_subst expr where init_subst = mkEmptySubst (mkInScopeSet (exprFreeVars expr)) -- It's potentially important to make a proper in-scope set @@ -118,12 +118,14 @@ simpleOptExpr expr -- It's a bit painful to call exprFreeVars, because it makes -- three passes instead of two (occ-anal, and go) -simpleOptExprWith :: Subst -> InExpr -> OutExpr +simpleOptExprWith :: DynFlags -> Subst -> InExpr -> OutExpr -- See Note [The simple optimiser] -simpleOptExprWith subst expr +simpleOptExprWith dflags subst expr = simple_opt_expr init_env (occurAnalyseExpr expr) where - init_env = SOE { soe_inl = emptyVarEnv, soe_subst = subst } + init_env = SOE { soe_dflags = dflags + , soe_inl = emptyVarEnv + , soe_subst = subst } ---------------------- simpleOptPgm :: DynFlags -> Module @@ -141,7 +143,7 @@ simpleOptPgm dflags this_mod binds rules (\_ -> False) {- No rules active -} rules binds - (final_env, binds') = foldl do_one (emptyEnv, []) occ_anald_binds + (final_env, binds') = foldl do_one (emptyEnv dflags, []) occ_anald_binds final_subst = soe_subst final_env rules' = substRulesForImportedIds final_subst rules @@ -159,7 +161,8 @@ simpleOptPgm dflags this_mod binds rules type SimpleClo = (SimpleOptEnv, InExpr) data SimpleOptEnv - = SOE { soe_inl :: IdEnv SimpleClo + = SOE { soe_dflags :: DynFlags + , soe_inl :: IdEnv SimpleClo -- Deals with preInlineUnconditionally; things -- that occur exactly once and are inlined -- without having first been simplified @@ -174,13 +177,15 @@ instance Outputable SimpleOptEnv where , text "soe_subst =" <+> ppr subst ] <+> text "}" -emptyEnv :: SimpleOptEnv -emptyEnv = SOE { soe_inl = emptyVarEnv - , soe_subst = emptySubst } +emptyEnv :: DynFlags -> SimpleOptEnv +emptyEnv dflags + = SOE { soe_dflags = dflags + , soe_inl = emptyVarEnv + , soe_subst = emptySubst } soeZapSubst :: SimpleOptEnv -> SimpleOptEnv -soeZapSubst (SOE { soe_subst = subst }) - = SOE { soe_inl = emptyVarEnv, soe_subst = zapSubstEnv subst } +soeZapSubst env@(SOE { soe_subst = subst }) + = env { soe_inl = emptyVarEnv, soe_subst = zapSubstEnv subst } soeSetInScope :: SimpleOptEnv -> SimpleOptEnv -> SimpleOptEnv -- Take in-scope set from env1, and the rest from env2 @@ -209,13 +214,13 @@ simple_opt_expr env expr go (App e1 e2) = simple_app env e1 [(env,e2)] go (Type ty) = Type (substTy subst ty) - go (Coercion co) = Coercion (optCoercion (getTCvSubst subst) co) + go (Coercion co) = Coercion (optCoercion (soe_dflags env) (getTCvSubst subst) co) go (Lit lit) = Lit lit go (Tick tickish e) = mkTick (substTickish subst tickish) (go e) go (Cast e co) | isReflCo co' = go e | otherwise = Cast (go e) co' where - co' = optCoercion (getTCvSubst subst) co + co' = optCoercion (soe_dflags env) (getTCvSubst subst) co go (Let bind body) = case simple_opt_bind env bind of (env', Nothing) -> simple_opt_expr env' body @@ -350,7 +355,7 @@ simple_bind_pair env@(SOE { soe_inl = inl_env, soe_subst = subst }) (env { soe_subst = extendTvSubst subst in_bndr out_ty }, Nothing) | Coercion co <- in_rhs - , let out_co = optCoercion (getTCvSubst (soe_subst rhs_env)) co + , let out_co = optCoercion (soe_dflags env) (getTCvSubst (soe_subst rhs_env)) co = ASSERT( isCoVar in_bndr ) (env { soe_subst = extendCvSubst subst in_bndr out_co }, Nothing) @@ -493,8 +498,8 @@ subst_opt_id_bndr :: SimpleOptEnv -> InId -> (SimpleOptEnv, OutId) -- It's important to zap fragile OccInfo (which CoreSubst.substIdBndr -- carefully does not do) because simplOptExpr invalidates it -subst_opt_id_bndr (SOE { soe_subst = subst, soe_inl = inl }) old_id - = (SOE { soe_subst = new_subst, soe_inl = new_inl }, new_id) +subst_opt_id_bndr env@(SOE { soe_subst = subst, soe_inl = inl }) old_id + = (env { soe_subst = new_subst, soe_inl = new_inl }, new_id) where Subst in_scope id_subst tv_subst cv_subst = subst @@ -902,7 +907,7 @@ exprIsLambda_maybe (in_scope_set, id_unf) e -- Make sure there is hope to get a lambda , Just rhs <- expandUnfolding_maybe (id_unf f) -- Optimize, for beta-reduction - , let e' = simpleOptExprWith (mkEmptySubst in_scope_set) (rhs `mkApps` as) + , let e' = simpleOptExprWith unsafeGlobalDynFlags (mkEmptySubst in_scope_set) (rhs `mkApps` as) -- Recurse, because of possible casts , Just (x', e'', ts') <- exprIsLambda_maybe (in_scope_set, id_unf) e' , let res = Just (x', e'', ts++ts') diff --git a/compiler/coreSyn/CoreUnfold.hs b/compiler/coreSyn/CoreUnfold.hs index c1f78926e1..20c8d0d35b 100644 --- a/compiler/coreSyn/CoreUnfold.hs +++ b/compiler/coreSyn/CoreUnfold.hs @@ -85,7 +85,7 @@ mkTopUnfolding dflags is_bottoming rhs mkImplicitUnfolding :: DynFlags -> CoreExpr -> Unfolding -- For implicit Ids, do a tiny bit of optimising first mkImplicitUnfolding dflags expr - = mkTopUnfolding dflags False (simpleOptExpr expr) + = mkTopUnfolding dflags False (simpleOptExpr dflags expr) -- Note [Top-level flag on inline rules] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -107,14 +107,14 @@ mkDFunUnfolding bndrs con ops mkWwInlineRule :: CoreExpr -> Arity -> Unfolding mkWwInlineRule expr arity = mkCoreUnfolding InlineStable True - (simpleOptExpr expr) + (simpleOptExpr unsafeGlobalDynFlags expr) (UnfWhen { ug_arity = arity, ug_unsat_ok = unSaturatedOk , ug_boring_ok = boringCxtNotOk }) mkCompulsoryUnfolding :: CoreExpr -> Unfolding mkCompulsoryUnfolding expr -- Used for things that absolutely must be unfolded = mkCoreUnfolding InlineCompulsory True - (simpleOptExpr expr) + (simpleOptExpr unsafeGlobalDynFlags expr) (UnfWhen { ug_arity = 0 -- Arity of unfolding doesn't matter , ug_unsat_ok = unSaturatedOk, ug_boring_ok = boringCxtOk }) @@ -126,7 +126,7 @@ mkWorkerUnfolding dflags work_fn | isStableSource src = mkCoreUnfolding src top_lvl new_tmpl guidance where - new_tmpl = simpleOptExpr (work_fn tmpl) + new_tmpl = simpleOptExpr dflags (work_fn tmpl) guidance = calcUnfoldingGuidance dflags False new_tmpl mkWorkerUnfolding _ _ _ = noUnfolding @@ -141,7 +141,7 @@ mkInlineUnfolding expr True -- Note [Top-level flag on inline rules] expr' guide where - expr' = simpleOptExpr expr + expr' = simpleOptExpr unsafeGlobalDynFlags expr guide = UnfWhen { ug_arity = manifestArity expr' , ug_unsat_ok = unSaturatedOk , ug_boring_ok = boring_ok } @@ -155,7 +155,7 @@ mkInlineUnfoldingWithArity arity expr True -- Note [Top-level flag on inline rules] expr' guide where - expr' = simpleOptExpr expr + expr' = simpleOptExpr unsafeGlobalDynFlags expr guide = UnfWhen { ug_arity = arity , ug_unsat_ok = needSaturated , ug_boring_ok = boring_ok } @@ -165,14 +165,15 @@ mkInlinableUnfolding :: DynFlags -> CoreExpr -> Unfolding mkInlinableUnfolding dflags expr = mkUnfolding dflags InlineStable False False expr' where - expr' = simpleOptExpr expr + expr' = simpleOptExpr dflags expr -specUnfolding :: [Var] -> (CoreExpr -> CoreExpr) -> Arity -> Unfolding -> Unfolding +specUnfolding :: DynFlags -> [Var] -> (CoreExpr -> CoreExpr) -> Arity + -> Unfolding -> Unfolding -- See Note [Specialising unfoldings] -- specUnfolding spec_bndrs spec_app arity_decrease unf -- = \spec_bndrs. spec_app( unf ) -- -specUnfolding spec_bndrs spec_app arity_decrease +specUnfolding dflags spec_bndrs spec_app arity_decrease df@(DFunUnfolding { df_bndrs = old_bndrs, df_con = con, df_args = args }) = ASSERT2( arity_decrease == count isId old_bndrs - count isId spec_bndrs, ppr df ) mkDFunUnfolding spec_bndrs con (map spec_arg args) @@ -184,11 +185,11 @@ specUnfolding spec_bndrs spec_app arity_decrease -- \new_bndrs. MkD (spec_app(\old_bndrs. <op1>)) ... ditto <opn> -- The ASSERT checks the value part of that where - spec_arg arg = simpleOptExpr (spec_app (mkLams old_bndrs arg)) + spec_arg arg = simpleOptExpr dflags (spec_app (mkLams old_bndrs arg)) -- The beta-redexes created by spec_app will be -- simplified away by simplOptExpr -specUnfolding spec_bndrs spec_app arity_decrease +specUnfolding dflags spec_bndrs spec_app arity_decrease (CoreUnfolding { uf_src = src, uf_tmpl = tmpl , uf_is_top = top_lvl , uf_guidance = old_guidance }) @@ -199,13 +200,13 @@ specUnfolding spec_bndrs spec_app arity_decrease = let guidance = UnfWhen { ug_arity = old_arity - arity_decrease , ug_unsat_ok = unsat_ok , ug_boring_ok = boring_ok } - new_tmpl = simpleOptExpr (mkLams spec_bndrs (spec_app tmpl)) + new_tmpl = simpleOptExpr dflags (mkLams spec_bndrs (spec_app tmpl)) -- The beta-redexes created by spec_app will be -- simplified away by simplOptExpr in mkCoreUnfolding src top_lvl new_tmpl guidance -specUnfolding _ _ _ _ = noUnfolding +specUnfolding _ _ _ _ _ = noUnfolding {- Note [Specialising unfoldings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/compiler/deSugar/Desugar.hs b/compiler/deSugar/Desugar.hs index b987130802..532bd0077f 100644 --- a/compiler/deSugar/Desugar.hs +++ b/compiler/deSugar/Desugar.hs @@ -397,18 +397,18 @@ dsRule (L loc (HsRule _ name rule_act vars lhs rhs)) Left msg -> do { warnDs NoReason msg; return Nothing } ; Right (final_bndrs, fn_id, args) -> do - { let is_local = isLocalId fn_id + { dflags <- getDynFlags + ; let is_local = isLocalId fn_id -- NB: isLocalId is False of implicit Ids. This is good because -- we don't want to attach rules to the bindings of implicit Ids, -- because they don't show up in the bindings until just before code gen fn_name = idName fn_id - final_rhs = simpleOptExpr rhs'' -- De-crap it + final_rhs = simpleOptExpr dflags rhs'' -- De-crap it rule_name = snd (unLoc name) final_bndrs_set = mkVarSet final_bndrs arg_ids = filterOut (`elemVarSet` final_bndrs_set) $ exprsSomeFreeVarsList isId args - ; dflags <- getDynFlags ; rule <- dsMkUserRule this_mod is_local rule_name rule_act fn_name final_bndrs args final_rhs diff --git a/compiler/deSugar/DsBinds.hs b/compiler/deSugar/DsBinds.hs index ba904c1122..4b3c781c34 100644 --- a/compiler/deSugar/DsBinds.hs +++ b/compiler/deSugar/DsBinds.hs @@ -689,7 +689,7 @@ dsSpec mb_poly_rhs (L loc (SpecPrag poly_id spec_co spec_inl)) { dflags <- getDynFlags ; this_mod <- getModule ; let fn_unf = realIdUnfolding poly_id - spec_unf = specUnfolding spec_bndrs core_app arity_decrease fn_unf + spec_unf = specUnfolding dflags spec_bndrs core_app arity_decrease fn_unf spec_id = mkLocalId spec_name spec_ty `setInlinePragma` inl_prag `setIdUnfolding` spec_unf @@ -849,7 +849,7 @@ decomposeRuleLhs orig_bndrs orig_lhs = Left bad_shape_msg where lhs1 = drop_dicts orig_lhs - lhs2 = simpleOptExpr lhs1 -- See Note [Simplify rule LHS] + lhs2 = simpleOptExpr unsafeGlobalDynFlags lhs1 -- See Note [Simplify rule LHS] (fun2,args2) = collectArgs lhs2 lhs_fvs = exprFreeVars lhs2 diff --git a/compiler/simplCore/Simplify.hs b/compiler/simplCore/Simplify.hs index a4651bbfbd..c60d850cd0 100644 --- a/compiler/simplCore/Simplify.hs +++ b/compiler/simplCore/Simplify.hs @@ -1015,8 +1015,9 @@ simplCoercionF env co cont simplCoercion :: SimplEnv -> InCoercion -> SimplM OutCoercion simplCoercion env co - = let opt_co = optCoercion (getTCvSubst env) co - in seqCo opt_co `seq` return opt_co + = do { dflags <- getDynFlags + ; let opt_co = optCoercion dflags (getTCvSubst env) co + ; seqCo opt_co `seq` return opt_co } ----------------------------------- -- | Push a TickIt context outwards past applications and cases, as diff --git a/compiler/specialise/Specialise.hs b/compiler/specialise/Specialise.hs index bc3e27f674..13a7cb7474 100644 --- a/compiler/specialise/Specialise.hs +++ b/compiler/specialise/Specialise.hs @@ -1346,7 +1346,7 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs = (inl_prag { inl_inline = NoUserInline }, noUnfolding) | otherwise - = (inl_prag, specUnfolding poly_tyvars spec_app + = (inl_prag, specUnfolding dflags poly_tyvars spec_app arity_decrease fn_unf) arity_decrease = length spec_dict_args diff --git a/compiler/types/OptCoercion.hs b/compiler/types/OptCoercion.hs index ba779f9a29..e86227181f 100644 --- a/compiler/types/OptCoercion.hs +++ b/compiler/types/OptCoercion.hs @@ -83,11 +83,15 @@ an ambient substitution, which is why a LiftingContext stores a TCvSubst. -} -optCoercion :: TCvSubst -> Coercion -> NormalCo +optCoercion :: DynFlags -> TCvSubst -> Coercion -> NormalCo -- ^ optCoercion applies a substitution to a coercion, -- *and* optimises it to reduce its size -optCoercion env co - | hasNoOptCoercion unsafeGlobalDynFlags = substCo env co +optCoercion dflags env co + | hasNoOptCoercion dflags = substCo env co + | otherwise = optCoercion' env co + +optCoercion' :: TCvSubst -> Coercion -> NormalCo +optCoercion' env co | debugIsOn = let out_co = opt_co1 lc False co (Pair in_ty1 in_ty2, in_role) = coercionKindRole co @@ -350,7 +354,7 @@ opt_co4 env sym rep r (CoherenceCo co1 co2) | TransCo col1' cor1' <- co1' = if sym then opt_trans in_scope col1' - (optCoercion (zapTCvSubst (lcTCvSubst env)) + (optCoercion' (zapTCvSubst (lcTCvSubst env)) (mkCoherenceRightCo cor1' co2')) else opt_trans in_scope (mkCoherenceCo col1' co2') cor1' |
