Simon Peyton Jones pushed to branch wip/spj-try-opt-coercion at Glasgow Haskell Compiler / GHC

Commits:

18 changed files:

Changes:

  • compiler/GHC/Builtin/PrimOps.hs
    ... ... @@ -438,7 +438,7 @@ follows, in decreasing order of permissiveness:
    438 438
         In particular, we cannot safely rewrite such an invalid call to a runtime
    
    439 439
         error; we must emit code that produces a valid Word32#.  (If we're lucky,
    
    440 440
         Core Lint may complain that the result of such a rewrite violates
    
    441
    -    Note [Core binding invariants: nested non-rec] (#16742), but the rewrite
    
    441
    +    Note [Nested non-rec binding invariants] (#16742), but the rewrite
    
    442 442
         is always wrong!)  See also Note [Guarding against silly shifts] in
    
    443 443
         GHC.Core.Opt.ConstantFold.
    
    444 444
     
    
    ... ... @@ -581,7 +581,7 @@ Several predicates on primops test this flag:
    581 581
       * The "no-float-out" thing is achieved by ensuring that we never let-bind a
    
    582 582
         saturated primop application unless it has NoEffect.  The RHS of a
    
    583 583
         let-binding (which can float in and out freely) satisfies
    
    584
    -    exprOkForSpeculation; this is Note [Core binding invariants: nested non-rec].
    
    584
    +    exprOkForSpeculation; this is Note [Nested non-rec binding invariants].
    
    585 585
         And exprOkForSpeculation is false of a saturated primop application unless it
    
    586 586
         has NoEffect.
    
    587 587
     
    

  • compiler/GHC/Core.hs
    ... ... @@ -397,27 +397,27 @@ Note [Core binding invariants]
    397 397
     A core binding, `CoreBind`, obeys these invariants:
    
    398 398
     
    
    399 399
     * For /top level/ or /recursive/ bindings,
    
    400
    -  see Note [Top-level binding invariants]
    
    400
    +  see Note [Top/rec binding invariants]
    
    401 401
     
    
    402 402
     * For /nested/ (not top-level) /non-recursive/ bindings,
    
    403
    -  see Note [Nested binding invariants]
    
    403
    +  see Note [Nested non-rec binding invariants]
    
    404 404
     
    
    405
    -Note [Top-level binding invariants]
    
    406
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    405
    +Note [Top/rec binding invariants]
    
    406
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    407 407
     A /top-level/ or /recursive/ binding must
    
    408 408
     
    
    409
    -  * be of lifted type
    
    410
    -OR
    
    409
    +  * be of lifted type, OR
    
    410
    +
    
    411 411
       * have a RHS that is a primitive string literal
    
    412
    -    (see Note [Core top-level string literals], or
    
    413
    -OR
    
    414
    -  * have a rhs that is (Coercion co)
    
    415
    -OR
    
    416
    -  * be a worker or wrapper for an unlifted non-newtype data constructor; see (TL1).
    
    412
    +    (see Note [Core top-level string literals], OR
    
    413
    +
    
    414
    +  * have a rhs that is (Coercion co), OR
    
    415
    +
    
    416
    +  * be a worker or wrapper for an unlifted non-newtype
    
    417
    +    data constructor; see (TL1).
    
    417 418
     
    
    418
    -For the non-top-level, non-recursive case see Note [Nested binding invariants].
    
    419
    -(NB: this Note applies to recursive as well as top-level bindings, but I wanted
    
    420
    -a short title!)
    
    419
    +For the non-top-level, non-recursive case
    
    420
    +see Note [Nested non-rec binding invariants].
    
    421 421
     
    
    422 422
     See "Type#type_classification" in GHC.Core.Type
    
    423 423
     for the meaning of "lifted" vs. "unlifted".
    
    ... ... @@ -439,8 +439,8 @@ constructor worker or wrapper
    439 439
                  S1 = S1
    
    440 440
           We allow this top-level unlifted binding to exist.
    
    441 441
     
    
    442
    -Note [Nested binding invariants]
    
    443
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    442
    +Note [Nested non-rec binding invariants]
    
    443
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    444 444
     A /non-top-level/, /non-recursive/ binding must
    
    445 445
       * Be a join point; see Note [Invariants on join points]
    
    446 446
     OR
    
    ... ... @@ -471,7 +471,7 @@ The Core binding invariants are initially enforced by mkCoreLet in GHC.Core.Make
    471 471
     Historical Note [The let/app invariant]
    
    472 472
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    473 473
     Before 2022 GHC used the "let/app invariant", which applied
    
    474
    -Note [Nested binding invariants] to the argument of an application,
    
    474
    +Note [Nested non-rec binding invariants] to the argument of an application,
    
    475 475
     as well as to the RHS of a let.  This made some kind of sense, because 'let' can
    
    476 476
     always be encoded as application: let x=rhs in b = (\x.b) rhs
    
    477 477
     
    
    ... ... @@ -641,8 +641,8 @@ checked by Core Lint.
    641 641
        multiplicity of the corresponding field /scaled by the multiplicity of the
    
    642 642
        case binder/. Checked in lintCoreAlt.
    
    643 643
     
    
    644
    -Note [Core type and coercion invariant]
    
    645
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    644
    +Note [Core type and coercion invariants]
    
    645
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    646 646
     We allow `let` to bind type and coercion variables.
    
    647 647
     
    
    648 648
     * A type or coercion binding is always /non-recursive/
    
    ... ... @@ -887,7 +887,7 @@ Join points must follow these invariants:
    887 887
     However, join points have simpler invariants in other ways
    
    888 888
     
    
    889 889
       5. A join point can have an unboxed type without the RHS being
    
    890
    -     ok-for-speculation; see 
    
    890
    +     ok-for-speculation; see
    
    891 891
          e.g.  let j :: Int# = factorial x in ...
    
    892 892
     
    
    893 893
       6. The RHS of join point is not required to have a fixed runtime representation,
    
    ... ... @@ -2095,8 +2095,8 @@ mkDoubleLit d = Lit (mkLitDouble d)
    2095 2095
     mkDoubleLitDouble d = Lit (mkLitDouble (toRational d))
    
    2096 2096
     
    
    2097 2097
     -- | Bind all supplied binding groups over an expression in a nested let expression.
    
    2098
    --- Assumes that the rhs satisfies Note [Nested binding invariants].  Prefer to use
    
    2099
    --- 'GHC.Core.Make.mkCoreLets' if possible, which does guarantee the invariant
    
    2098
    +-- Assumes that the rhs satisfies Note [Nested non-rec binding invariants].
    
    2099
    +-- Prefer to use 'GHC.Core.Make.mkCoreLets' if possible, which does guarantee the invariant
    
    2100 2100
     mkLets        :: [Bind b] -> Expr b -> Expr b
    
    2101 2101
     -- | Bind all supplied binders over an expression in a nested lambda expression. Prefer to
    
    2102 2102
     -- use 'GHC.Core.Make.mkCoreLams' if possible
    

  • compiler/GHC/Core/Coercion/Opt.hs
    ... ... @@ -270,10 +270,12 @@ optCoRefl subst in_co
    270 270
       = let out_co = opt_co_refl subst in_co
    
    271 271
             (Pair in_l in_r) = coercionKind in_co
    
    272 272
             (Pair out_l out_r) = coercionKind out_co
    
    273
    -    in if (in_l `eqType` out_l) && (in_r `eqType` out_r)
    
    273
    +        in_l' = substTy subst in_l
    
    274
    +        in_r' = substTy subst in_r
    
    275
    +    in if (in_l' `eqType` out_l) && (in_r' `eqType` out_r)
    
    274 276
            then out_co
    
    275
    -       else pprTrace "optReflCo" (vcat [ text "in_l:"  <+> ppr in_l
    
    276
    -                                       , text "in_r:"  <+> ppr in_r
    
    277
    +       else pprTrace "optReflCo" (vcat [ text "in_l':"  <+> ppr in_l'
    
    278
    +                                       , text "in_r':"  <+> ppr in_r'
    
    277 279
                                            , text "out_l:" <+> ppr out_l
    
    278 280
                                            , text "out_r:" <+> ppr out_r
    
    279 281
                                            , text "in_co:" <+> ppr in_co
    

  • compiler/GHC/Core/Make.hs
    ... ... @@ -113,7 +113,7 @@ sortQuantVars vs = sorted_tcvs ++ ids
    113 113
     -- appropriate (see "GHC.Core#let_can_float_invariant")
    
    114 114
     mkCoreLet :: HasDebugCallStack => CoreBind -> CoreExpr -> CoreExpr
    
    115 115
     mkCoreLet (NonRec bndr rhs) body
    
    116
    -  = -- See Note [Core binding invariants: nested non-rec]
    
    116
    +  = -- See Note [Nested non-rec binding invariants]
    
    117 117
         bindNonRec bndr rhs body
    
    118 118
     mkCoreLet bind body
    
    119 119
       = Let bind body
    

  • compiler/GHC/Core/Opt/CSE.hs
    ... ... @@ -287,8 +287,8 @@ Here is another reason that we do not use SUBSTITUTE for
    287 287
     all trivial expressions. Consider
    
    288 288
        case x |> co of (y::Array# Int) { ... }
    
    289 289
     
    
    290
    -We do not want to extend the substitution with (y -> x |> co); since y
    
    291
    -is of unlifted type, this would destroy Note [Nested binding invariants]
    
    290
    +We do not want to extend the substitution with (y -> x |> co); since y is of
    
    291
    +unlifted type, this would destroy Note [Nested non-rec binding invariants]
    
    292 292
     if (x |> co) was not ok-for-speculation.
    
    293 293
     
    
    294 294
     But surely (x |> co) is ok-for-speculation, because it's a trivial
    

  • compiler/GHC/Core/Opt/ConstantFold.hs
    ... ... @@ -1607,7 +1607,7 @@ as follows:
    1607 1607
         in ...
    
    1608 1608
     
    
    1609 1609
     This was originally done in the fix to #16449 but this breaks
    
    1610
    -Note [Nested binding invariants] in GHC.Core, as noted in #16742.  For the
    
    1610
    +Note [Nested non-rec binding invariants] in GHC.Core, as noted in #16742.  For the
    
    1611 1611
     reasons discussed under "NoEffect" in Note [Classifying primop effects] (in
    
    1612 1612
     GHC.Builtin.PrimOps) there is no safe way to rewrite the argument of I# such
    
    1613 1613
     that it bottoms.
    
    ... ... @@ -2177,7 +2177,7 @@ BigNat). These rules implement the same kind of constant folding as we have for
    2177 2177
     Int#/Word#/etc. primops. See builtinBignumRules.
    
    2178 2178
     
    
    2179 2179
     These rules are built-in because they can't be expressed as regular rules for
    
    2180
    -now. The reason is that due to Note [Nested binding invariants] in GHC.Core,
    
    2180
    +now. The reason is that due to Note [Nested non-rec binding invariants] in GHC.Core,
    
    2181 2181
     GHC is too conservative with some bignum operations and they don't match rules.
    
    2182 2182
     For example:
    
    2183 2183
     
    
    ... ... @@ -2185,8 +2185,8 @@ For example:
    2185 2185
     
    
    2186 2186
     doesn't constant-fold into `integerAdd 2 x` with a regular rule. That's because
    
    2187 2187
     GHC never floats in `integerAdd 1 x` to form `integerAdd 1 (integerAdd 1 x)`
    
    2188
    -because of Note [Nested binding invariants] (it doesn't know if `integerAdd`
    
    2189
    -terminates).
    
    2188
    +because of Note [Nested non-rec binding invariants] (it doesn't know if
    
    2189
    +`integerAdd` terminates).
    
    2190 2190
     
    
    2191 2191
     In the built-in rule for `integerAdd` we can access the unfolding of `r` and we
    
    2192 2192
     can perform the appropriate substitution.
    

  • compiler/GHC/Core/Opt/FloatIn.hs
    ... ... @@ -665,7 +665,7 @@ noFloatIntoRhs is_rec bndr rhs
    665 665
       = isRec is_rec -- Joins are one-shot iff non-recursive
    
    666 666
     
    
    667 667
       | definitelyUnliftedType (idType bndr)
    
    668
    -  = True  -- Preserve Note [Nested binding invariants],
    
    668
    +  = True  -- Preserve Note [Nested non-rec binding invariants],
    
    669 669
               -- see Note [noFloatInto considerations]
    
    670 670
     
    
    671 671
       | otherwise
    
    ... ... @@ -691,7 +691,7 @@ When do we want to float bindings into
    691 691
        - noFloatIntoArg: the argument of a function application
    
    692 692
     
    
    693 693
     Definitely don't float into RHS if it has unlifted type;
    
    694
    -that would destroy Note [Nested binding invariants].
    
    694
    +that would destroy Note [Nested non-rec binding invariants].
    
    695 695
     
    
    696 696
     * Wrinkle 1: do not float in if
    
    697 697
          (a) any non-one-shot value lambdas
    

  • compiler/GHC/Core/Opt/SetLevels.hs
    ... ... @@ -1003,11 +1003,11 @@ Why? Because it's important /not/ to transform
    1003 1003
          let x = a /# 3
    
    1004 1004
     to
    
    1005 1005
          let x = case bx of I# a -> a /# 3
    
    1006
    -because the let binding no longer obeys Note [Nested binding invariants].
    
    1006
    +because the let binding no longer obeys Note [Nested non-rec binding invariants].
    
    1007 1007
     But (a /# 3) is ok-for-spec due to a special hack that says division operators
    
    1008 1008
     can't fail when the denominator is definitely non-zero.  And yet that same
    
    1009 1009
     expression says False to exprIsCheap.  Simplest way to guarantee
    
    1010
    -Note [Nested binding invariants] is to use the same function!
    
    1010
    +Note [Nested non-rec binding invariants] is to use the same function!
    
    1011 1011
     
    
    1012 1012
     If an expression is okay for speculation, we could also float it out
    
    1013 1013
     *without* boxing and unboxing, since evaluating it early is okay.
    

  • compiler/GHC/Core/Opt/Simplify/Env.hs
    ... ... @@ -749,8 +749,10 @@ Examples
    749 749
       NonRec x# (y +# 3)    FltOkSpec   -- Unboxed, but ok-for-spec'n
    
    750 750
     
    
    751 751
       NonRec x* (f y)       FltCareful  -- Strict binding; might fail or diverge
    
    752
    -  NonRec x# (a /# b)    FltCareful  -- Might fail; does not satisfy Note [Nested binding invariants]
    
    753
    -  NonRec x# (f y)       FltCareful  -- Might diverge; does not satisfy Note [Nested binding invariants]
    
    752
    +  NonRec x# (a /# b)    FltCareful  -- Might fail; does not satisfy
    
    753
    +                                     --    Note [Nested non-rec binding invariants]
    
    754
    +  NonRec x# (f y)       FltCareful  -- Might diverge; does not satisfy
    
    755
    +                                     --    Note [Nested non-rec binding invariants]
    
    754 756
     -}
    
    755 757
     
    
    756 758
     data LetFloats = LetFloats (OrdList OutBind) FloatFlag
    
    ... ... @@ -763,7 +765,8 @@ data FloatFlag
    763 765
       = FltLifted   -- All bindings are lifted and lazy *or*
    
    764 766
                     --     consist of a single primitive string literal
    
    765 767
                     -- Hence ok to float to top level, or recursive
    
    766
    -                -- NB: consequence: all bindings satisfy Note [Nested binding invariants]
    
    768
    +                -- NB: consequence: all bindings satisfy
    
    769
    +                --     Note [Nested non-rec binding invariants]
    
    767 770
     
    
    768 771
       | FltOkSpec   -- All bindings are FltLifted *or*
    
    769 772
                     --      strict (perhaps because unlifted,
    
    ... ... @@ -772,12 +775,14 @@ data FloatFlag
    772 775
                     -- Hence ok to float out of the RHS
    
    773 776
                     -- of a lazy non-recursive let binding
    
    774 777
                     -- (but not to top level, or into a rec group)
    
    775
    -                -- NB: consequence: all bindings satisfy Note [Nested binding invariants]
    
    778
    +                -- NB: consequence: all bindings satisfy
    
    779
    +                --     Note [Nested non-rec binding invariants]
    
    776 780
     
    
    777 781
       | FltCareful  -- At least one binding is strict (or unlifted)
    
    778 782
                     --      and not guaranteed cheap
    
    779 783
                     -- Do not float these bindings out of a lazy let!
    
    780
    -                -- NB: some bindings may not satisfy Note [Nested binding invariants]
    
    784
    +                -- NB: some bindings may not satisfy
    
    785
    +                --     Note [Nested non-rec binding invariants]
    
    781 786
     
    
    782 787
     instance Outputable LetFloats where
    
    783 788
       ppr (LetFloats binds ff) = ppr ff $$ ppr (fromOL binds)
    
    ... ... @@ -962,8 +967,10 @@ wrapFloats (SimplFloats { sfLetFloats = LetFloats bs flag
    962 967
          -- Note: Always safe to put the joins on the inside
    
    963 968
          -- since the values can't refer to them
    
    964 969
       where
    
    965
    -    mk_let | FltCareful <- flag = mkCoreLet -- Need to enforce Note [Nested binding invariants]
    
    966
    -           | otherwise          = Let       -- Note [Nested binding invariants] holds
    
    970
    +    mk_let | FltCareful <- flag
    
    971
    +           = mkCoreLet -- Need to enforce Note [Nested non-rec binding invariants]
    
    972
    +           | otherwise
    
    973
    +           = Let       -- Note [Nested non-rec binding invariants] holds
    
    967 974
     
    
    968 975
     wrapJoinFloatsX :: SimplFloats -> OutExpr -> (SimplFloats, OutExpr)
    
    969 976
     -- Wrap the sfJoinFloats of the env around the expression,
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -315,7 +315,7 @@ simplLazyBind :: TopLevelFlag -> RecFlag
    315 315
                   -> (InExpr, SimplEnv)     -- The RHS and its static environment
    
    316 316
                   -> SimplM (SimplFloats, SimplEnv)
    
    317 317
     -- Precondition: Ids only, no TyVars; not a JoinId
    
    318
    --- Precondition: rhs obeys Note [Nested binding invariants]
    
    318
    +-- Precondition: rhs obeys Note [Nested non-rec binding invariants]
    
    319 319
     simplLazyBind top_lvl is_rec (bndr,unf_se) (bndr1,env) (rhs,rhs_se)
    
    320 320
       = assert (isId bndr )
    
    321 321
         assertPpr (not (isJoinId bndr)) (ppr bndr) $
    
    ... ... @@ -397,7 +397,7 @@ simplAuxBind :: String
    397 397
     -- The binder comes from a case expression (case binder or alternative)
    
    398 398
     -- and so does not have rules, unfolding, inline pragmas etc.
    
    399 399
     --
    
    400
    --- Precondition: rhs satisfies Note [Nested binding invariants]
    
    400
    +-- Precondition: rhs satisfies Note [Nested non-rec binding invariants]
    
    401 401
     
    
    402 402
     simplAuxBind _str env bndr new_rhs
    
    403 403
       | assertPpr (isId bndr && not (isJoinId bndr)) (ppr bndr) $
    
    ... ... @@ -950,7 +950,7 @@ completeBind :: BindContext
    950 950
     --      * or by adding to the floats in the envt
    
    951 951
     --
    
    952 952
     -- Binder /can/ be a JoinId
    
    953
    --- Precondition: rhs obeys Note [Nested binding invariants]
    
    953
    +-- Precondition: rhs obeys Note [Nested non-rec binding invariants]
    
    954 954
     completeBind bind_cxt (old_bndr, unf_se) (new_bndr, new_rhs, env)
    
    955 955
       | isCoVar old_bndr
    
    956 956
       = case new_rhs of
    
    ... ... @@ -1290,7 +1290,7 @@ simplExprF1 env (Let (NonRec bndr rhs) body) cont
    1290 1290
            ; simplExprF (extendTvSubst env bndr ty') body cont }
    
    1291 1291
     
    
    1292 1292
       | Just env' <- preInlineUnconditionally env NotTopLevel bndr rhs env
    
    1293
    -    -- Because of Note [Nested binding invariants], it's ok to
    
    1293
    +    -- Because of Note [Nested non-rec binding invariants], it's ok to
    
    1294 1294
         -- inline freely, or to drop the binding if it is dead.
    
    1295 1295
       = do { simplTrace "SimplBindr:inline-uncond2" (ppr bndr <+> ppr rhs) $
    
    1296 1296
              tick (PreInlineUnconditionally bndr)
    
    ... ... @@ -1594,13 +1594,13 @@ rebuild_go env expr cont
    1594 1594
     completeBindX :: SimplEnv
    
    1595 1595
                   -> FromWhat
    
    1596 1596
                   -> InId -> OutExpr   -- Non-recursively bind this Id to this (simplified) expression
    
    1597
    -                                   -- (Note [Nested binding invariants] may not be satisfied)
    
    1597
    +                                   -- (Note [Nested non-rec binding invariants] may not be satisfied)
    
    1598 1598
                   -> InExpr            -- In this body
    
    1599 1599
                   -> SimplCont         -- Consumed by this continuation
    
    1600 1600
                   -> SimplM (SimplFloats, OutExpr)
    
    1601 1601
     completeBindX env from_what bndr rhs body cont
    
    1602 1602
       | FromBeta arg_levity <- from_what
    
    1603
    -  , needsCaseBindingL arg_levity rhs -- Enforcing Note [Nested binding invariants]
    
    1603
    +  , needsCaseBindingL arg_levity rhs -- Enforcing Note [Nested non-rec binding invariants]
    
    1604 1604
       = do { (env1, bndr1)   <- simplNonRecBndr env bndr  -- Lambda binders don't have rules
    
    1605 1605
            ; (floats, expr') <- simplNonRecBody env1 from_what body cont
    
    1606 1606
            -- Do not float floats past the Case binder below
    
    ... ... @@ -1887,7 +1887,7 @@ simplNonRecE :: HasDebugCallStack
    1887 1887
     -- It deals with strict bindings, via the StrictBind continuation,
    
    1888 1888
     -- which may abort the whole process.
    
    1889 1889
     --
    
    1890
    --- from_what=FromLet => the RHS satisfies Note [Nested binding invariants]
    
    1890
    +-- from_what=FromLet => the RHS satisfies Note [Nested non-rec binding invariants]
    
    1891 1891
     -- Otherwise it may or may not satisfy it.
    
    1892 1892
     
    
    1893 1893
     simplNonRecE env from_what bndr (rhs, rhs_se) body cont
    
    ... ... @@ -1909,8 +1909,8 @@ simplNonRecE env from_what bndr (rhs, rhs_se) body cont
    1909 1909
       where
    
    1910 1910
         is_strict_bind = case from_what of
    
    1911 1911
            FromBeta Unlifted -> True
    
    1912
    -       -- If we are coming from a beta-reduction (FromBeta) we must
    
    1913
    -       -- establish Note [Nested binding invariants], so go via StrictBind
    
    1912
    +       -- If we are coming from a beta-reduction (FromBeta) we must establish
    
    1913
    +       -- Note [Nested non-rec binding invariants], so go via StrictBind
    
    1914 1914
            -- If not, the invariant holds already, and it's optional.
    
    1915 1915
     
    
    1916 1916
            -- (FromBeta Lifted) or FromLet: look at the demand info
    
    ... ... @@ -2857,7 +2857,7 @@ this transformation:
    2857 2857
     We treat the unlifted and lifted cases separately:
    
    2858 2858
     
    
    2859 2859
     * Unlifted case: 'e' satisfies exprOkForSpeculation
    
    2860
    -  (ok-for-spec is needed to satisfy Note [Nested binding invariants].
    
    2860
    +  (ok-for-spec is needed to satisfy Note [Nested non-rec binding invariants].
    
    2861 2861
       This turns     case a +# b of r -> ...r...
    
    2862 2862
       into           let r = a +# b in ...r...
    
    2863 2863
       and thence     .....(a +# b)....
    
    ... ... @@ -3112,7 +3112,7 @@ rebuildCase env scrut case_bndr alts cont
    3112 3112
           assert (null bs) $
    
    3113 3113
           do { (floats1, env') <- simplAuxBind "rebuildCase" env case_bndr case_bndr_rhs
    
    3114 3114
                  -- scrut is a constructor application,
    
    3115
    -             -- hence satisfies Note [Nested binding invariants]
    
    3115
    +             -- hence satisfies Note [Nested non-rec binding invariants]
    
    3116 3116
              ; (floats2, expr') <- simplExprF env' rhs cont
    
    3117 3117
              ; case wfloats of
    
    3118 3118
                  [] -> return (floats1 `addFloats` floats2, expr')
    
    ... ... @@ -3624,13 +3624,14 @@ We pin on a (OtherCon []) unfolding to the case-binder of a Case,
    3624 3624
     even though it'll be over-ridden in every case alternative with a more
    
    3625 3625
     informative unfolding.  Why?  Because suppose a later, less clever, pass
    
    3626 3626
     simply replaces all occurrences of the case binder with the binder itself;
    
    3627
    -then Lint may complain about failing Note [Nested binding invariants].  Example
    
    3627
    +then Lint may complain about failing Note [Nested non-rec binding invariants].
    
    3628
    +Example:
    
    3628 3629
         case e of b { DEFAULT -> let v = reallyUnsafePtrEquality# b y in ....
    
    3629 3630
                     ; K       -> blah }
    
    3630 3631
     
    
    3631
    -Note [Nested binding invariants] requires that y is evaluated in the call to
    
    3632
    -reallyUnsafePtrEquality#, which it is.  But we still want that to be true if we
    
    3633
    -propagate binders to occurrences.
    
    3632
    +Note [Nested non-rec binding invariants] requires that y is evaluated in the
    
    3633
    +call to reallyUnsafePtrEquality#, which it is.  But we still want that to be
    
    3634
    +true if we propagate binders to occurrences.
    
    3634 3635
     
    
    3635 3636
     This showed up in #13027.
    
    3636 3637
     
    
    ... ... @@ -3732,7 +3733,7 @@ knownCon env scrut dc_floats dc dc_ty_args dc_args bndr bs rhs cont
    3732 3733
                  -- occur in the RHS; and simplAuxBind may therefore discard it.
    
    3733 3734
                  -- Nevertheless we must keep it if the case-binder is alive,
    
    3734 3735
                  -- because it may be used in the con_app.  See Note [knownCon occ info]
    
    3735
    -             -- NB: arg satisfies Note [Nested binding invariants]
    
    3736
    +             -- NB: arg satisfies Note [Nested non-rec binding invariants]
    
    3736 3737
                ; (floats1, env2) <- simplAuxBind "knownCon" env' b' arg
    
    3737 3738
                ; (floats2, env3) <- bind_args env2 bs' args
    
    3738 3739
                ; return (floats1 `addFloats` floats2, env3) }
    

  • compiler/GHC/Core/Opt/Simplify/Utils.hs
    ... ... @@ -1491,8 +1491,8 @@ preInlineUnconditionally
    1491 1491
         :: SimplEnv -> TopLevelFlag -> InId
    
    1492 1492
         -> InExpr -> StaticEnv  -- These two go together
    
    1493 1493
         -> Maybe SimplEnv       -- Returned env has extended substitution
    
    1494
    --- Precondition: rhs satisfies Note [Nested binding invariants]
    
    1495
    --- See Note [Nested binding invariants] in GHC.Core
    
    1494
    +-- Precondition: rhs satisfies Note [Nested non-rec binding invariants]
    
    1495
    +-- See Note [Nested non-rec binding invariants] in GHC.Core
    
    1496 1496
     -- Reason: we don't want to inline single uses, or discard dead bindings,
    
    1497 1497
     --         for unlifted, side-effect-ful bindings
    
    1498 1498
     preInlineUnconditionally env top_lvl bndr rhs rhs_env
    
    ... ... @@ -1638,7 +1638,7 @@ postInlineUnconditionally
    1638 1638
         -> InId -> OutId    -- The binder (*not* a CoVar), including its unfolding
    
    1639 1639
         -> OutExpr
    
    1640 1640
         -> Bool
    
    1641
    --- Precondition: rhs satisfies Note [Nested binding invariants] in GHC.Core
    
    1641
    +-- Precondition: rhs satisfies Note [Nested non-rec binding invariants] in GHC.Core
    
    1642 1642
     -- Reason: we don't want to inline single uses, or discard dead bindings,
    
    1643 1643
     --         for unlifted, side-effect-ful bindings
    
    1644 1644
     postInlineUnconditionally env bind_cxt old_bndr bndr rhs
    

  • compiler/GHC/Core/Opt/Specialise.hs
    ... ... @@ -1937,14 +1937,14 @@ where
    1937 1937
     
    
    1938 1938
     Left to itself, the specialiser would float the bindings for `x` and `n` to top
    
    1939 1939
     level, so we can specialise `wombat`.  But we can't have a top-level ByteArray#
    
    1940
    -(see Note [Core letrec invariant] in GHC.Core).  Boo.
    
    1940
    +(see Note [Top/rec binding invariants] in GHC.Core).  Boo.
    
    1941 1941
     
    
    1942 1942
     This is pretty exotic, so we take a simple way out: in specBind (the NonRec
    
    1943 1943
     case) do not float the binding itself unless it satisfies exprIsTopLevelBindable.
    
    1944 1944
     This is conservative: maybe the RHS of `x` has a free var that would stop it
    
    1945 1945
     floating to top level anyway; but that is hard to spot (since we don't know what
    
    1946 1946
     the non-top-level in-scope binders are) and rare (since the binding must satisfy
    
    1947
    -Note [Nested binding invariants] in GHC.Core).
    
    1947
    +Note [Nested non-rec binding invariants] in GHC.Core).
    
    1948 1948
     
    
    1949 1949
     
    
    1950 1950
     Note [Specialising Calls]
    

  • compiler/GHC/Core/SimpleOpt.hs
    ... ... @@ -381,7 +381,8 @@ simple_app env e0@(Lam {}) as0@(_:_)
    381 381
             -- See Note [Dark corner with representation polymorphism]
    
    382 382
             needsCaseBinding (idType b') (snd a)
    
    383 383
             -- This arg must not be inlined (side-effects) and cannot be let-bound,
    
    384
    -        -- due to Note [Nested binding invariants]. So simply case-bind it here.
    
    384
    +        -- due to Note [Nested non-rec binding invariants].
    
    385
    +        -- So simply case-bind it here.
    
    385 386
           , let a' = simple_opt_clo (soeInScope env) a
    
    386 387
           = mkDefaultCase a' b' $ do_beta env' body as
    
    387 388
     
    

  • compiler/GHC/Core/Utils.hs
    ... ... @@ -2042,15 +2042,15 @@ But we restrict it sharply:
    2042 2042
                                                    ; False -> e2 }
    
    2043 2043
                            in ...) ...
    
    2044 2044
     
    
    2045
    -  Does the RHS of v satisfy Note [Nested binding invariants]?
    
    2045
    +  Does the RHS of v satisfy Note [Nested non-rec binding invariants]?
    
    2046 2046
       Previously we said yes, on the grounds that y is evaluated.  But the
    
    2047 2047
       binder-swap done by GHC.Core.Opt.SetLevels would transform the inner
    
    2048 2048
       alternative to
    
    2049 2049
     
    
    2050 2050
          DEFAULT -> ... (let v::Int# = case x of { ... }
    
    2051 2051
                          in ...) ....
    
    2052
    -  which does /not/ satisfy Note [Nested bindings invariants], because x is
    
    2053
    -  not evaluated. See Note [Binder-swap during float-out]
    
    2052
    +  which does /not/ satisfy Note [Nested non-rec bindings invariants],
    
    2053
    +  because x is not evaluated. See Note [Binder-swap during float-out]
    
    2054 2054
       in GHC.Core.Opt.SetLevels.  To avoid this awkwardness it seems simpler
    
    2055 2055
       to stick to unlifted scrutinees where the issue does not
    
    2056 2056
       arise.
    
    ... ... @@ -2134,7 +2134,7 @@ extremely useful for float-out, changes these expressions to
    2134 2134
     
    
    2135 2135
     And now the expression does not obey the let-can-float invariant!  Yikes!
    
    2136 2136
     Moreover we really might float (dataToTagLarge# x) outside the case,
    
    2137
    -and then it really, really doesn't obey Note [Nested binding invariants].
    
    2137
    +and then it really, really doesn't obey Note [Nested non-rec binding invariants].
    
    2138 2138
     
    
    2139 2139
     The solution is simple: exprOkForSpeculation does not try to take
    
    2140 2140
     advantage of the evaluated-ness of (lifted) variables.  And it returns
    
    ... ... @@ -2144,7 +2144,7 @@ by marking the relevant primops as "ThrowsException" or
    2144 2144
     GHC.Builtin.PrimOps.
    
    2145 2145
     
    
    2146 2146
     Note that exprIsHNF /can/ and does take advantage of evaluated-ness;
    
    2147
    -it doesn't have the trickiness of Note [Nested binding invariants]
    
    2147
    +it doesn't have the trickiness of Note [Nested non-rec binding invariants]
    
    2148 2148
     to worry about.
    
    2149 2149
     
    
    2150 2150
     ************************************************************************
    

  • compiler/GHC/CoreToStg/Prep.hs
    ... ... @@ -302,7 +302,7 @@ expose the values:
    302 302
     see Note [wantFloatLocal].)
    
    303 303
     If `v` is bound at the top-level, we might even float `sat` to top-level;
    
    304 304
     see Note [Floating out of top level bindings].
    
    305
    -For nested let bindings, we have to keep in mind Note [Core letrec invariant]
    
    305
    +For nested let bindings, we have to keep in mind Note [Core binding invariants],
    
    306 306
     and may exploit strict contexts; see Note [wantFloatLocal].
    
    307 307
     
    
    308 308
     There are 3 main categories of floats, encoded in the `FloatingBind` type:
    
    ... ... @@ -1509,7 +1509,7 @@ Wrinkles:
    1509 1509
     
    
    1510 1510
     (FS1) We detect string literals in `cpeBind Rec{}` and float them out anyway;
    
    1511 1511
           otherwise we'd try to bind a string literal in a letrec, violating
    
    1512
    -      Note [Core letrec invariant]. Since we know that literals don't have
    
    1512
    +      Note [Top/rec binding invariants]. Since we know that literals don't have
    
    1513 1513
           free variables, we float further.
    
    1514 1514
           Arguably, we could just as well relax the letrec invariant for
    
    1515 1515
           string literals, or anthing that is a value (lifted or not).
    
    ... ... @@ -2363,7 +2363,7 @@ Wrinkles:
    2363 2363
                    x = f y r
    
    2364 2364
                    y = [x]
    
    2365 2365
             in e
    
    2366
    -      and now we have violated Note [Core letrec invariant].
    
    2366
    +      and now we have violated Note [Top/rec binding invariants].
    
    2367 2367
           So we preempt this case in `wantFloatLocal`, responding `FloatNone` unless
    
    2368 2368
           all floats are `TopLvlFloatable`.
    
    2369 2369
     -}
    

  • compiler/GHC/Driver/DynFlags.hs
    ... ... @@ -1233,7 +1233,7 @@ optLevelFlags -- see Note [Documenting optimisation flags]
    1233 1233
         , ([1,2],   Opt_DoCleverArgEtaExpansion) -- See Note [Eta expansion of arguments in CorePrep]
    
    1234 1234
         , ([0,1,2], Opt_DoEtaReduction)          -- See Note [Eta-reduction in -O0]
    
    1235 1235
         , ([0,1,2], Opt_ProfManualCcs )
    
    1236
    -    , ([0,1,2], Opt_OptCoercion )    -- See Note [Coercion optimisation] in GHC.Core.Coercion.Opt
    
    1236
    +    , ([2], Opt_OptCoercion )    -- See Note [Coercion optimisation] in GHC.Core.Coercion.Opt
    
    1237 1237
         , ([2], Opt_DictsStrict)
    
    1238 1238
     
    
    1239 1239
         , ([0],     Opt_IgnoreInterfacePragmas)
    

  • testsuite/tests/linear/should_compile/T26332.hs
    ... ... @@ -5,6 +5,12 @@ module T26332 where
    5 5
     
    
    6 6
     import Unsafe.Coerce
    
    7 7
     
    
    8
    +-- This function should be accepted by the typechecker, and should be
    
    9
    +-- linear-correct in the output of the desugarer, but will fail
    
    10
    +-- -dlinear-core-lint (which does a linear-lint check after every simplifier
    
    11
    +-- pass.  Because the optimiser discards a cast on `f` that only affects
    
    12
    +-- linearity
    
    13
    +
    
    8 14
     toLinear
    
    9 15
       :: forall a b p q.
    
    10 16
          (a %p-> b) %1-> (a %q-> b)
    

  • testsuite/tests/linear/should_compile/all.T
    ... ... @@ -42,7 +42,7 @@ test('T19400', unless(compiler_debugged(), skip), compile, [''])
    42 42
     test('T20023', normal, compile, [''])
    
    43 43
     test('T22546', normal, compile, [''])
    
    44 44
     test('T23025', normal, compile, ['-dlinear-core-lint'])
    
    45
    -test('T26332', normal, compile, ['-O -dlinear-core-lint'])
    
    45
    +test('T26332', normal, compile_fail, ['-O'])
    
    46 46
     test('LinearRecUpd', normal, compile, [''])
    
    47 47
     test('T23814', normal, compile, [''])
    
    48 48
     test('LinearLet', normal, compile, [''])