Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC

Commits:

1 changed file:

Changes:

  • compiler/GHC/Core/Opt/Specialise.hs
    ... ... @@ -1205,14 +1205,21 @@ specExpr env (Tick tickish body)
    1205 1205
     ---------------- Applications might generate a call instance --------------------
    
    1206 1206
     specExpr env expr@(App {})
    
    1207 1207
       = do { let (fun_in, args_in) = collectArgs expr
    
    1208
    +       ; (fun_out, uds_fun)   <- specExpr env fun_in
    
    1208 1209
            ; (args_out, uds_args) <- mapAndCombineSM (specExpr env) args_in
    
    1209
    -       ; let env_args = env `bringFloatedDictsIntoScope` ud_binds uds_args
    
    1210
    -                -- Some dicts may have floated out of args_in;
    
    1211
    -                -- they should be in scope for fireRewriteRules (#21689)
    
    1212
    -             (fun_in', args_out') = fireRewriteRules env_args fun_in args_out
    
    1213
    -       ; (fun_out', uds_fun) <- specExpr env fun_in'
    
    1210
    +       ; let uds_app  = uds_fun `thenUDs` uds_args
    
    1211
    +             env_args = zapSubst env `bringFloatedDictsIntoScope` ud_binds uds_app
    
    1212
    +                -- zapSubst: we have now fully applied the substitution
    
    1213
    +                -- bringFloatedDictsIntoScope: some dicts may have floated out of
    
    1214
    +                -- args_in; they should be in scope for fireRewriteRules (#21689)
    
    1215
    +
    
    1216
    +       -- Try firing rewrite rules
    
    1217
    +       -- See Note [Fire rules in the specialiser]
    
    1218
    +       ; let (fun_out', args_out') = fireRewriteRules env_args fun_out args_out
    
    1219
    +
    
    1220
    +       -- Make a call record, and return
    
    1214 1221
            ; let uds_call = mkCallUDs env fun_out' args_out'
    
    1215
    -       ; return (fun_out' `mkApps` args_out', uds_fun `thenUDs` uds_call `thenUDs` uds_args) }
    
    1222
    +       ; return (fun_out' `mkApps` args_out', uds_app `thenUDs` uds_call) }
    
    1216 1223
     
    
    1217 1224
     ---------------- Lambda/case require dumping of usage details --------------------
    
    1218 1225
     specExpr env e@(Lam {})
    
    ... ... @@ -1246,17 +1253,18 @@ specExpr env (Let bind body)
    1246 1253
     -- See Note [Specialisation modulo dictionary selectors]
    
    1247 1254
     --     Note [ClassOp/DFun selection]
    
    1248 1255
     --     Note [Fire rules in the specialiser]
    
    1249
    -fireRewriteRules :: SpecEnv -> InExpr -> [OutExpr] -> (InExpr, [OutExpr])
    
    1256
    +fireRewriteRules :: SpecEnv   -- Substitution is already zapped
    
    1257
    +                 -> OutExpr -> [OutExpr] -> (OutExpr, [OutExpr])
    
    1250 1258
     fireRewriteRules env (Var f) args
    
    1251 1259
       | let rules = getRules (se_rules env) f
    
    1252 1260
       , Just (rule, expr) <- specLookupRule env f args activeInInitialPhase rules
    
    1253 1261
       , let rest_args    = drop (ruleArity rule) args -- See Note [Extra args in the target]
    
    1254
    -        zapped_subst = Core.zapSubst (se_subst env)
    
    1255
    -        expr'        = simpleOptExprWith defaultSimpleOpts zapped_subst expr
    
    1262
    +        zapped_subst = se_subst env   -- Just needed for the InScopeSet
    
    1263
    +        expr'        = simpleOptExprWith defaultSimpleOpts zapped_subst (mkApps expr rest_args)
    
    1256 1264
                            -- simplOptExpr needed because lookupRule returns
    
    1257 1265
                            --   (\x y. rhs) arg1 arg2
    
    1258 1266
       , (fun', args') <- collectArgs expr'
    
    1259
    -  = fireRewriteRules env fun' (args'++rest_args)
    
    1267
    +  = fireRewriteRules env fun' args'
    
    1260 1268
     fireRewriteRules _ fun args = (fun, args)
    
    1261 1269
     
    
    1262 1270
     --------------
    
    ... ... @@ -1669,10 +1677,19 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
    1669 1677
                ; let all_rule_bndrs = poly_qvars ++ rule_bndrs
    
    1670 1678
                      env' = env { se_subst = subst'' }
    
    1671 1679
     
    
    1672
    -{-
    
    1673
    -           ; pprTrace "spec_call" (vcat
    
    1680
    +           -- Check for (a) usefulness and (b) not already covered
    
    1681
    +           -- See (SC1) in Note [Specialisations already covered]
    
    1682
    +           ; let all_rules = rules_acc ++ existing_rules
    
    1683
    +                 -- all_rules: we look both in the rules_acc (generated by this invocation
    
    1684
    +                 --   of specCalls), and in existing_rules (passed in to specCalls)
    
    1685
    +                 already_covered = alreadyCovered env' all_rule_bndrs fn
    
    1686
    +                                                  rule_lhs_args is_active all_rules
    
    1687
    +
    
    1688
    +{-         ; pprTrace "spec_call" (vcat
    
    1674 1689
                     [ text "fun:       "  <+> ppr fn
    
    1675 1690
                     , text "call info: "  <+> ppr _ci
    
    1691
    +                , text "useful:    "  <+> ppr useful
    
    1692
    +                , text "already_covered:"  <+> ppr already_covered
    
    1676 1693
                     , text "poly_qvars: " <+> ppr poly_qvars
    
    1677 1694
                     , text "useful:    "  <+> ppr useful
    
    1678 1695
                     , text "all_rule_bndrs:"  <+> ppr all_rule_bndrs
    
    ... ... @@ -1681,17 +1698,13 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
    1681 1698
                     , text "dx_binds:"   <+> ppr dx_binds
    
    1682 1699
                     , text "spec_args: "  <+> ppr spec_args
    
    1683 1700
                     , text "rhs_bndrs"    <+> ppr rhs_bndrs
    
    1684
    -                , text "rhs_body"     <+> ppr rhs_body ]) $
    
    1701
    +                , text "rhs_body"     <+> ppr rhs_body
    
    1702
    +                , text "subst''" <+> ppr subst'' ]) $
    
    1685 1703
                  return ()
    
    1686 1704
     -}
    
    1687 1705
     
    
    1688
    -           -- Check for (a) usefulness and (b) not already covered
    
    1689
    -           -- See (SC1) in Note [Specialisations already covered]
    
    1690
    -           ; let all_rules = rules_acc ++ existing_rules
    
    1691
    -                 -- all_rules: we look both in the rules_acc (generated by this invocation
    
    1692
    -                 --   of specCalls), and in existing_rules (passed in to specCalls)
    
    1693
    -           ; if not useful  -- No useful specialisation
    
    1694
    -                || alreadyCovered env' all_rule_bndrs fn rule_lhs_args is_active all_rules
    
    1706
    +           ; if not useful          -- No useful specialisation
    
    1707
    +                || already_covered  -- Useful, but done already
    
    1695 1708
                  then return spec_acc
    
    1696 1709
                  else
    
    1697 1710
     
    
    ... ... @@ -1702,6 +1715,12 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
    1702 1715
                  -- Run the specialiser on the specialised RHS
    
    1703 1716
                ; (rhs_body', rhs_uds) <- specExpr env'' rhs_body
    
    1704 1717
     
    
    1718
    +{-         ; pprTrace "spec_call2" (vcat
    
    1719
    +                 [ text "fun:" <+> ppr fn
    
    1720
    +                 , text "rhs_body':" <+> ppr rhs_body' ]) $
    
    1721
    +             return ()
    
    1722
    +-}
    
    1723
    +
    
    1705 1724
                -- Make the RHS of the specialised function
    
    1706 1725
                ; let spec_rhs_bndrs = spec_bndrs ++ inner_rhs_bndrs'
    
    1707 1726
                      (rhs_uds1, inner_dumped_dbs) = dumpUDs spec_rhs_bndrs rhs_uds