Simon Peyton Jones pushed to branch wip/T20264 at Glasgow Haskell Compiler / GHC

Commits:

7 changed files:

Changes:

  • compiler/GHC/Core.hs
    ... ... @@ -489,6 +489,15 @@ Wrinkles:
    489 489
       (which is always substituted) with the tyvar-replete-with-unfolding, rather
    
    490 490
       than merely extending the in-scope set as we do for Ids.
    
    491 491
     
    
    492
    +So: (TCL1) + (TCL2) =
    
    493
    +  EITHER `a` has an unfolding at its binding site,
    
    494
    +     and that unfolding is replicated at every occurrence site
    
    495
    +  OR it doesn't and the occurrences don't either.
    
    496
    +
    
    497
    +
    
    498
    +OR we could insist that tyvar bindings always have an unfolding, and use
    
    499
    +a beta-redex if not.
    
    500
    +
    
    492 501
     Note [Core top-level string literals]
    
    493 502
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    494 503
     As an exception to the usual rule that top-level binders must be lifted,
    

  • compiler/GHC/Core/Opt/Simplify/Env.hs
    ... ... @@ -854,7 +854,8 @@ doFloatFromRhs env lvl rec strict_bind tvs (SimplFloats { sfLetFloats = LetFloat
    854 854
          cant_float_types
    
    855 855
            | not (null tvs), any isTyCoVar float_bndrs
    
    856 856
            = (pprTraceWhen (any isId float_bndrs)
    
    857
    -            "WARNING-TyCo: skipping abstractFloats" (ppr fs)) $
    
    857
    +            "WARNING-TyCo: skipping abstractFloats"
    
    858
    +            (text "binders" <+> ppr (fmap bindersOf fs)))
    
    858 859
              True
    
    859 860
            | otherwise
    
    860 861
            = False
    

  • compiler/GHC/Core/Opt/Specialise.hs
    ... ... @@ -33,6 +33,7 @@ import GHC.Core.Utils ( exprIsTrivial, exprIsTopLevelBindable
    33 33
                               , mkCast, exprType, exprIsHNF
    
    34 34
                               , stripTicksTop, mkInScopeSetBndrs )
    
    35 35
     import GHC.Core.FVs
    
    36
    +import GHC.Core.TyCo.FVs( someTyCoVarsOfTypeList )
    
    36 37
     import GHC.Core.Opt.Arity( collectBindersPushingCo )
    
    37 38
     import GHC.Core.Opt.Monad
    
    38 39
     import GHC.Core.Opt.Simplify.Env ( SimplPhase(..), isActive )
    
    ... ... @@ -658,17 +659,17 @@ specProgram guts@(ModGuts { mg_module = this_mod
    658 659
                               , se_rules  = rule_env
    
    659 660
                               , se_dflags = dflags }
    
    660 661
     
    
    661
    -             go []           = return ([], emptyUDs)
    
    662
    +             go []           = return (nilOL, emptyUDs)
    
    662 663
                  go (bind:binds) = do (bind', binds', uds') <- specBind TopLevel top_env bind $ \_ ->
    
    663 664
                                                                go binds
    
    664
    -                                  return (bind' ++ binds', uds')
    
    665
    +                                  return (bind' `appOL` binds', uds')
    
    665 666
     
    
    666 667
                  -- Specialise the bindings of this module
    
    667 668
            ; (binds', uds) <- runSpecM (go binds)
    
    668 669
     
    
    669 670
            ; (spec_rules, spec_binds) <- specImports top_env uds
    
    670 671
     
    
    671
    -       ; return (guts { mg_binds = spec_binds ++ binds'
    
    672
    +       ; return (guts { mg_binds = spec_binds ++ fromOL binds'
    
    672 673
                           , mg_rules = spec_rules ++ local_rules }) }
    
    673 674
     
    
    674 675
     {-
    
    ... ... @@ -677,7 +678,7 @@ Note [Wrap bindings returned by specImports]
    677 678
     'specImports' returns a set of specialized bindings. However, these are lacking
    
    678 679
     necessary floated dictionary bindings, which are returned by
    
    679 680
     UsageDetails(ud_binds). These dictionaries need to be brought into scope with
    
    680
    -'wrapDictBinds' before the bindings returned by 'specImports' can be used. See,
    
    681
    +'wrapFloatBinds' before the bindings returned by 'specImports' can be used. See,
    
    681 682
     for instance, the 'specImports' call in 'specProgram'.
    
    682 683
     
    
    683 684
     
    
    ... ... @@ -763,7 +764,7 @@ specImports :: SpecEnv
    763 764
     specImports top_env (MkUD { ud_binds = dict_binds, ud_calls = calls })
    
    764 765
       | not $ gopt Opt_CrossModuleSpecialise (se_dflags top_env)
    
    765 766
         -- See Note [Disabling cross-module specialisation]
    
    766
    -  = return ([], wrapDictBinds dict_binds [])
    
    767
    +  = return ([], wrapFloatBinds dict_binds [])
    
    767 768
     
    
    768 769
       | otherwise
    
    769 770
       = do { let env_w_dict_bndrs = top_env `bringFloatedDictsIntoScope` dict_binds
    
    ... ... @@ -771,7 +772,7 @@ specImports top_env (MkUD { ud_binds = dict_binds, ud_calls = calls })
    771 772
     
    
    772 773
                  -- Make a Rec: see Note [Glom the bindings if imported functions are specialised]
    
    773 774
                  --
    
    774
    -             -- wrapDictBinds: don't forget to wrap the specialized bindings with
    
    775
    +             -- wrapFloatBinds: don't forget to wrap the specialized bindings with
    
    775 776
                  --   bindings for the needed dictionaries.
    
    776 777
                  --   See Note [Wrap bindings returned by specImports]
    
    777 778
                  --
    
    ... ... @@ -780,9 +781,9 @@ specImports top_env (MkUD { ud_binds = dict_binds, ud_calls = calls })
    780 781
            ; let (rules_for_locals, rules_for_imps) = partition isLocalRule spec_rules
    
    781 782
                  local_rule_base = extendRuleBaseList emptyRuleBase rules_for_locals
    
    782 783
                  final_binds
    
    783
    -               | null spec_binds = wrapDictBinds dict_binds []
    
    784
    +               | null spec_binds = wrapFloatBinds dict_binds []
    
    784 785
                    | otherwise       = glomValBinds $
    
    785
    -                                   wrapDictBinds dict_binds                          $
    
    786
    +                                   wrapFloatBinds dict_binds                          $
    
    786 787
                                        map (mapBindBndrs (addRulesToId local_rule_base)) $
    
    787 788
                                        spec_binds
    
    788 789
     
    
    ... ... @@ -791,10 +792,10 @@ specImports top_env (MkUD { ud_binds = dict_binds, ud_calls = calls })
    791 792
     
    
    792 793
     -- | Specialise a set of calls to imported bindings
    
    793 794
     spec_imports :: SpecEnv          -- Passed in so that all top-level Ids are in scope
    
    794
    -                                 ---In-scope set includes the FloatedDictBinds
    
    795
    +                                 ---In-scope set includes the FloatBinds
    
    795 796
                  -> [Id]             -- Stack of imported functions being specialised
    
    796 797
                                      -- See Note [specImport call stack]
    
    797
    -             -> FloatedDictBinds -- Dict bindings, used /only/ for filterCalls
    
    798
    +             -> FloatBinds -- Dict bindings, used /only/ for filterCalls
    
    798 799
                                      -- See Note [Avoiding loops in specImports]
    
    799 800
                  -> CallDetails      -- Calls for imported things
    
    800 801
                  -> CoreM ( SpecEnv      -- Env contains the new rules
    
    ... ... @@ -824,10 +825,10 @@ spec_imports env callers dict_binds calls
    824 825
                ; return (env, rules1 ++ rules2, spec_binds1 ++ spec_binds2) }
    
    825 826
     
    
    826 827
     spec_import :: SpecEnv               -- Passed in so that all top-level Ids are in scope
    
    827
    -                                     ---In-scope set includes the FloatedDictBinds
    
    828
    +                                     ---In-scope set includes the FloatBinds
    
    828 829
                 -> [Id]                  -- Stack of imported functions being specialised
    
    829 830
                                          -- See Note [specImport call stack]
    
    830
    -            -> FloatedDictBinds      -- Dict bindings, used /only/ for filterCalls
    
    831
    +            -> FloatBinds      -- Dict bindings, used /only/ for filterCalls
    
    831 832
                                          -- See Note [Avoiding loops in specImports]
    
    832 833
                 -> CallInfoSet           -- Imported function and calls for it
    
    833 834
                 -> CoreM ( SpecEnv
    
    ... ... @@ -889,7 +890,7 @@ spec_import env callers dict_binds cis@(CIS fn _)
    889 890
                                         (dict_binds `thenFDBs` dict_binds1)
    
    890 891
                                         new_calls
    
    891 892
     
    
    892
    -       ; let final_binds = wrapDictBinds dict_binds1 $
    
    893
    +       ; let final_binds = wrapFloatBinds dict_binds1 $
    
    893 894
                                spec_binds2 ++ spec_binds1
    
    894 895
     
    
    895 896
            ; return (env, rules2 ++ rules1, final_binds) }
    
    ... ... @@ -1161,6 +1162,20 @@ And if the call is to the same type, one specialisation is enough.
    1161 1162
     Avoiding this recursive specialisation loop is one reason for the
    
    1162 1163
     'callers' stack passed to specImports and specImport.
    
    1163 1164
     
    
    1165
    +Note [Specialisation and type-variable bindings]
    
    1166
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1167
    +GHC allows let-bindings for type variables e.g.
    
    1168
    +     a::Type = Type (Maybe b)
    
    1169
    +We need to account for these when specialising:
    
    1170
    +
    
    1171
    +(STV1) The ci_fvs field of a CallInfo includes free TyVars
    
    1172
    +
    
    1173
    +(STV2) When dumping calls, in `deleteCallsMentioning`, we ignore
    
    1174
    +   free tyvars when Opt_PolymorphicSpecialisation is on.
    
    1175
    +   See (MP1) in Note [Specialising polymorphic dictionaries]
    
    1176
    +
    
    1177
    +(STV3) A FloatBind can be a type binding; see `bindAuxiliaryTyVars`
    
    1178
    +
    
    1164 1179
     
    
    1165 1180
     ************************************************************************
    
    1166 1181
     *                                                                      *
    
    ... ... @@ -1287,8 +1302,8 @@ specLam env bndrs body
    1287 1302
       = specExpr env body
    
    1288 1303
       | otherwise
    
    1289 1304
       = do { (body', uds) <- specExpr env body
    
    1290
    -       ; let (free_uds, dumped_dbs) = dumpUDs bndrs uds
    
    1291
    -       ; return (mkLams bndrs (wrapDictBindsE dumped_dbs body'), free_uds) }
    
    1305
    +       ; let (free_uds, dumped_dbs) = dumpUDs env bndrs uds
    
    1306
    +       ; return (mkLams bndrs (wrapFloatBindsE dumped_dbs body'), free_uds) }
    
    1292 1307
     
    
    1293 1308
     --------------
    
    1294 1309
     specTickish :: SpecEnv -> CoreTickish -> CoreTickish
    
    ... ... @@ -1313,8 +1328,8 @@ specCase env scrut case_bndr alts
    1313 1328
         (env_alt, case_bndr') = substBndr env case_bndr
    
    1314 1329
         spec_alt (Alt con args rhs)
    
    1315 1330
           = do { (rhs', uds) <- specExpr env_rhs rhs
    
    1316
    -           ; let (free_uds, dumped_dbs) = dumpUDs (case_bndr' : args') uds
    
    1317
    -           ; return (Alt con args' (wrapDictBindsE dumped_dbs rhs'), free_uds) }
    
    1331
    +           ; let (free_uds, dumped_dbs) = dumpUDs env (case_bndr' : args') uds
    
    1332
    +           ; return (Alt con args' (wrapFloatBindsE dumped_dbs rhs'), free_uds) }
    
    1318 1333
             where
    
    1319 1334
               (env_rhs, args') = substBndrs env_alt args
    
    1320 1335
     
    
    ... ... @@ -1420,8 +1435,8 @@ End of Historical Note
    1420 1435
     ************************************************************************
    
    1421 1436
     -}
    
    1422 1437
     
    
    1423
    -bringFloatedDictsIntoScope :: SpecEnv -> FloatedDictBinds -> SpecEnv
    
    1424
    -bringFloatedDictsIntoScope env (FDB { fdb_bndrs = dx_bndrs })
    
    1438
    +bringFloatedDictsIntoScope :: SpecEnv -> FloatBinds -> SpecEnv
    
    1439
    +bringFloatedDictsIntoScope env (FDB { fbs_bndrs = dx_bndrs })
    
    1425 1440
       = -- pprTrace "brought into scope" (ppr dx_bndrs) $
    
    1426 1441
         env {se_subst=subst'}
    
    1427 1442
       where
    
    ... ... @@ -1432,7 +1447,7 @@ specBind :: TopLevelFlag
    1432 1447
                            -- top level binders in scope
    
    1433 1448
              -> InBind
    
    1434 1449
              -> (SpecEnv -> SpecM (body, UsageDetails))    -- Process the body
    
    1435
    -         -> SpecM ( [OutBind]           -- New bindings
    
    1450
    +         -> SpecM ( OrdList OutBind     -- New bindings
    
    1436 1451
                       , body                -- Body
    
    1437 1452
                       , UsageDetails)       -- And info to pass upstream
    
    1438 1453
     -- Returned UsageDetails:
    
    ... ... @@ -1448,13 +1463,13 @@ specBind top_lvl env (NonRec tv (Type rhs_ty)) do_body
    1448 1463
     
    
    1449 1464
            ; let rhs_ty' = substTy env rhs_ty
    
    1450 1465
                  bind' = NonRec tv' (Type rhs_ty')
    
    1451
    -             (free_uds, dump_dbs, float_all) = dumpBindUDs True [tv'] body_uds
    
    1452
    -             final_binds = mkDB bind' : fromOL dump_dbs
    
    1466
    +             (free_uds, dump_dbs, float_all) = dumpBindUDs env True [tv'] body_uds
    
    1467
    +             final_binds = unitOL (mkDB bind') `appOL` dump_dbs
    
    1453 1468
     
    
    1454 1469
            ; if float_all then
    
    1455
    -              return ([], body', free_uds `snocDictBinds` final_binds)
    
    1470
    +              return (nilOL, body', free_uds `snocFloatBinds` final_binds)
    
    1456 1471
              else
    
    1457
    -              return (map db_bind final_binds, body', free_uds) }
    
    1472
    +              return (fmap fb_bind final_binds, body', free_uds) }
    
    1458 1473
     
    
    1459 1474
     specBind top_lvl env (NonRec fn rhs) do_body
    
    1460 1475
       = do { (rhs', rhs_uds) <- specExpr env rhs
    
    ... ... @@ -1486,31 +1501,30 @@ specBind top_lvl env (NonRec fn rhs) do_body
    1486 1501
     
    
    1487 1502
            ; let can_float_this_one = exprIsTopLevelBindable rhs (idType fn)
    
    1488 1503
                      -- exprIsTopLevelBindable: see Note [Care with unlifted bindings]
    
    1489
    -             (free_uds, dump_dbs, float_all) = dumpBindUDs can_float_this_one [fn4] body_uds1
    
    1504
    +             (free_uds, dump_dbs, float_all) = dumpBindUDs env can_float_this_one [fn4] body_uds1
    
    1490 1505
                  all_free_uds                    = free_uds `thenUDs` rhs_uds
    
    1491 1506
     
    
    1492 1507
                  pairs = spec_defns ++ [(fn4, rhs')]
    
    1493 1508
                             -- fn4 mentions the spec_defns in its rules,
    
    1494 1509
                             -- so put the latter first
    
    1495 1510
     
    
    1496
    -             final_binds :: [DictBind]
    
    1511
    +             final_binds :: OrdList FloatBind
    
    1497 1512
                  -- See Note [From non-recursive to recursive]
    
    1498 1513
                  final_binds | not (isNilOL dump_dbs)
    
    1499 1514
                              , not (null spec_defns)
    
    1500
    -                         = [recWithDumpedDicts pairs dump_dbs]
    
    1515
    +                         = unitOL (recWithDumpedDicts pairs dump_dbs)
    
    1501 1516
                              | otherwise
    
    1502
    -                         = [mkDB $ NonRec b r | (b,r) <- pairs]
    
    1503
    -                           ++ fromOL dump_dbs
    
    1504
    -
    
    1517
    +                         = toOL [mkDB $ NonRec b r | (b,r) <- pairs]
    
    1518
    +                           `appOL` dump_dbs
    
    1505 1519
     
    
    1506 1520
            ; if float_all then
    
    1507 1521
                  -- Rather than discard the calls mentioning the bound variables
    
    1508 1522
                  -- we float this (dictionary) binding along with the others
    
    1509
    -              return ([], body', all_free_uds `snocDictBinds` final_binds)
    
    1523
    +              return (nilOL, body', all_free_uds `snocFloatBinds` final_binds)
    
    1510 1524
              else
    
    1511 1525
                  -- No call in final_uds mentions bound variables,
    
    1512 1526
                  -- so we can just leave the binding here
    
    1513
    -              return (map db_bind final_binds, body', all_free_uds) }
    
    1527
    +              return (fmap fb_bind final_binds, body', all_free_uds) }
    
    1514 1528
     
    
    1515 1529
     
    
    1516 1530
     specBind top_lvl env (Rec pairs) do_body
    
    ... ... @@ -1538,14 +1552,14 @@ specBind top_lvl env (Rec pairs) do_body
    1538 1552
                                   <- specDefns rec_env uds2 (bndrs2 `zip` rhss)
    
    1539 1553
                             ; return (bndrs3, spec_defns3 ++ spec_defns2, uds3) }
    
    1540 1554
     
    
    1541
    -       ; let (final_uds, dumped_dbs, float_all) = dumpBindUDs True bndrs1 uds3
    
    1555
    +       ; let (final_uds, dumped_dbs, float_all) = dumpBindUDs env True bndrs1 uds3
    
    1542 1556
                  final_bind = recWithDumpedDicts (spec_defns3 ++ zip bndrs3 rhss')
    
    1543 1557
                                                  dumped_dbs
    
    1544 1558
     
    
    1545 1559
            ; if float_all then
    
    1546
    -              return ([], body', final_uds `snocDictBind` final_bind)
    
    1560
    +              return (nilOL, body', final_uds `snocFloatBind` final_bind)
    
    1547 1561
              else
    
    1548
    -              return ([db_bind final_bind], body', final_uds) }
    
    1562
    +              return (unitOL (fb_bind final_bind), body', final_uds) }
    
    1549 1563
     
    
    1550 1564
     
    
    1551 1565
     ---------------------------
    
    ... ... @@ -1700,21 +1714,21 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
    1700 1714
                      already_covered = alreadyCovered env' rule_bndrs fn
    
    1701 1715
                                                       rule_lhs_args is_active all_rules
    
    1702 1716
     
    
    1703
    ---         ; pprTrace "spec_call" (vcat
    
    1704
    ---                [ text "fun:       "  <+> ppr fn
    
    1705
    ---                , text "call info: "  <+> ppr _ci
    
    1706
    ---                , text "useful:    "  <+> ppr useful
    
    1707
    ---                , text "already_covered:"  <+> ppr already_covered
    
    1708
    ---                , text "useful:    "  <+> ppr useful
    
    1709
    ---                , text "rule_bndrs:"  <+> ppr (sep (map (pprBndr LambdaBind) rule_bndrs))
    
    1710
    ---                , text "rule_lhs_args:"  <+> ppr rule_lhs_args
    
    1711
    ---                , text "spec_bndrs:" <+> ppr (sep (map (pprBndr LambdaBind) spec_bndrs))
    
    1712
    ---                , text "dx_binds:"   <+> ppr dx_binds
    
    1713
    ---                , text "spec_args: "  <+> ppr spec_args
    
    1714
    ---                , text "rhs_bndrs"    <+> ppr (sep (map (pprBndr LambdaBind) rhs_bndrs))
    
    1715
    ---                , text "rhs_body"     <+> ppr rhs_body
    
    1716
    ---                , text "subst'" <+> ppr subst'
    
    1717
    ---                ]) $ return ()
    
    1717
    +--          ; pprTrace "spec_call" (vcat
    
    1718
    +--                 [ text "fun:       "  <+> ppr fn
    
    1719
    +--                 , text "call info: "  <+> ppr _ci
    
    1720
    +--                 , text "useful:    "  <+> ppr useful
    
    1721
    +--                 , text "already_covered:"  <+> ppr already_covered
    
    1722
    +--                 , text "useful:    "  <+> ppr useful
    
    1723
    +--                 , text "rule_bndrs:"  <+> ppr (sep (map (pprBndr LambdaBind) rule_bndrs))
    
    1724
    +--                 , text "rule_lhs_args:"  <+> ppr rule_lhs_args
    
    1725
    +--                 , text "spec_bndrs:" <+> ppr (sep (map (pprBndr LambdaBind) spec_bndrs))
    
    1726
    +--                 , text "dx_binds:"   <+> ppr dx_binds
    
    1727
    +--                 , text "spec_args: "  <+> ppr spec_args
    
    1728
    +--                 , text "rhs_bndrs"    <+> ppr (sep (map (pprBndr LambdaBind) rhs_bndrs))
    
    1729
    +--                 , text "rhs_body"     <+> ppr rhs_body
    
    1730
    +--                 , text "subst'" <+> ppr subst'
    
    1731
    +--                 ]) $ return ()
    
    1718 1732
     
    
    1719 1733
     
    
    1720 1734
                ; if not useful          -- No useful specialisation
    
    ... ... @@ -1731,12 +1745,12 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
    1731 1745
     
    
    1732 1746
                -- Make the RHS of the specialised function
    
    1733 1747
                ; let spec_rhs_bndrs = spec_bndrs ++ inner_rhs_bndrs'
    
    1734
    -                 (rhs_uds2, inner_dumped_dbs) = dumpUDs spec_rhs_bndrs $
    
    1735
    -                                                dx_binds `consDictBinds` rhs_uds
    
    1748
    +                 (rhs_uds2, inner_dumped_dbs) = dumpUDs env spec_rhs_bndrs $
    
    1749
    +                                                dx_binds `consFloatBinds` rhs_uds
    
    1736 1750
                      -- dx_binds comes from the arguments to the call,
    
    1737 1751
                      -- and so can mention poly_qvars but no other local binders
    
    1738 1752
                      spec_rhs = mkLams spec_rhs_bndrs           $
    
    1739
    -                            wrapDictBindsE inner_dumped_dbs rhs_body'
    
    1753
    +                            wrapFloatBindsE inner_dumped_dbs rhs_body'
    
    1740 1754
                      rule_rhs_args = spec_bndrs
    
    1741 1755
     
    
    1742 1756
                      -- Maybe add a void arg to the specialised function,
    
    ... ... @@ -1757,7 +1771,8 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
    1757 1771
                      -- The wrap_unf_body applies the original unfolding to the specialised
    
    1758 1772
                      -- arguments, not forgetting to wrap the dx_binds around the outside (#22358)
    
    1759 1773
                      simpl_opts = initSimpleOpts dflags
    
    1760
    -                 wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds
    
    1774
    +                 wrap_unf_body body = wrapFloatBindsE dx_binds $
    
    1775
    +                                      body `mkApps` spec_args
    
    1761 1776
                      spec_unf = specUnfolding simpl_opts rule_rhs_args1 wrap_unf_body
    
    1762 1777
                                               rule_lhs_args fn_unf
    
    1763 1778
     
    
    ... ... @@ -2529,10 +2544,11 @@ instance Outputable SpecArg where
    2529 2544
       ppr UnspecType    = text "UnspecType"
    
    2530 2545
       ppr UnspecArg     = text "UnspecArg"
    
    2531 2546
     
    
    2532
    -specArgsFVs :: InterestingVarFun -> [SpecArg] -> FV
    
    2533
    --- Find the free vars of the SpecArgs that are not already in scope
    
    2534
    -specArgsFVs interesting args
    
    2535
    -  = filterFV interesting $
    
    2547
    +specArgsFVs :: [SpecArg] -> VarSet
    
    2548
    +-- Find the free vars of the SpecArgs
    
    2549
    +specArgsFVs args
    
    2550
    +  = fvVarSet $
    
    2551
    +    filterFV isLocalVar $   -- Including TyVars
    
    2536 2552
         foldr (unionFV . get) emptyFV args
    
    2537 2553
       where
    
    2538 2554
         get :: SpecArg -> FV
    
    ... ... @@ -2607,15 +2623,15 @@ specHeader
    2607 2623
                     -- `$sf = \spec_bndrs. let { dx_binds } in <orig-rhs> spec_arg`
    
    2608 2624
                   , [OutBndr]    -- spec_bndrs: Binders for $sf, and args for the RHS
    
    2609 2625
                                  --             of the RULE. Subset of rule_bndrs.
    
    2610
    -              , [DictBind]   -- dx_binds:   Auxiliary dictionary bindings
    
    2626
    +              , OrdList FloatBind  -- dx_binds:   Auxiliary dictionary bindings
    
    2611 2627
                   , [OutExpr]    -- spec_args:  Specialised arguments for unfolding
    
    2612 2628
                                  --             Same length as "Args for LHS of rule"
    
    2613 2629
                   )
    
    2614 2630
     
    
    2615 2631
     -- If we run out of binders, stop immediately
    
    2616 2632
     -- See Note [Specialisation Must Preserve Sharing]
    
    2617
    -specHeader subst [] _  = pure (False, subst, [], [], [], [], [])
    
    2618
    -specHeader subst _  [] = pure (False, subst, [], [], [], [], [])
    
    2633
    +specHeader subst [] _  = pure (False, subst, [], [], [], nilOL, [])
    
    2634
    +specHeader subst _  [] = pure (False, subst, [], [], [], nilOL, [])
    
    2619 2635
     
    
    2620 2636
     -- We want to specialise on type 'T1', and so we must construct a substitution
    
    2621 2637
     -- 'a->T1', as well as a LHS argument for the resulting RULE and unfolding
    
    ... ... @@ -2671,20 +2687,23 @@ specHeader subst (bndr:bndrs) (_ : args)
    2671 2687
     -- a wildcard binder to match the dictionary (See Note [Specialising Calls] for
    
    2672 2688
     -- the nitty-gritty), as a LHS rule and unfolding details.
    
    2673 2689
     specHeader subst (bndr:bndrs) (SpecDict dict_arg : args)
    
    2674
    -  = do { -- Make up a fresh binder to use in the RULE
    
    2690
    +  = do { let (tv_bndrs, tv_binds) = bindAuxiliaryTyVars subst dict_arg
    
    2691
    +             subst1 = subst `Core.extendSubstInScopeSet` tv_bndrs
    
    2692
    +
    
    2693
    +         -- Make up a fresh binder to use in the RULE
    
    2675 2694
              -- It might turn into a dict binding (via bindAuxiliaryDict) which we
    
    2676 2695
              -- then float, so we use cloneIdBndr to get a completely fresh binder
    
    2677
    -         u <- getUniqueM
    
    2678
    -       ; let (subst1, bndr') = Core.cloneBndr subst u (zapIdOccInfo bndr)
    
    2696
    +       ; u <- getUniqueM
    
    2697
    +       ; let (subst2, bndr') = Core.cloneBndr subst1 u (zapIdOccInfo bndr)
    
    2679 2698
                      -- zapIdOccInfo: see Note [Zap occ info in rule binders]
    
    2680 2699
     
    
    2681 2700
              -- Extend the substitution to map bndr :-> dict_arg, for use in the RHS
    
    2682
    -       ; let (subst2, dx_bind, spec_dict) = bindAuxiliaryDict subst1 bndr bndr' dict_arg
    
    2701
    +       ; let (subst3, dx1, spec_dict) = bindAuxiliaryDict subst2 bndr bndr' dict_arg
    
    2683 2702
     
    
    2684
    -       ; (_, subst3, rule_bs, rule_es, spec_bs, dx, spec_args) <- specHeader subst2 bndrs args
    
    2703
    +       ; (_, subst4, rule_bs, rule_es, spec_bs, dx, spec_args) <- specHeader subst3 bndrs args
    
    2685 2704
     
    
    2686
    -       ; let dx' = case dx_bind of { Nothing -> dx; Just d -> d : dx }
    
    2687
    -       ; pure ( True, subst3      -- Ha!  A useful specialisation!
    
    2705
    +       ; let dx' = tv_binds `appOL` dx1 `appOL` dx
    
    2706
    +       ; pure ( True, subst4      -- Ha!  A useful specialisation!
    
    2688 2707
                   , bndr' : rule_bs, Var bndr' : rule_es
    
    2689 2708
                   , spec_bs,    dx', spec_dict : spec_args ) }
    
    2690 2709
     
    
    ... ... @@ -2713,13 +2732,46 @@ specHeader subst (bndr:bndrs) (UnspecArg : args)
    2713 2732
                   , bndrs ++ spec_bs, dx, dummy_arg : spec_args ) }
    
    2714 2733
     
    
    2715 2734
     
    
    2735
    +bindAuxiliaryTyVars :: Subst -> CoreExpr -> (TyVarSet, OrdList FloatBind)
    
    2736
    +bindAuxiliaryTyVars subst dict_arg
    
    2737
    +  = go emptyVarSet need_bind_tvs
    
    2738
    +  where
    
    2739
    +    go _ []
    
    2740
    +      = (emptyVarSet, nilOL)
    
    2741
    +    go tv_bndrs (tv:tvs)
    
    2742
    +       | tv `elemVarSet` tv_bndrs
    
    2743
    +       = go tv_bndrs tvs
    
    2744
    +       | Just unf <- tyVarUnfolding_maybe tv
    
    2745
    +       , (child_bndrs, child_binds) <- go tv_bndrs (someTyCoVarsOfTypeList needs_binding unf)
    
    2746
    +       , let tv_bndrs1 = child_bndrs `extendVarSet` tv
    
    2747
    +       , (rest_bndrs, rest_binds) <- go tv_bndrs1 tvs
    
    2748
    +       = ( rest_bndrs
    
    2749
    +         , child_binds `appOL` unitOL (mkDB (NonRec tv (Type unf)))
    
    2750
    +                       `appOL` rest_binds )
    
    2751
    +       | otherwise
    
    2752
    +       = pprTrace "addTyVarBindings: unxpected 1" (ppr tv $$ ppr dict_arg) $
    
    2753
    +         go tv_bndrs tvs
    
    2754
    +
    
    2755
    +    need_bind_tvs = exprSomeFreeVarsList needs_binding dict_arg
    
    2756
    +    in_scope = substInScopeSet subst
    
    2757
    +    needs_binding var
    
    2758
    +      | isGlobalVar var
    
    2759
    +      = False
    
    2760
    +      | var `elemInScopeSet` in_scope
    
    2761
    +      = False
    
    2762
    +      | otherwise
    
    2763
    +      = case tyVarUnfolding_maybe var of
    
    2764
    +          Just {} -> True
    
    2765
    +          Nothing -> pprPanic "addTyVarBindings: unexpected 2"
    
    2766
    +                       (ppr var $$ ppr dict_arg)
    
    2767
    +
    
    2716 2768
     -- | Binds a dictionary argument to a fresh name, to preserve sharing
    
    2717 2769
     bindAuxiliaryDict
    
    2718 2770
       :: Subst
    
    2719 2771
       -> InId -> OutId -> OutExpr -- Original dict binder, and the witnessing expression
    
    2720
    -  -> ( Subst          -- Substitutes for orig_dict_id
    
    2721
    -     , Maybe DictBind -- Auxiliary dict binding, if any
    
    2722
    -     , OutExpr)       -- Witnessing expression (always trivial)
    
    2772
    +  -> ( Subst            -- Substitutes for orig_dict_id
    
    2773
    +     , OrdList FloatBind -- Auxiliary dict binding, if any
    
    2774
    +     , OutExpr)         -- Witnessing expression (always trivial)
    
    2723 2775
     bindAuxiliaryDict subst orig_dict_id fresh_dict_id dict_arg
    
    2724 2776
     
    
    2725 2777
       -- If the dictionary argument is trivial,
    
    ... ... @@ -2727,7 +2779,7 @@ bindAuxiliaryDict subst orig_dict_id fresh_dict_id dict_arg
    2727 2779
       | exprIsTrivial dict_arg
    
    2728 2780
       , let subst' = Core.extendSubst subst orig_dict_id dict_arg
    
    2729 2781
       = -- pprTrace "bindAuxiliaryDict:trivial" (ppr orig_dict_id <+> ppr dict_arg) $
    
    2730
    -    (subst', Nothing, dict_arg)
    
    2782
    +    (subst', nilOL, dict_arg)
    
    2731 2783
     
    
    2732 2784
       | otherwise  -- Non-trivial dictionary arg; make an auxiliary binding
    
    2733 2785
       , let fresh_dict_id' = fresh_dict_id `addDictUnfolding` dict_arg
    
    ... ... @@ -2737,7 +2789,7 @@ bindAuxiliaryDict subst orig_dict_id fresh_dict_id dict_arg
    2737 2789
                         `Core.extendSubstInScope` fresh_dict_id'
    
    2738 2790
                         -- Ensure the new unfolding is in the in-scope set
    
    2739 2791
       = -- pprTrace "bindAuxiliaryDict:non-trivial" (ppr orig_dict_id <+> ppr fresh_dict_id') $
    
    2740
    -    (subst', Just dict_bind, Var fresh_dict_id')
    
    2792
    +    (subst', unitOL dict_bind, Var fresh_dict_id')
    
    2741 2793
     
    
    2742 2794
     addDictUnfolding :: Id -> CoreExpr -> Id
    
    2743 2795
     -- Add unfolding for freshly-bound Ids: see Note [Make the new dictionaries interesting]
    
    ... ... @@ -2767,34 +2819,34 @@ in the dictionary Id.
    2767 2819
     ********************************************************************* -}
    
    2768 2820
     
    
    2769 2821
     data UsageDetails
    
    2770
    -  = MkUD { ud_binds :: !FloatedDictBinds
    
    2822
    +  = MkUD { ud_binds :: !FloatBinds
    
    2771 2823
              , ud_calls :: !CallDetails }
    
    2772
    -    -- INVARIANT: suppose bs = fdb_bndrs ud_binds
    
    2824
    +    -- INVARIANT: suppose bs = fbs_bndrs ud_binds
    
    2773 2825
         -- Then 'calls' may *mention* 'bs',
    
    2774 2826
         -- but there should be no calls *for* bs
    
    2775 2827
     
    
    2776
    -data FloatedDictBinds  -- See Note [Floated dictionary bindings]
    
    2777
    -  = FDB { fdb_binds :: !(OrdList DictBind)
    
    2828
    +data FloatBinds  -- See Note [Floated dictionary bindings]
    
    2829
    +  = FDB { fbs_binds :: !(OrdList FloatBind)
    
    2778 2830
                    -- The order is important;
    
    2779 2831
                    -- in ds1 `appOL` ds2, bindings in ds2 can depend on those in ds1
    
    2780 2832
     
    
    2781
    -        , fdb_bndrs :: !IdSet
    
    2782
    -    }          -- ^ The binders of 'fdb_binds'.
    
    2833
    +        , fbs_bndrs :: !IdSet
    
    2834
    +    }          -- ^ The binders of 'fbs_binds'.
    
    2783 2835
                    -- Caches a superset of the expression
    
    2784
    -               --   `mkVarSet (bindersOfDictBinds fdb_binds))`
    
    2836
    +               --   `mkVarSet (bindersOfFloatBinds fbs_binds))`
    
    2785 2837
                    -- for later addition to an InScopeSet
    
    2786 2838
     
    
    2787
    --- | A 'DictBind' is a binding along with a cached set containing its free
    
    2839
    +-- | A 'FloatBind' is a binding along with a cached set containing its free
    
    2788 2840
     -- variables (both type variables and dictionaries). We need this set
    
    2789
    --- in splitDictBinds, when filtering bindings to decide which are
    
    2841
    +-- in splitFloatBinds, when filtering bindings to decide which are
    
    2790 2842
     -- captured by a binder
    
    2791
    -data DictBind = DB { db_bind :: CoreBind, db_fvs :: VarSet }
    
    2843
    +data FloatBind = DB { fb_bind :: CoreBind, fb_fvs :: VarSet }
    
    2792 2844
     
    
    2793
    -bindersOfDictBind :: DictBind -> [Id]
    
    2794
    -bindersOfDictBind = bindersOf . db_bind
    
    2845
    +bindersOfFloatBind :: FloatBind -> [Id]
    
    2846
    +bindersOfFloatBind = bindersOf . fb_bind
    
    2795 2847
     
    
    2796
    -bindersOfDictBinds :: Foldable f => f DictBind -> [Id]
    
    2797
    -bindersOfDictBinds = bindersOfBinds . foldr ((:) . db_bind) []
    
    2848
    +bindersOfFloatBinds :: Foldable f => f FloatBind -> [Id]
    
    2849
    +bindersOfFloatBinds = bindersOfBinds . foldr ((:) . fb_bind) []
    
    2798 2850
     
    
    2799 2851
     {- Note [Floated dictionary bindings]
    
    2800 2852
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -2819,7 +2871,7 @@ and continue. But then we have to add $c== to the floats, and so on.
    2819 2871
     These all float above the binding for 'f', and now we can
    
    2820 2872
     successfully specialise 'f'.
    
    2821 2873
     
    
    2822
    -So the DictBinds in (ud_binds :: OrdList DictBind) may contain
    
    2874
    +So the FloatBinds in (ud_binds :: OrdList FloatBind) may contain
    
    2823 2875
     non-dictionary bindings too.
    
    2824 2876
     
    
    2825 2877
     Note [Specialising polymorphic dictionaries]
    
    ... ... @@ -2853,9 +2905,8 @@ Here are the moving parts:
    2853 2905
             CIS wimwam (CI { ci_key = [@(ST s), dMST @s]
    
    2854 2906
                            , ci_fvs = {dMST} })
    
    2855 2907
           when we come to the /\s.  Instead, we simply let it continue to float
    
    2856
    -      upwards. Hence ci_fvs is an IdSet, listing the /Ids/ that
    
    2857
    -      are free in the call, but not the /TyVars/.  Hence using specArgFreeIds
    
    2858
    -      in singleCall.
    
    2908
    +      upwards. We deal with this in `deleteCallsMentioning`,
    
    2909
    +      when `Opt_PolymorphicSpecialisation` is on
    
    2859 2910
     
    
    2860 2911
       NB to be fully kosher we should explicitly quantifying the CallInfo
    
    2861 2912
       over 's', but we don't bother.  This would matter if there was an
    
    ... ... @@ -2953,8 +3004,8 @@ over too many type variables. But that too is now fixed;
    2953 3004
     see Note [Which type variables to abstract over] in that module.
    
    2954 3005
     -}
    
    2955 3006
     
    
    2956
    -instance Outputable DictBind where
    
    2957
    -  ppr (DB { db_bind = bind, db_fvs = fvs })
    
    3007
    +instance Outputable FloatBind where
    
    3008
    +  ppr (DB { fb_bind = bind, fb_fvs = fvs })
    
    2958 3009
         = text "DB" <+> braces (sep [ text "fvs: " <+> ppr fvs
    
    2959 3010
                                     , text "bind:" <+> ppr bind ])
    
    2960 3011
     
    
    ... ... @@ -2964,15 +3015,15 @@ instance Outputable UsageDetails where
    2964 3015
                     [text "binds" <+> equals <+> ppr dbs,
    
    2965 3016
                      text "calls" <+> equals <+> ppr calls]))
    
    2966 3017
     
    
    2967
    -instance Outputable FloatedDictBinds where
    
    2968
    -  ppr (FDB { fdb_binds = binds }) = ppr binds
    
    3018
    +instance Outputable FloatBinds where
    
    3019
    +  ppr (FDB { fbs_binds = binds }) = ppr binds
    
    2969 3020
     
    
    2970 3021
     emptyUDs :: UsageDetails
    
    2971 3022
     emptyUDs = MkUD { ud_binds = emptyFDBs, ud_calls = emptyDVarEnv }
    
    2972 3023
     
    
    2973 3024
     
    
    2974
    -emptyFDBs :: FloatedDictBinds
    
    2975
    -emptyFDBs = FDB { fdb_binds = nilOL, fdb_bndrs = emptyVarSet }
    
    3025
    +emptyFDBs :: FloatBinds
    
    3026
    +emptyFDBs = FDB { fbs_binds = nilOL, fbs_bndrs = emptyVarSet }
    
    2976 3027
     
    
    2977 3028
     ------------------------------------------------------------
    
    2978 3029
     type CallDetails  = DIdEnv CallInfoSet
    
    ... ... @@ -2990,9 +3041,9 @@ data CallInfo
    2990 3041
       = CI { ci_key  :: [SpecArg]   -- Arguments of the call
    
    2991 3042
                                     -- See Note [The (CI-KEY) invariant]
    
    2992 3043
     
    
    2993
    -       , ci_fvs  :: IdSet       -- Free Ids of the ci_key call
    
    3044
    +       , ci_fvs  :: IdSet       -- All free vars of ci_key arguments
    
    2994 3045
                                     -- /not/ including the main id itself, of course
    
    2995
    -                                -- NB: excluding tyvars:
    
    3046
    +                                -- NB: including tyvars:
    
    2996 3047
                                     --     See Note [Specialising polymorphic dictionaries]
    
    2997 3048
         }
    
    2998 3049
     
    
    ... ... @@ -3047,21 +3098,15 @@ getTheta = fmap piTyBinderType . filter isInvisiblePiTyBinder . filter isAnonPiT
    3047 3098
     
    
    3048 3099
     
    
    3049 3100
     ------------------------------------------------------------
    
    3050
    -singleCall :: SpecEnv -> Id -> [SpecArg] -> UsageDetails
    
    3051
    -singleCall spec_env id args
    
    3101
    +singleCall :: Id -> [SpecArg] -> UsageDetails
    
    3102
    +singleCall id args
    
    3052 3103
       = MkUD {ud_binds = emptyFDBs,
    
    3053 3104
               ud_calls = unitDVarEnv id $ CIS id $
    
    3054
    -                     unitBag (CI { ci_key  = args
    
    3055
    -                                 , ci_fvs  = fvVarSet call_fvs }) }
    
    3105
    +                     unitBag call_info }
    
    3056 3106
       where
    
    3057
    -    poly_spec = gopt Opt_PolymorphicSpecialisation (se_dflags spec_env)
    
    3058
    -
    
    3059
    -    -- With -fpolymorphic-specialisation, keep just local /Ids/
    
    3060
    -    -- Otherwise, keep /all/ free vars including TyVars
    
    3061
    -    -- See (MP1) in Note [Specialising polymorphic dictionaries]
    
    3062
    -    -- But NB: we don't include the 'id' itself.
    
    3063
    -    call_fvs | poly_spec = specArgsFVs isLocalId args
    
    3064
    -             | otherwise = specArgsFVs isLocalVar args
    
    3107
    +    call_info = CI { ci_key  = args
    
    3108
    +                   , ci_fvs  = specArgsFVs args }
    
    3109
    +    -- See (STV1) in Note [Specialisation and type-variable bindings]
    
    3065 3110
     
    
    3066 3111
     mkCallUDs :: SpecEnv -> OutExpr -> [OutExpr] -> UsageDetails
    
    3067 3112
     mkCallUDs env fun args
    
    ... ... @@ -3076,7 +3121,7 @@ mkCallUDs' env f args
    3076 3121
       | wantCallsFor env f    -- We want it, and...
    
    3077 3122
       , not (null ci_key)     -- this call site has a useful specialisation
    
    3078 3123
       = -- pprTrace "mkCallUDs: keeping" _trace_doc
    
    3079
    -    singleCall env f ci_key
    
    3124
    +    singleCall f ci_key
    
    3080 3125
     
    
    3081 3126
       | otherwise  -- See also Note [Specialisations already covered]
    
    3082 3127
       = -- pprTrace "mkCallUDs: discarding" _trace_doc
    
    ... ... @@ -3352,21 +3397,21 @@ thenUDs (MkUD {ud_binds = db1, ud_calls = calls1})
    3352 3397
       = MkUD { ud_binds       = db1    `thenFDBs`   db2
    
    3353 3398
              , ud_calls       = calls1 `unionCalls`  calls2 }
    
    3354 3399
     
    
    3355
    -thenFDBs :: FloatedDictBinds -> FloatedDictBinds -> FloatedDictBinds
    
    3356
    --- Combine FloatedDictBinds
    
    3400
    +thenFDBs :: FloatBinds -> FloatBinds -> FloatBinds
    
    3401
    +-- Combine FloatBinds
    
    3357 3402
     -- In (dbs1 `thenFDBs` dbs2), dbs2 may mention dbs1 but not vice versa
    
    3358
    -thenFDBs (FDB { fdb_binds = dbs1, fdb_bndrs = bs1 })
    
    3359
    -         (FDB { fdb_binds = dbs2, fdb_bndrs = bs2 })
    
    3360
    -  = FDB { fdb_binds = dbs1 `appOL` dbs2
    
    3361
    -        , fdb_bndrs = bs1  `unionVarSet` bs2 }
    
    3403
    +thenFDBs (FDB { fbs_binds = dbs1, fbs_bndrs = bs1 })
    
    3404
    +         (FDB { fbs_binds = dbs2, fbs_bndrs = bs2 })
    
    3405
    +  = FDB { fbs_binds = dbs1 `appOL` dbs2
    
    3406
    +        , fbs_bndrs = bs1  `unionVarSet` bs2 }
    
    3362 3407
     
    
    3363 3408
     -----------------------------
    
    3364
    -_dictBindBndrs :: OrdList DictBind -> [Id]
    
    3365
    -_dictBindBndrs dbs = foldr ((++) . bindersOf . db_bind) [] dbs
    
    3409
    +_dictBindBndrs :: OrdList FloatBind -> [Id]
    
    3410
    +_dictBindBndrs dbs = foldr ((++) . bindersOf . fb_bind) [] dbs
    
    3366 3411
     
    
    3367
    --- | Construct a 'DictBind' from a 'CoreBind'
    
    3368
    -mkDB :: CoreBind -> DictBind
    
    3369
    -mkDB bind = DB { db_bind = bind, db_fvs = bind_fvs bind }
    
    3412
    +-- | Construct a 'FloatBind' from a 'CoreBind'
    
    3413
    +mkDB :: CoreBind -> FloatBind
    
    3414
    +mkDB bind = DB { fb_bind = bind, fb_fvs = bind_fvs bind }
    
    3370 3415
     
    
    3371 3416
     -- | Identify the free variables of a 'CoreBind'
    
    3372 3417
     bind_fvs :: CoreBind -> VarSet
    
    ... ... @@ -3397,54 +3442,54 @@ pair_fvs (bndr, rhs) = bndr_fvs `unionVarSet` rhs_fvs
    3397 3442
             --         whether a dictionary binding depends on an imported
    
    3398 3443
             --         DFun in case we try to specialise that imported DFun
    
    3399 3444
     
    
    3400
    --- | Flatten a set of "dumped" 'DictBind's, and some other binding
    
    3445
    +-- | Flatten a set of "dumped" 'FloatBind's, and some other binding
    
    3401 3446
     -- pairs, into a single recursive binding.
    
    3402
    -recWithDumpedDicts :: [(Id,CoreExpr)] -> OrdList DictBind -> DictBind
    
    3447
    +recWithDumpedDicts :: [(Id,CoreExpr)] -> OrdList FloatBind -> FloatBind
    
    3403 3448
     recWithDumpedDicts pairs dbs
    
    3404
    -  = DB { db_bind = Rec bindings
    
    3405
    -       , db_fvs = fvs `delVarSetList` map fst bindings }
    
    3449
    +  = DB { fb_bind = Rec bindings
    
    3450
    +       , fb_fvs = fvs `delVarSetList` map fst bindings }
    
    3406 3451
       where
    
    3407 3452
         (bindings, fvs) = foldr add ([], emptyVarSet)
    
    3408 3453
                                     (dbs `snocOL` mkDB (Rec pairs))
    
    3409
    -    add (DB { db_bind = bind, db_fvs = fvs }) (prs_acc, fvs_acc)
    
    3454
    +    add (DB { fb_bind = bind, fb_fvs = fvs }) (prs_acc, fvs_acc)
    
    3410 3455
           = case bind of
    
    3411 3456
               NonRec b r -> ((b,r) : prs_acc, fvs')
    
    3412 3457
               Rec prs1   -> (prs1 ++ prs_acc, fvs')
    
    3413 3458
           where
    
    3414 3459
             fvs' = fvs_acc `unionVarSet` fvs
    
    3415 3460
     
    
    3416
    -snocDictBind :: UsageDetails -> DictBind -> UsageDetails
    
    3417
    -snocDictBind uds@MkUD{ud_binds= FDB { fdb_binds = dbs, fdb_bndrs = bs }} db
    
    3418
    -  = uds { ud_binds = FDB { fdb_binds = dbs `snocOL` db
    
    3419
    -                         , fdb_bndrs = bs `extendVarSetList` bindersOfDictBind db } }
    
    3461
    +snocFloatBind :: UsageDetails -> FloatBind -> UsageDetails
    
    3462
    +snocFloatBind uds@MkUD{ud_binds= FDB { fbs_binds = dbs, fbs_bndrs = bs }} db
    
    3463
    +  = uds { ud_binds = FDB { fbs_binds = dbs `snocOL` db
    
    3464
    +                         , fbs_bndrs = bs `extendVarSetList` bindersOfFloatBind db } }
    
    3420 3465
     
    
    3421
    -snocDictBinds :: UsageDetails -> [DictBind] -> UsageDetails
    
    3466
    +snocFloatBinds :: UsageDetails -> OrdList FloatBind -> UsageDetails
    
    3422 3467
     -- Add ud_binds to the tail end of the bindings in uds
    
    3423
    -snocDictBinds uds@MkUD{ud_binds=FDB{ fdb_binds = binds, fdb_bndrs = bs }} dbs
    
    3424
    -  = uds { ud_binds = FDB { fdb_binds = binds `appOL`        (toOL dbs)
    
    3425
    -                         , fdb_bndrs = bs    `extendVarSetList` bindersOfDictBinds dbs } }
    
    3468
    +snocFloatBinds uds@MkUD{ud_binds=FDB{ fbs_binds = binds, fbs_bndrs = bs }} dbs
    
    3469
    +  = uds { ud_binds = FDB { fbs_binds = binds `appOL`            dbs
    
    3470
    +                         , fbs_bndrs = bs    `extendVarSetList` bindersOfFloatBinds dbs } }
    
    3426 3471
     
    
    3427
    -consDictBinds :: [DictBind] -> UsageDetails -> UsageDetails
    
    3428
    -consDictBinds dbs uds@MkUD{ud_binds=FDB{fdb_binds = binds, fdb_bndrs = bs}}
    
    3429
    -  = uds { ud_binds = FDB{ fdb_binds = toOL dbs `appOL` binds
    
    3430
    -                        , fdb_bndrs = bs `extendVarSetList` bindersOfDictBinds dbs } }
    
    3472
    +consFloatBinds :: OrdList FloatBind -> UsageDetails -> UsageDetails
    
    3473
    +consFloatBinds dbs uds@MkUD{ud_binds=FDB{fbs_binds = binds, fbs_bndrs = bs}}
    
    3474
    +  = uds { ud_binds = FDB{ fbs_binds = dbs `appOL` binds
    
    3475
    +                        , fbs_bndrs = bs `extendVarSetList` bindersOfFloatBinds dbs } }
    
    3431 3476
     
    
    3432
    -wrapDictBinds :: FloatedDictBinds -> [CoreBind] -> [CoreBind]
    
    3433
    -wrapDictBinds (FDB { fdb_binds = dbs }) binds
    
    3477
    +wrapFloatBinds :: FloatBinds -> [CoreBind] -> [CoreBind]
    
    3478
    +wrapFloatBinds (FDB { fbs_binds = dbs }) binds
    
    3434 3479
       = foldr add binds dbs
    
    3435 3480
       where
    
    3436
    -    add (DB { db_bind = bind }) binds = bind : binds
    
    3481
    +    add (DB { fb_bind = bind }) binds = bind : binds
    
    3437 3482
     
    
    3438
    -wrapDictBindsE :: OrdList DictBind -> CoreExpr -> CoreExpr
    
    3439
    -wrapDictBindsE dbs expr
    
    3483
    +wrapFloatBindsE :: OrdList FloatBind -> CoreExpr -> CoreExpr
    
    3484
    +wrapFloatBindsE dbs expr
    
    3440 3485
       = foldr add expr dbs
    
    3441 3486
       where
    
    3442
    -    add (DB { db_bind = bind }) expr = Let bind expr
    
    3487
    +    add (DB { fb_bind = bind }) expr = Let bind expr
    
    3443 3488
     
    
    3444 3489
     ----------------------
    
    3445
    -dumpUDs :: [CoreBndr] -> UsageDetails -> (UsageDetails, OrdList DictBind)
    
    3490
    +dumpUDs :: SpecEnv -> [CoreBndr] -> UsageDetails -> (UsageDetails, OrdList FloatBind)
    
    3446 3491
     -- Used at binder; just dump anything mentioning the binder
    
    3447
    -dumpUDs bndrs uds@(MkUD { ud_binds = orig_dbs, ud_calls = orig_calls })
    
    3492
    +dumpUDs env bndrs uds@(MkUD { ud_binds = orig_dbs, ud_calls = orig_calls })
    
    3448 3493
       | null bndrs = (uds, nilOL)  -- Common in case alternatives
    
    3449 3494
       | otherwise  = -- pprTrace "dumpUDs" (vcat
    
    3450 3495
                      --   [ text "bndrs" <+> ppr bndrs
    
    ... ... @@ -3455,19 +3500,20 @@ dumpUDs bndrs uds@(MkUD { ud_binds = orig_dbs, ud_calls = orig_calls })
    3455 3500
       where
    
    3456 3501
         free_uds = uds { ud_binds = free_dbs, ud_calls = free_calls }
    
    3457 3502
         bndr_set = mkVarSet bndrs
    
    3458
    -    (free_dbs, dump_dbs, dump_set) = splitDictBinds orig_dbs bndr_set
    
    3503
    +    (free_dbs, dump_dbs, dump_set) = splitFloatBinds orig_dbs bndr_set
    
    3459 3504
     
    
    3460 3505
         -- Delete calls:
    
    3461 3506
         --   * For any binder in `bndrs`
    
    3462 3507
         --   * That mention a dictionary bound in `dump_set`
    
    3463 3508
         -- These variables aren't in scope "above" the binding and the `dump_dbs`,
    
    3464 3509
         -- so no call should mention them.  (See #26682.)
    
    3465
    -    free_calls = deleteCallsMentioning dump_set $
    
    3510
    +    free_calls = deleteCallsMentioning env dump_set $
    
    3466 3511
                      deleteCallsFor bndrs orig_calls
    
    3467 3512
     
    
    3468
    -dumpBindUDs :: Bool   -- Main binding can float to top
    
    3513
    +dumpBindUDs :: SpecEnv
    
    3514
    +            -> Bool   -- Main binding can float to top
    
    3469 3515
                 -> [CoreBndr] -> UsageDetails
    
    3470
    -            -> (UsageDetails, OrdList DictBind, Bool)
    
    3516
    +            -> (UsageDetails, OrdList FloatBind, Bool)
    
    3471 3517
     -- Used at a let(rec) binding.
    
    3472 3518
     -- We return a boolean indicating whether the binding itself
    
    3473 3519
     --    is mentioned, directly or indirectly, by any of the ud_calls;
    
    ... ... @@ -3475,17 +3521,17 @@ dumpBindUDs :: Bool -- Main binding can float to top
    3475 3521
     --    See Note [Floated dictionary bindings]
    
    3476 3522
     -- If the boolean is True, then the returned ud_calls can mention `bndrs`;
    
    3477 3523
     -- if False, then returned ud_calls must not mention `bndrs`
    
    3478
    -dumpBindUDs can_float_bind bndrs (MkUD { ud_binds = orig_dbs, ud_calls = orig_calls })
    
    3524
    +dumpBindUDs env can_float_bind bndrs (MkUD { ud_binds = orig_dbs, ud_calls = orig_calls })
    
    3479 3525
       = ( MkUD { ud_binds = free_dbs, ud_calls = free_calls2 }
    
    3480 3526
         , dump_dbs
    
    3481 3527
         , can_float_bind && calls_mention_bndrs )
    
    3482 3528
       where
    
    3483 3529
         bndr_set = mkVarSet bndrs
    
    3484
    -    (free_dbs, dump_dbs, dump_set) = splitDictBinds orig_dbs bndr_set
    
    3530
    +    (free_dbs, dump_dbs, dump_set) = splitFloatBinds orig_dbs bndr_set
    
    3485 3531
         free_calls1 = deleteCallsFor bndrs orig_calls
    
    3486 3532
         calls_mention_bndrs = dump_set `intersectsVarSet` callDetailsFVs free_calls1
    
    3487 3533
         free_calls2 | can_float_bind = free_calls1
    
    3488
    -                | otherwise      = deleteCallsMentioning dump_set free_calls1
    
    3534
    +                | otherwise      = deleteCallsMentioning env dump_set free_calls1
    
    3489 3535
     
    
    3490 3536
     callsForMe :: Id -> UsageDetails -> (UsageDetails, [CallInfo])
    
    3491 3537
     callsForMe fn uds@MkUD { ud_binds = orig_dbs, ud_calls = orig_calls }
    
    ... ... @@ -3502,22 +3548,22 @@ callsForMe fn uds@MkUD { ud_binds = orig_dbs, ud_calls = orig_calls }
    3502 3548
                             Just cis -> filterCalls cis orig_dbs
    
    3503 3549
     
    
    3504 3550
     ----------------------
    
    3505
    -filterCalls :: CallInfoSet -> FloatedDictBinds -> [CallInfo]
    
    3551
    +filterCalls :: CallInfoSet -> FloatBinds -> [CallInfo]
    
    3506 3552
     -- Remove
    
    3507 3553
     --   (a) dominated calls: (MP3) in Note [Specialising polymorphic dictionaries]
    
    3508 3554
     --   (b) loopy DFuns: Note [Avoiding loops (DFuns)]
    
    3509
    -filterCalls (CIS fn call_bag) (FDB { fdb_binds = dbs })
    
    3555
    +filterCalls (CIS fn call_bag) (FDB { fbs_binds = dbs })
    
    3510 3556
       | isDFunId fn  = filter ok_call de_dupd_calls  -- Deals with (b)
    
    3511 3557
       | otherwise    = de_dupd_calls
    
    3512 3558
       where
    
    3513 3559
         de_dupd_calls = removeDupCalls call_bag -- Deals with (a)
    
    3514 3560
     
    
    3515 3561
         dump_set = foldl' go (unitVarSet fn) dbs
    
    3516
    -      -- This dump-set could also be computed by splitDictBinds
    
    3517
    -      --   (_,_,dump_set) = splitDictBinds dbs {fn}
    
    3562
    +      -- This dump-set could also be computed by splitFloatBinds
    
    3563
    +      --   (_,_,dump_set) = splitFloatBinds dbs {fn}
    
    3518 3564
           -- But this variant is shorter
    
    3519 3565
     
    
    3520
    -    go so_far (DB { db_bind = bind, db_fvs = fvs })
    
    3566
    +    go so_far (DB { fb_bind = bind, fb_fvs = fvs })
    
    3521 3567
            | fvs `intersectsVarSet` so_far
    
    3522 3568
            = extendVarSetList so_far (bindersOf bind)
    
    3523 3569
            | otherwise = so_far
    
    ... ... @@ -3558,16 +3604,16 @@ beats_or_same (CI { ci_key = args1 }) (CI { ci_key = args2 })
    3558 3604
         go_arg _              _              = False
    
    3559 3605
     
    
    3560 3606
     ----------------------
    
    3561
    -splitDictBinds :: FloatedDictBinds -> IdSet -> (FloatedDictBinds, OrdList DictBind, IdSet)
    
    3562
    --- splitDictBinds dbs bndrs returns
    
    3607
    +splitFloatBinds :: FloatBinds -> IdSet -> (FloatBinds, OrdList FloatBind, IdSet)
    
    3608
    +-- splitFloatBinds dbs bndrs returns
    
    3563 3609
     --   (free_dbs, dump_dbs, dump_set)
    
    3564 3610
     -- where
    
    3565 3611
     --   * dump_dbs depends, transitively on bndrs
    
    3566 3612
     --   * free_dbs does not depend on bndrs
    
    3567 3613
     --   * dump_set = bndrs `union` bndrs(dump_dbs)
    
    3568
    -splitDictBinds (FDB { fdb_binds = dbs, fdb_bndrs = bs }) bndr_set
    
    3569
    -   = (FDB { fdb_binds = free_dbs
    
    3570
    -          , fdb_bndrs = bs `minusVarSet` dump_set }
    
    3614
    +splitFloatBinds (FDB { fbs_binds = dbs, fbs_bndrs = bs }) bndr_set
    
    3615
    +   = (FDB { fbs_binds = free_dbs
    
    3616
    +          , fbs_bndrs = bs `minusVarSet` dump_set }
    
    3571 3617
          , dump_dbs, dump_set)
    
    3572 3618
        where
    
    3573 3619
         (free_dbs, dump_dbs, dump_set)
    
    ... ... @@ -3576,7 +3622,7 @@ splitDictBinds (FDB { fdb_binds = dbs, fdb_bndrs = bs }) bndr_set
    3576 3622
                     -- we're accumulating the set of dumped ids in dump_set
    
    3577 3623
     
    
    3578 3624
         split_db (free_dbs, dump_dbs, dump_idset) db
    
    3579
    -        | DB { db_bind = bind, db_fvs = fvs } <- db
    
    3625
    +        | DB { fb_bind = bind, fb_fvs = fvs } <- db
    
    3580 3626
             , dump_idset `intersectsVarSet` fvs     -- Dump it
    
    3581 3627
             = (free_dbs, dump_dbs `snocOL` db,
    
    3582 3628
                extendVarSetList dump_idset (bindersOf bind))
    
    ... ... @@ -3586,15 +3632,26 @@ splitDictBinds (FDB { fdb_binds = dbs, fdb_bndrs = bs }) bndr_set
    3586 3632
     
    
    3587 3633
     
    
    3588 3634
     ----------------------
    
    3589
    -deleteCallsMentioning :: VarSet -> CallDetails -> CallDetails
    
    3635
    +deleteCallsMentioning :: SpecEnv -> VarSet -> CallDetails -> CallDetails
    
    3590 3636
     -- Remove calls mentioning any Id in bndrs
    
    3591 3637
     -- NB: The call is allowed to mention TyVars in bndrs
    
    3592 3638
     --     Note [Specialising polymorphic dictionaries]
    
    3593 3639
     --     ci_fvs are just the free /Ids/
    
    3594
    -deleteCallsMentioning bndrs calls
    
    3640
    +deleteCallsMentioning env bndrs calls
    
    3595 3641
       = mapDVarEnv (ciSetFilter keep_call) calls
    
    3596 3642
       where
    
    3597
    -    keep_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` bndrs
    
    3643
    +    keep_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` bad_bndrs
    
    3644
    +
    
    3645
    +    poly_spec = gopt Opt_PolymorphicSpecialisation (se_dflags env)
    
    3646
    +
    
    3647
    +    -- With -fpolymorphic-specialisation, we allow calls to float outside
    
    3648
    +    -- the binding of a TyVar, so we restrict the bad_bndrs to just the Ids
    
    3649
    +    -- See (STV2) in Note [Specialisation and type-variable bindings]
    
    3650
    +    -- and (MP1) in Note [Specialising polymorphic dictionaries]
    
    3651
    +    -- But NB: we don't include the 'id' itself.
    
    3652
    +    bad_bndrs | poly_spec = filterVarSet isId bndrs
    
    3653
    +              | otherwise = bndrs
    
    3654
    +
    
    3598 3655
     
    
    3599 3656
     deleteCallsFor :: [Id] -> CallDetails -> CallDetails
    
    3600 3657
     -- Remove calls *for* bndrs
    

  • compiler/GHC/Core/TyCo/FVs.hs
    ... ... @@ -6,7 +6,7 @@ module GHC.Core.TyCo.FVs
    6 6
             tyCoVarsOfTypeDSet, tyCoVarsOfTypesDSet,
    
    7 7
     
    
    8 8
             tyCoFVsBndr, tyCoFVsVarBndr, tyCoFVsVarBndrs,
    
    9
    -        tyCoFVsOfType, tyCoVarsOfTypeList,
    
    9
    +        tyCoFVsOfType, tyCoVarsOfTypeList, someTyCoVarsOfTypeList,
    
    10 10
             tyCoFVsOfTypes, tyCoVarsOfTypesList,
    
    11 11
             deepTcvFolder,
    
    12 12
     
    
    ... ... @@ -601,6 +601,9 @@ tyCoVarsOfTypeList :: Type -> [TyCoVar]
    601 601
     -- See Note [Free variables of types]
    
    602 602
     tyCoVarsOfTypeList ty = fvVarList $ tyCoFVsOfType ty
    
    603 603
     
    
    604
    +someTyCoVarsOfTypeList :: InterestingVarFun -> Type -> [TyCoVar]
    
    605
    +someTyCoVarsOfTypeList fv_cand ty = fvVarList $ filterFV fv_cand $ tyCoFVsOfType ty
    
    606
    +
    
    604 607
     -- | Returns free variables of types, including kind variables as
    
    605 608
     -- a deterministic set. For type synonyms it does /not/ expand the
    
    606 609
     -- synonym.
    

  • compiler/GHC/Core/TyCo/Subst.hs
    ... ... @@ -510,13 +510,13 @@ zipCoEnv cvs cos
    510 510
     
    
    511 511
     instance Outputable Subst where
    
    512 512
       ppr (Subst in_scope ids tvs cvs)
    
    513
    -        =  text "<InScope =" <+> in_scope_doc
    
    514
    -        $$ text " IdSubst   =" <+> ppr ids
    
    515
    -        $$ text " TvSubst   =" <+> ppr tvs
    
    516
    -        $$ text " CvSubst   =" <+> ppr cvs
    
    513
    +        =  vcat [ -- text "<InScope =" <+> _in_scope_doc,
    
    514
    +                  text " IdSubst   =" <+> ppr ids,
    
    515
    +                  text " TvSubst   =" <+> ppr tvs,
    
    516
    +                  text " CvSubst   =" <+> ppr cvs ]
    
    517 517
              <> char '>'
    
    518 518
         where
    
    519
    -    in_scope_doc = pprVarSet (getInScopeVars in_scope) (braces . fsep . map ppr)
    
    519
    +      _in_scope_doc = pprVarSet (getInScopeVars in_scope) (braces . fsep . map ppr)
    
    520 520
     
    
    521 521
     {-
    
    522 522
     %************************************************************************
    

  • compiler/GHC/Core/Utils.hs
    ... ... @@ -143,6 +143,7 @@ exprType e = go emptyVarSet e
    143 143
         --   should return (Maybe (Int,b)), having expanded out the `a`
    
    144 144
         expand = expandTyVarUnfoldings
    
    145 145
     
    
    146
    +    go :: VarSet -> CoreExpr -> Type
    
    146 147
         go tvs (Var var)         = expand tvs $ idType var
    
    147 148
         go tvs (Lit lit)         = expand tvs $ literalType lit
    
    148 149
         go tvs (Coercion co)     = expand tvs $ coercionType co
    
    ... ... @@ -1379,7 +1380,12 @@ coercionIsTrivial :: Coercion -> Bool
    1379 1380
     coercionIsTrivial co = coercionSize co < 10    -- Try this out
    
    1380 1381
     
    
    1381 1382
     {-# INLINE trivial_expr_fold #-}
    
    1382
    -trivial_expr_fold :: (Id -> r) -> (Literal -> r) -> r -> r -> CoreExpr -> r
    
    1383
    +trivial_expr_fold :: (Coercion -> Bool)  -- Whether a coercion is trivial
    
    1384
    +                  -> (Id -> r)           -- What to do for a Var
    
    1385
    +                  -> (Literal -> r)      -- What to do for a Lit
    
    1386
    +                  -> r                   -- What do to for other trivial
    
    1387
    +                  -> r                   -- What to do for non-trivial
    
    1388
    +                  -> CoreExpr -> r
    
    1383 1389
     -- ^ The worker function for Note [exprIsTrivial] and Note [getIdFromTrivialExpr]
    
    1384 1390
     -- This is meant to have the code of both functions in one place and make it
    
    1385 1391
     -- easy to derive custom predicates.
    
    ... ... @@ -1394,7 +1400,7 @@ trivial_expr_fold :: (Id -> r) -> (Literal -> r) -> r -> r -> CoreExpr -> r
    1394 1400
     -- * Type application or abstraction
    
    1395 1401
     -- * Ticks other than `tickishIsCode`
    
    1396 1402
     -- * `case e of {}` an empty case
    
    1397
    -trivial_expr_fold k_id k_lit k_triv k_not_triv = go
    
    1403
    +trivial_expr_fold co_is_triv k_id k_lit k_triv k_not_triv = go
    
    1398 1404
       where
    
    1399 1405
         -- If you change this function, be sure to change
    
    1400 1406
         -- SetLevels.notWorthFloating as well!
    
    ... ... @@ -1402,14 +1408,14 @@ trivial_expr_fold k_id k_lit k_triv k_not_triv = go
    1402 1408
         go (Var v)                              = k_id v  -- See Note [Variables are trivial]
    
    1403 1409
         go (Lit l)    | litIsTrivial l          = k_lit l
    
    1404 1410
         go (Type _)                             = k_triv
    
    1405
    -    go (Coercion co) | coercionIsTrivial co = k_triv
    
    1411
    +    go (Coercion co) | co_is_triv co        = k_triv
    
    1406 1412
         go (App f arg)
    
    1407 1413
           | not (isRuntimeArg arg)              = go f
    
    1408 1414
           | exprIsUnaryClassFun f               = go arg
    
    1409 1415
           | otherwise                           = k_not_triv
    
    1410 1416
         go (Lam b e)   | not (isRuntimeVar b)   = go e
    
    1411 1417
         go (Tick t e)  | not (tickishIsCode t)  = go e              -- See Note [Tick trivial]
    
    1412
    -    go (Cast e co) | coercionIsTrivial co   = go e
    
    1418
    +    go (Cast e co) | co_is_triv co          = go e
    
    1413 1419
         go (Let b e)   | isTyCoBind b           = go e
    
    1414 1420
            -- ToDo: what about a non-triv coercion?
    
    1415 1421
         go (Case e b _ as)
    
    ... ... @@ -1420,7 +1426,7 @@ trivial_expr_fold k_id k_lit k_triv k_not_triv = go
    1420 1426
         go _                                  = k_not_triv
    
    1421 1427
     
    
    1422 1428
     exprIsTrivial :: CoreExpr -> Bool
    
    1423
    -exprIsTrivial e = trivial_expr_fold (const True) (const True) True False e
    
    1429
    +exprIsTrivial e = trivial_expr_fold coercionIsTrivial (const True) (const True) True False e
    
    1424 1430
     
    
    1425 1431
     {-
    
    1426 1432
     Note [getIdFromTrivialExpr]
    
    ... ... @@ -1441,12 +1447,12 @@ T12076lit for an example where this matters.
    1441 1447
     
    
    1442 1448
     getIdFromTrivialExpr :: HasDebugCallStack => CoreExpr -> Id
    
    1443 1449
     -- See Note [getIdFromTrivialExpr]
    
    1444
    -getIdFromTrivialExpr e = trivial_expr_fold id (const panic) panic panic e
    
    1450
    +getIdFromTrivialExpr e = trivial_expr_fold (const True) id (const panic) panic panic e
    
    1445 1451
       where
    
    1446 1452
         panic = pprPanic "getIdFromTrivialExpr" (ppr e)
    
    1447 1453
     
    
    1448 1454
     getIdFromTrivialExpr_maybe :: CoreExpr -> Maybe Id
    
    1449
    -getIdFromTrivialExpr_maybe e = trivial_expr_fold Just (const Nothing) Nothing Nothing e
    
    1455
    +getIdFromTrivialExpr_maybe e = trivial_expr_fold (const True) Just (const Nothing) Nothing Nothing e
    
    1450 1456
     
    
    1451 1457
     {- *********************************************************************
    
    1452 1458
     *                                                                      *
    
    ... ... @@ -3299,8 +3305,6 @@ Wrinkles
    3299 3305
              = \a. \(x:[a]). let @b = [a] in
    
    3300 3306
                              reverse (x:b)
    
    3301 3307
       where the /occurrence/ Var (x:b) has a different type to the /binding/ x:[a].
    
    3302
    -  Worse
    
    3303
    -
    
    3304 3308
     -}
    
    3305 3309
     
    
    3306 3310
     type AbsVar        = Var
    
    ... ... @@ -3317,26 +3321,33 @@ mkPolyAbsLams :: forall b. (b -> AbsVar, Var -> b -> b)
    3317 3321
     mkPolyAbsLams (getter,setter) bndrs body
    
    3318 3322
       = go emptyVarSet [] bndrs
    
    3319 3323
       where
    
    3320
    -    go :: TyVarSet   -- Earlier TyVar bndrs that have TyVarUnfoldings
    
    3321
    -       -> [Bind b]   -- Accumulated impedence-matching bindings (reversed)
    
    3322
    -       -> [b]        -- Binders, bs
    
    3323
    -       -> Expr b     -- The resulting lambda
    
    3324
    -    go _ binds [] = mkLets (reverse binds) body
    
    3324
    +    wrap_bind :: Expr b -> (b,Expr b) -> Expr b
    
    3325
    +    -- wrap_bind e (bndr, rhs)  =   (\bndr.e) rhs
    
    3326
    +    -- Very like  let bndr=rhs in e
    
    3327
    +    -- but, for type-bindings at least, does not require that the occurrences
    
    3328
    +    -- of bndr have the unfolding from the let-binding
    
    3329
    +    wrap_bind e (bndr, rhs) = App (Lam bndr e) rhs
    
    3330
    +
    
    3331
    +    go :: TyVarSet     -- Earlier TyVar bndrs that have TyVarUnfoldings
    
    3332
    +       -> [(b,Expr b)] -- Accumulated impedence-matching bindings (reversed)
    
    3333
    +       -> [b]          -- Binders, bs
    
    3334
    +       -> Expr b       -- The resulting lambda
    
    3335
    +    go _ binds [] = foldl wrap_bind body binds
    
    3325 3336
     
    
    3326 3337
         go unf_tvs binds (bndr:bndrs)
    
    3327 3338
     
    
    3328 3339
           | Just ty <- tyVarUnfolding_maybe var
    
    3329
    -      = go (unf_tvs `extendVarSet` var) (NonRec bndr (Type ty) : binds) bndrs
    
    3340
    +      = go (unf_tvs `extendVarSet` var) ((bndr, Type ty) : binds) bndrs
    
    3330 3341
     
    
    3331 3342
           | isTyVar var, change_ty
    
    3332 3343
           , let binds' | isDeadBinder var = binds
    
    3333
    -                   | otherwise        = NonRec bndr (Type (mkTyVarTy var1)) : binds
    
    3344
    +                   | otherwise        = (bndr, varToCoreExpr var1) : binds
    
    3334 3345
                 -- Why this let-binding?
    
    3335 3346
           = Lam (setter var1 bndr) (go unf_tvs binds' bndrs)
    
    3336 3347
     
    
    3337 3348
           | isId var, change_ty || change_unf
    
    3338 3349
           , let binds' | isDeadBinder var = binds
    
    3339
    -                   | otherwise        = NonRec bndr (varToCoreExpr id2) : binds
    
    3350
    +                   | otherwise        = (bndr, varToCoreExpr id2) : binds
    
    3340 3351
           = Lam (setter id2 bndr) (go unf_tvs binds' bndrs)
    
    3341 3352
     
    
    3342 3353
           | otherwise
    

  • compiler/GHC/CoreToStg.hs
    ... ... @@ -598,9 +598,9 @@ sumPrimReps _ = []
    598 598
     getStgArgFromTrivialArg :: HasDebugCallStack => CoreArg -> StgArg
    
    599 599
     -- A (non-erased) trivial CoreArg corresponds to an atomic StgArg.
    
    600 600
     -- CoreArgs may not immediately look trivial, e.g., `case e of {}` or
    
    601
    --- `case unsafeequalityProof of UnsafeRefl -> e` might intervene.
    
    601
    +-- `case unsafeEqualityProof of UnsafeRefl -> e` might intervene.
    
    602 602
     -- Good thing we can just call `trivial_expr_fold` here.
    
    603
    -getStgArgFromTrivialArg e = trivial_expr_fold StgVarArg StgLitArg panic panic e
    
    603
    +getStgArgFromTrivialArg e = trivial_expr_fold (const True) StgVarArg StgLitArg panic panic e
    
    604 604
       where
    
    605 605
         panic = pprPanic "getStgArgFromTrivialArg" (ppr e)
    
    606 606