Simon Peyton Jones pushed to branch wip/case-bndr-unf at Glasgow Haskell Compiler / GHC

Commits:

18 changed files:

Changes:

  • changelog.d/T27962
    1
    +section: compiler
    
    2
    +issues: #27962
    
    3
    +mrs: !16829
    
    4
    +synopsis:
    
    5
    +  Fix a Lint error when using `runRW#` and `coerce` together
    
    6
    +description:
    
    7
    +  Just an internal compiler bug, of long standing.

  • changelog.d/T27963
    1
    +section: compiler
    
    2
    +issues: #27963
    
    3
    +mrs: !16829
    
    4
    +synopsis:
    
    5
    +  Fix a rather obscure interaction of `coerce` and RULES
    
    6
    +description:
    
    7
    +  A `coerce` could prevent a RULE firing.

  • compiler/GHC/Core.hs
    ... ... @@ -1393,6 +1393,151 @@ same way as above, otherwise the analysis would not be conservative wrt. the
    1393 1393
     lenient semantics (which includes the strict one). It is also much harder to
    
    1394 1394
     explain and maintain, as it turned out.
    
    1395 1395
     
    
    1396
    +Note [Core binder IdInfo invariants]
    
    1397
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1398
    +We allow the following IdInfo on different sorts of Core binders.
    
    1399
    +See the fields in GHC.Types.Id.Info.IdInfo:
    
    1400
    +
    
    1401
    +We classify binders into
    
    1402
    +  * let-binders                    let x=rhs in body
    
    1403
    +  * lambda binders                 (\x. e)
    
    1404
    +  * case binders                   case e of x { ... }
    
    1405
    +  * case-alternative binders       case e of _ { K x y -> ... }
    
    1406
    +
    
    1407
    +                         Let     Lambda   Case/case-alt
    
    1408
    +    ---------------------------------------------
    
    1409
    +    Occurrence           Yes     Yes      Yes
    
    1410
    +
    
    1411
    +    InlinePrag           Yes     No       No
    
    1412
    +    Strictness (DmdSig)  Yes     No       No
    
    1413
    +    CPR info (CprSig)    Yes     No       No
    
    1414
    +    CAF                  Yes     No       No
    
    1415
    +    Arity                Yes     No       No
    
    1416
    +    Call-arity           Yes     No       No
    
    1417
    +    Rules (RuleInfo)     Yes     No       No
    
    1418
    +    Unfolding            Yes     No(CBI1) evaldUnfolding only (CBI2)
    
    1419
    +    Demand info          Yes     Yes      Yes
    
    1420
    +    One-shot             No      Yes      No
    
    1421
    +    ------------------------------------------------
    
    1422
    +
    
    1423
    +The predicate `GHC.Types.Id.lamBndrInfoOK` checks the Lambda and Case columns
    
    1424
    +of this table (except one-shot info), and Core Lint applies it to every
    
    1425
    +non-let binder (`lintIdBndr`).
    
    1426
    +
    
    1427
    +Generally, lambda binders have only IdInfo that describes their /use/
    
    1428
    +(e.g. occ-info, demand info) not their /definition/.   See esp (CBI1).
    
    1429
    +
    
    1430
    +Case and case-alternative binders are similar because again they lack a definition,
    
    1431
    +and because they can /become/ a lambda binder when `mkDupableAlt` abstracts over them.
    
    1432
    +
    
    1433
    +Places that must take care to maintain these invariants (#27965):
    
    1434
    +
    
    1435
    +* The desugarer, when desugaring a strict binding  let !x = rhs in body,
    
    1436
    +  generates  case x of x { DEFAULT -> body }; the case binder must not inherit
    
    1437
    +  x's IdInfo.  See `GHC.HsToCore.Utils.seqVar`.
    
    1438
    +
    
    1439
    +* `GHC.Core.Utils.bindNonRec` (used by `mkCoreLet`, and hence by the
    
    1440
    +  Simplifier's `wrapFloats`), which turns  let x = rhs in body  into
    
    1441
    +  case rhs of x { DEFAULT -> body }  when `rhs` is unlifted and not
    
    1442
    +  ok-for-speculation.  Here `x` may well have a let-unfolding, e.g. one made
    
    1443
    +  by `makeTrivial`.
    
    1444
    +
    
    1445
    +* `GHC.Core.Opt.SpecConstr.mkSeqs`, which builds  case arg of arg' { DEFAULT -> rhs }
    
    1446
    +  where `arg` may be an imported Id with an unfolding.
    
    1447
    +
    
    1448
    +All three use `GHC.Types.Id.mkCaseBndrFromLetBndr`.
    
    1449
    +
    
    1450
    +* The Simplifier's `simplNonRecE` does not use a StrictBind continuation for a
    
    1451
    +  strict let-binding  let x = rhs in body  if `x` has RULES, a stable unfolding,
    
    1452
    +  or a non-default inline pragma; for if it did, `mkDupableContWithDmds` might
    
    1453
    +  turn `x` into the lambda binder of a join point.  See `use_strict_bind`.
    
    1454
    +
    
    1455
    +(CBI1) Based on #17530 and #21496 we never attach unfoldings of any kind to lambda
    
    1456
    +       binders, not even `evaldUnfolding`.
    
    1457
    +
    
    1458
    +       It's just too easy for the call site to change and invalidate the unfolding.
    
    1459
    +       E.g. the caller of the lambda drops a seq (e.g. because the lambda is strict
    
    1460
    +       in its binder) which in turn makes the OtherCon[] unfolding a lie.  So
    
    1461
    +       unfoldings on lambda binders can never really be trusted when on lambda
    
    1462
    +       binders if there is the chance of the call site to change. So it's easiest to
    
    1463
    +       just never attach any to lambda binders to begin with, as well as stripping
    
    1464
    +       them off if we e.g. float out an expression while abstracting over some
    
    1465
    +       arguments.
    
    1466
    +
    
    1467
    +(CBI2) See Note [Evaluated-ness on case binders]
    
    1468
    +
    
    1469
    +(CBI3) Note that /occurrences/ may have IdInfo that is not present on the binder.
    
    1470
    +   Notably, consider  case e of r { Just x -> ..r...; Nothing -> ...r... }
    
    1471
    +   The occurrence of `r` in the (Just x) branch will have an unfolding `Just x`,
    
    1472
    +   and similarly in the `Nothing` branch.  But the /binder/ of `r` has only
    
    1473
    +   `evaldUnfolding` See Note [Evaluated-ness on case binders]
    
    1474
    +
    
    1475
    +Note [Evaluated-ness on case binders]
    
    1476
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1477
    +The binding site of an Id in case expression (case-binder or case alternative) may
    
    1478
    +carry an `OtherCon []` (aka `evaldUnfolding`).  meaning "this variable is certainly
    
    1479
    +evaluated".  Specifically:
    
    1480
    +
    
    1481
    +* Case binders are always evaluated.  `GHC.Core.Opt.Simplify.Iteration.simplAlts` and
    
    1482
    +  CorePrep add `evaldUnfolding` to every case binder.
    
    1483
    +
    
    1484
    +* Case-alternative binders for strict constructor fields
    
    1485
    +  binders)
    
    1486
    +      data T = MkT !Int Int
    
    1487
    +      case x of MkT y z -> ...
    
    1488
    +  `y` gets an evaldUnfolding.
    
    1489
    +
    
    1490
    +  This is done by `GHC.Core.Utils.dataConRepFSInstPat` (used by the interface-file loader,
    
    1491
    +  among others), `GHC.Core.SimpleOpt`, the Simplifier (`adjustFieldsIdInfo`), and
    
    1492
    +  worker/wrapper (for the argument and CPR result binders it makes;
    
    1493
    +  see Note [Record evaluated-ness in worker/wrapper] in GHC.Core.Opt.WorkWrap.Utils).
    
    1494
    +
    
    1495
    +Why is this information on the /binder/?  Within the Simplifier it is not
    
    1496
    +needed there: in each case alternative the Simplifier adds a more precise
    
    1497
    +unfolding for the case binder (and evaluated-ness for strict-field binders) to
    
    1498
    +its in-scope set, and refreshes every occurrence from that.  But many other
    
    1499
    +passes rebuild variable occurrences /from the binder/: substitution-based
    
    1500
    +passes (SimpleOpt, Specialise, SpecConstr, CSE), SetLevels/FloatOut, the binder
    
    1501
    +swap in the occurrence analyser, CoreTidy, and CorePrep.  After such a pass,
    
    1502
    +an occurrence knows that the variable is evaluated only if the binder does.
    
    1503
    +
    
    1504
    +That knowledge is used, mainly via `exprIsHNF`/`varIsHNF` (not by
    
    1505
    +`exprOkForSpeculation`; see Note [exprOkForSpeculation and evaluated variables]
    
    1506
    +in GHC.Core.Utils), by:
    
    1507
    +
    
    1508
    +* CorePrep: deciding whether a let-binding is a value (allocate directly) or
    
    1509
    +  a thunk, e.g. `let x = Box y` where `y` is a strict field.
    
    1510
    +  See Note [Pin evaluatedness on floats] in GHC.CoreToStg.Prep.  CorePrep runs
    
    1511
    +  just after CoreTidy, which propagates binder IdInfo to occurrences.
    
    1512
    +
    
    1513
    +* SetLevels/FloatOut: floating single-alternative cases out of loops, when the
    
    1514
    +  scrutinee is evaluated; see Note [Floating single-alternative cases] in
    
    1515
    +  GHC.Core.Opt.SetLevels.  Also the call-by-value marks given to abstracted
    
    1516
    +  variables (`GHC.Types.Id.transferPolyIdInfo`).
    
    1517
    +
    
    1518
    +* Worker/wrapper: `move_transit_vars` avoids an unboxed 1-tuple for a single
    
    1519
    +  evaluated transit variable (test T18109); and the CPR result binders of the
    
    1520
    +  wrapper remain evaluated (tests T13077a, #13027).  The latter matters because
    
    1521
    +  unboxed-tuple alternatives take a fast path in the Simplifier's
    
    1522
    +  `adjustFieldsIdInfo`, and so get evaluated-ness only from the binder.
    
    1523
    +
    
    1524
    +* SimpleOpt: eliminating a case on an evaluated variable, and `mkFieldSeqFloats`.
    
    1525
    +
    
    1526
    +* Minor heuristic uses: FloatIn (the late FloatIn runs after FloatOut and CSE
    
    1527
    +  with no Simplifier in between) and occurrences created by CSE or the binder
    
    1528
    +  swap, until the next Simplifier run.
    
    1529
    +
    
    1530
    +Core Lint does /not/ depend on this information.  Nor does anything in STG or
    
    1531
    +tag inference.
    
    1532
    +
    
    1533
    +Removing the information from the binders would require these passes to track
    
    1534
    +evaluated-ness in an environment instead (as SpecConstr already does with its
    
    1535
    +ValueEnv), which they currently don't.  So we allow an OtherCon unfolding (and
    
    1536
    +only that) on case binders and case-alternative binders:
    
    1537
    +see the table in Note [Core binder IdInfo invariants]
    
    1538
    +
    
    1539
    +
    
    1540
    +
    
    1396 1541
     ************************************************************************
    
    1397 1542
     *                                                                      *
    
    1398 1543
                 In/Out type synonyms
    
    ... ... @@ -1742,16 +1887,6 @@ floatBinders (FloatTick {}) = []
    1742 1887
     
    
    1743 1888
     The @Unfolding@ type is declared here to avoid numerous loops
    
    1744 1889
     
    
    1745
    -Note [Never put `OtherCon` unfoldings on lambda binders]
    
    1746
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1747
    -Based on #21496 we never attach unfoldings of any kind to lambda binders.
    
    1748
    -It's just too easy for the call site to change and invalidate the unfolding.
    
    1749
    -E.g. the caller of the lambda drops a seq (e.g. because the lambda is strict in it's binder)
    
    1750
    -which in turn makes the OtherCon[] unfolding a lie.
    
    1751
    -So unfoldings on lambda binders can never really be trusted when on lambda binders if there
    
    1752
    -is the chance of the call site to change. So it's easiest to just never attach any
    
    1753
    -to lambda binders to begin with, as well as stripping them off if we e.g. float out
    
    1754
    -and expression while abstracting over some arguments.
    
    1755 1890
     -}
    
    1756 1891
     
    
    1757 1892
     -- | Records the /unfolding/ of an identifier, which is approximately the form the
    

  • compiler/GHC/Core/Lint.hs
    ... ... @@ -1858,6 +1858,15 @@ lintIdBndr top_lvl bind_site id thing_inside
    1858 1858
              hang (text "Lambda binder" <+> quotes (ppr id) <+> text "has an unfolding")
    
    1859 1859
                 2 (ppr unf)
    
    1860 1860
     
    
    1861
    +       -- Check that lambda, case, and case-alternative binders have
    
    1862
    +       -- only the IdInfo permitted by the table in
    
    1863
    +       -- Note [Core binder IdInfo invariants] in GHC.Core
    
    1864
    +       ; checkL (is_let_bind || lamBndrInfoOK id) $
    
    1865
    +         hang (text "Non-let binder" <+> quotes (ppr id)
    
    1866
    +               <+> text "has IdInfo that only a let-binder may have")
    
    1867
    +            2 (vcat [ text "Binding site:" <+> text (show_site bind_site)
    
    1868
    +                    , text "IdInfo:" <+> ppr (idInfo id) ])
    
    1869
    +
    
    1861 1870
            ; addLoc (IdTy id) (lintValueType id_ty)
    
    1862 1871
     
    
    1863 1872
            ; addInScopeId id thing_inside }
    
    ... ... @@ -1869,6 +1878,12 @@ lintIdBndr top_lvl bind_site id thing_inside
    1869 1878
                         LetBind -> True
    
    1870 1879
                         _       -> False
    
    1871 1880
     
    
    1881
    +    show_site :: BindingSite -> String
    
    1882
    +    show_site LambdaBind  = "lambda"
    
    1883
    +    show_site CaseBind    = "case binder"
    
    1884
    +    show_site CasePatBind = "case alternative"
    
    1885
    +    show_site LetBind     = "let"
    
    1886
    +
    
    1872 1887
     {-
    
    1873 1888
     %************************************************************************
    
    1874 1889
     %*                                                                      *
    

  • compiler/GHC/Core/Opt/Simplify/Env.hs
    ... ... @@ -28,7 +28,7 @@ module GHC.Core.Opt.Simplify.Env (
    28 28
             SimplEnvIS,  checkSimplEnvIS, pprBadSimplEnvIS,
    
    29 29
     
    
    30 30
             -- * Substitution results
    
    31
    -        SimplSR(..), substId, lookupRecBndr,
    
    31
    +        SimplClo(..), simplCloExpr, substId, lookupRecBndr,
    
    32 32
     
    
    33 33
             -- * Simplifying 'Id' binders
    
    34 34
             simplNonRecBndr, simplNonRecJoinBndr, simplRecBndrs, simplRecJoinBndrs,
    
    ... ... @@ -61,7 +61,7 @@ import GHC.Core.Opt.Simplify.Monad
    61 61
     import GHC.Core.Rules.Config ( RuleOpts(..) )
    
    62 62
     import GHC.Core
    
    63 63
     import GHC.Core.Utils
    
    64
    -import GHC.Core.Subst( substExprSC )
    
    64
    +import GHC.Core.Subst( substExpr )
    
    65 65
     import GHC.Core.Unfold
    
    66 66
     import GHC.Core.TyCo.Subst (emptyIdSubstEnv, mkSubst)
    
    67 67
     import GHC.Core.Multiplicity( Scaled(..), mkMultMul )
    
    ... ... @@ -470,18 +470,26 @@ pprSimplEnv env
    470 470
        ppr_one v | isId v = ppr v <+> ppr (idUnfolding v)
    
    471 471
                  | otherwise = ppr v
    
    472 472
     
    
    473
    -type SimplIdSubst = IdEnv SimplSR -- IdId |--> OutExpr
    
    473
    +type SimplIdSubst = IdEnv SimplClo -- IdId |--> OutExpr
    
    474 474
             -- See Note [Extending the IdSubstEnv] in GHC.Core.Subst
    
    475 475
     
    
    476
    --- | A substitution result.
    
    477
    -data SimplSR
    
    476
    +-- | A "closure" used in the Simplifier.  It is used
    
    477
    +--     * as the range of the substitution, 'SimplIdSubst'
    
    478
    +--     * as the argument in an 'ApplyToVal' continuation
    
    479
    +-- Roughly: either an (InExpr, StaticEnv) pair for an
    
    480
    +--                 as-yet-unsimplified expression
    
    481
    +--          or     an OutExpr, for an already-simplified one
    
    482
    +-- It's a bit like thunk: we may "evaluate" the SimplClo in a ApplyToVal
    
    483
    +--   and thereby transform it from `ContEx` to `DoneEx`
    
    484
    +--   This happens in the `ApplyToVal` case of `mkDupableContWithDmds`
    
    485
    +--   See Note [The argument of ApplyToVal] in GHC.Core.Opt.Simplify.Utils
    
    486
    +data SimplClo
    
    478 487
       = DoneEx OutExpr JoinPointHood
    
    479 488
            -- If  x :-> DoneEx e ja   is in the SimplIdSubst
    
    480 489
            -- then replace occurrences of x by e
    
    481 490
            -- and  ja = Just a <=> x is a join-point of arity a
    
    482 491
            -- See Note [Join arity in SimplIdSubst]
    
    483 492
     
    
    484
    -
    
    485 493
       | DoneId OutId
    
    486 494
            -- If  x :-> DoneId v   is in the SimplIdSubst
    
    487 495
            -- then replace occurrences of x by v
    
    ... ... @@ -490,11 +498,11 @@ data SimplSR
    490 498
     
    
    491 499
       | ContEx SimplEnv
    
    492 500
                InExpr
    
    493
    -           MOutCoercion  -- See Note [The sc_cast field of ApplyToVal]
    
    501
    +           MOutCoercion  -- See Note [The MOutCoercion field of ContEx]
    
    494 502
           -- If   x :-> ContEx static_env e mco   is in the SimplISubst
    
    495 503
           -- then replace occurrences of x by (subst static_env e) |> mco
    
    496 504
     
    
    497
    -instance Outputable SimplSR where
    
    505
    +instance Outputable SimplClo where
    
    498 506
       ppr (DoneId v)    = text "DoneId" <+> ppr v
    
    499 507
       ppr (DoneEx e mj) = text "DoneEx" <> pp_mj <+> ppr e
    
    500 508
         where
    
    ... ... @@ -637,7 +645,7 @@ reSimplifying :: SimplEnv -> Bool
    637 645
     reSimplifying (SimplEnv { seInlineDepth = n }) = n>0
    
    638 646
     
    
    639 647
     ---------------------
    
    640
    -extendIdSubst :: SimplEnv -> Id -> SimplSR -> SimplEnv
    
    648
    +extendIdSubst :: SimplEnv -> Id -> SimplClo -> SimplEnv
    
    641 649
     extendIdSubst env@(SimplEnv {seIdSubst = subst}) var res
    
    642 650
       = assertPpr (isId var && not (isCoVar var)) (ppr var) $
    
    643 651
         env { seIdSubst = extendVarEnv subst var res }
    
    ... ... @@ -1032,7 +1040,7 @@ So we want to look up the inner X.g_34 in the substitution, where we'll
    1032 1040
     find that it has been substituted by b.  (Or conceivably cloned.)
    
    1033 1041
     -}
    
    1034 1042
     
    
    1035
    -substId :: SimplEnv -> InId -> SimplSR
    
    1043
    +substId :: SimplEnv -> InId -> SimplClo
    
    1036 1044
     -- Returns DoneEx only on a non-Var expression
    
    1037 1045
     substId (SimplEnv { seInScope = in_scope, seIdSubst = ids }) v
    
    1038 1046
       = case lookupVarEnv ids v of  -- Note [Global Ids in the substitution]
    
    ... ... @@ -1364,15 +1372,18 @@ getTCvSubst (SimplEnv { seInScope = in_scope, seTvSubst = tv_env, seCvSubst = cv
    1364 1372
     
    
    1365 1373
     getFullSubst :: InScopeSet -> SimplEnv -> Subst
    
    1366 1374
     getFullSubst in_scope (SimplEnv { seIdSubst = id_env, seTvSubst = tv_env, seCvSubst = cv_env })
    
    1367
    -  = mkSubst in_scope (mapVarEnv to_expr id_env) tv_env cv_env
    
    1375
    +  = mkSubst in_scope (mapVarEnv (simplCloExpr in_scope) id_env) tv_env cv_env
    
    1376
    +
    
    1377
    +simplCloExpr :: InScopeSet -> SimplClo -> OutExpr
    
    1378
    +-- Turn a SimplClo into an OutExpr, by applying the substitution
    
    1379
    +-- (if any) and the pending cast (if any)
    
    1380
    +simplCloExpr _        (DoneEx e _)       = e
    
    1381
    +simplCloExpr _        (DoneId v)         = Var v
    
    1382
    +simplCloExpr in_scope (ContEx env e mco) = mkCastMCo e' mco
    
    1368 1383
       where
    
    1369
    -    to_expr :: SimplSR -> CoreExpr
    
    1370
    -    -- A tiresome impedence-matcher
    
    1371
    -    to_expr (DoneEx e _)       = e
    
    1372
    -    to_expr (DoneId v)         = Var v
    
    1373
    -    to_expr (ContEx env e mco) = mkCastMCo e' mco
    
    1374
    -      where
    
    1375
    -        e' = GHC.Core.Subst.substExprSC (getFullSubst in_scope env) e
    
    1384
    +    e' = GHC.Core.Subst.substExpr (getFullSubst in_scope env) e
    
    1385
    +    -- NB: we use substExpr, not substExprSC: we want to get the benefit of
    
    1386
    +    --     knowing what is evaluated etc, via the in-scope set
    
    1376 1387
     
    
    1377 1388
     substTy :: HasDebugCallStack => SimplEnv -> Type -> Type
    
    1378 1389
     substTy env ty = Type.substTy (getTCvSubst env) ty
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -285,8 +285,8 @@ simplRecOrTopPair :: SimplEnv
    285 285
                       -> SimplM (SimplFloats, SimplEnv)
    
    286 286
     
    
    287 287
     simplRecOrTopPair env bind_cxt old_bndr new_bndr rhs
    
    288
    -  | Just env' <- preInlineUnconditionally env (bindContextLevel bind_cxt)
    
    289
    -                                          old_bndr (UnSimplified env) rhs MRefl
    
    288
    +  | Just env' <- preInlineLetUnconditionally env (bindContextLevel bind_cxt)
    
    289
    +                                             old_bndr rhs env
    
    290 290
       = {-#SCC "simplRecOrTopPair-pre-inline-uncond" #-}
    
    291 291
         simplTrace "SimplBindr:inline-uncond1" (ppr old_bndr) $
    
    292 292
         do { tick (PreInlineUnconditionally old_bndr)
    
    ... ... @@ -1226,17 +1226,8 @@ simplExprF1 env (Tick t expr) cont = {-#SCC "simplTick" #-} simplTick env t exp
    1226 1226
     simplExprF1 env (Coercion co)  cont = {-#SCC "simplCoercionF" #-} simplCoercionF env co cont
    
    1227 1227
     
    
    1228 1228
     simplExprF1 env (Cast body co) cont
    
    1229
    -  = do  { co1 <- {-#SCC "simplCast-simplCoercion" #-}
    
    1230
    -                 simplCoercion env co
    
    1231
    -
    
    1232
    -        ; let cont1 = {-#SCC "simplCast-addCoerce" #-}
    
    1233
    -                      if isReflCo co1
    
    1234
    -                      then cont  -- See Note [Optimising reflexivity]
    
    1235
    -                      else pushCast env co1 cont
    
    1236
    -                           -- True <=> co1 is optimised
    
    1237
    -
    
    1238
    -        ; {-#SCC "simplCast-simplExprF" #-}
    
    1239
    -          simplExprF env body cont1 }
    
    1229
    +  = do  { co1 <- simplCoercion env co
    
    1230
    +        ; simplExprF env body (pushCast env co1 cont) }
    
    1240 1231
     
    
    1241 1232
     simplExprF1 env (App fun arg) cont
    
    1242 1233
       = {-#SCC "simplExprF1-App" #-} case arg of
    
    ... ... @@ -1264,9 +1255,9 @@ simplExprF1 env (App fun arg) cont
    1264 1255
               -- observed the quadratic behavior, so this extra entanglement
    
    1265 1256
               -- seems not worthwhile.
    
    1266 1257
             simplExprF env fun $
    
    1267
    -        ApplyToVal { sc_arg = arg, sc_env = UnSimplified env
    
    1258
    +        ApplyToVal { sc_arg = ContEx env arg MRefl, sc_dup = NoDup
    
    1268 1259
                        , sc_hole_ty = substTy env (exprType fun)
    
    1269
    -                   , sc_cast = MRefl, sc_cont = cont }
    
    1260
    +                   , sc_cont = cont }
    
    1270 1261
     
    
    1271 1262
     simplExprF1 env expr@(Lam {}) cont
    
    1272 1263
       = {-#SCC "simplExprF1-Lam" #-}
    
    ... ... @@ -1301,7 +1292,7 @@ simplExprF1 env (Let (NonRec bndr rhs) body) cont
    1301 1292
         do { ty' <- simplType env ty
    
    1302 1293
            ; simplExprF (extendTvSubst env bndr ty') body cont }
    
    1303 1294
     
    
    1304
    -  | Just env' <- preInlineUnconditionally env NotTopLevel bndr (UnSimplified env) rhs MRefl
    
    1295
    +  | Just env' <- preInlineLetUnconditionally env NotTopLevel bndr rhs env
    
    1305 1296
         -- Because of the let-can-float invariant, it's ok to
    
    1306 1297
         -- inline freely, or to drop the binding if it is dead.
    
    1307 1298
       = do { simplTrace "SimplBindr:inline-uncond2" (ppr bndr) $
    
    ... ... @@ -1637,9 +1628,8 @@ rebuild_go env expr cont
    1637 1628
           ApplyToTy  { sc_arg_ty = ty, sc_cont = cont}
    
    1638 1629
             -> rebuild_go env (App expr (Type ty)) cont
    
    1639 1630
     
    
    1640
    -      ApplyToVal { sc_arg = arg, sc_env = arg_se, sc_cast = arg_mco
    
    1641
    -                 , sc_cont = cont, sc_hole_ty = fun_ty }
    
    1642
    -        -> do { arg' <- simplArg env Nothing fun_ty arg_se arg arg_mco
    
    1631
    +      ApplyToVal { sc_arg = arg, sc_cont = cont, sc_hole_ty = fun_ty }
    
    1632
    +        -> do { arg' <- simplArg env Nothing fun_ty arg
    
    1643 1633
                   ; rebuild_go env (App expr arg') cont }
    
    1644 1634
     
    
    1645 1635
     completeBindX :: SimplEnv
    
    ... ... @@ -1653,6 +1643,7 @@ completeBindX env from_what bndr rhs body cont
    1653 1643
       | FromBeta arg_levity <- from_what
    
    1654 1644
       , needsCaseBindingL arg_levity rhs -- Enforcing the let-can-float-invariant
    
    1655 1645
       = do { (env1, bndr1)   <- simplNonRecBndr env bndr  -- Lambda binders don't have rules
    
    1646
    +                            -- See Note [Core binder IdInfo invariants] in GHC.Core
    
    1656 1647
            ; (floats, expr') <- simplNonRecBody env1 from_what body cont
    
    1657 1648
            -- Do not float floats past the Case binder below
    
    1658 1649
            ; let expr'' = wrapFloats floats expr'
    
    ... ... @@ -1686,69 +1677,12 @@ completeBindX env from_what bndr rhs body cont
    1686 1677
             ; let all_floats = rhs_floats `addFloats` bind_float `addFloats` body_floats
    
    1687 1678
             ; return ( all_floats, body' ) }
    
    1688 1679
     
    
    1689
    -{-
    
    1690
    -************************************************************************
    
    1680
    +
    
    1681
    +{- *********************************************************************
    
    1691 1682
     *                                                                      *
    
    1692
    -\subsection{Lambdas}
    
    1683
    +                Arguments
    
    1693 1684
     *                                                                      *
    
    1694
    -************************************************************************
    
    1695
    --}
    
    1696
    -
    
    1697
    -{- Note [Optimising reflexivity]
    
    1698
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1699
    -It's important (for compiler performance) to get rid of reflexivity as soon
    
    1700
    -as it appears.  See #11735, #14737, and #15019.
    
    1701
    -
    
    1702
    -In particular, we want to behave well on
    
    1703
    -
    
    1704
    - *  e |> co1 |> co2
    
    1705
    -    where the two happen to cancel out entirely. That is quite common;
    
    1706
    -    e.g. a newtype wrapping and unwrapping cancel.
    
    1707
    -
    
    1708
    -
    
    1709
    - * (f |> co) @t1 @t2 ... @tn x1 .. xm
    
    1710
    -   Here we will use pushCoTyArg and pushCoValArg successively, which
    
    1711
    -   build up SelCo stacks.  Silly to do that if co is reflexive.
    
    1712
    -
    
    1713
    -However, we don't want to call isReflexiveCo too much, because it uses
    
    1714
    -type equality which is expensive on big types (#14737 comment:7).
    
    1715
    -
    
    1716
    -A good compromise (determined experimentally) seems to be to call
    
    1717
    -isReflexiveCo
    
    1718
    - * when composing casts, and
    
    1719
    - * at the end
    
    1720
    -
    
    1721
    -In investigating this I saw missed opportunities for on-the-fly
    
    1722
    -coercion shrinkage. See #15090.
    
    1723
    -
    
    1724
    -Note [Avoid re-simplifying coercions]
    
    1725
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1726
    -In some benchmarks (with deeply nested cases) we successively push
    
    1727
    -casts onto the SimplCont.  We don't want to call the coercion optimiser
    
    1728
    -on each successive composition -- that's at least quadratic.  So:
    
    1729
    -
    
    1730
    -* The CastIt constructor in SimplCont has a `sc_opt :: Bool` flag to
    
    1731
    -  record whether the coercion optimiser has been applied to the coercion.
    
    1732
    -
    
    1733
    -* In `simplCast`, when we see (Cast e co), we simplify `co` to get
    
    1734
    -  an OutCoercion, and built a CastIt with sc_opt=True.
    
    1735
    -
    
    1736
    -  Actually not quite: if we are simplifying the result of inlining an
    
    1737
    -  unfolding (seInlineDepth > 0), then instead of /optimising/ it again,
    
    1738
    -  just /substitute/ which is cheaper.  See `simplCoercion`.
    
    1739
    -
    
    1740
    -* In `pushCast` if we combine this new coercion with an existing one,
    
    1741
    -  we build a CastIt for (co1 ; co2) with sc_opt=False.
    
    1742
    -
    
    1743
    -* When unpacking a CastIt, in `rebuild`, we optimise the (presumably
    
    1744
    -  composed) coercion if sc_opt=False; this is done by `optOutCoercion`.
    
    1745
    -
    
    1746
    -* When duplicating a continuation in `mkDupableContWithDmds`, before
    
    1747
    -  duplicating a CastIt, optimise the coercion. Otherwise we'll end up
    
    1748
    -  optimising it separately in the duplicate copies.
    
    1749
    -
    
    1750
    -* See also Note [The sc_cast field of ApplyToVal] in GHC.Core.Opt.Simplify.Utils.
    
    1751
    --}
    
    1685
    +********************************************************************* -}
    
    1752 1686
     
    
    1753 1687
     simplArg :: SimplEnvIS              -- ^ Used only for its InScopeSet
    
    1754 1688
              -> Maybe ArgInfo           -- ^ Just <=> This arg `ai` occurs in an app
    
    ... ... @@ -1756,15 +1690,12 @@ simplArg :: SimplEnvIS -- ^ Used only for its InScopeSet
    1756 1690
                                         --   how `f` uses `ai`, affecting the Stop
    
    1757 1691
                                         --   continuation passed to 'simplExprC'
    
    1758 1692
              -> OutType                 -- ^ Type of the function applied to this arg
    
    1759
    -         -> StaticEnv -> CoreExpr   -- ^ Expression with its static envt
    
    1760
    -         -> MOutCoercion            -- Wrap this around the result
    
    1693
    +         -> SimplClo                -- ^ The argument
    
    1761 1694
              -> SimplM OutExpr
    
    1762
    -simplArg _ _ _ (Simplified {}) arg mco
    
    1763
    -  = -- See Note [Avoid repeated simplification]
    
    1764
    -    case mco of
    
    1765
    -       MRefl  -> return arg       -- Vastly common case
    
    1766
    -       MCo co -> return (mkCast arg co)
    
    1767
    -simplArg env mb_arg_info fun_ty (UnSimplified arg_se) arg mco
    
    1695
    +-- See Note [The argument of ApplyToVal] in GHC.Core.Opt.Simplify.Utils
    
    1696
    +simplArg _ _ _ (DoneEx arg _) = return arg  -- See Note [Avoid repeated simplification]
    
    1697
    +simplArg _ _ _ (DoneId v)     = return (Var v)
    
    1698
    +simplArg env mb_arg_info fun_ty (ContEx arg_se arg mco)
    
    1768 1699
       = do { let arg_env' = arg_se `setInScopeFromE` env
    
    1769 1700
                  arg_ty   = funArgTy fun_ty
    
    1770 1701
                  stop     = case mb_arg_info of
    
    ... ... @@ -1773,13 +1704,12 @@ simplArg env mb_arg_info fun_ty (UnSimplified arg_se) arg mco
    1773 1704
                  cont     = addCastMCo mco stop
    
    1774 1705
            ; simplExprC arg_env' arg cont }
    
    1775 1706
     
    
    1776
    -{-
    
    1777
    -************************************************************************
    
    1707
    +
    
    1708
    +{- *********************************************************************
    
    1778 1709
     *                                                                      *
    
    1779
    -\subsection{Lambdas}
    
    1710
    +                Lambdas
    
    1780 1711
     *                                                                      *
    
    1781
    -************************************************************************
    
    1782
    --}
    
    1712
    +********************************************************************* -}
    
    1783 1713
     
    
    1784 1714
     simplNonRecBody :: SimplEnv -> FromWhat
    
    1785 1715
                     -> InExpr -> SimplCont
    
    ... ... @@ -1806,13 +1736,9 @@ simpl_lam env bndr body (ApplyToTy { sc_arg_ty = arg_ty, sc_cont = cont })
    1806 1736
     
    
    1807 1737
     -- Value beta-reduction
    
    1808 1738
     -- This works for /coercion/ lambdas too
    
    1809
    -simpl_lam env bndr body (ApplyToVal { sc_arg = arg, sc_env = arg_se
    
    1810
    -                                    , sc_cast = arg_mco, sc_cont = cont
    
    1739
    +simpl_lam env bndr body (ApplyToVal { sc_arg = arg, sc_cont = cont
    
    1811 1740
                                         , sc_hole_ty = fun_ty})
    
    1812
    -  | Just env' <- preInlineUnconditionally env NotTopLevel bndr arg_se arg arg_mco
    
    1813
    -  , not (needsCaseBindingL arg_levity arg)
    
    1814
    -              -- Ok to test arg::InExpr in needsCaseBinding because
    
    1815
    -              -- exprOkForSpeculation is stable under simplification
    
    1741
    +  | Just env' <- preInlineBetaUnconditionally env arg_levity bndr arg
    
    1816 1742
       = simplTrace "SimplBindr:inline-uncond3"
    
    1817 1743
              (ppr bndr <+> text ":=" <+> ppr arg) $
    
    1818 1744
         do { tick (BetaReduction bndr)
    
    ... ... @@ -1823,14 +1749,14 @@ simpl_lam env bndr body (ApplyToVal { sc_arg = arg, sc_env = arg_se
    1823 1749
       = do { tick (BetaReduction bndr)
    
    1824 1750
            ; let from_what = FromBeta arg_levity
    
    1825 1751
     
    
    1826
    -       ; case (arg_se, arg_mco) of
    
    1827
    -           (UnSimplified arg_env, MRefl)
    
    1752
    +       ; case arg of
    
    1753
    +           ContEx arg_env arg_expr MRefl
    
    1828 1754
                  -- Optimisation: when there is no wrapping coercion use simplNonRecE
    
    1829 1755
                  -- so that the clever floating out of let-bindings can take place
    
    1830 1756
                  -- in this round of the Simplifier
    
    1831
    -             -> simplNonRecE env from_what bndr (arg, arg_env) body cont
    
    1757
    +             -> simplNonRecE env from_what bndr (arg_expr, arg_env) body cont
    
    1832 1758
     
    
    1833
    -           _ -> do { arg' <- simplArg env Nothing fun_ty arg_se arg arg_mco
    
    1759
    +           _ -> do { arg' <- simplArg env Nothing fun_ty arg
    
    1834 1760
                        ; completeBindX env from_what bndr arg' body cont }
    
    1835 1761
            }
    
    1836 1762
       where
    
    ... ... @@ -1869,7 +1795,7 @@ simplLamBndr :: SimplEnv -> InBndr -> SimplM (SimplEnv, OutBndr)
    1869 1795
     -- could have a stable unfolding;
    
    1870 1796
     -- see Historical Note [Case binders and join points]
    
    1871 1797
     -- But now it is much simpler! We now only remove unfoldings.
    
    1872
    --- See Note [Never put `OtherCon` unfoldings on lambda binders]
    
    1798
    +-- See (CBI1) in Note [Core binder IdInfo invariants]
    
    1873 1799
     simplLamBndr env bndr = simplBinder env (zapIdUnfolding bndr)
    
    1874 1800
     
    
    1875 1801
     simplLamBndrs :: SimplEnv -> [InBndr] -> SimplM (SimplEnv, [OutBndr])
    
    ... ... @@ -1903,7 +1829,7 @@ simplNonRecE :: HasDebugCallStack
    1903 1829
     
    
    1904 1830
     simplNonRecE env from_what bndr (rhs, rhs_se) body cont
    
    1905 1831
       | assert (isId bndr && not (isJoinId bndr) ) $
    
    1906
    -    is_strict_bind
    
    1832
    +    use_strict_bind
    
    1907 1833
       = -- Evaluate RHS strictly
    
    1908 1834
         simplExprF (rhs_se `setInScopeFromE` env) rhs
    
    1909 1835
                    (StrictBind { sc_bndr = bndr, sc_body = body, sc_from = from_what
    
    ... ... @@ -1918,14 +1844,31 @@ simplNonRecE env from_what bndr (rhs, rhs_se) body cont
    1918 1844
            ; return (floats1 `addFloats` floats2, expr') }
    
    1919 1845
     
    
    1920 1846
       where
    
    1921
    -    is_strict_bind = case from_what of
    
    1922
    -       FromBeta Unlifted -> True
    
    1847
    +    info = idInfo bndr
    
    1848
    +
    
    1849
    +    use_strict_bind
    
    1923 1850
            -- If we are coming from a beta-reduction (FromBeta) we must
    
    1924
    -       -- establish the let-can-float invariant, so go via StrictBind
    
    1851
    +       -- establish the let-can-float invariant, so we must go via StrictBind
    
    1925 1852
            -- If not, the invariant holds already, and it's optional.
    
    1853
    +       | FromBeta Unlifted <- from_what
    
    1854
    +       = True
    
    1855
    +
    
    1856
    +       -- Not if the demand is non-strict
    
    1857
    +       | not (isStrUsedDmd (demandInfo info))
    
    1858
    +       = False
    
    1859
    +
    
    1860
    +       -- Not if case-of-case is off
    
    1861
    +       -- See (SB1) in Note [StrictBind]
    
    1862
    +       | not (seCaseCase env)
    
    1863
    +       = False
    
    1864
    +
    
    1865
    +       -- Not for things with RULES or INLINE or NOINLINE
    
    1866
    +       -- See (SB3) in Note [StrictBind]
    
    1867
    +       | FromLet <- from_what
    
    1868
    +       , not (lamBndrInfoOK bndr)
    
    1869
    +       =  False
    
    1926 1870
     
    
    1927
    -       -- (FromBeta Lifted) or FromLet: look at the demand info
    
    1928
    -       _ -> seCaseCase env && isStrUsedDmd (idDemandInfo bndr)
    
    1871
    +       | otherwise = True
    
    1929 1872
     
    
    1930 1873
     
    
    1931 1874
     ------------------
    
    ... ... @@ -2262,11 +2205,14 @@ simplOutId env fun cont
    2262 2205
       | fun `hasKey` runRWKey
    
    2263 2206
       , ApplyToTy  { sc_cont = cont1 } <- cont
    
    2264 2207
       , ApplyToTy  { sc_cont = cont2, sc_arg_ty = hole_ty } <- cont1
    
    2265
    -  , ApplyToVal { sc_cont = cont3, sc_arg = arg, sc_cast = arg_mco
    
    2266
    -               , sc_env = arg_se, sc_hole_ty = fun_ty } <- cont2
    
    2208
    +  , ApplyToVal { sc_cont = cont3, sc_arg = arg_clo, sc_hole_ty = fun_ty } <- cont2
    
    2267 2209
       -- Do this even if (contIsStop cont), or if seCaseCase is off.
    
    2268 2210
       -- See Note [No eta-expansion in runRW#]
    
    2269
    -  = do { let (_saf,arg_env) = mkAltEnv env arg_se
    
    2211
    +  = do { let (arg_env, arg, arg_mco)
    
    2212
    +                = case arg_clo of
    
    2213
    +                    ContEx se e mco -> (se `setInScopeFromE` env, e, mco)
    
    2214
    +                    DoneEx e _      -> (env, e,     MRefl)
    
    2215
    +                    DoneId v        -> (env, Var v, MRefl)
    
    2270 2216
     
    
    2271 2217
                  overall_res_ty = contResultType cont3
    
    2272 2218
                  -- hole_ty is the type of the current runRW# application
    
    ... ... @@ -2281,23 +2227,32 @@ simplOutId env fun cont
    2281 2227
            --    * If we don't do this we get a beta-redex every time, so the
    
    2282 2228
            --      simplifier keeps doing more iterations.
    
    2283 2229
            --    * Even more important: see Note [No eta-expansion in runRW#]
    
    2230
    +       --
    
    2231
    +       -- But only if there is no pending cast on the argument (#27962);
    
    2232
    +       -- if there is, the general case below deals with it properly
    
    2284 2233
            ; arg' <- case arg of
    
    2285
    -           Lam s body -> do { (env', s') <- simplBinder arg_env s
    
    2286
    -                            ; body' <- simplExprC env' body inner_cont
    
    2287
    -                            ; return (Lam s' body') }
    
    2288
    -                            -- Important: do not try to eta-expand this lambda
    
    2289
    -                            -- See Note [No eta-expansion in runRW#]
    
    2234
    +           Lam s body
    
    2235
    +             | MRefl <- arg_mco
    
    2236
    +             -> do { (env', s') <- simplBinder arg_env s
    
    2237
    +                   ; body' <- simplExprC env' body inner_cont
    
    2238
    +                   ; return (Lam s' body') }
    
    2239
    +                   -- Important: do not try to eta-expand this lambda
    
    2240
    +                   -- See Note [No eta-expansion in runRW#]
    
    2290 2241
     
    
    2291 2242
                _ -> do { s' <- newId (fsLit "s") ManyTy realWorldStatePrimTy
    
    2292 2243
                        ; let (m,_,_) = splitFunTy fun_ty
    
    2293 2244
                              env'  = arg_env `addNewInScopeIds` [s']
    
    2294 2245
                              hole_ty = mkVisFunTy m realWorldStatePrimTy new_runrw_res_ty
    
    2295 2246
                              cont' = pushCastMCo env' arg_mco $
    
    2296
    -                                 ApplyToVal { sc_arg = Var s', sc_cast = MRefl
    
    2297
    -                                            , sc_env = Simplified OkDup
    
    2247
    +                                 ApplyToVal { sc_arg  = DoneId s'
    
    2248
    +                                            , sc_dup  = dup
    
    2298 2249
                                                 , sc_cont = inner_cont
    
    2299 2250
                                                 , sc_hole_ty = hole_ty }
    
    2300 2251
                                      -- cont' applies to s', then K
    
    2252
    +                         -- The argument (Var s') is small, but inner_cont may not be
    
    2253
    +                         -- dupable; see (AV2) in Note [The argument of ApplyToVal]
    
    2254
    +                         dup | contIsDupable inner_cont = OkDup
    
    2255
    +                             | otherwise                = NoDup
    
    2301 2256
                        ; body' <- simplExprC env' arg cont'
    
    2302 2257
                        ; return (Lam s' body') }
    
    2303 2258
     
    
    ... ... @@ -2364,13 +2319,12 @@ rebuildCall env info (ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_c
    2364 2319
     
    
    2365 2320
     ---------- Simplify value arguments --------------------
    
    2366 2321
     rebuildCall env fun_info
    
    2367
    -            (ApplyToVal { sc_arg = arg, sc_env = arg_se, sc_cast = arg_mco
    
    2368
    -                        , sc_hole_ty = fun_ty, sc_cont = cont })
    
    2369
    -  | UnSimplified arg_env <- arg_se
    
    2322
    +            (ApplyToVal { sc_arg = arg, sc_hole_ty = fun_ty, sc_cont = cont })
    
    2323
    +  | ContEx arg_env arg_expr arg_mco <- arg
    
    2370 2324
       , isStrictArgInfo fun_info  -- Strict arguments
    
    2371 2325
       , seCaseCase env            -- But only when case-of-case is on.
    
    2372 2326
                                   -- See Note [Case-of-case and full laziness]
    
    2373
    -  = simplExprF (arg_env `setInScopeFromE` env) arg $
    
    2327
    +  = simplExprF (arg_env `setInScopeFromE` env) arg_expr $
    
    2374 2328
         addCastMCo arg_mco $
    
    2375 2329
         StrictArg { sc_fun = fun_info, sc_fun_ty = fun_ty
    
    2376 2330
                   , sc_dup = NoDup
    
    ... ... @@ -2382,7 +2336,7 @@ rebuildCall env fun_info
    2382 2336
       -- There is no benefit (unlike in a let-binding), and we'd
    
    2383 2337
       -- have to be very careful about bogus strictness through
    
    2384 2338
       -- floating a demanded let.
    
    2385
    -  = do  { arg' <- simplArg env (Just fun_info) fun_ty arg_se arg arg_mco
    
    2339
    +  = do  { arg' <- simplArg env (Just fun_info) fun_ty arg
    
    2386 2340
             ; rebuildCall env (addValArgTo fun_info  arg' fun_ty) cont }
    
    2387 2341
     
    
    2388 2342
     ---------- No further useful info, revert to generic rebuild ------------
    
    ... ... @@ -2530,11 +2484,11 @@ Then
    2530 2484
      * We simplify BIG before trying the rule; but the rule does not fire
    
    2531 2485
        (forcing this simplification is why we have the RULE in this example)
    
    2532 2486
      * We inline f = \x. g x, in `simpl_lam`
    
    2533
    - * So if `simpl_lam` did preInlineUnconditionally we get (g BIG)
    
    2487
    + * So if `simpl_lam` did preInlineBetaUnconditionally we get (g BIG)
    
    2534 2488
      * Now if g has a RULE we'll simplify BIG again, and this whole thing can
    
    2535 2489
        iterate.
    
    2536 2490
      * However, if `f` did not have a RULE, so that BIG has /not/ already been
    
    2537
    -   simplified, we /want/ to do preInlineUnconditionally in simpl_lam.
    
    2491
    +   simplified, we /want/ to do preInlineBetaUnconditionally in simpl_lam.
    
    2538 2492
     
    
    2539 2493
     So we go to some effort to avoid repeatedly simplifying the same thing.
    
    2540 2494
     Suppose we are in the Plan (AFTER) case of rule application, for a rule
    
    ... ... @@ -2543,8 +2497,9 @@ and a call
    2543 2497
           f (e1,e2)
    
    2544 2498
     Then:
    
    2545 2499
     
    
    2546
    -* The (sc_env :: StaticEnv) field of ApplyToVal records if the argument
    
    2547
    -  has been evaluated.  See Note [StaticEnv] in GHC.Core.Opt.Simplify.Utils.
    
    2500
    +* The (sc_arg :: SimplClo) field of ApplyToVal records if the argument
    
    2501
    +  has been simplified: it is a DoneEx if so, and a ContEx if not.
    
    2502
    +  See Note [The argument of ApplyToVal] in GHC.Core.Opt.Simplify.Utils.
    
    2548 2503
     
    
    2549 2504
     * The rule fires returning
    
    2550 2505
          RuleMatch { rm_rhs = (\x y. ...x..), rm_args = [ e1, e2 ] }
    
    ... ... @@ -2557,17 +2512,17 @@ Then:
    2557 2512
       is the reason that `RuleMatch` separates the two.
    
    2558 2513
     
    
    2559 2514
     * `fireRuleAFTER` uses `pushOutArgs` to push [ e1, e2 ] back onto the
    
    2560
    -  continuation with sc_env=Simplified NoDup.
    
    2515
    +  continuation as (DoneEx e1) and (DoneEx e2).
    
    2561 2516
     
    
    2562 2517
     * Beta-reduction fires (in `simpl_lam`) for the \x.
    
    2563 2518
     
    
    2564 2519
     * Suppose `x` occurs many times.  Then we want to behave like `let x=e1 in ..`,
    
    2565
    -  but we use `simplArg`, which in turn uses that `sc_env` flag to avoid
    
    2520
    +  but we use `simplArg`, which in turn uses the DoneEx to avoid
    
    2566 2521
       re-simplifying `e1`.
    
    2567 2522
     
    
    2568 2523
     * Suppose `x` occurs just once or not at all; then the call to
    
    2569
    -  `preInlineUnconditionally` in `simpl_lam` will fire, and extend the
    
    2570
    -  substitution with
    
    2524
    +  `preInlineBetaUnconditionally` in `simpl_lam` will fire, and extend the
    
    2525
    +  substitution with the very same SimplClo
    
    2571 2526
           x :-> DoneEx e1
    
    2572 2527
     
    
    2573 2528
     * At the /occurrence/ of `x`, the function `simplInId` calls `simplOutExpr`
    
    ... ... @@ -2774,8 +2729,7 @@ trySeqRules in_env scrut rhs cont
    2774 2729
                      , ValArg { as_arg = no_cast_scrut
    
    2775 2730
                               , as_dmd = seqDmd
    
    2776 2731
                               , as_hole_ty = res3_ty } ]
    
    2777
    -    rule_cont = ApplyToVal { sc_env = UnSimplified in_env, sc_arg = rhs
    
    2778
    -                           , sc_cast = MRefl
    
    2732
    +    rule_cont = ApplyToVal { sc_arg = ContEx in_env rhs MRefl, sc_dup = NoDup
    
    2779 2733
                                , sc_cont = cont, sc_hole_ty = res4_ty }
    
    2780 2734
     
    
    2781 2735
         out_args = [Type rhs_rep, Type scrut_ty, Type rhs_ty, no_cast_scrut]
    
    ... ... @@ -3420,6 +3374,7 @@ simplAlts (saf,env0) scrut case_bndr alts cont'
    3420 3374
             ; let case_bndr2 = case_bndr1 `setIdUnfolding` evaldUnfolding
    
    3421 3375
                   env2       = modifyInScope env1 case_bndr2
    
    3422 3376
                   -- See Note [Case binder evaluated-ness]
    
    3377
    +              -- and Note [Evaluated-ness on case binders] in GHC.Core
    
    3423 3378
                   fam_envs   = seFamEnvs env0
    
    3424 3379
     
    
    3425 3380
             ; (alt_env', scrut', case_bndr') <- improveSeq fam_envs (saf,env2) scrut
    
    ... ... @@ -3879,8 +3834,8 @@ knownCon env scrut dc dc_args case_bndr alt_bndrs rhs cont
    3879 3834
             return ( emptyFloats env
    
    3880 3835
                    , extendIdSubst env case_bndr (DoneEx scrut NotJoinPoint))
    
    3881 3836
     
    
    3882
    -      | Just env' <- preInlineUnconditionally env NotTopLevel case_bndr
    
    3883
    -                            (UnSimplified env) con_app MRefl
    
    3837
    +      | Just env' <- preInlineLetUnconditionally env NotTopLevel case_bndr
    
    3838
    +                                                 con_app env
    
    3884 3839
           = return (emptyFloats env', env')
    
    3885 3840
     
    
    3886 3841
           | otherwise
    
    ... ... @@ -4043,7 +3998,7 @@ mkDupableContWithDmds env dmds (TickIt t cont)
    4043 3998
     mkDupableContWithDmds env _
    
    4044 3999
          cont1@(StrictBind { sc_bndr = bndr, sc_body = body, sc_from = from_what
    
    4045 4000
                            , sc_env = se, sc_cont = cont})
    
    4046
    --- See Note [Duplicating StrictBind]
    
    4001
    +-- See (SB2) in Note [StrictBind]
    
    4047 4002
     -- K[ let x = <> in b ]  -->   join j x = K[ b ]
    
    4048 4003
     --                             j <>
    
    4049 4004
       = do { let sb_env = case se of
    
    ... ... @@ -4060,7 +4015,10 @@ mkDupableContWithDmds env _
    4060 4015
            ; let join_body = wrapFloats floats1 join_inner
    
    4061 4016
                  res_ty    = contResultType cont
    
    4062 4017
     
    
    4063
    -       ; mkDupableStrictBind env bndr' join_body res_ty }
    
    4018
    +       -- bndr' is about to become a lambda binder, so it must have suitable
    
    4019
    +       -- IdInfo; simplNonRecE ensures this.  See Note [Core binder IdInfo invariants]
    
    4020
    +       ; assertPpr (lamBndrInfoOK bndr') (ppr bndr' $$ ppr (idInfo bndr')) $
    
    4021
    +         mkDupableStrictBind env bndr' join_body res_ty }
    
    4064 4022
     
    
    4065 4023
     mkDupableContWithDmds env _
    
    4066 4024
         (StrictArg { sc_fun = fun, sc_cont = cont
    
    ... ... @@ -4111,8 +4069,7 @@ mkDupableContWithDmds env dmds
    4111 4069
                                         , sc_arg_ty = arg_ty, sc_hole_ty = hole_ty }) }
    
    4112 4070
     
    
    4113 4071
     mkDupableContWithDmds env dmds
    
    4114
    -    (ApplyToVal { sc_arg = arg, sc_env = se, sc_cast = arg_mco
    
    4115
    -                , sc_cont = cont, sc_hole_ty = hole_ty })
    
    4072
    +    (ApplyToVal { sc_arg = arg, sc_cont = cont, sc_hole_ty = hole_ty })
    
    4116 4073
       =     -- e.g.         [...hole...] (...arg...)
    
    4117 4074
             --      ==>
    
    4118 4075
             --              let a = ...arg...
    
    ... ... @@ -4124,12 +4081,12 @@ mkDupableContWithDmds env dmds
    4124 4081
                     expectNonEmpty dmds
    
    4125 4082
             ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont
    
    4126 4083
             ; let env' = env `setInScopeFromF` floats1
    
    4127
    -        ; arg' <- simplArg env' Nothing hole_ty se arg arg_mco
    
    4084
    +        ; arg' <- simplArg env' Nothing hole_ty arg
    
    4128 4085
             ; (let_floats2, triv_arg) <- makeTrivial env' NotTopLevel dmd (fsLit "karg") arg'
    
    4129 4086
             ; let all_floats = floats1 `addLetFloats` let_floats2
    
    4130 4087
             ; return ( all_floats
    
    4131
    -                 , ApplyToVal { sc_arg = triv_arg, sc_env = Simplified OkDup
    
    4132
    -                              , sc_cast = MRefl, sc_cont = cont', sc_hole_ty = hole_ty }) }
    
    4088
    +                 , ApplyToVal { sc_arg = DoneEx triv_arg NotJoinPoint, sc_dup = OkDup
    
    4089
    +                              , sc_cont = cont', sc_hole_ty = hole_ty }) }
    
    4133 4090
     
    
    4134 4091
     mkDupableContWithDmds env _
    
    4135 4092
         (Select { sc_bndr = case_bndr, sc_alts = alts, sc_env = se, sc_cont = cont })
    
    ... ... @@ -4253,7 +4210,9 @@ mkDupableAlt _env case_bndr jfloats (Alt con alt_bndrs alt_rhs_in)
    4253 4210
                              | otherwise = v
    
    4254 4211
     
    
    4255 4212
                   -- No lambda binder has an unfolding, but (currently) case binders can,
    
    4256
    -              -- so we must zap them here.
    
    4213
    +              -- so we must zap them here.  But case binders never have a pragma,
    
    4214
    +              -- stable unfolding or RULES, so there is no need to zap those.
    
    4215
    +              -- See Note [Core binder IdInfo invariants] in GHC.Core
    
    4257 4216
                   join_rhs   = mkLams (map zapIdUnfolding final_bndrs) rhs_with_seqs
    
    4258 4217
     
    
    4259 4218
             ; join_bndr <- newJoinId filtered_binders rhs_ty'
    
    ... ... @@ -4569,7 +4528,7 @@ There are two ways to make it duplicable.
    4569 4528
                       ; False -> jump $j r2 }
    
    4570 4529
     
    
    4571 4530
       Notice that Plan B is very like the way we handle strict bindings;
    
    4572
    -  see Note [Duplicating StrictBind].  And Plan B is exactly what we'd
    
    4531
    +  see Note [StrictBind].  And Plan B is exactly what we'd
    
    4573 4532
       get if we turned use a case expression to evaluate the strict arg:
    
    4574 4533
     
    
    4575 4534
            case (case x of { True -> r1; False -> r2 }) of
    
    ... ... @@ -4642,23 +4601,54 @@ Note [Inline small things to avoid creating a thunk] in
    4642 4601
     Simplify.Utils. But if we do inline them, the entire process will
    
    4643 4602
     repeat -- back to exponential behaviour.
    
    4644 4603
     
    
    4645
    -So we are careful to keep the demand-info on a2 and a3.  Then they'll
    
    4646
    -be /strict/ let-bindings, which will be dealt with by StrictBind.
    
    4647
    -That's why contIsDupableWithDmds is careful to propagage demand
    
    4648
    -info to the auxiliary bindings it creates.  See the Demand argument
    
    4649
    -to makeTrivial.
    
    4650
    -
    
    4651
    -Note [Duplicating StrictBind]
    
    4652
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    4653
    -We make a StrictBind duplicable in a very similar way to
    
    4654
    -that for case expressions.  After all,
    
    4655
    -   let x* = e in b   is similar to    case e of x -> b
    
    4656
    -
    
    4657
    -So we potentially make a join-point for the body, thus:
    
    4658
    -   let x = <> in b   ==>   join j x = b
    
    4659
    -                           in j <>
    
    4660
    -
    
    4661
    -Just like StrictArg in fact -- and indeed they share code.
    
    4604
    +So we are careful to keep the demand-info on a2 and a3.  Then they'll be
    
    4605
    +/strict/ let-bindings, which will be dealt with by `StrictBind` (see
    
    4606
    +Note [StrictBind]).  That's why `contIsDupableWithDmds` is careful to
    
    4607
    +propagate demand info to the auxiliary bindings it creates.  See the
    
    4608
    +`Demand` argument to `makeTrivial`.
    
    4609
    +
    
    4610
    +Note [StrictBind]
    
    4611
    +~~~~~~~~~~~~~~~~~
    
    4612
    +We use StrictBind when we fine
    
    4613
    +   let x! = rhs in body
    
    4614
    +where the `x` is definitely demanded in body.  When this happens we can
    
    4615
    +float out case-expressions etc from inside `e`; e.g.
    
    4616
    +   let { x! = case a of (p,q) -> rhs } in b
    
    4617
    +-->
    
    4618
    +   case a of (p,q) -> let x! = rhs in b
    
    4619
    +
    
    4620
    +We simplify `rhs` with a StrictBind continuation that continues with
    
    4621
    +`body`
    
    4622
    +
    
    4623
    +(SB1) We only use StrictBind when case-of-case is on:
    
    4624
    +   see Note [Case-of-case and full laziness]
    
    4625
    +
    
    4626
    +(SB2) We make a StrictBind /duplicable/ in a very similar way to
    
    4627
    +   that for case expressions.  After all,
    
    4628
    +      let x! = e in b   is similar to    case e of x -> b
    
    4629
    +
    
    4630
    +   So we potentially make a join-point for the body, thus:
    
    4631
    +     let x = <> in b   ==>   join j x = b
    
    4632
    +                             in j <>
    
    4633
    +
    
    4634
    +   Just like StrictArg in fact -- and indeed they share code.
    
    4635
    +
    
    4636
    +(SB3) We do not do use StrictBind if the binder `x` has:
    
    4637
    +      * A stable unfolding
    
    4638
    +      * RULES
    
    4639
    +      * An inlining activation that is not always active.
    
    4640
    +   Why not? Because these things won't survive if we duplicate the join point.
    
    4641
    +   For example:
    
    4642
    +       let {-# NOINLINE x #-}
    
    4643
    +           x! = case y of { ... }
    
    4644
    +       in blah
    
    4645
    +   If we make a join point  j x = blah, we have nowhere convenient
    
    4646
    +   to put that NOINLINE.  Ditto INLINE or RULES.  It's very unusual,
    
    4647
    +   so no harm in simply not using StrictBind.  But it does happen;
    
    4648
    +   one example is this, in the Applicative (ST s) instance in
    
    4649
    +   GHC.Internal.Control.Monad.St.Lazy.Imp
    
    4650
    +         {-# NOINLINE res1 #-}
    
    4651
    +         !res1 = unST fm s
    
    4662 4652
     
    
    4663 4653
     Note [Join point abstraction]  Historical note
    
    4664 4654
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

  • compiler/GHC/Core/Opt/Simplify/Utils.hs
    ... ... @@ -12,7 +12,8 @@ module GHC.Core.Opt.Simplify.Utils (
    12 12
             tryEtaExpandRhs, wantEtaExpansion,
    
    13 13
     
    
    14 14
             -- Inlining,
    
    15
    -        preInlineUnconditionally, postInlineUnconditionally,
    
    15
    +        preInlineLetUnconditionally, preInlineBetaUnconditionally,
    
    16
    +        postInlineUnconditionally,
    
    16 17
             activeRule,
    
    17 18
             getUnfoldingInRuleMatch,
    
    18 19
             updModeForStableUnfoldings, updModeForRuleLHS, updModeForRuleRHS,
    
    ... ... @@ -174,16 +175,14 @@ data SimplCont
    174 175
                                     -- Invariant: never an identity coercion
    
    175 176
           , sc_opt  :: Bool         -- True <=> sc_co has had optCoercion applied to it
    
    176 177
                                     --      See Note [Avoid re-simplifying coercions]
    
    177
    -                                --      in GHC.Core.Opt.Simplify.Iteration
    
    178 178
           , sc_cont :: SimplCont }
    
    179 179
     
    
    180 180
       | ApplyToVal         -- (ApplyToVal arg K)[e] = K[ e arg ]
    
    181 181
           { sc_hole_ty :: OutType    -- Type of the function, presumably (forall a. blah)
    
    182 182
                                      -- See Note [The hole type in ApplyToTy]
    
    183
    -      , sc_env  :: StaticEnv     -- See Note [StaticEnv]
    
    184
    -      , sc_arg  :: CoreExpr      -- The argument
    
    185
    -      , sc_cast :: MOutCoercion  -- Wrap this OutCoercion around the (simplified) argument
    
    186
    -                                 -- See Note [The sc_cast field of ApplyToVal]
    
    183
    +      , sc_dup  :: DupFlag       -- See Note [The argument of ApplyToVal]
    
    184
    +      , sc_arg  :: SimplClo      -- The argument
    
    185
    +                                 -- Invariant: if sc_arg is a ContEx, then sc_dup = NoDup
    
    187 186
           , sc_cont :: SimplCont }
    
    188 187
     
    
    189 188
       | ApplyToTy          -- (ApplyToTy ty K)[e] = K[ e ty ]
    
    ... ... @@ -201,6 +200,7 @@ data SimplCont
    201 200
       -- The two strict forms have no DupFlag, because we never duplicate them
    
    202 201
       | StrictBind          -- (StrictBind x b K)[e] = let x = e in K[b]
    
    203 202
                             --       or, equivalently,  = K[ (\x.b) e ]
    
    203
    +                        -- See Note [StrictBind] in GHC.Core.Opt.Simplify.Iteration
    
    204 204
           { sc_from  :: FromWhat
    
    205 205
           , sc_env   :: StaticEnv  -- See Note [StaticEnv]
    
    206 206
                                    -- The sc_env in StrictBind is never (Simplified NoDup)
    
    ... ... @@ -252,49 +252,85 @@ perhapsSubstTy (UnSimplified env) ty = substTy env ty
    252 252
     
    
    253 253
     {- Note [StaticEnv]
    
    254 254
     ~~~~~~~~~~~~~~~~~~~
    
    255
    -Consider ApplyToVal, which has
    
    256
    -    sc_env :: StaticEnv
    
    257
    -    sc_arg :: CoreExpr
    
    258
    -Initially, `sc_arg` is an un-simplified InExpr, and `sc_env` is (UnSimplified env),
    
    259
    -where `env` gives meaning to the free variables of `sc_arg`; in particular, `env`
    
    260
    -may have substitutions that must apply to the argument.
    
    261
    -
    
    262
    -But sometimes we simplify the argument, and in that case, `sc_arg` is an OutExpr,
    
    263
    -the simplified argument, and `sc_env` is (Simplified NoDup) or (Simplified OkDup).
    
    264
    -The former is the safe, conservative option, but in `mkDupableCont` we want to make
    
    265
    -the continuation duplicable, so we make the argument small and tag it with
    
    266
    -(Simplified OkDup).
    
    267
    -
    
    268
    -We later simplify the argument, e.g. in `simplArg`.  Then
    
    269
    -  * If sc_env is Simplified, it's a no-op
    
    270
    -  * If sc_env is (UnSimplified arg_env) we simplify `sc_arg` with
    
    271
    -     - Its captured envt `arg_env`
    
    255
    +Consider Select, which has
    
    256
    +    sc_env  :: StaticEnv
    
    257
    +    sc_bndr :: Id
    
    258
    +    sc_alts :: [CoreAlt]
    
    259
    +Initially, `sc_bndr` and `sc_alts` are un-simplified InThings, and `sc_env` is
    
    260
    +(UnSimplified env), where `env` gives meaning to their free variables; in
    
    261
    +particular, `env` may have substitutions that must apply to them.
    
    262
    +
    
    263
    +But sometimes (notably in `mkDupableCont`) we simplify them, and in that case
    
    264
    +`sc_bndr` and `sc_alts` are OutThings, and `sc_env` is (Simplified dup).
    
    265
    +
    
    266
    +When we finally simplify the alternatives (see `mkAltEnv`)
    
    267
    +  * If sc_env is Simplified, there is nothing to do
    
    268
    +  * If sc_env is (UnSimplified alt_env) we simplify them with
    
    269
    +     - Their captured envt `alt_env`
    
    272 270
          - but overriding its InScopeSet with the larger one at the
    
    273 271
            simplification point.
    
    274 272
         Why override the InScopeSet?  Example:
    
    275
    -          (let y = ey in f) ex
    
    276
    -    By the time we simplify ex, 'y' will be in scope.
    
    277
    -  All this is done in `simplArg`.
    
    273
    +          case (let y = ey in f) of alts
    
    274
    +    By the time we simplify alts, 'y' will be in scope.
    
    278 275
     
    
    279 276
     Note that:
    
    280 277
     
    
    281 278
     * In the Simplified case there is no environment, because the substitution has
    
    282 279
       already been applied.
    
    283 280
     
    
    284
    -* We say sc_arg :: CoreExpr, rather than sc_arg :: InExpr or sc_arg :: OutExpr,
    
    285
    -  because whether it is InExpr or OutExpr depends on `sc_env`
    
    281
    +* We say sc_alts :: [CoreAlt], rather than [InAlt] or [OutAlt],
    
    282
    +  because whether they are InAlts or OutAlts depends on `sc_env`
    
    283
    +
    
    284
    +* Same deal for StrictBind, where the StaticEnv scopes over sc_bndr and sc_body.
    
    286 285
     
    
    287
    -* Same deal for Select, and StrictBind, but the StaticEnv scopes over
    
    288
    -    * sc_bndr and sc_alts (for Select)
    
    289
    -    * sc_bndr and sc_body (for StrictBind)
    
    286
    +* ApplyToVal is similar, but simpler: it uses a SimplClo instead.
    
    287
    +  See Note [The argument of ApplyToVal].
    
    290 288
     
    
    291
    -* Even though the InScopeSet of an (UnSimplified se) is overridden in `simplArg`,
    
    292
    -  that InScopeSet is not irrelevant: it should include all the free vars of
    
    293
    -  applying the substitution to the InExpr. Reason: contHoleType uses perhapsSubstTy
    
    294
    -  to apply the substitution to the expression, and that (rightly) gives ASSERT
    
    295
    -  failures if the InScopeSet isn't big enough.
    
    289
    +* Even though the InScopeSet of an (UnSimplified se) is overridden, that
    
    290
    +  InScopeSet is not irrelevant: it should include all the free vars of
    
    291
    +  applying the substitution to the InThing. Reason: contHoleType uses
    
    292
    +  perhapsSubstTy to apply the substitution to the binder, and that
    
    293
    +  (rightly) gives ASSERT failures if the InScopeSet isn't big enough.
    
    296 294
     
    
    297 295
     (SE1) If dup = OkToDup, then continuation k is also ok-to-dup
    
    296
    +
    
    297
    +Note [The argument of ApplyToVal]
    
    298
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    299
    +ApplyToVal has
    
    300
    +    sc_dup :: DupFlag
    
    301
    +    sc_arg :: SimplClo
    
    302
    +
    
    303
    +Initially, `sc_arg` is (ContEx env arg MRefl), where `arg` is the un-simplified
    
    304
    +InExpr, and `env` gives meaning to the free variables of `arg`; in particular,
    
    305
    +`env` may have substitutions that must apply to the argument.
    
    306
    +
    
    307
    +But sometimes we simplify the argument, and in that case, `sc_arg` is
    
    308
    +(DoneEx arg' NotJoinPoint), where `arg'` is the simplified argument.
    
    309
    +
    
    310
    +The `sc_dup` flag says whether the continuation can be duplicated.  NoDup is
    
    311
    +the safe, conservative option, but in `mkDupableCont` we want to make the
    
    312
    +continuation duplicable, so we make the argument small (and hence a DoneEx)
    
    313
    +and set `sc_dup` to OkDup.  Invariants:
    
    314
    +
    
    315
    +  (AV1) If `sc_arg` is a ContEx, then `sc_dup` is NoDup.
    
    316
    +
    
    317
    +  (AV2) If `sc_dup` is OkDup then `sc_cont` is also ok-to-dup; see (SE1)
    
    318
    +        in Note [StaticEnv].
    
    319
    +
    
    320
    +We later simplify the argument, in `simplArg`.  Then
    
    321
    +  * If `sc_arg` is a DoneEx (or DoneId), it's a no-op
    
    322
    +  * If `sc_arg` is (ContEx arg_env arg mco) we simplify `arg` with
    
    323
    +     - Its captured envt `arg_env`
    
    324
    +     - but overriding its InScopeSet with the larger one at the
    
    325
    +       simplification point.
    
    326
    +    Why override the InScopeSet?  Example:
    
    327
    +          (let y = ey in f) ex
    
    328
    +    By the time we simplify ex, 'y' will be in scope.
    
    329
    +    Then we wrap the cast `mco` around the result.
    
    330
    +    See Note [The MOutCoercion field of ContEx].
    
    331
    +
    
    332
    +Using a SimplClo for the argument means that it can be substituted for a lambda
    
    333
    +binder, in `preInlineBetaUnconditionally`, without further ado.
    
    298 334
     -}
    
    299 335
     
    
    300 336
     instance Outputable DupFlag where
    
    ... ... @@ -312,9 +348,9 @@ instance Outputable SimplCont where
    312 348
         = (text "TickIt" <+> ppr t) $$ ppr cont
    
    313 349
       ppr (ApplyToTy  { sc_arg_ty = ty, sc_cont = cont })
    
    314 350
         = (text "ApplyToTy" <+> pprParendType ty) $$ ppr cont
    
    315
    -  ppr (ApplyToVal { sc_arg = arg, sc_env = env, sc_cont = cont, sc_hole_ty = hole_ty })
    
    316
    -    = (hang (text "ApplyToVal" <> braces (ppr env) <+> text "hole-ty:" <+> pprParendType hole_ty)
    
    317
    -          2 (pprParendExpr arg))
    
    351
    +  ppr (ApplyToVal { sc_arg = arg, sc_dup = dup, sc_cont = cont, sc_hole_ty = hole_ty })
    
    352
    +    = (hang (text "ApplyToVal" <> braces (ppr dup) <+> text "hole-ty:" <+> pprParendType hole_ty)
    
    353
    +          2 (ppr arg))
    
    318 354
           $$ ppr cont
    
    319 355
       ppr (StrictBind { sc_bndr = b, sc_cont = cont })
    
    320 356
         = (text "StrictBind" <+> ppr b) $$ ppr cont
    
    ... ... @@ -433,8 +469,8 @@ pushOutArgs fun_ty (arg:args) cont
    433 469
       = ApplyToTy { sc_hole_ty = fun_ty, sc_arg_ty = ty
    
    434 470
                   , sc_cont = pushOutArgs (piResultTy fun_ty ty) args cont }
    
    435 471
       | otherwise
    
    436
    -  = ApplyToVal { sc_hole_ty = fun_ty, sc_cast = MRefl
    
    437
    -               , sc_arg = arg, sc_env = Simplified NoDup
    
    472
    +  = ApplyToVal { sc_hole_ty = fun_ty
    
    473
    +               , sc_arg = DoneEx arg NotJoinPoint, sc_dup = NoDup
    
    438 474
                    , sc_cont = pushOutArgs (funResultTy fun_ty) args  cont}
    
    439 475
     
    
    440 476
     pushArgSpecs :: [ArgSpec]   -- In normal, forward order
    
    ... ... @@ -445,7 +481,7 @@ pushArgSpec :: ArgSpec -> SimplCont -> SimplCont
    445 481
     pushArgSpec (TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty }) cont
    
    446 482
       = ApplyToTy  { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = cont }
    
    447 483
     pushArgSpec (ValArg { as_arg = arg, as_hole_ty = hole_ty }) cont
    
    448
    -  = ApplyToVal { sc_arg = arg, sc_env = Simplified NoDup, sc_cast = MRefl
    
    484
    +  = ApplyToVal { sc_arg = DoneEx arg NotJoinPoint, sc_dup = NoDup
    
    449 485
                    , sc_hole_ty = hole_ty, sc_cont = cont }
    
    450 486
     
    
    451 487
     argSpecArg :: ArgSpec -> OutExpr
    
    ... ... @@ -496,7 +532,12 @@ contIsStop _ = False
    496 532
     contIsDupable :: SimplCont -> Bool
    
    497 533
     contIsDupable (Stop {})                    = True
    
    498 534
     contIsDupable (ApplyToTy  { sc_cont = k }) = contIsDupable k
    
    499
    -contIsDupable (ApplyToVal { sc_env = se }) = okToDupSE se -- See (SE1) in Note [StaticEnv]
    
    535
    +contIsDupable (ApplyToVal { sc_dup = dup, sc_arg = arg })
    
    536
    +  = assertPpr (not (okToDup dup && is_cont_ex arg)) (ppr arg) $
    
    537
    +    okToDup dup -- See (AV1,AV2) in Note [The argument of ApplyToVal]
    
    538
    +  where
    
    539
    +    is_cont_ex (ContEx {}) = True
    
    540
    +    is_cont_ex _           = False
    
    500 541
     contIsDupable (Select { sc_env = se })     = okToDupSE se -- ...ditto...
    
    501 542
     contIsDupable (StrictBind { sc_env = se }) = okToDupSE se -- ...ditto...
    
    502 543
     contIsDupable (StrictArg { sc_dup = dup }) = okToDup dup  -- ...ditto...
    
    ... ... @@ -605,8 +646,8 @@ contArgs env cont
    605 646
         lone (CastIt {})     = False  --     stops it being "lone"
    
    606 647
         lone _               = True
    
    607 648
     
    
    608
    -    go args (ApplyToVal { sc_arg = arg, sc_env = se, sc_cont = k })
    
    609
    -                                        = go (interestingArg env se arg : args) k
    
    649
    +    go args (ApplyToVal { sc_arg = arg, sc_cont = k })
    
    650
    +                                        = go (interestingArg env arg : args) k
    
    610 651
         go args (ApplyToTy { sc_cont = k }) = go args k
    
    611 652
         go args (CastIt { sc_cont = k })    = go args k
    
    612 653
         go args k                           = (False, reverse args, k)
    
    ... ... @@ -621,15 +662,13 @@ contOutArgs env cont
    621 662
         go (ApplyToTy { sc_arg_ty = ty, sc_cont = cont })
    
    622 663
           = Type ty : go cont
    
    623 664
     
    
    624
    -    go (ApplyToVal { sc_arg = arg, sc_env = se, sc_cont = cont })
    
    625
    -      = case se of
    
    626
    -          Simplified {}    -> arg : go cont
    
    627
    -          UnSimplified env -> GHC.Core.Subst.substExpr (getFullSubst in_scope env) arg : go cont
    
    628
    -        -- Make sure we apply the static environment `sc_env` as a substitution
    
    665
    +    go (ApplyToVal { sc_arg = arg, sc_cont = cont })
    
    666
    +      = simplCloExpr in_scope arg : go cont
    
    667
    +        -- Make sure we apply the static environment of a ContEx as a substitution
    
    629 668
             --   to get an OutExpr.  See (BF1) in Note [tryRules: plan (BEFORE)]
    
    630 669
             --   in GHC.Core.Opt.Simplify.Iteration
    
    631
    -        -- NB: we use substExpr, not substExprSC: we want to get the benefit of
    
    632
    -        --     knowing what is evaluated etc, via the in-scope set
    
    670
    +        -- simplCloExpr also wraps the pending cast (if any) around the argument;
    
    671
    +        --   omitting it can make a rule fail to match (#27963)
    
    633 672
     
    
    634 673
         -- No more arguments
    
    635 674
         go _ = []
    
    ... ... @@ -826,23 +865,86 @@ make use of the strictness info for the function.
    826 865
     *                                                                      *
    
    827 866
     ********************************************************************* -}
    
    828 867
     
    
    829
    -{- Note [The sc_cast field of ApplyToVal]
    
    830
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    868
    +{- Note [The MOutCoercion field of ContEx]
    
    869
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    831 870
     In the `ApplyToVal` case of `pushCast` we want to push an `OutCoercion` into the
    
    832
    -argument.  But the argument may or may not have been simplified (see Note [StaticEnv])
    
    833
    -so we definitely can't just wrap the cast around the argument. Instead we store it
    
    834
    -in the `sc_cast` field -- this is the whole reason for the `sc_cast` field.
    
    871
    +argument.  But the argument may or may not have been simplified (see Note [The
    
    872
    +argument of ApplyToVal]):
    
    873
    +
    
    874
    +* If it has been simplified, it is (DoneEx arg' _), and we can simply wrap the
    
    875
    +  cast around `arg'`.
    
    876
    +
    
    877
    +* If it has not, it is (ContEx env arg mco), and we definitely can't just wrap
    
    878
    +  the (Out)cast around the InExpr `arg`. Instead we compose it with `mco` --
    
    879
    +  this is the whole reason for the MOutCoercion field of `ContEx`.
    
    880
    +
    
    881
    +All this is done by `mkCloCastMCo`.
    
    835 882
     
    
    836 883
     We deal with that pending cast mainly in `simplArg`.
    
    837 884
     
    
    838 885
     But we /also/ sometimes want to substitute that argument for a lambda-binder, in
    
    839
    -`preInlineUnconditionally`.  So we also have to put that pending cast into
    
    840
    -`ContEx`; hence the MOutCoercion field of `ContEx`.  Then we deal with it
    
    841
    -appropriately when /applying/ the substitution in `simplInId`.
    
    886
    +`preInlineBetaUnconditionally`; and since the substitution maps an Id to a SimplClo,
    
    887
    +the pending cast comes along for free.  Then we deal with it appropriately when
    
    888
    +/applying/ the substitution in `simplInId`.
    
    889
    +
    
    890
    +Note [Optimising reflexivity]
    
    891
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    892
    +It's important (for compiler performance) to get rid of reflexivity as soon
    
    893
    +as it appears.  See #11735, #14737, and #15019.
    
    894
    +
    
    895
    +In particular, we want to behave well on
    
    896
    +
    
    897
    + *  e |> co1 |> co2
    
    898
    +    where the two happen to cancel out entirely. That is quite common;
    
    899
    +    e.g. a newtype wrapping and unwrapping cancel.
    
    900
    +
    
    901
    +
    
    902
    + * (f |> co) @t1 @t2 ... @tn x1 .. xm
    
    903
    +   Here we will use pushCoTyArg and pushCoValArg successively, which
    
    904
    +   build up SelCo stacks.  Silly to do that if co is reflexive.
    
    905
    +
    
    906
    +However, we don't want to call isReflexiveCo too much, because it uses
    
    907
    +type equality which is expensive on big types (#14737 comment:7).
    
    908
    +
    
    909
    +A good compromise (determined experimentally) seems to be to call
    
    910
    +isReflexiveCo
    
    911
    + * when composing casts, and
    
    912
    + * at the end
    
    913
    +
    
    914
    +In investigating this I saw missed opportunities for on-the-fly
    
    915
    +coercion shrinkage. See #15090.
    
    916
    +
    
    917
    +Note [Avoid re-simplifying coercions]
    
    918
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    919
    +In some benchmarks (with deeply nested cases) we successively push
    
    920
    +casts onto the SimplCont.  We don't want to call the coercion optimiser
    
    921
    +on each successive composition -- that's at least quadratic.  So:
    
    922
    +
    
    923
    +* The CastIt constructor in SimplCont has a `sc_opt :: Bool` flag to
    
    924
    +  record whether the coercion optimiser has been applied to the coercion.
    
    925
    +
    
    926
    +* In `simplCast`, when we see (Cast e co), we simplify `co` to get
    
    927
    +  an OutCoercion, and built a CastIt with sc_opt=True.
    
    928
    +
    
    929
    +  Actually not quite: if we are simplifying the result of inlining an
    
    930
    +  unfolding (seInlineDepth > 0), then instead of /optimising/ it again,
    
    931
    +  just /substitute/ which is cheaper.  See `simplCoercion`.
    
    932
    +
    
    933
    +* In `pushCast` if we combine this new coercion with an existing one,
    
    934
    +  we build a CastIt for (co1 ; co2) with sc_opt=False.
    
    935
    +
    
    936
    +* When unpacking a CastIt, in `rebuild`, we optimise the (presumably
    
    937
    +  composed) coercion if sc_opt=False; this is done by `optOutCoercion`.
    
    938
    +
    
    939
    +* When duplicating a continuation in `mkDupableContWithDmds`, before
    
    940
    +  duplicating a CastIt, optimise the coercion. Otherwise we'll end up
    
    941
    +  optimising it separately in the duplicate copies.
    
    942
    +
    
    943
    +* See also Note [The MOutCoercion field of ContEx]
    
    842 944
     -}
    
    843 945
     
    
    844 946
     optOutCoercion :: SimplEnvIS -> OutCoercion -> Bool -> OutCoercion
    
    845
    --- See Note [Avoid re-simplifying coercions] in GHC.Core.Opt.Simplify.Iteration
    
    947
    +-- See Note [Avoid re-simplifying coercions]
    
    846 948
     optOutCoercion env co already_optimised
    
    847 949
       | already_optimised = co  -- Ditto
    
    848 950
       | otherwise         = optCoercion opts empty_subst co
    
    ... ... @@ -862,7 +964,8 @@ pushCastMCo env (MCo co) cont = pushCast env co cont
    862 964
     
    
    863 965
     pushCast :: SimplEnv -> OutCoercion -> SimplCont -> SimplCont
    
    864 966
     pushCast env co cont
    
    865
    -  = go co True cont
    
    967
    +  | isReflCo co = cont     -- See Note [Optimising reflexivity]
    
    968
    +  | otherwise   = go co True cont
    
    866 969
       where
    
    867 970
     
    
    868 971
         -- ToDo:   pushCast Refl (ApplylToVal arg1 (ApplyToVal arg2 ...))
    
    ... ... @@ -871,7 +974,7 @@ pushCast env co cont
    871 974
         go co1 _ (CastIt { sc_co = co2, sc_cont = cont })  -- See Note [Optimising reflexivity] in GHC.Core.Opt.Simplify.Iteration
    
    872 975
           = go (mkTransCo co1 co2) False cont
    
    873 976
                       -- False: (mkTransCo co1 co2) is not fully optimised
    
    874
    -                  -- See Note [Avoid re-simplifying coercions] in GHC.Core.Opt.Simplify.Iteration
    
    977
    +                  -- See Note [Avoid re-simplifying coercions]
    
    875 978
     
    
    876 979
         go co co_is_opt (ApplyToTy { sc_arg_ty = arg_ty, sc_cont = tail })
    
    877 980
           | Just (tyL, arg_ty', m_co') <- pushCoTyArg co arg_ty
    
    ... ... @@ -886,21 +989,17 @@ pushCast env co cont
    886 989
         -- where   co :: (s1->s2) ~ (t1->t2)
    
    887 990
         --         co1 :: t1 ~ s1
    
    888 991
         --         co2 :: s2 ~ t2
    
    889
    -    go co co_is_opt cont@(ApplyToVal { sc_arg = arg, sc_env = arg_se
    
    890
    -                                     , sc_cast = arg_mco, sc_cont = tail })
    
    992
    +    go co co_is_opt cont@(ApplyToVal { sc_arg = arg, sc_cont = tail })
    
    891 993
           | not co_is_opt
    
    892 994
           = -- pushCoValArg duplicates the coercion, so optimise first
    
    893 995
             go (optOutCoercion (zapSubstEnv env) co co_is_opt) True cont
    
    894 996
     
    
    895 997
           | Just (tyL, m_co1, m_co2) <- pushCoValArg co
    
    896 998
           = {-#SCC "addCoerce-pushCoValArg" #-}
    
    897
    -        -- Dealing with m_co1 is the entire reason for the sc_cast field
    
    898
    -        -- of ApplyToVal; see Note [The sc_cast field of ApplyToVal]
    
    899
    -        ApplyToVal { sc_arg  = arg
    
    900
    -                   , sc_env  = arg_se
    
    901
    -                   , sc_cast = arg_mco `mkTransMCo` m_co1
    
    902
    -                   , sc_cont = go_mco m_co2 True tail
    
    903
    -                   , sc_hole_ty = tyL }
    
    999
    +        -- See Note [The MOutCoercion field of ContEx]
    
    1000
    +        cont { sc_arg     = mkCloCastMCo arg m_co1
    
    1001
    +             , sc_cont    = go_mco m_co2 True tail
    
    1002
    +             , sc_hole_ty = tyL }
    
    904 1003
     
    
    905 1004
         go co co_is_opt cont
    
    906 1005
           | isReflCo co = cont  -- Having this at the end makes a huge
    
    ... ... @@ -914,6 +1013,13 @@ pushCast env co cont
    914 1013
         go_mco MRefl    _   cont = cont
    
    915 1014
         go_mco (MCo co) opt cont = go co opt cont
    
    916 1015
     
    
    1016
    +mkCloCastMCo :: SimplClo -> MOutCoercion -> SimplClo
    
    1017
    +-- See Note [The MOutCoercion field of ContEx]
    
    1018
    +mkCloCastMCo clo               MRefl    = clo
    
    1019
    +mkCloCastMCo (DoneId v)        (MCo co) = DoneEx (mkCast (Var v) co) NotJoinPoint
    
    1020
    +mkCloCastMCo (DoneEx e _)      (MCo co) = DoneEx (mkCast e co)       NotJoinPoint
    
    1021
    +mkCloCastMCo (ContEx se e mco) (MCo co) = ContEx se e (mco `mkTransMCo` MCo co)
    
    1022
    +
    
    917 1023
     
    
    918 1024
     {-
    
    919 1025
     ************************************************************************
    
    ... ... @@ -1227,19 +1333,17 @@ Wrinkles:
    1227 1333
     
    
    1228 1334
     -}
    
    1229 1335
     
    
    1230
    -interestingArg :: SimplEnv -> StaticEnv -> CoreExpr -> ArgSummary
    
    1336
    +interestingArg :: SimplEnv -> SimplClo -> ArgSummary
    
    1231 1337
     -- See Note [Interesting arguments]
    
    1232
    -interestingArg env se e
    
    1233
    -  = case se of
    
    1234
    -      Simplified {}           -> go env                                0 e
    
    1235
    -      UnSimplified static_env -> go (static_env `setInScopeFromE` env) 0 e
    
    1338
    +interestingArg env clo
    
    1339
    +  = go_clo env 0 clo
    
    1236 1340
       where
    
    1341
    +    go_clo _   n (DoneId v)       = go_var n v
    
    1342
    +    go_clo env n (DoneEx e _)     = go (zapSubstEnv env)          n e
    
    1343
    +    go_clo env n (ContEx se e _)  = go (se `setInScopeFromE` env) n e
    
    1344
    +
    
    1237 1345
         -- n is # value args to which the expression is applied
    
    1238
    -    go env n (Var v)
    
    1239
    -       = case substId env v of
    
    1240
    -           DoneId v'            -> go_var n v'
    
    1241
    -           DoneEx e _           -> go (zapSubstEnv env)          n e
    
    1242
    -           ContEx se e _mco     -> go (se `setInScopeFromE` env) n e
    
    1346
    +    go env n (Var v) = go_clo env n (substId env v)
    
    1243 1347
     
    
    1244 1348
         go _   _ (Lit l)
    
    1245 1349
            | isLitRubbish l        = NonTrivArg -- See (IA3) in Note [Interesting arguments]
    
    ... ... @@ -1738,15 +1842,15 @@ is a term (not a coercion) so we can't necessarily inline the latter in
    1738 1842
     the former.
    
    1739 1843
     -}
    
    1740 1844
     
    
    1741
    -preInlineUnconditionally
    
    1845
    +preInlineLetUnconditionally
    
    1742 1846
         :: SimplEnv -> TopLevelFlag -> InId
    
    1743
    -    -> StaticEnv -> CoreExpr -> MOutCoercion  -- The argument
    
    1847
    +    -> InExpr -> SimplEnv   -- These two go together
    
    1744 1848
         -> Maybe SimplEnv       -- Returned env has extended substitution
    
    1745 1849
     -- Precondition: rhs satisfies the let-can-float invariant
    
    1746 1850
     -- See Note [Core let-can-float invariant] in GHC.Core
    
    1747 1851
     -- Reason: we don't want to inline single uses, or discard dead bindings,
    
    1748 1852
     --         for unlifted, side-effect-ful bindings
    
    1749
    -preInlineUnconditionally env top_lvl bndr rhs_se rhs rhs_mco
    
    1853
    +preInlineLetUnconditionally env top_lvl bndr rhs rhs_env
    
    1750 1854
       | not pre_inline_unconditionally           = Nothing
    
    1751 1855
       | not active                               = Nothing
    
    1752 1856
       | isTopLevel top_lvl && isDeadEndId bndr   = Nothing -- Note [Top-level bottoming Ids]
    
    ... ... @@ -1758,26 +1862,15 @@ preInlineUnconditionally env top_lvl bndr rhs_se rhs rhs_mco
    1758 1862
     
    
    1759 1863
       -- See Note [Stable unfoldings and preInlineUnconditionally]
    
    1760 1864
       | not (isInlinePragma inline_prag)
    
    1761
    -  , Just inl <- maybeUnfoldingTemplate unf   = assertPpr (isReflMCo rhs_mco) (ppr bndr) $
    
    1762
    -                                               Just $! (extend_subst_with inl)
    
    1865
    +  , Just inl <- maybeUnfoldingTemplate unf   = Just $! (extend_subst_with inl)
    
    1763 1866
     
    
    1764 1867
       | otherwise                                = Nothing
    
    1765 1868
       where
    
    1766 1869
         unf = idUnfolding bndr
    
    1767 1870
     
    
    1768
    -    -- If the rhs is /not/ already simplified, extend the envt with ContEx, which captures
    
    1769
    -    --    the the lexical environment for us to restore in `simplInId`.
    
    1770
    -    -- If the rhs /is/ already simplified, then extend the envt with DoneEx;
    
    1771
    -    --    That makes `simplInId` call `simplOutExpr` which avoids re-simplifying
    
    1772
    -    --    the RHS.
    
    1773
    -    -- See Note [Avoid repeated simplification] in GHC.Core.Opt.Simplify.Iteration
    
    1774
    -    extend_subst_with inl_rhs
    
    1775
    -      = extendIdSubst env bndr $!
    
    1776
    -        case rhs_se of
    
    1777
    -          Simplified _ -> case rhs_mco of
    
    1778
    -                             MRefl  -> DoneEx inl_rhs NotJoinPoint -- Common case
    
    1779
    -                             MCo co -> DoneEx (mkCast inl_rhs co) NotJoinPoint
    
    1780
    -          UnSimplified rhs_env -> ContEx rhs_env inl_rhs rhs_mco
    
    1871
    +    -- The rhs is not yet simplified, so extend the envt with ContEx, which
    
    1872
    +    -- captures the lexical environment for us to restore in `simplInId`.
    
    1873
    +    extend_subst_with inl_rhs = extendIdSubst env bndr $! ContEx rhs_env inl_rhs MRefl
    
    1781 1874
     
    
    1782 1875
         one_occ IAmDead = True -- Happens in ((\x.1) v)
    
    1783 1876
         one_occ OneOcc{ occ_n_br   = 1
    
    ... ... @@ -1793,39 +1886,6 @@ preInlineUnconditionally env top_lvl bndr rhs_se rhs rhs_mco
    1793 1886
                  -- See Note [pre/postInlineUnconditionally in gentle mode]
    
    1794 1887
         inline_prag = idInlinePragma bndr
    
    1795 1888
     
    
    1796
    --- Be very careful before inlining inside a lambda, because (a) we must not
    
    1797
    --- invalidate occurrence information, and (b) we want to avoid pushing a
    
    1798
    --- single allocation (here) into multiple allocations (inside lambda).
    
    1799
    --- Inlining a *function* with a single *saturated* call would be ok, mind you.
    
    1800
    ---      || (if is_cheap && not (canInlineInLam rhs) then pprTrace "preinline" (ppr bndr <+> ppr rhs) ok else ok)
    
    1801
    ---      where
    
    1802
    ---              is_cheap = exprIsCheap rhs
    
    1803
    ---              ok = is_cheap && int_cxt
    
    1804
    -
    
    1805
    -        --      int_cxt         The context isn't totally boring
    
    1806
    -        -- E.g. let f = \ab.BIG in \y. map f xs
    
    1807
    -        --      Don't want to substitute for f, because then we allocate
    
    1808
    -        --      its closure every time the \y is called
    
    1809
    -        -- But: let f = \ab.BIG in \y. map (f y) xs
    
    1810
    -        --      Now we do want to substitute for f, even though it's not
    
    1811
    -        --      saturated, because we're going to allocate a closure for
    
    1812
    -        --      (f y) every time round the loop anyhow.
    
    1813
    -
    
    1814
    -        -- canInlineInLam => free vars of rhs are (Once in_lam) or Many,
    
    1815
    -        -- so substituting rhs inside a lambda doesn't change the occ info.
    
    1816
    -        -- Sadly, not quite the same as exprIsHNF.
    
    1817
    -    canInlineInLam (Lit _)    = True
    
    1818
    -    canInlineInLam (Cast e _) = canInlineInLam e
    
    1819
    -    canInlineInLam (Lam b e)  = isRuntimeVar b || canInlineInLam e
    
    1820
    -    canInlineInLam (Tick t e) = not (tickishIsCode t) && canInlineInLam e
    
    1821
    -    canInlineInLam (Var v)    = case idOccInfo v of
    
    1822
    -                                  OneOcc { occ_in_lam = IsInsideLam } -> True
    
    1823
    -                                  ManyOccs {}                         -> True
    
    1824
    -                                  _                                   -> False
    
    1825
    -    canInlineInLam _          = False
    
    1826
    -      -- not ticks.  Counting ticks cannot be duplicated, and non-counting
    
    1827
    -      -- ticks around a Lam will disappear anyway.
    
    1828
    -
    
    1829 1889
         early_phase =
    
    1830 1890
           case sePhase env of
    
    1831 1891
             SimplPhase p -> p /= FinalPhase
    
    ... ... @@ -1856,6 +1916,97 @@ preInlineUnconditionally env top_lvl bndr rhs_se rhs rhs_mco
    1856 1916
         -- (Nor can we check for `exprIsExpandable rhs`, because that needs to look
    
    1857 1917
         -- at the non-existent unfolding for the `I# 2#` which is also floated out.)
    
    1858 1918
     
    
    1919
    +preInlineBetaUnconditionally
    
    1920
    +    :: SimplEnv -> Levity -> InId
    
    1921
    +    -> SimplClo             -- The argument
    
    1922
    +    -> Maybe SimplEnv       -- Returned env has extended substitution
    
    1923
    +-- Like preInlineLetUnconditionally, but for a beta-redex (\bndr. body) arg
    
    1924
    +-- The argument may or may not be already simplified (DoneEx or ContEx)
    
    1925
    +--
    
    1926
    +-- The binder is a lambda binder and so lacks most IdInfo;
    
    1927
    +--   see Note [Core binder IdInfo invariants]
    
    1928
    +--
    
    1929
    +-- Compared to preInlineLetUnconditionally we omit some checks:
    
    1930
    +--   * The binder is never top-level, so no need for the
    
    1931
    +--     Note [Top-level bottoming Ids] check, nor for `early_phase`
    
    1932
    +--   * A lambda binder is never a join point, so no need for the
    
    1933
    +--     Note [Do not inline exit join points] check
    
    1934
    +--   * A lambda binder never has an inline pragma, a stable unfolding, or RULES
    
    1935
    +--     (see `lamBndrInfoOK`), so no need to check activation, nor for
    
    1936
    +--     Note [Stable unfoldings and preInlineUnconditionally]
    
    1937
    +--
    
    1938
    +-- And we add one extra one
    
    1939
    +--   * Check the let-can-float invariant, and don't inline if not
    
    1940
    +
    
    1941
    +preInlineBetaUnconditionally env levity bndr arg
    
    1942
    +  | assertPpr (lamBndrInfoOK bndr) (ppr bndr) $
    
    1943
    +    not pre_inline_unconditionally           = Nothing
    
    1944
    +  | isCoVar bndr                             = Nothing -- Note [Do not inline CoVars unconditionally]
    
    1945
    +  | not (one_occ (idOccInfo bndr))           = Nothing
    
    1946
    +  | needs_case_binding                       = Nothing  -- Enforce the let-can-float invariant
    
    1947
    +  | otherwise                                = Just $! extendIdSubst env bndr arg
    
    1948
    +    -- If the arg is not yet simplified, it is a ContEx, which captures the
    
    1949
    +    --    lexical environment for us to restore in `simplInId`.
    
    1950
    +    -- If the arg is already simplified, then it is a DoneEx;
    
    1951
    +    --    That makes `simplInId` call `simplOutExpr` which avoids re-simplifying
    
    1952
    +    --    the arg.
    
    1953
    +    -- See Note [Avoid repeated simplification] in GHC.Core.Opt.Simplify.Iteration
    
    1954
    +  where
    
    1955
    +    pre_inline_unconditionally = sePreInline env
    
    1956
    +
    
    1957
    +    needs_case_binding = needsCaseBindingL levity rhs
    
    1958
    +    -- Ok to test an InExpr or OutExpr in needsCaseBindingL because
    
    1959
    +    -- exprOkForSpeculation is stable under simplification
    
    1960
    +
    
    1961
    +    rhs :: CoreExpr   -- Can be InExpr or OutExpr, but here it does not matter
    
    1962
    +    rhs = case arg of
    
    1963
    +            ContEx _ e _ -> e          -- InExpr
    
    1964
    +            DoneEx e _   -> e          -- OutExpr
    
    1965
    +            DoneId v     -> Var v      -- OutExpr
    
    1966
    +
    
    1967
    +    one_occ IAmDead = True -- Happens in ((\x.1) v)
    
    1968
    +    one_occ OneOcc{ occ_n_br   = 1
    
    1969
    +                  , occ_in_lam = NotInsideLam }   = True
    
    1970
    +    one_occ OneOcc{ occ_n_br   = 1
    
    1971
    +                  , occ_in_lam = IsInsideLam
    
    1972
    +                  , occ_int_cxt = IsInteresting } = canInlineInLam rhs
    
    1973
    +    one_occ _                                     = False
    
    1974
    +
    
    1975
    +
    
    1976
    +canInlineInLam :: CoreExpr -> Bool
    
    1977
    +-- Be very careful before inlining inside a lambda, because (a) we must not
    
    1978
    +-- invalidate occurrence information, and (b) we want to avoid pushing a
    
    1979
    +-- single allocation (here) into multiple allocations (inside lambda).
    
    1980
    +-- Inlining a *function* with a single *saturated* call would be ok, mind you.
    
    1981
    +--      || (if is_cheap && not (canInlineInLam rhs) then pprTrace "preinline" (ppr bndr <+> ppr rhs) ok else ok)
    
    1982
    +--      where
    
    1983
    +--              is_cheap = exprIsCheap rhs
    
    1984
    +--              ok = is_cheap && int_cxt
    
    1985
    +
    
    1986
    +        --      int_cxt         The context isn't totally boring
    
    1987
    +        -- E.g. let f = \ab.BIG in \y. map f xs
    
    1988
    +        --      Don't want to substitute for f, because then we allocate
    
    1989
    +        --      its closure every time the \y is called
    
    1990
    +        -- But: let f = \ab.BIG in \y. map (f y) xs
    
    1991
    +        --      Now we do want to substitute for f, even though it's not
    
    1992
    +        --      saturated, because we're going to allocate a closure for
    
    1993
    +        --      (f y) every time round the loop anyhow.
    
    1994
    +
    
    1995
    +        -- canInlineInLam => free vars of rhs are (Once in_lam) or Many,
    
    1996
    +        -- so substituting rhs inside a lambda doesn't change the occ info.
    
    1997
    +        -- Sadly, not quite the same as exprIsHNF.
    
    1998
    +canInlineInLam (Lit _)    = True
    
    1999
    +canInlineInLam (Cast e _) = canInlineInLam e
    
    2000
    +canInlineInLam (Lam b e)  = isRuntimeVar b || canInlineInLam e
    
    2001
    +canInlineInLam (Tick t e) = not (tickishIsCode t) && canInlineInLam e
    
    2002
    +canInlineInLam (Var v)    = case idOccInfo v of
    
    2003
    +                              OneOcc { occ_in_lam = IsInsideLam } -> True
    
    2004
    +                              ManyOccs {}                         -> True
    
    2005
    +                              _                                   -> False
    
    2006
    +canInlineInLam _          = False
    
    2007
    +  -- not ticks.  Counting ticks cannot be duplicated, and non-counting
    
    2008
    +  -- ticks around a Lam will disappear anyway.
    
    2009
    +
    
    1859 2010
     {-
    
    1860 2011
     ************************************************************************
    
    1861 2012
     *                                                                      *
    

  • compiler/GHC/Core/Opt/SpecConstr.hs
    ... ... @@ -2068,7 +2068,11 @@ mkSeqs seqees res_ty rhs =
    2068 2068
             -- Argument representing strict field and it's worth passing via cbv
    
    2069 2069
             | wantCbvForId arg_id
    
    2070 2070
             = Case (Var arg_id)
    
    2071
    -               (localiseId arg_id)  -- See (SCF1) in Note [SpecConstr and strict fields]
    
    2071
    +               (mkCaseBndrFromLetBndr (localiseId arg_id))
    
    2072
    +                   -- localiseId: see (SCF1) in Note [SpecConstr and strict fields]
    
    2073
    +                   -- mkCaseBndrFromLetBndr: arg_id may have IdInfo (e.g. an unfolding,
    
    2074
    +                   --   if it is a global) that a case binder must not have; see
    
    2075
    +                   --   Note [Core binder IdInfo invariants] in GHC.Core
    
    2072 2076
                    res_ty
    
    2073 2077
                    ([Alt DEFAULT [] rhs])
    
    2074 2078
     
    

  • compiler/GHC/Core/Opt/WorkWrap/Utils.hs
    ... ... @@ -1041,7 +1041,7 @@ unbox_one_arg opts arg_var
    1041 1041
     
    
    1042 1042
                  -- Apply str info to new args. Also remove OtherCon unfoldings so they
    
    1043 1043
                  -- don't end up in lambda binders of the worker.
    
    1044
    -             -- See Note [Never put `OtherCon` unfoldings on lambda binders]
    
    1044
    +             -- See (CBI1) in Note [Core binder IdInfo invariants]
    
    1045 1045
                  arg_ids' = map zapIdUnfolding $
    
    1046 1046
                             zipWithEqual setIdDemandInfo arg_ids ds
    
    1047 1047
     
    
    ... ... @@ -1711,8 +1711,7 @@ unbox_one_result opts res_bndr
    1711 1711
     move_transit_vars :: [Id] -> (CoreExpr -> CoreExpr -> CoreExpr, CoreExpr)
    
    1712 1712
     move_transit_vars vars
    
    1713 1713
       | [var] <- vars
    
    1714
    -  , let var_ty = idType var
    
    1715
    -  , isUnliftedType var_ty || exprIsHNF (Var var)
    
    1714
    +  , varIsHNF var  -- NB: True of variables of unlifted type
    
    1716 1715
       -- See Note [No unboxed tuple for single, unlifted transit var]
    
    1717 1716
       --   * Wrapper: `unbox scrut alt = (case <scrut> of a -> <alt>)`
    
    1718 1717
       --   * Worker:  `tup = a`
    
    ... ... @@ -1816,7 +1815,7 @@ return unboxed instead of in an unboxed singleton tuple:
    1816 1815
         We want  `$wh :: Int# -> [Int]`.
    
    1817 1816
         We'd get `$wh :: Int# -> (# [Int] #)`.
    
    1818 1817
     
    
    1819
    -By considering vars as unlifted that satisfy 'exprIsHNF', we catch (3).
    
    1818
    +By considering vars as unlifted that satisfy 'varIsHNF', we catch (3).
    
    1820 1819
     Why not check for 'exprOkForSpeculation'? Quite perplexingly, evaluated vars
    
    1821 1820
     are not ok-for-spec, see Note [exprOkForSpeculation and evaluated variables].
    
    1822 1821
     For (1) and (2) we would have to look at the term. WW only looks at the
    

  • compiler/GHC/Core/Ppr.hs
    ... ... @@ -637,6 +637,7 @@ instance Outputable IdInfo where
    637 637
         [ (has_prag,         text "InlPrag=" <> pprInlineDebug prag_info)
    
    638 638
         , (has_occ,          text "Occ=" <> ppr occ_info)
    
    639 639
         , (has_dmd,          text "Dmd=" <> ppr dmd_info)
    
    640
    +    , (has_cpr,          text "Cpr=" <> ppr dmd_info)
    
    640 641
         , (has_lbv ,         text "OS=" <> ppr lbv_info)
    
    641 642
         , (has_arity,        text "Arity=" <> int arity)
    
    642 643
         , (has_called_arity, text "CallArity=" <> int called_arity)
    
    ... ... @@ -658,6 +659,9 @@ instance Outputable IdInfo where
    658 659
           lbv_info  = oneShotInfo info
    
    659 660
           has_lbv   = not (hasNoOneShotInfo lbv_info)
    
    660 661
     
    
    662
    +      cpr = cprSigInfo info
    
    663
    +      has_cpr = not $ isTopCprSig cpr
    
    664
    +
    
    661 665
           arity = arityInfo info
    
    662 666
           has_arity = arity /= 0
    
    663 667
     
    

  • compiler/GHC/Core/Utils.hs
    ... ... @@ -29,7 +29,7 @@ module GHC.Core.Utils (
    29 29
             exprIsTrivial, getIdFromTrivialExpr, getIdFromTrivialExpr_maybe,
    
    30 30
             trivial_expr_fold,
    
    31 31
             exprIsDupable, exprIsCheap, exprIsExpandable, exprIsCheapX, CheapAppFun,
    
    32
    -        exprIsHNF, exprOkForSpeculation, exprOkToDiscard, exprOkForSpecEval,
    
    32
    +        exprIsHNF, varIsHNF, exprOkForSpeculation, exprOkToDiscard, exprOkForSpecEval,
    
    33 33
             exprIsWorkFree, exprIsConLike,
    
    34 34
             isCheapApp, isExpandableApp, isSaturatedConApp,
    
    35 35
             exprIsTickedString, exprIsTickedString_maybe,
    
    ... ... @@ -756,7 +756,10 @@ bindNonRec bndr rhs body
    756 756
       | needsCaseBinding (idType bndr) rhs = case_bind
    
    757 757
       | otherwise                          = let_bind
    
    758 758
       where
    
    759
    -    case_bind = mkDefaultCase rhs bndr body
    
    759
    +    case_bind = mkDefaultCase rhs (mkCaseBndrFromLetBndr bndr) body
    
    760
    +                -- mkCaseBndrFromLetBndr: bndr may have IdInfo suitable for a
    
    761
    +                -- let-binder; see Note [Core binder IdInfo invariants]
    
    762
    +                -- in GHC.Core
    
    760 763
         let_bind  = Let (NonRec bndr rhs) body
    
    761 764
     
    
    762 765
     -- | `needsCaseBinding` tests whether we have to use a @case@ rather than @let@
    
    ... ... @@ -2630,12 +2633,37 @@ it doesn't have the trickiness of the let-can-float invariant to worry about.
    2630 2633
     exprIsHNF :: CoreExpr -> Bool           -- True => Value-lambda, constructor, PAP
    
    2631 2634
     exprIsHNF = exprIsHNFlike isDataConWorkId isEvaldUnfolding True
    
    2632 2635
     
    
    2636
    +-- | @varIsHNF v@ is the same as @exprIsHNF (Var v)@, but avoids building
    
    2637
    +-- the @Var@ only to take it apart again
    
    2638
    +varIsHNF :: Var -> Bool
    
    2639
    +varIsHNF = varIsHNFlike isDataConWorkId isEvaldUnfolding
    
    2640
    +
    
    2633 2641
     -- | Similar to 'exprIsHNF' but includes CONLIKE functions as well as
    
    2634 2642
     -- data constructors. Conlike arguments are considered interesting by the
    
    2635 2643
     -- inliner.
    
    2636 2644
     exprIsConLike :: CoreExpr -> Bool       -- True => lambda, conlike, PAP
    
    2637 2645
     exprIsConLike = exprIsHNFlike isConLikeId isConLikeUnfolding False
    
    2638 2646
     
    
    2647
    +varIsHNFlike :: (Var -> Bool) -> (Unfolding -> Bool) -> Var -> Bool
    
    2648
    +-- The (Var v) case of exprIsHNFlike
    
    2649
    +{-# INLINE varIsHNFlike #-}
    
    2650
    +varIsHNFlike is_con is_con_unf v
    
    2651
    +  =  idArity v > 0 || is_con v
    
    2652
    +        -- A PAP is a value, as is a nullary constructor, so that [] and ()
    
    2653
    +        -- are values, for example; and (e.g.) primops that don't have unfoldings.
    
    2654
    +        -- This is (id_app_is_value v []) in exprIsHNFlike
    
    2655
    +
    
    2656
    +  || is_con_unf (idUnfolding v)
    
    2657
    +        -- Check the thing's unfolding; it might be bound to a value
    
    2658
    +        --   or to a guaranteed-evaluated variable (isEvaldUnfolding)
    
    2659
    +        --   Contrast with Note [exprOkForSpeculation and evaluated variables]
    
    2660
    +        -- We don't look through loop breakers here, which is a bit conservative
    
    2661
    +        -- but otherwise I worry that if an Id's unfolding is just itself,
    
    2662
    +        -- we could get an infinite loop
    
    2663
    +
    
    2664
    +  || definitelyUnliftedType (idType v)
    
    2665
    +        -- Unlifted binders are always evaluated (#20140)
    
    2666
    +
    
    2639 2667
     -- | Returns true for values or value-like expressions. These are lambdas,
    
    2640 2668
     -- constructors / CONLIKE functions (as determined by the function argument)
    
    2641 2669
     -- or PAPs.
    
    ... ... @@ -2649,20 +2677,8 @@ exprIsHNFlike is_con is_con_unf rubbish_lit_result e
    2649 2677
       = -- pprTraceWith "hnf" (\r -> ppr r <+> ppr e) $
    
    2650 2678
         is_hnf_like e
    
    2651 2679
       where
    
    2652
    -    is_hnf_like (Var v) -- NB: There are no value args at this point
    
    2653
    -      =  id_app_is_value v [] -- Catches nullary constructors,
    
    2654
    -                              --      so that [] and () are values, for example
    
    2655
    -                              -- and (e.g.) primops that don't have unfoldings
    
    2656
    -      || is_con_unf (idUnfolding v)
    
    2657
    -        -- Check the thing's unfolding; it might be bound to a value
    
    2658
    -        --   or to a guaranteed-evaluated variable (isEvaldUnfolding)
    
    2659
    -        --   Contrast with Note [exprOkForSpeculation and evaluated variables]
    
    2660
    -        -- We don't look through loop breakers here, which is a bit conservative
    
    2661
    -        -- but otherwise I worry that if an Id's unfolding is just itself,
    
    2662
    -        -- we could get an infinite loop
    
    2663
    -
    
    2664
    -      || definitelyUnliftedType (idType v)
    
    2665
    -        -- Unlifted binders are always evaluated (#20140)
    
    2680
    +    is_hnf_like (Var v) = varIsHNFlike is_con is_con_unf v
    
    2681
    +                          -- NB: There are no value args at this point
    
    2666 2682
     
    
    2667 2683
         is_hnf_like (Lit lit)
    
    2668 2684
           | isLitRubbish lit = rubbish_lit_result
    

  • compiler/GHC/HsToCore/Utils.hs
    ... ... @@ -264,8 +264,14 @@ bindMatchId new mid body
    264 264
     -- Used to force variables when desugaring strict binders. It's crucial that the
    
    265 265
     -- variable is shadowed by the case binder. See Wrinkle 1 in
    
    266 266
     -- Note [Desugar Strict binds] in GHC.HsToCore.Binds.
    
    267
    +--
    
    268
    +-- The case binder has the same Name (and hence Unique), type and multiplicity
    
    269
    +-- as `var`, but not its IdInfo: `var` may have, say, a NOINLINE pragma, but a
    
    270
    +-- case binder must not; see Note [Core binder IdInfo invariants]
    
    271
    +-- in GHC.Core, and #27965.  E.g. `res1` in GHC.Internal.Control.Monad.ST.Lazy.Imp
    
    272
    +-- has a NOINLINE pragma.
    
    267 273
     seqVar :: Var -> CoreExpr -> CoreExpr
    
    268
    -seqVar var body = mkDefaultCase (Var var) var body
    
    274
    +seqVar var body = mkDefaultCase (Var var) (mkCaseBndrFromLetBndr var) body
    
    269 275
     
    
    270 276
     mkCoLetMatchResult :: HasDebugCallStack => CoreBind -> MatchResult CoreExpr -> MatchResult CoreExpr
    
    271 277
     mkCoLetMatchResult bind = fmap (mkCoreLet bind)
    

  • compiler/GHC/Types/Id.hs
    ... ... @@ -94,6 +94,7 @@ module GHC.Types.Id (
    94 94
             idArity,
    
    95 95
             idCallArity, idFunRepArity,
    
    96 96
             idSpecialisation, idCoreRules, idHasRules,
    
    97
    +        lamBndrInfoOK,
    
    97 98
             idCafInfo, idLFInfo_maybe,
    
    98 99
             idOneShotInfo,
    
    99 100
             idOccInfo,
    
    ... ... @@ -102,7 +103,7 @@ module GHC.Types.Id (
    102 103
             alwaysActiveUnfoldingFun, whenActiveUnfoldingFun, noUnfoldingFun,
    
    103 104
     
    
    104 105
             -- ** Writing 'IdInfo' fields
    
    105
    -        setIdUnfolding, zapIdUnfolding, setCaseBndrEvald,
    
    106
    +        setIdUnfolding, zapIdUnfolding, setCaseBndrEvald, mkCaseBndrFromLetBndr,
    
    106 107
             setIdArity,
    
    107 108
             setIdCallArity,
    
    108 109
     
    
    ... ... @@ -881,10 +882,21 @@ setCaseBndrEvald :: StrictnessMark -> Id -> Id
    881 882
     -- itself, and any pattern-bound variables that are argument of a
    
    882 883
     -- strict constructor.  It just marks the variable as already-evaluated,
    
    883 884
     -- so that (for example) a subsequent 'seq' can be dropped
    
    885
    +-- See Note [Evaluated-ness on case binders] in GHC.Core
    
    884 886
     setCaseBndrEvald str id
    
    885 887
       | isMarkedStrict str = id `setIdUnfolding` evaldUnfolding
    
    886 888
       | otherwise          = id
    
    887 889
     
    
    890
    +-- | Make a case binder from a binder that might have been let-bound, e.g.
    
    891
    +--      let x = rhs in body   ==>   case rhs of x { DEFAULT -> body }
    
    892
    +-- The let-binder may have IdInfo (an unfolding, an inline pragma, RULES)
    
    893
    +-- that a case binder must not have, so we keep its Name, type, multiplicity
    
    894
    +-- and IdDetails, but reset its IdInfo, except that we record that it is
    
    895
    +-- evaluated.
    
    896
    +-- See Note [Core binder IdInfo invariants] in GHC.Core
    
    897
    +mkCaseBndrFromLetBndr :: Id -> Id
    
    898
    +mkCaseBndrFromLetBndr id = id `setIdInfo` (vanillaIdInfo `setUnfoldingInfo` evaldUnfolding)
    
    899
    +
    
    888 900
     -- | Similar to trimUnfolding, but also removes evaldness info.
    
    889 901
     zapIdUnfolding :: Id -> Id
    
    890 902
     zapIdUnfolding v
    
    ... ... @@ -905,6 +917,32 @@ idCoreRules id = ruleInfoRules (idSpecialisation id)
    905 917
     idHasRules :: Id -> Bool
    
    906 918
     idHasRules id = not (isEmptyRuleInfo (idSpecialisation id))
    
    907 919
     
    
    920
    +-- | True <=> the Id has only the IdInfo permitted on a lambda, case, or
    
    921
    +-- case-alternative binder.  See the table in Note [Core binder IdInfo invariants]
    
    922
    +-- in GHC.Core; Core Lint checks this invariant.
    
    923
    +--
    
    924
    +-- We allow occurrence info, demand info, and one-shot info (which the table
    
    925
    +-- permits only on lambda binders, but a case binder may be about to become one).
    
    926
    +-- We also allow an `OtherCon []` unfolding; lambda binders must have no unfolding
    
    927
    +-- at all, but Lint checks that separately.
    
    928
    +lamBndrInfoOK :: Id -> Bool
    
    929
    +lamBndrInfoOK id
    
    930
    +  =  isDefaultInlinePragma (inlinePragInfo info)
    
    931
    +  && isNopSig (dmdSigInfo info)
    
    932
    +  && isTopCprSig (cprSigInfo info)
    
    933
    +  && mayHaveCafRefs (cafInfo info)
    
    934
    +  && arityInfo info == unknownArity
    
    935
    +  && callArityInfo info == unknownArity
    
    936
    +  && isEmptyRuleInfo (ruleInfo info)
    
    937
    +  && unf_ok (realUnfoldingInfo info)
    
    938
    +  where
    
    939
    +    info = idInfo id
    
    940
    +
    
    941
    +    -- See Note [Evaluated-ness on case binders] in GHC.Core
    
    942
    +    unf_ok NoUnfolding   = True
    
    943
    +    unf_ok (OtherCon []) = True
    
    944
    +    unf_ok _             = False
    
    945
    +
    
    908 946
     setIdSpecialisation :: Id -> RuleInfo -> Id
    
    909 947
     setIdSpecialisation id spec_info = modifyIdInfo (`setRuleInfo` spec_info) id
    
    910 948
     
    

  • testsuite/tests/simplCore/should_compile/T27962.hs
    1
    +{-# LANGUAGE MagicHash #-}
    
    2
    +
    
    3
    +module T27962 where
    
    4
    +
    
    5
    +import GHC.Exts
    
    6
    +
    
    7
    +newtype N = MkN Int
    
    8
    +
    
    9
    +-- After inlining myRun, we get  (runRW# @LiftedRep @Int |> co) (\_ -> ...)
    
    10
    +-- and the simplifier pushes co into the argument of runRW#.
    
    11
    +-- #27962: the simplifier dropped that cast, yielding ill-typed Core
    
    12
    +myRun :: (State# RealWorld -> N) -> N
    
    13
    +myRun = coerce (runRW# :: (State# RealWorld -> Int) -> Int)
    
    14
    +{-# INLINE myRun #-}
    
    15
    +
    
    16
    +foo x = myRun (\_ -> MkN (x+1))

  • testsuite/tests/simplCore/should_compile/T27963.hs
    1
    +{-# OPTIONS_GHC -Wno-inline-rule-shadowing #-}
    
    2
    +
    
    3
    +module T27963 where
    
    4
    +
    
    5
    +-- This test is pretty delicate because it relies on a function
    
    6
    +-- that has BOTH a rule AND an INLINE pragma
    
    7
    +--
    
    8
    +-- See #27963 for some discussion
    
    9
    +--
    
    10
    +-- Still, it should (just) work
    
    11
    +
    
    12
    +import GHC.Exts
    
    13
    +
    
    14
    +newtype N = MkN Int
    
    15
    +
    
    16
    +f x = x
    
    17
    +{-# INLINE f #-}
    
    18
    +{-# RULES "f/42" forall x. f x = 42::Int #-}
    
    19
    +
    
    20
    +-- The rule "f/42" should fire in both h1 and h2
    
    21
    +h1,h2 :: N -> Int
    
    22
    +h1 n = f (coerce n) + 0
    
    23
    +h2 n = (coerce f) n + 0   -- #27963: the rule did not fire here

  • testsuite/tests/simplCore/should_compile/T27963.stderr
    1
    +Rule fired: f/42 (T27963)
    
    2
    +Rule fired: f/42 (T27963)

  • testsuite/tests/simplCore/should_compile/T27965.hs
    1
    +-- Lint checks that we don't produce a lambda-binder
    
    2
    +-- with a NOINLINE pragma on it (#27965)
    
    3
    +
    
    4
    +module T27965 where
    
    5
    +
    
    6
    +h fm s = let {-# NOINLINE res1 #-}
    
    7
    +             !res1 = fm s
    
    8
    +             !(f, s') = res1
    
    9
    +         in (f+1::Int, s')

  • testsuite/tests/simplCore/should_compile/all.T
    ... ... @@ -629,3 +629,7 @@ test('T27749',
    629 629
     test('T27629', only_ways(['optasm']), makefile_test, ['T27629'])
    
    630 630
     test('T27936', normal, compile, [''])
    
    631 631
     test('T27910', grep_errmsg(r'KnownBranch'), compile, ['-O -dno-typeable-binds -ddump-simpl-stats -dsuppress-uniques'])
    
    632
    +test('T27962', normal, compile, [''])
    
    633
    +test('T27962a', [extra_files(['T27962.hs'])], multimod_compile, ['T27962', '-v0 -O'])
    
    634
    +test('T27963', [grep_errmsg(r'f/42')], compile, ['-O -ddump-rule-firings'])
    
    635
    +test('T27965', normal, compile, [''])