Simon Peyton Jones pushed to branch wip/spj-try-opt-coercion at Glasgow Haskell Compiler / GHC
Commits:
-
eb6c0cc3
by Simon Peyton Jones at 2026-01-15T14:17:12+00:00
-
8a1aa810
by Simon Peyton Jones at 2026-01-15T16:54:19+00:00
6 changed files:
- compiler/GHC/Core.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/Types/Literal.hs
Changes:
| ... | ... | @@ -190,7 +190,7 @@ These data types are the heart of the compiler |
| 190 | 190 | --
|
| 191 | 191 | -- See Note [Core binding invariants]
|
| 192 | 192 | -- See Note [Representation polymorphism invariants]
|
| 193 | --- See Note [Core type and coercion invariant]
|
|
| 193 | +-- See Note [Core type and coercion invariants]
|
|
| 194 | 194 | --
|
| 195 | 195 | -- * Case expression. Operationally this corresponds to evaluating
|
| 196 | 196 | -- the scrutinee (expression examined) to weak head normal form
|
| ... | ... | @@ -449,7 +449,7 @@ OR |
| 449 | 449 | * Have a RHS that is ok-for-speculation
|
| 450 | 450 | |
| 451 | 451 | NB: this only applies to /non-recursive/ bindings. For recursive
|
| 452 | -(or top-level) bindings see Note [Top-level binding invariants].
|
|
| 452 | +(or top-level) bindings see Note [Top/rec binding invariants].
|
|
| 453 | 453 | |
| 454 | 454 | This means that the let can be floated around
|
| 455 | 455 | without difficulty. For example, this is OK:
|
| ... | ... | @@ -2122,13 +2122,13 @@ mkLetRec [] body = body |
| 2122 | 2122 | mkLetRec bs body = Let (Rec bs) body
|
| 2123 | 2123 | |
| 2124 | 2124 | -- | Create a binding group where a type variable is bound to a type.
|
| 2125 | --- Per Note [Core type and coercion invariant],
|
|
| 2125 | +-- Per Note [Core type and coercion invariants],
|
|
| 2126 | 2126 | -- this can only be used to bind something in a non-recursive @let@ expression
|
| 2127 | 2127 | mkTyBind :: TyVar -> Type -> CoreBind
|
| 2128 | 2128 | mkTyBind tv ty = NonRec tv (Type ty)
|
| 2129 | 2129 | |
| 2130 | 2130 | -- | Create a binding group where a type variable is bound to a type.
|
| 2131 | --- Per Note [Core type and coercion invariant],
|
|
| 2131 | +-- Per Note [Core type and coercion invariants],
|
|
| 2132 | 2132 | -- this can only be used to bind something in a non-recursive @let@ expression
|
| 2133 | 2133 | mkCoBind :: CoVar -> Coercion -> CoreBind
|
| 2134 | 2134 | mkCoBind cv co = NonRec cv (Coercion co)
|
| ... | ... | @@ -183,7 +183,7 @@ Note [Linting type lets] |
| 183 | 183 | In the desugarer, it's very very convenient to be able to say (in effect)
|
| 184 | 184 | let a = Type Bool in
|
| 185 | 185 | let x::a = True in <body>
|
| 186 | -That is, use a type let. See Note [Core type and coercion invariant] in "GHC.Core".
|
|
| 186 | +That is, use a type let. See Note [Core type and coercion invariants] in "GHC.Core".
|
|
| 187 | 187 | One place it is used is in mkWwBodies; see Note [Join points and beta-redexes]
|
| 188 | 188 | in GHC.Core.Opt.WorkWrap.Utils. (Maybe there are other "clients" of this feature; I'm not sure).
|
| 189 | 189 | |
| ... | ... | @@ -582,7 +582,7 @@ lintLetBind top_lvl rec_flag binder rhs rhs_ty |
| 582 | 582 | ; ensureEqTys binder_ty rhs_ty (mkRhsMsg binder (text "RHS") rhs_ty)
|
| 583 | 583 | |
| 584 | 584 | -- If the binding is for a CoVar, the RHS should be (Coercion co)
|
| 585 | - -- See Note [Core type and coercion invariant] in GHC.Core
|
|
| 585 | + -- See Note [Core type and coercion invariants] in GHC.Core
|
|
| 586 | 586 | ; checkL (not (isCoVar binder) || isCoArg rhs)
|
| 587 | 587 | (mkLetErr binder rhs)
|
| 588 | 588 |
| ... | ... | @@ -26,7 +26,7 @@ import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr, zapLambdaBndrs, scrutOkForBind |
| 26 | 26 | import GHC.Core.Make ( FloatBind, mkImpossibleExpr, castBottomExpr )
|
| 27 | 27 | import qualified GHC.Core.Make
|
| 28 | 28 | import GHC.Core.Coercion hiding ( substCo, substCoVar )
|
| 29 | -import GHC.Core.Coercion.Opt
|
|
| 29 | +-- import GHC.Core.Coercion.Opt
|
|
| 30 | 30 | import GHC.Core.Reduction
|
| 31 | 31 | import GHC.Core.FamInstEnv ( FamInstEnv, topNormaliseType_maybe )
|
| 32 | 32 | import GHC.Core.DataCon
|
| ... | ... | @@ -1390,7 +1390,8 @@ simplCoercionF env co cont |
| 1390 | 1390 | |
| 1391 | 1391 | simplCoercion :: SimplEnv -> InCoercion -> SimplM OutCoercion
|
| 1392 | 1392 | simplCoercion env co
|
| 1393 | - = do { let out_co = optCoRefl (getTCvSubst env) co
|
|
| 1393 | + = do { let out_co = -- optCoRefl (getTCvSubst env) co
|
|
| 1394 | + substCo env co
|
|
| 1394 | 1395 | ; seqCo out_co `seq` return out_co }
|
| 1395 | 1396 | |
| 1396 | 1397 | -----------------------------------
|
| ... | ... | @@ -3211,7 +3212,7 @@ doCaseToLet :: OutExpr -- Scrutinee |
| 3211 | 3212 | -- Can we transform thus? let { b = scrut } in body
|
| 3212 | 3213 | doCaseToLet scrut case_bndr
|
| 3213 | 3214 | | isTyCoVar case_bndr -- Respect GHC.Core
|
| 3214 | - = isTyCoArg scrut -- Note [Core type and coercion invariant]
|
|
| 3215 | + = isTyCoArg scrut -- Note [Core type and coercion invariants]
|
|
| 3215 | 3216 | |
| 3216 | 3217 | | isUnliftedType (exprType scrut)
|
| 3217 | 3218 | -- We can call isUnliftedType here: scrutinees always have a fixed RuntimeRep (see FRRCase).
|
| ... | ... | @@ -610,7 +610,7 @@ simple_bind_pair env@(SOE { soe_inl = inl_env, soe_subst = subst, soe_opts = opt |
| 610 | 610 | |
| 611 | 611 | | assertPpr (isNonCoVarId in_bndr) (ppr in_bndr)
|
| 612 | 612 | -- The previous two guards got rid of tyvars and coercions
|
| 613 | - -- See Note [Core type and coercion invariant] in GHC.Core
|
|
| 613 | + -- See Note [Core type and coercion invariants] in GHC.Core
|
|
| 614 | 614 | pre_inline_unconditionally
|
| 615 | 615 | = (env { soe_inl = extendVarEnv inl_env in_bndr clo }, Nothing)
|
| 616 | 616 | |
| ... | ... | @@ -694,7 +694,7 @@ simple_out_bind_pair env@(SOE { soe_subst = subst, soe_opts = opts }) |
| 694 | 694 | occ_info active stable_unf top_level
|
| 695 | 695 | | assertPpr (isNonCoVarId in_bndr) (ppr in_bndr)
|
| 696 | 696 | -- Type and coercion bindings are caught earlier
|
| 697 | - -- See Note [Core type and coercion invariant]
|
|
| 697 | + -- See Note [Core type and coercion invariants]
|
|
| 698 | 698 | post_inline_unconditionally
|
| 699 | 699 | = ( env' { soe_subst = extendIdSubst subst in_bndr out_rhs }
|
| 700 | 700 | , Nothing)
|
| ... | ... | @@ -577,7 +577,7 @@ can be eliminated by expanding the synonym. |
| 577 | 577 | Note [Binding coercions]
|
| 578 | 578 | ~~~~~~~~~~~~~~~~~~~~~~~~
|
| 579 | 579 | Consider binding a CoVar, c = e. Then, we must satisfy
|
| 580 | -Note [Core type and coercion invariant] in GHC.Core,
|
|
| 580 | +Note [Core type and coercion invariants] in GHC.Core,
|
|
| 581 | 581 | which allows only (Coercion co) on the RHS.
|
| 582 | 582 | |
| 583 | 583 | ************************************************************************
|
| ... | ... | @@ -1813,10 +1813,11 @@ exprIsUnaryClassFun _ = False |
| 1813 | 1813 | -- See also Note [Classifying primop effects] in "GHC.Builtin.PrimOps"
|
| 1814 | 1814 | -- and Note [Transformations affected by primop effects].
|
| 1815 | 1815 | --
|
| 1816 | --- 'exprOkForSpeculation' is used in the definition of Note [Nested binding
|
|
| 1817 | --- invariants]in GHC.Core. It is therefore frequently called on arguments of
|
|
| 1818 | --- unlifted type, especially via 'needsCaseBinding'. But it is sometimes
|
|
| 1819 | --- called on expressions of lifted type as well. For example, see
|
|
| 1816 | +-- 'exprOkForSpeculation' is used in the definition of
|
|
| 1817 | +-- Note [Nested non-rec binding invariants] in GHC.Core. It is therefore
|
|
| 1818 | +-- frequently called on arguments of unlifted type, especially via
|
|
| 1819 | +-- 'needsCaseBinding'. But it is sometimes called on expressions of
|
|
| 1820 | +-- lifted type as well. For example, see
|
|
| 1820 | 1821 | -- Note [Speculative evaluation] in "GHC.CoreToStg.Prep".
|
| 1821 | 1822 | |
| 1822 | 1823 | exprOkForSpeculation, exprOkToDiscard :: CoreExpr -> Bool
|
| ... | ... | @@ -2049,7 +2050,7 @@ But we restrict it sharply: |
| 2049 | 2050 | |
| 2050 | 2051 | DEFAULT -> ... (let v::Int# = case x of { ... }
|
| 2051 | 2052 | in ...) ....
|
| 2052 | - which does /not/ satisfy Note [Nested non-rec bindings invariants],
|
|
| 2053 | + which does /not/ satisfy Note [Nested non-rec binding invariants],
|
|
| 2053 | 2054 | because x is not evaluated. See Note [Binder-swap during float-out]
|
| 2054 | 2055 | in GHC.Core.Opt.SetLevels. To avoid this awkwardness it seems simpler
|
| 2055 | 2056 | to stick to unlifted scrutinees where the issue does not
|
| ... | ... | @@ -1004,7 +1004,7 @@ data type. Here are the moving parts: |
| 1004 | 1004 | levity/runtime-rep polymorphism naturally uphold this invariant.
|
| 1005 | 1005 | |
| 1006 | 1006 | INVARIANT 2: we never make a rubbish literal of type (a ~# b). Reason:
|
| 1007 | - see Note [Core type and coercion invariant] in GHC.Core. We can't substitute
|
|
| 1007 | + see Note [Core type and coercion invariants] in GHC.Core. We can't substitute
|
|
| 1008 | 1008 | a LitRubbish inside a coercion, so it's best not to make one. They are zero
|
| 1009 | 1009 | width anyway, so passing absent ones around costs nothing. If we wanted
|
| 1010 | 1010 | an absent filler of type (a ~# b) we should use (Coercion (UnivCo ...)),
|