Simon Peyton Jones pushed to branch wip/T26989 at Glasgow Haskell Compiler / GHC
Commits:
9bbd56e8 by Simon Peyton Jones at 2026-04-27T23:54:56+01:00
Wibbles
- - - - -
4 changed files:
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
Changes:
=====================================
compiler/GHC/Core/Coercion.hs
=====================================
@@ -426,7 +426,8 @@ decomposeFunCo :: HasDebugCallStack
decomposeFunCo (FunCo { fco_mult = w, fco_arg = co1, fco_res = co2 })
= (w, co1, co2)
- -- Short-circuits the calls to mkSelCo
+ -- Fast path that short-circuits the calls to mkSelCo,
+ -- even though they would give the exact same answers
decomposeFunCo co
= assertPpr all_ok (ppr co) $
=====================================
compiler/GHC/Core/Opt/Arity.hs
=====================================
@@ -2691,10 +2691,11 @@ same fix.
-- | `tryEtaReduce [x,y,z] e sd` returns `Just e'` if `\x y z -> e` is evaluated
-- according to `sd` and can soundly and gainfully be eta-reduced to `e'`.
--- See Note [Eta reduction soundness]
--- and Note [Eta reduction makes sense] when that is the case.
tryEtaReduce :: UnVarSet -> [Var] -> CoreExpr -> SubDemand -> Maybe CoreExpr
-- Return an expression equal to (\bndrs. body)
+-- See Note [Eta reduction soundness]
+-- and Note [Eta reduction makes sense] when that is the case.
+-- and Note [Eta reduction based on evaluation context] for the `eval_sd` arg
tryEtaReduce rec_ids bndrs body eval_sd
= go (reverse bndrs) body (mkRepReflCo (exprType body))
where
=====================================
compiler/GHC/Core/Opt/Simplify/Iteration.hs
=====================================
@@ -1729,10 +1729,15 @@ optOutCoercion env co already_optimised
opts = seOptCoercionOpts env
addCastMCo :: MOutCoercion -> SimplCont -> SimplCont
--- Simpler version of `pushCast` when optionally want to add a cast to the top
+-- Simpler, non-monadic version of pushCastMCo when we are certain that
+-- the cast should be at the top; i.e. cont is Stop or StrictArg
addCastMCo MRefl cont = cont
addCastMCo (MCo co) cont = CastIt { sc_co = co, sc_opt = False, sc_cont = cont }
+pushCastMCo :: SimplEnv -> MOutCoercion -> SimplCont -> SimplM SimplCont
+pushCastMCo _env MRefl cont = return cont
+pushCastMCo env (MCo co) cont = pushCast env co cont
+
pushCast :: SimplEnv -> OutCoercion -> SimplCont -> SimplM SimplCont
pushCast env co cont
= go co True cont
@@ -1753,7 +1758,7 @@ pushCast env co cont
-- NB! As the cast goes past, the
-- type of the hole changes (#16312)
- -- (f |> co) e ===> (f (e |> co1)) |> co2
+ -- (f |> co) arg ===> (f (arg |> co1)) |> co2
-- where co :: (s1->s2) ~ (t1->t2)
-- co1 :: t1 ~ s1
-- co2 :: s2 ~ t2
@@ -1763,12 +1768,14 @@ pushCast env co cont
= -- pushCoValArg duplicates the coercion, so optimise first
go (optOutCoercion (zapSubstEnv env) co co_is_opt) True cont
+-- ToDo: return coercionLKind. And similarly pushCoTyArg
+
| Just (m_co1, m_co2) <- pushCoValArg co
= {-#SCC "addCoerce-pushCoValArg" #-}
do { tail' <- go_mco m_co2 co_is_opt tail
; return (ApplyToVal { sc_arg = arg
, sc_env = arg_se
- , sc_cast = m_co1 `mkTransMCo` arg_mco
+ , sc_cast = arg_mco `mkTransMCo` m_co1
, sc_cont = tail'
, sc_hole_ty = coercionLKind co }) }
@@ -1778,6 +1785,7 @@ pushCast env co cont
-- See Note [Optimising reflexivity]
| otherwise = return (CastIt { sc_co = co, sc_opt = co_is_opt, sc_cont = cont })
+-- ToDo: pushCast Refl (ApplylToVal arg1 (ApplyToVal arg2 ...)) will do lots of unnecessary work.
-- If the first parameter is MRefl, then simplifying revealed a
-- reflexive coercion. Omit.
@@ -2295,7 +2303,8 @@ simplInId env var cont
| otherwise
= case substId env var of
ContEx se e mco
- -> simplExprF (se `setInScopeFromE` env) e (addCastMCo mco cont)
+ -> do { cont' <- pushCastMCo env mco cont
+ ; simplExprF (se `setInScopeFromE` env) e cont' }
-- Don't trimJoinCont; haven't already simplified e,
-- so the cont is not embodied in e
@@ -2393,10 +2402,12 @@ simplOutId env fun cont
_ -> do { s' <- newId (fsLit "s") ManyTy realWorldStatePrimTy
; let (m,_,_) = splitFunTy fun_ty
env' = arg_env `addNewInScopeIds` [s']
- cont' = addCastMCo arg_mco $
- ApplyToVal { sc_arg = Var s', sc_cast = MRefl
- , sc_env = Simplified OkDup, sc_cont = inner_cont
- , sc_hole_ty = mkVisFunTy m realWorldStatePrimTy new_runrw_res_ty }
+ hole_ty = mkVisFunTy m realWorldStatePrimTy new_runrw_res_ty
+ ; cont' <- pushCastMCo env' arg_mco $
+ ApplyToVal { sc_arg = Var s', sc_cast = MRefl
+ , sc_env = Simplified OkDup
+ , sc_cont = inner_cont
+ , sc_hole_ty = hole_ty }
-- cont' applies to s', then K
; body' <- simplExprC env' arg cont'
; return (Lam s' body') }
=====================================
compiler/GHC/Core/Opt/Simplify/Utils.hs
=====================================
@@ -620,26 +620,33 @@ dropContArgs n cont = pprPanic "dropContArgs" (ppr n $$ ppr cont)
-- For example, when simplifying the argument `e` in `f e` and `f` has the
-- demand signature `
participants (1)
-
Simon Peyton Jones (@simonpj)