Simon Peyton Jones pushed to branch wip/T23162-spj at Glasgow Haskell Compiler / GHC

Commits:

9 changed files:

Changes:

  • compiler/GHC/Core/Opt/CallArity.hs
    ... ... @@ -598,9 +598,8 @@ callArityBind boring_vars ae_body int (NonRec v rhs)
    598 598
     
    
    599 599
     -- Recursive let. See Note [Recursion and fixpointing]
    
    600 600
     callArityBind boring_vars ae_body int b@(Rec binds)
    
    601
    -  = -- (if length binds > 300 then
    
    602
    -    -- pprTrace "callArityBind:Rec"
    
    603
    -    --           (vcat [ppr (Rec binds'), ppr ae_body, ppr int, ppr ae_rhs]) else id) $
    
    601
    +  = -- pprTrace "callArityBind:Rec"
    
    602
    +    --          (vcat [ppr (map fst binds), ppr ae_body, ppr int, ppr ae_rhs]) $
    
    604 603
         (final_ae, Rec binds')
    
    605 604
       where
    
    606 605
         -- See Note [Taking boring variables into account]
    
    ... ... @@ -614,7 +613,9 @@ callArityBind boring_vars ae_body int b@(Rec binds)
    614 613
     
    
    615 614
         fix :: [(Id, Maybe (Bool, Arity, CallArityRes), CoreExpr)] -> (CallArityRes, [(Id, CoreExpr)])
    
    616 615
         fix ann_binds
    
    617
    -        | -- pprTrace "callArityBind:fix" (vcat [ppr ann_binds, ppr any_change, ppr ae]) $
    
    616
    +        | -- pprTrace "callArityBind:fix" (vcat
    
    617
    +          --    [ text "binds" <+> vcat [ppr (id,stuff) | (id,stuff,_rhs) <- ann_binds]
    
    618
    +          --   , ppr any_change, ppr ae]) $
    
    618 619
               any_change
    
    619 620
             = fix ann_binds'
    
    620 621
             | otherwise
    
    ... ... @@ -650,7 +651,12 @@ callArityBind boring_vars ae_body int b@(Rec binds)
    650 651
                               | safe_arity == 0 = ae_rhs -- If it is not a function, its body is evaluated only once
    
    651 652
                               | otherwise       = calledMultipleTimes ae_rhs
    
    652 653
     
    
    653
    -                  i' = i `setIdCallArity` trimmed_arity
    
    654
    +                  i' = -- (if trimmed_arity == new_arity then id else
    
    655
    +                       --    pprTrace "trimming"
    
    656
    +                       --       (vcat [ ppr i <+> ppr new_arity <+> ppr trimmed_arity
    
    657
    +                       --             , text "safe" <+> ppr safe_arity
    
    658
    +                       --             , text "is_thunk" <+> ppr is_thunk ])) $
    
    659
    +                       i `setIdCallArity` trimmed_arity
    
    654 660
     
    
    655 661
                   in (True, (i', Just (called_once, new_arity, ae_rhs'), rhs'))
    
    656 662
               where
    

  • compiler/GHC/Core/TyCo/FVs.hs
    ... ... @@ -66,7 +66,10 @@ import GHC.Types.Unique.Set
    66 66
     
    
    67 67
     import GHC.Types.Var.Set
    
    68 68
     import GHC.Types.Var.Env
    
    69
    +
    
    69 70
     import GHC.Utils.Misc
    
    71
    +import GHC.Utils.EndoOS
    
    72
    +
    
    70 73
     import GHC.Data.Pair
    
    71 74
     
    
    72 75
     import Data.Semigroup
    
    ... ... @@ -285,9 +288,9 @@ done by the Call Arity pass.
    285 288
     TL;DR: check this regularly!
    
    286 289
     -}
    
    287 290
     
    
    288
    -runTyCoVars :: Endo TyCoVarSet -> TyCoVarSet
    
    291
    +runTyCoVars :: EndoOS TyCoVarSet -> TyCoVarSet
    
    289 292
     {-# INLINE runTyCoVars #-}
    
    290
    -runTyCoVars f = appEndo f emptyVarSet
    
    293
    +runTyCoVars f = appEndoOS f emptyVarSet
    
    291 294
     
    
    292 295
     {- *********************************************************************
    
    293 296
     *                                                                      *
    
    ... ... @@ -320,28 +323,37 @@ tyCoVarsOfMCo (MCo co) = tyCoVarsOfCo co
    320 323
     tyCoVarsOfCos :: [Coercion] -> TyCoVarSet
    
    321 324
     tyCoVarsOfCos cos = runTyCoVars (deep_cos cos)
    
    322 325
     
    
    323
    -deep_ty  :: Type       -> Endo TyCoVarSet
    
    324
    -deep_tys :: [Type]     -> Endo TyCoVarSet
    
    325
    -deep_co  :: Coercion   -> Endo TyCoVarSet
    
    326
    -deep_cos :: [Coercion] -> Endo TyCoVarSet
    
    326
    +deep_ty  :: Type       -> EndoOS TyCoVarSet
    
    327
    +deep_tys :: [Type]     -> EndoOS TyCoVarSet
    
    328
    +deep_co  :: Coercion   -> EndoOS TyCoVarSet
    
    329
    +deep_cos :: [Coercion] -> EndoOS TyCoVarSet
    
    327 330
     (deep_ty, deep_tys, deep_co, deep_cos) = foldTyCo deepTcvFolder emptyVarSet
    
    328 331
     
    
    329
    -deepTcvFolder :: TyCoFolder TyCoVarSet (Endo TyCoVarSet)
    
    332
    +deepTcvFolder :: TyCoFolder TyCoVarSet (EndoOS TyCoVarSet)
    
    333
    +-- It's important that we use a one-shot EndoOS, to ensure that all
    
    334
    +-- the free-variable finders are eta-expanded.  Lacking the one-shot-ness
    
    335
    +-- led to some big slow downs.  See Note [The one-shot state monad trick]
    
    336
    +-- in GHC.Utils.Monad
    
    330 337
     deepTcvFolder = TyCoFolder { tcf_view = noView  -- See Note [Free vars and synonyms]
    
    331 338
                                , tcf_tyvar = do_tcv, tcf_covar = do_tcv
    
    332 339
                                , tcf_hole  = do_hole, tcf_tycobinder = do_bndr }
    
    333 340
       where
    
    334
    -    do_tcv is v = Endo do_it
    
    341
    +    do_tcv is v = EndoOS do_it
    
    335 342
           where
    
    336 343
             do_it acc | v `elemVarSet` is  = acc
    
    337 344
                       | v `elemVarSet` acc = acc
    
    338
    -                  | otherwise          = appEndo (deep_ty (varType v)) $
    
    345
    +                  | otherwise          = appEndoOS (deep_ty (varType v)) $
    
    339 346
                                              acc `extendVarSet` v
    
    340 347
     
    
    348
    +    do_bndr :: TyCoVarSet -> TyVar -> ForAllTyFlag -> TyCoVarSet
    
    341 349
         do_bndr is tcv _ = extendVarSet is tcv
    
    342
    -    do_hole is hole  = do_tcv is (coHoleCoVar hole)
    
    343
    -                       -- See Note [CoercionHoles and coercion free variables]
    
    344
    -                       -- in GHC.Core.TyCo.Rep
    
    350
    +
    
    351
    +    do_hole :: VarSet -> CoercionHole -> EndoOS TyCoVarSet
    
    352
    +    do_hole _is hole = deep_ty (varType (coHoleCoVar hole))
    
    353
    +                     -- We don't collect the CoercionHole itself, but we /do/
    
    354
    +                     -- need to collect the free variables of its /kind/
    
    355
    +                     -- See (CHFV1) in Note [CoercionHoles and coercion free variables]
    
    356
    +                     -- in GHC.Core.TyCo.Rep
    
    345 357
     
    
    346 358
     {- *********************************************************************
    
    347 359
     *                                                                      *
    
    ... ... @@ -378,18 +390,18 @@ shallowTyCoVarsOfCoVarEnv cos = shallowTyCoVarsOfCos (nonDetEltsUFM cos)
    378 390
       -- It's OK to use nonDetEltsUFM here because we immediately
    
    379 391
       -- forget the ordering by returning a set
    
    380 392
     
    
    381
    -shallow_ty  :: Type       -> Endo TyCoVarSet
    
    382
    -shallow_tys :: [Type]     -> Endo TyCoVarSet
    
    383
    -shallow_co  :: Coercion   -> Endo TyCoVarSet
    
    384
    -shallow_cos :: [Coercion] -> Endo TyCoVarSet
    
    393
    +shallow_ty  :: Type       -> EndoOS TyCoVarSet
    
    394
    +shallow_tys :: [Type]     -> EndoOS TyCoVarSet
    
    395
    +shallow_co  :: Coercion   -> EndoOS TyCoVarSet
    
    396
    +shallow_cos :: [Coercion] -> EndoOS TyCoVarSet
    
    385 397
     (shallow_ty, shallow_tys, shallow_co, shallow_cos) = foldTyCo shallowTcvFolder emptyVarSet
    
    386 398
     
    
    387
    -shallowTcvFolder :: TyCoFolder TyCoVarSet (Endo TyCoVarSet)
    
    399
    +shallowTcvFolder :: TyCoFolder TyCoVarSet (EndoOS TyCoVarSet)
    
    388 400
     shallowTcvFolder = TyCoFolder { tcf_view = noView  -- See Note [Free vars and synonyms]
    
    389 401
                                   , tcf_tyvar = do_tcv, tcf_covar = do_tcv
    
    390 402
                                   , tcf_hole  = do_hole, tcf_tycobinder = do_bndr }
    
    391 403
       where
    
    392
    -    do_tcv is v = Endo do_it
    
    404
    +    do_tcv is v = EndoOS do_it
    
    393 405
           where
    
    394 406
             do_it acc | v `elemVarSet` is  = acc
    
    395 407
                       | v `elemVarSet` acc = acc
    
    ... ... @@ -427,13 +439,13 @@ coVarsOfTypes tys = runTyCoVars (deep_cv_tys tys)
    427 439
     coVarsOfCo    co  = runTyCoVars (deep_cv_co co)
    
    428 440
     coVarsOfCos   cos = runTyCoVars (deep_cv_cos cos)
    
    429 441
     
    
    430
    -deep_cv_ty  :: Type       -> Endo CoVarSet
    
    431
    -deep_cv_tys :: [Type]     -> Endo CoVarSet
    
    432
    -deep_cv_co  :: Coercion   -> Endo CoVarSet
    
    433
    -deep_cv_cos :: [Coercion] -> Endo CoVarSet
    
    442
    +deep_cv_ty  :: Type       -> EndoOS CoVarSet
    
    443
    +deep_cv_tys :: [Type]     -> EndoOS CoVarSet
    
    444
    +deep_cv_co  :: Coercion   -> EndoOS CoVarSet
    
    445
    +deep_cv_cos :: [Coercion] -> EndoOS CoVarSet
    
    434 446
     (deep_cv_ty, deep_cv_tys, deep_cv_co, deep_cv_cos) = foldTyCo deepCoVarFolder emptyVarSet
    
    435 447
     
    
    436
    -deepCoVarFolder :: TyCoFolder TyCoVarSet (Endo CoVarSet)
    
    448
    +deepCoVarFolder :: TyCoFolder TyCoVarSet (EndoOS CoVarSet)
    
    437 449
     deepCoVarFolder = TyCoFolder { tcf_view = noView
    
    438 450
                                  , tcf_tyvar = do_tyvar, tcf_covar = do_covar
    
    439 451
                                  , tcf_hole  = do_hole, tcf_tycobinder = do_bndr }
    
    ... ... @@ -445,17 +457,18 @@ deepCoVarFolder = TyCoFolder { tcf_view = noView
    445 457
           -- the tyvar won't end up in the accumulator, so
    
    446 458
           -- we'd look repeatedly.  Blargh.
    
    447 459
     
    
    448
    -    do_covar is v = Endo do_it
    
    460
    +    do_bndr is tcv _ = extendVarSet is tcv
    
    461
    +
    
    462
    +    do_covar is v = EndoOS do_it
    
    449 463
           where
    
    450 464
             do_it acc | v `elemVarSet` is  = acc
    
    451 465
                       | v `elemVarSet` acc = acc
    
    452
    -                  | otherwise          = appEndo (deep_cv_ty (varType v)) $
    
    466
    +                  | otherwise          = appEndoOS (deep_cv_ty (varType v)) $
    
    453 467
                                              acc `extendVarSet` v
    
    454 468
     
    
    455
    -    do_bndr is tcv _ = extendVarSet is tcv
    
    456
    -    do_hole is hole  = do_covar is (coHoleCoVar hole)
    
    457
    -                       -- See Note [CoercionHoles and coercion free variables]
    
    458
    -                       -- in GHC.Core.TyCo.Rep
    
    469
    +    do_hole _ _ = mempty
    
    470
    +      -- See (CHFV1) in Note [CoercionHoles and coercion free variables]
    
    471
    +      -- in GHC.Core.TyCo.Rep
    
    459 472
     
    
    460 473
     ------- Same again, but for DCoVarSet ----------
    
    461 474
     --    But this time the free vars are shallow
    
    ... ... @@ -480,7 +493,7 @@ closeOverKinds :: TyCoVarSet -> TyCoVarSet
    480 493
     -- add the deep free variables of its kind
    
    481 494
     closeOverKinds vs = nonDetStrictFoldVarSet do_one vs vs
    
    482 495
       where
    
    483
    -    do_one v acc = appEndo (deep_ty (varType v)) acc
    
    496
    +    do_one v acc = appEndoOS (deep_ty (varType v)) acc
    
    484 497
     
    
    485 498
     {- --------------- Alternative version 1 (using FV) ------------
    
    486 499
     closeOverKinds = fvVarSet . closeOverKindsFV . nonDetEltsUniqSet
    
    ... ... @@ -661,9 +674,8 @@ tyCoFVsOfCo (FunCo { fco_mult = w, fco_arg = co1, fco_res = co2 }) fv_cand in_sc
    661 674
       = (tyCoFVsOfCo co1 `unionFV` tyCoFVsOfCo co2 `unionFV` tyCoFVsOfCo w) fv_cand in_scope acc
    
    662 675
     tyCoFVsOfCo (CoVarCo v) fv_cand in_scope acc
    
    663 676
       = tyCoFVsOfCoVar v fv_cand in_scope acc
    
    664
    -tyCoFVsOfCo (HoleCo h) fv_cand in_scope acc
    
    665
    -  = tyCoFVsOfCoVar (coHoleCoVar h) fv_cand in_scope acc
    
    666
    -    -- See Note [CoercionHoles and coercion free variables]
    
    677
    +tyCoFVsOfCo (HoleCo {}) fv_cand in_scope acc = emptyFV fv_cand in_scope acc
    
    678
    +    -- Ignore holes: see (CHFV1) in Note [CoercionHoles and coercion free variables]
    
    667 679
     tyCoFVsOfCo (AxiomCo _ cs)    fv_cand in_scope acc = tyCoFVsOfCos cs  fv_cand in_scope acc
    
    668 680
     tyCoFVsOfCo (UnivCo { uco_lty = t1, uco_rty = t2, uco_deps = deps}) fv_cand in_scope acc
    
    669 681
       = (tyCoFVsOfCos deps `unionFV` tyCoFVsOfType t1
    

  • compiler/GHC/Core/TyCo/Rep.hs
    ... ... @@ -1804,17 +1804,23 @@ Other notes about HoleCo:
    1804 1804
     
    
    1805 1805
     Note [CoercionHoles and coercion free variables]
    
    1806 1806
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1807
    -Why does a CoercionHole contain a CoVar, as well as reference to
    
    1808
    -fill in?  Because we want to treat that CoVar as a free variable of
    
    1809
    -the coercion.  See #14584, and Note [What prevents a
    
    1810
    -constraint from floating] in GHC.Tc.Solver, item (4):
    
    1807
    +Why does a CoercionHole contain a CoVar, as well as reference to fill in?
    
    1808
    +  * It really helps for debug pretty-printing.
    
    1809
    +  * It carries a type which makes `coercionKind` and `coercionRole` work
    
    1810
    +  * It has a Unique, which gives the hole an identity; see calls to `ctEvEvId`
    
    1811
    +
    
    1812
    +(CHFV1) We do not treat a CoercionHole as a free variable of a coercion.
    
    1813
    +  In the past we did: See #14584, and Note [What prevents a constraint from floating]
    
    1814
    +  in GHC.Tc.Solver, item (4):
    
    1811 1815
     
    
    1812 1816
             forall k. [W] co1 :: t1 ~# t2 |> co2
    
    1813 1817
                       [W] co2 :: k ~# *
    
    1814 1818
     
    
    1815
    -Here co2 is a CoercionHole. But we /must/ know that it is free in
    
    1816
    -co1, because that's all that stops it floating outside the
    
    1817
    -implication.
    
    1819
    +   Here co2 is a CoercionHole. But we /must/ know that it is free in
    
    1820
    +   co1, because that's all that stops it floating outside the
    
    1821
    +   implication.
    
    1822
    +
    
    1823
    +   But nowadays this is all irrelevant because we don't float constraints.
    
    1818 1824
     
    
    1819 1825
     Note [CoercionHoles and CoHoleSets]
    
    1820 1826
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

  • compiler/GHC/Tc/Solver/Equality.hs
    ... ... @@ -554,24 +554,21 @@ can_eq_nc_forall ev eq_rel s1 s2
    554 554
                        ; traceTcS "Trying to solve the implication" (ppr s1 $$ ppr s2 $$ ppr wanteds)
    
    555 555
     
    
    556 556
                        -- Solve the `wanteds` in a nested context
    
    557
    -                   ; ev_binds_var <- newNoTcEvBinds
    
    557
    +                   -- Use the /same/ TcEvBinds var as the context; we do not expect any dict binds
    
    558
    +                   -- but we do want to record any used Given coercions (in `evb_tcvs`) so that
    
    559
    +                   -- they are kept alive by `neededEvVars`. Admittedly they are free in `all_co`,
    
    560
    +                   -- but only if we zonk it, which `neededEvVars` does not do (see test T7196).
    
    561
    +                   ; ev_binds_var <- getTcEvBindsVar
    
    558 562
                        ; residual_wanted <- nestImplicTcS skol_info_anon ev_binds_var tclvl $
    
    559 563
                                             solveSimpleWanteds wanteds
    
    560 564
     
    
    561 565
                        ; return (all_co, isSolvedWC residual_wanted) }
    
    562 566
     
    
    563
    -
    
    564 567
           -- Kick out any inerts constraints that mention unified type variables
    
    565 568
           ; kickOutAfterUnification unifs
    
    566 569
     
    
    567 570
           ; if solved
    
    568
    -        then do { all_co <- zonkCo all_co
    
    569
    -                     -- setWantedEq will add `all_co` to the `ebv_tcvs`, to record
    
    570
    -                     -- that `all_co` is used.  But if `all_co` contains filled
    
    571
    -                     -- CoercionHoles, from the nested solve, and we may miss the
    
    572
    -                     -- use of CoVars.  Test T7196 showed this up
    
    573
    -
    
    574
    -                ; setWantedEq orig_dest emptyCoHoleSet all_co
    
    571
    +        then do { setWantedEq orig_dest emptyCoHoleSet all_co
    
    575 572
                          -- emptyCoHoleSet: fully solved, so all_co has no holes
    
    576 573
                     ; stopWith ev "Polytype equality: solved" }
    
    577 574
     
    
    ... ... @@ -2935,8 +2932,7 @@ lookup_eq_in_qcis :: CtEvidence -> EqRel -> TcType -> TcType -> SolverStage ()
    2935 2932
     --    [W] t1 ~# t2
    
    2936 2933
     -- and a Given quantified contraint like (forall a b. blah => a ~ b)
    
    2937 2934
     -- Why?  See Note [Looking up primitive equalities in quantified constraints]
    
    2938
    --- See also GHC.Tc.Solver.Dict
    
    2939
    --- Note [Equality superclasses in quantified constraints]
    
    2935
    +-- See also GHC.Tc.Solver.Dict Note [Equality superclasses in quantified constraints]
    
    2940 2936
     lookup_eq_in_qcis (CtGiven {}) _ _ _
    
    2941 2937
       = nopStage ()
    
    2942 2938
     
    
    ... ... @@ -2952,10 +2948,18 @@ lookup_eq_in_qcis ev@(CtWanted (WantedCt { ctev_dest = dest, ctev_loc = loc }))
    2952 2948
       where
    
    2953 2949
         hole = case dest of
    
    2954 2950
                  HoleDest hole -> hole   -- Equality constraints have HoleDest
    
    2955
    -             _ -> pprPanic "lookup_eq_in_qcis" (ppr dest) 
    
    2951
    +             _ -> pprPanic "lookup_eq_in_qcis" (ppr dest)
    
    2956 2952
     
    
    2957 2953
         try :: SwapFlag -> SolverStage ()
    
    2958
    -    try swap -- First try looking for (lhs ~ rhs)
    
    2954
    +    -- E.g. We are trying to solve (say)
    
    2955
    +    --             [W] g : [Int] ~# b)
    
    2956
    +    --      from   [G] forall x. blah => b ~ [x]   -- A quantified constraint
    
    2957
    +    -- We can solve it like this
    
    2958
    +    --     d::b~[Int] := $df @Int blah        -- Apply the quantified constraint
    
    2959
    +    --     g'::b~#[Int] := sc_sel d           -- Binding, extract the coercion from d
    
    2960
    +    --     g(co-hole) := sym g'               -- Fill the original coercion hole
    
    2961
    +    -- Here g' is a fresh coercion variable.
    
    2962
    +    try swap
    
    2959 2963
            | Just (cls, tys) <- unSwap swap (boxEqPred eq_rel) lhs rhs
    
    2960 2964
            = Stage $
    
    2961 2965
              do { let cls_pred = mkClassPred cls tys
    
    ... ... @@ -2965,7 +2969,7 @@ lookup_eq_in_qcis ev@(CtWanted (WantedCt { ctev_dest = dest, ctev_loc = loc }))
    2965 2969
                     OneInst {}
    
    2966 2970
                       -> do { dict_ev <- newWantedEvVarNC loc emptyCoHoleSet cls_pred
    
    2967 2971
                             ; chooseInstance dict_ev res
    
    2968
    -                        ; let co_var = coHoleCoVar hole
    
    2972
    +                        ; co_var <- newEvVar (unSwap swap (mkEqPred eq_rel) lhs rhs)
    
    2969 2973
                             ; setEvBind (mkWantedEvBind co_var EvCanonical (mk_sc_sel cls tys dict_ev))
    
    2970 2974
                             ; fillCoercionHole hole emptyCoHoleSet $
    
    2971 2975
                               maybeSymCo swap (mkCoVarCo co_var)
    

  • compiler/GHC/Tc/Types/Evidence.hs
    ... ... @@ -392,6 +392,8 @@ data EvBindsVar
    392 392
           --  so that we can report unused given constraints,
    
    393 393
           --  in GHC.Tc.Solver.neededEvVars
    
    394 394
           -- See Note [Tracking redundant constraints] in GHC.Tc.Solver
    
    395
    +      -- Also: we garbage-collect unused bindings in `neededEvVars`,
    
    396
    +      --       so this matters for correctness too.
    
    395 397
         }
    
    396 398
     
    
    397 399
       | CoEvBindsVar {  -- See Note [Coercion evidence only]
    

  • compiler/GHC/Tc/Utils/TcType.hs
    ... ... @@ -234,9 +234,11 @@ import GHC.Builtin.Names
    234 234
     import GHC.Builtin.Types ( coercibleClass, eqClass, heqClass, unitTyConKey
    
    235 235
                              , listTyCon, constraintKind )
    
    236 236
     import GHC.Types.Basic
    
    237
    -import GHC.Utils.Misc
    
    238 237
     import GHC.Data.Maybe
    
    239 238
     import GHC.Data.List.SetOps ( getNth, findDupsEq )
    
    239
    +
    
    240
    +import GHC.Utils.Misc
    
    241
    +import GHC.Utils.EndoOS
    
    240 242
     import GHC.Utils.Outputable
    
    241 243
     import GHC.Utils.Panic
    
    242 244
     
    
    ... ... @@ -1176,11 +1178,11 @@ exactTyCoVarsOfTypes :: [Type] -> TyCoVarSet
    1176 1178
     exactTyCoVarsOfType  ty  = runTyCoVars (exact_ty ty)
    
    1177 1179
     exactTyCoVarsOfTypes tys = runTyCoVars (exact_tys tys)
    
    1178 1180
     
    
    1179
    -exact_ty  :: Type       -> Endo TyCoVarSet
    
    1180
    -exact_tys :: [Type]     -> Endo TyCoVarSet
    
    1181
    +exact_ty  :: Type       -> EndoOS TyCoVarSet
    
    1182
    +exact_tys :: [Type]     -> EndoOS TyCoVarSet
    
    1181 1183
     (exact_ty, exact_tys, _, _) = foldTyCo exactTcvFolder emptyVarSet
    
    1182 1184
     
    
    1183
    -exactTcvFolder :: TyCoFolder TyCoVarSet (Endo TyCoVarSet)
    
    1185
    +exactTcvFolder :: TyCoFolder TyCoVarSet (EndoOS TyCoVarSet)
    
    1184 1186
     exactTcvFolder = deepTcvFolder { tcf_view = coreView }
    
    1185 1187
                      -- This is the key line
    
    1186 1188
     
    

  • compiler/GHC/Types/Unique/DSM.hs
    ... ... @@ -168,7 +168,7 @@ instance MonadGetUnique USM.UniqSM where
    168 168
     newtype UniqDSMT m result = UDSMT' (DUniqSupply -> m (result, DUniqSupply))
    
    169 169
       deriving (Functor)
    
    170 170
     
    
    171
    --- Similar to GHC.Utils.Monad.State.Strict, using Note [The one-shot state monad trick]
    
    171
    +-- Similar to GHC.Utils.Monad, using Note [The one-shot state monad trick]
    
    172 172
     -- Using the one-shot trick is necessary for performance.
    
    173 173
     -- Using transfomer's strict `StateT` regressed some performance tests in 1-2%.
    
    174 174
     -- The one-shot trick here fixes those regressions.
    

  • compiler/GHC/Utils/EndoOS.hs
    1
    +{-# LANGUAGE PatternSynonyms #-}
    
    2
    +
    
    3
    +-- | One-shot endomorphisms
    
    4
    +--   Mostly for backwards compatibility.
    
    5
    +
    
    6
    +-- One-shot endomorphisms
    
    7
    +-- Like GHC.Internal.Data.Semigroup.Internal.Endo, but uting
    
    8
    +-- the one-shot trick from
    
    9
    +--    Note [The one-shot state monad trick] in  GHC.Utils.Monad.
    
    10
    +
    
    11
    +module GHC.Utils.EndoOS( EndoOS(EndoOS, appEndoOS ) ) where
    
    12
    +
    
    13
    +import GHC.Prelude
    
    14
    +
    
    15
    +import Data.Semigroup
    
    16
    +import GHC.Exts (oneShot)
    
    17
    +
    
    18
    +newtype EndoOS a = EndoOS' { appEndoOS :: a -> a }
    
    19
    +
    
    20
    +
    
    21
    +instance Semigroup (EndoOS a) where
    
    22
    +  f <> g = EndoOS (appEndoOS f . appEndoOS g)
    
    23
    +
    
    24
    +instance Monoid (EndoOS a) where
    
    25
    +   mempty  = EndoOS id
    
    26
    +
    
    27
    +pattern EndoOS :: (a->a) -> EndoOS a
    
    28
    +pattern EndoOS f <- EndoOS' f
    
    29
    +      where
    
    30
    +        EndoOS f = EndoOS' (oneShot f)
    
    31
    +                         -- ^^^^^^ The one-shot trick!

  • compiler/ghc.cabal.in
    ... ... @@ -997,6 +997,7 @@ Library
    997 997
             GHC.Utils.Containers.Internal.BitUtil
    
    998 998
             GHC.Utils.Containers.Internal.StrictPair
    
    999 999
             GHC.Utils.Error
    
    1000
    +        GHC.Utils.EndoOS
    
    1000 1001
             GHC.Utils.Exception
    
    1001 1002
             GHC.Utils.Fingerprint
    
    1002 1003
             GHC.Utils.FV