I discovered by accident that we were generating utterly useless
specialisations. See Note [Interesting dictionary arguments] in Specialise.
This patch used SimplUtils.interestingArg to restrict specialisation to
cases where the dictionary acutally has some information to give us.
substBndr, substBndrs, substTy, substInScope,
cloneIdBndr, cloneIdBndrs, cloneRecIdBndrs
)
substBndr, substBndrs, substTy, substInScope,
cloneIdBndr, cloneIdBndrs, cloneRecIdBndrs
)
+import SimplUtils ( interestingArg )
import VarSet
import VarEnv
import CoreSyn
import VarSet
import VarEnv
import CoreSyn
Still, this is no great hardship, because we intend to eliminate
overloading altogether anyway!
Still, this is no great hardship, because we intend to eliminate
overloading altogether anyway!
A note about non-tyvar dictionaries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Some Ids have types like
A note about non-tyvar dictionaries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Some Ids have types like
But it is simpler and more uniform to specialise wrt these dicts too;
and in future GHC is likely to support full fledged type signatures
like
But it is simpler and more uniform to specialise wrt these dicts too;
and in future GHC is likely to support full fledged type signatures
like
%************************************************************************
%************************************************************************
-- *don't* say what the value of the implicit param is!
|| not (spec_tys `lengthIs` n_tyvars)
|| not ( dicts `lengthIs` n_dicts)
-- *don't* say what the value of the implicit param is!
|| not (spec_tys `lengthIs` n_tyvars)
|| not ( dicts `lengthIs` n_dicts)
+ || not (any interestingArg dicts) -- Note [Interesting dictionary arguments]
|| maybeToBool (lookupRule (\_act -> True) (substInScope subst) emptyRuleBase f args)
-- There's already a rule covering this call. A typical case
-- is where there's an explicit user-provided rule. Then
|| maybeToBool (lookupRule (\_act -> True) (substInScope subst) emptyRuleBase f args)
-- There's already a rule covering this call. A typical case
-- is where there's an explicit user-provided rule. Then
mk_spec_ty tyvar ty
| tyvar `elemVarSet` constrained_tyvars = Just ty
| otherwise = Nothing
mk_spec_ty tyvar ty
| tyvar `elemVarSet` constrained_tyvars = Just ty
| otherwise = Nothing
-------------------------------------------------------------
+Note [Interesting dictionary arguments]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider this
+ \a.\d:Eq a. let f = ... in ...(f d)...
+There really is not much point in specialising f wrt the dictionary d,
+because the code for the specialised f is not improved at all, because
+d is lambda-bound. We simply get junk specialisations.
+
+We re-use the function SimplUtils.interestingArg function to determine
+what sort of dictionary arguments have *some* information in them.
+
+
+\begin{code}
plusUDs :: UsageDetails -> UsageDetails -> UsageDetails
plusUDs (MkUD {dict_binds = db1, calls = calls1, ud_fvs = fvs1})
(MkUD {dict_binds = db2, calls = calls2, ud_fvs = fvs2})
plusUDs :: UsageDetails -> UsageDetails -> UsageDetails
plusUDs (MkUD {dict_binds = db1, calls = calls1, ud_fvs = fvs1})
(MkUD {dict_binds = db2, calls = calls2, ud_fvs = fvs2})