From eadc1f0591ac7ad3e6ed284b4f8530ba94ee8fa2 Mon Sep 17 00:00:00 2001 From: Simon Peyton Jones Date: Tue, 10 May 2022 17:18:28 +0100 Subject: Specialiser: saturate DFuns correctly Ticket #21489 showed that the saturation mechanism for DFuns (see Note Specialising DFuns) should use both UnspecType and UnspecArg. We weren't doing that; but this MR fixes that problem. No test case because it's hard to tickle, but it showed up in Gergo's work with GHC-as-a-library. --- compiler/GHC/Core/Opt/Specialise.hs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/GHC/Core/Opt/Specialise.hs b/compiler/GHC/Core/Opt/Specialise.hs index 76b76a972d..1e429a4c1e 100644 --- a/compiler/GHC/Core/Opt/Specialise.hs +++ b/compiler/GHC/Core/Opt/Specialise.hs @@ -1501,9 +1501,12 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs -> SpecM SpecInfo spec_call spec_acc@(rules_acc, pairs_acc, uds_acc) _ci@(CI { ci_key = call_args }) = -- See Note [Specialising Calls] - do { let all_call_args | is_dfun = call_args ++ repeat UnspecArg + do { let all_call_args | is_dfun = saturating_call_args -- See Note [Specialising DFuns] | otherwise = call_args - -- See Note [Specialising DFuns] + saturating_call_args = call_args ++ map mk_extra_dfun_arg (dropList call_args rhs_bndrs) + mk_extra_dfun_arg bndr | isTyVar bndr = UnspecType + | otherwise = UnspecArg + ; ( useful, rhs_env2, leftover_bndrs , rule_bndrs, rule_lhs_args , spec_bndrs1, dx_binds, spec_args) <- specHeader env_with_dict_bndrs @@ -1641,8 +1644,8 @@ specLookupRule env fn args rules DFuns have a special sort of unfolding (DFunUnfolding), and these are hard to specialise a DFunUnfolding to give another DFunUnfolding unless the DFun is fully applied (#18120). So, in the case of DFunIds -we simply extend the CallKey with trailing UnspecArgs, so we'll -generate a rule that completely saturates the DFun. +we simply extend the CallKey with trailing UnspecTypes/UnspecArgs, +so that we'll generate a rule that completely saturates the DFun. There is an ASSERT that checks this, in the DFunUnfolding case of GHC.Core.Unfold.Make.specUnfolding. -- cgit v1.2.1