Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC

Commits:

7 changed files:

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
    

  • compiler/GHC/Tc/Utils/Unify.hs
    ... ... @@ -1853,8 +1853,8 @@ where we eta-expanded that (:). But now foldr expects an argument
    1853 1853
     with ->{Many} and gets an argument with ->{m1} or ->{m2}, and Lint
    
    1854 1854
     complains.
    
    1855 1855
     
    
    1856
    -The easiest solution was to use tcEqMult in tc_sub_type_deep, and
    
    1857
    -insist on equality. This is only in the DeepSubsumption code anyway.
    
    1856
    +The easiest solution was to unify the multiplicities in tc_sub_type_deep,
    
    1857
    +insisting on equality. This is only in the DeepSubsumption code anyway.
    
    1858 1858
     
    
    1859 1859
     Note [FunTy vs non-FunTy case in tc_sub_type_deep]
    
    1860 1860
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -2047,10 +2047,7 @@ tc_sub_type_deep pos unify inst_orig ctxt ty_actual ty_expected
    2047 2047
                               -- GenSigCtxt: See Note [Setting the argument context]
    
    2048 2048
                ; res_wrap  <- tc_sub_type_deep (Result pos) unify inst_orig ctxt act_res exp_res
    
    2049 2049
     
    
    2050
    -             -- See Note [Multiplicity in deep subsumption]
    
    2051
    -           ; tcEqMult inst_orig act_mult exp_mult
    
    2052
    -
    
    2053
    -           ; mkWpFun_FRR pos
    
    2050
    +           ; mkWpFun_FRR unify pos
    
    2054 2051
                    act_af act_mult act_arg act_res
    
    2055 2052
                    exp_af exp_mult exp_arg exp_res
    
    2056 2053
                    arg_wrap res_wrap
    
    ... ... @@ -2058,20 +2055,32 @@ tc_sub_type_deep pos unify inst_orig ctxt ty_actual ty_expected
    2058 2055
           where
    
    2059 2056
             given_orig = GivenOrigin (SigSkol GenSigCtxt exp_arg [])
    
    2060 2057
     
    
    2061
    --- | Like 'mkWpFun', except that it performs representation-polymorphism
    
    2062
    --- checks on the argument type.
    
    2058
    +-- | Like 'mkWpFun', except that it performs the necessary
    
    2059
    +-- representation-polymorphism checks on the argument type in the case that
    
    2060
    +-- we introduce a lambda abstraction.
    
    2063 2061
     mkWpFun_FRR
    
    2064
    -  :: Position p
    
    2062
    +  :: (TcType -> TcType -> TcM TcCoercionN) -- ^ how to unify
    
    2063
    +  -> Position p
    
    2065 2064
       -> FunTyFlag -> Type -> TcType -> Type --   actual FunTy
    
    2066 2065
       -> FunTyFlag -> Type -> TcType -> Type -- expected FunTy
    
    2067 2066
       -> HsWrapper -- ^ exp_arg ~> act_arg
    
    2068 2067
       -> HsWrapper -- ^ act_res ~> exp_res
    
    2069 2068
       -> TcM HsWrapper -- ^ act_funTy ~> exp_funTy
    
    2070
    -mkWpFun_FRR pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res arg_wrap res_wrap
    
    2071
    -  | needs_eta
    
    2072
    -  -- See Wrinkle [Representation-polymorphism checking during subtyping]
    
    2073
    -  = do { (exp_arg_co,  exp_arg_frr) <- hasFixedRuntimeRep (FRRDeepSubsumption True pos) exp_arg
    
    2074
    -       ; (act_arg_co, _act_arg_frr) <- hasFixedRuntimeRep (FRRDeepSubsumption False pos) act_arg
    
    2069
    +mkWpFun_FRR unify pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res arg_wrap res_wrap
    
    2070
    +  = do { ((exp_arg_co, exp_arg_frr), (act_arg_co, _act_arg_frr)) <-
    
    2071
    +            if needs_frr_checks
    
    2072
    +              -- See Wrinkle [Representation-polymorphism checking during subtyping]
    
    2073
    +            then do { exp_frr_wrap <- hasFixedRuntimeRep (frr_ctxt True ) exp_arg
    
    2074
    +                    ; act_frr_wrap <- hasFixedRuntimeRep (frr_ctxt False) act_arg
    
    2075
    +                    ; return (exp_frr_wrap, act_frr_wrap) }
    
    2076
    +            else return ((mkNomReflCo exp_arg, exp_arg), (mkNomReflCo act_arg, act_arg))
    
    2077
    +
    
    2078
    +         -- Enforce equality of multiplicities (not the more natural sub-multiplicity).
    
    2079
    +         -- See Note [Multiplicity in deep subsumption]
    
    2080
    +       ; act_arg_mult_co <- unify act_mult exp_mult
    
    2081
    +           -- NB: don't use tcEqMult: that would require the evidence for
    
    2082
    +           -- equality to be Refl, but it might well not be (#26332).
    
    2083
    +
    
    2075 2084
            ; let
    
    2076 2085
                 exp_arg_fun_co =
    
    2077 2086
                   mkFunCo Nominal exp_af
    
    ... ... @@ -2080,7 +2089,7 @@ mkWpFun_FRR pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res
    2080 2089
                      (mkReflCo Nominal exp_res)
    
    2081 2090
                 act_arg_fun_co =
    
    2082 2091
                   mkFunCo Nominal act_af
    
    2083
    -                 (mkReflCo Nominal act_mult)
    
    2092
    +                 act_arg_mult_co
    
    2084 2093
                      act_arg_co
    
    2085 2094
                      (mkReflCo Nominal act_res)
    
    2086 2095
                 arg_wrap_frr =
    
    ... ... @@ -2090,24 +2099,16 @@ mkWpFun_FRR pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res
    2090 2099
                    --  arg_wrap :: exp_arg ~> act_arg
    
    2091 2100
                    --  arg_wrap_frr :: exp_arg_frr ~> act_arg_frr
    
    2092 2101
     
    
    2093
    -       -- NB: because of the needs_eta guard, we know that mkWpFun will
    
    2094
    -       -- return (WpFun ...); so we might as well just use the WpFun constructor.
    
    2095 2102
            ; return $
    
    2096 2103
                 mkWpCastN exp_arg_fun_co
    
    2097 2104
                   <.>
    
    2098
    -            WpFun arg_wrap_frr res_wrap (Scaled exp_mult exp_arg_frr)
    
    2105
    +            mkWpFun arg_wrap_frr res_wrap (Scaled exp_mult exp_arg_frr) exp_res
    
    2099 2106
                   <.>
    
    2100
    -            mkWpCastN act_arg_fun_co }
    
    2101
    -  | otherwise
    
    2102
    -  = return $
    
    2103
    -      mkWpFun arg_wrap res_wrap (Scaled exp_mult exp_arg) exp_res
    
    2104
    -        -- NB: because of 'needs_eta', this will never actually be a WpFun.
    
    2105
    -        -- mkWpFun will turn it into a WpHole or WpCast, which is why
    
    2106
    -        -- we can skip the hasFixedRuntimeRep checks in this case.
    
    2107
    -        -- See Wrinkle [Representation-polymorphism checking during subtyping]
    
    2107
    +            mkWpCastN act_arg_fun_co
    
    2108
    +       }
    
    2108 2109
       where
    
    2109
    -    needs_eta :: Bool
    
    2110
    -    needs_eta =
    
    2110
    +    needs_frr_checks :: Bool
    
    2111
    +    needs_frr_checks =
    
    2111 2112
           not (hole_or_cast arg_wrap)
    
    2112 2113
             ||
    
    2113 2114
           not (hole_or_cast res_wrap)
    
    ... ... @@ -2115,6 +2116,12 @@ mkWpFun_FRR pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res
    2115 2116
         hole_or_cast WpHole = True
    
    2116 2117
         hole_or_cast (WpCast {}) = True
    
    2117 2118
         hole_or_cast _ = False
    
    2119
    +    frr_ctxt :: Bool -> FixedRuntimeRepContext
    
    2120
    +    frr_ctxt is_exp_ty =
    
    2121
    +      FRRDeepSubsumption
    
    2122
    +        { frrDSExpected = is_exp_ty
    
    2123
    +        , frrDSPosition = pos
    
    2124
    +        }
    
    2118 2125
     
    
    2119 2126
     -----------------------
    
    2120 2127
     deeplySkolemise :: SkolemInfo -> TcSigmaType
    

  • testsuite/tests/linear/should_compile/T26332.hs
    1
    +{-# LANGUAGE DeepSubsumption #-}
    
    2
    +{-# LANGUAGE LinearTypes #-}
    
    3
    +
    
    4
    +module T26332 where
    
    5
    +
    
    6
    +import Unsafe.Coerce
    
    7
    +
    
    8
    +toLinear
    
    9
    +  :: forall a b p q.
    
    10
    +     (a %p-> b) %1-> (a %q-> b)
    
    11
    +toLinear f = case unsafeEqualityProof @p @q of
    
    12
    +  UnsafeRefl -> f

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

  • testsuite/tests/profiling/should_compile/T26056.hs
    1
    +module M where
    
    2
    +
    
    3
    +import GHC.Exts      ( Any )
    
    4
    +import Unsafe.Coerce ( unsafeCoerce )
    
    5
    +
    
    6
    +data Sigma = MkT Any
    
    7
    +
    
    8
    +testSubList :: Maybe Bool -> Sigma -> Sigma
    
    9
    +testSubList (Just x) final = {-# SCC "y" #-} (
    
    10
    +   let x' = seq x ()
    
    11
    +   in case testSubList Nothing final of
    
    12
    +         MkT w -> {-# SCC "x" #-}
    
    13
    +                    (unsafeCoerce MkT (konst x' myHead (unsafeCoerce w))))
    
    14
    +testSubList Nothing final = final
    
    15
    +
    
    16
    +myHead :: [a] -> a
    
    17
    +myHead (x:_) = x
    
    18
    +
    
    19
    +konst :: () -> ([a] -> a) -> [a] -> a
    
    20
    +konst _ x = x
    
    21
    +{-# OPAQUE konst #-}

  • testsuite/tests/profiling/should_compile/all.T
    ... ... @@ -20,3 +20,4 @@ test('T14931', [test_opts, unless(have_dynamic(), skip)],
    20 20
     test('T15108', [test_opts], compile, ['-O -prof -fprof-auto'])
    
    21 21
     test('T19894', [test_opts, extra_files(['T19894'])], multimod_compile, ['Main', '-v0 -O2 -prof -fprof-auto -iT19894'])
    
    22 22
     test('T20938', [test_opts], compile, ['-O -prof'])
    
    23
    +test('T26056', [test_opts], compile, ['-O -prof'])

  • testsuite/tests/rts/exec_signals_child.c
    ... ... @@ -2,8 +2,11 @@
    2 2
     #include <stdio.h>
    
    3 3
     #include <errno.h>
    
    4 4
     
    
    5
    -// Prints the state of the signal handlers to stdout
    
    6
    -int main()
    
    5
    +// Prints the state of the signal handlers to stdout.
    
    6
    +// NOTE: We intentionally start at signal 1 (not 0). Signal number 0 is not a
    
    7
    +// real signal; passing 0 to sigismember/sigaction is undefined behaviour and
    
    8
    +// on Darwin was observed to yield memory corruption / junk bytes in output.
    
    9
    +int main(void)
    
    7 10
     {
    
    8 11
         int open = 0, i;
    
    9 12
         sigset_t blockedsigs;
    
    ... ... @@ -11,7 +14,7 @@ int main()
    11 14
         printf("ChildInfo { masked = [");
    
    12 15
     
    
    13 16
         sigprocmask(SIG_BLOCK, NULL, &blockedsigs);
    
    14
    -    for(i = 0; i < NSIG; ++i)
    
    17
    +    for(i = 1; i < NSIG; ++i)
    
    15 18
         {
    
    16 19
             int ret = sigismember(&blockedsigs, i);
    
    17 20
             if(ret >= 0)
    
    ... ... @@ -26,7 +29,7 @@ int main()
    26 29
         printf("], handlers = [");
    
    27 30
     
    
    28 31
         open = 0;
    
    29
    -    for(i = 0; i < NSIG; ++i)
    
    32
    +    for(i = 1; i < NSIG; ++i)
    
    30 33
         {
    
    31 34
             struct sigaction old;
    
    32 35
             if(sigaction(i, NULL, &old) >= 0)