#include "HsVersions.h"
import CmdLineOpts ( DynFlags, DynFlag(..) )
-import Id ( Id, idName, idType, mkUserLocal, idSpecialisation, isDataConWrapId )
+import Id ( Id, idName, idType, mkUserLocal )
import TcType ( Type, mkTyVarTy, tcSplitSigmaTy,
- tyVarsOfTypes, tyVarsOfTheta,
+ tyVarsOfTypes, tyVarsOfTheta, isClassPred,
mkForAllTys, tcCmpType
)
import Subst ( Subst, mkSubst, substTy, mkSubst, extendSubstList, mkInScopeSet,
import Util ( zipEqual, zipWithEqual, cmpList, lengthIs,
equalLength, lengthAtLeast, notNull )
import Outputable
-
+import FastString
infixr 9 `thenSM`
\end{code}
| rhs_tyvars `lengthIs` n_tyvars -- Rhs of fn's defn has right number of big lambdas
&& rhs_bndrs `lengthAtLeast` n_dicts -- and enough dict args
&& notNull calls_for_me -- And there are some calls to specialise
- && not (isDataConWrapId fn) -- And it's not a data con wrapper, which have
- -- stupid overloading that simply discard the dictionary
-- At one time I tried not specialising small functions
-- but sometimes there are big functions marked INLINE
n_tyvars = length tyvars
n_dicts = length theta
+ (rhs_tyvars, rhs_ids, rhs_body)
+ = collectTyAndValBinders (dropInline rhs)
-- It's important that we "see past" any INLINE pragma
-- else we'll fail to specialise an INLINE thing
- (inline_me, rhs') = dropInline rhs
- (rhs_tyvars, rhs_ids, rhs_body) = collectTyAndValBinders rhs'
rhs_dicts = take n_dicts rhs_ids
rhs_bndrs = rhs_tyvars ++ rhs_dicts
let
-- The rule to put in the function's specialisation is:
-- forall b,d, d1',d2'. f t1 b t3 d d1' d2' = f1 b d
- spec_env_rule = Rule (_PK_ ("SPEC " ++ showSDoc (ppr fn)))
+ spec_env_rule = Rule (mkFastString ("SPEC " ++ showSDoc (ppr fn)))
AlwaysActive
(poly_tyvars ++ rhs_dicts')
inst_args
| not (equalLength xs ys) = pprPanic "my_zipEqual" (ppr xs $$ ppr ys $$ (ppr fn <+> ppr call_ts) $$ ppr rhs)
| otherwise = zipEqual doc xs ys
-dropInline :: CoreExpr -> (Bool, CoreExpr)
-dropInline (Note InlineMe rhs) = (True, rhs)
-dropInline rhs = (False, rhs)
+dropInline :: CoreExpr -> CoreExpr
+dropInline (Note InlineMe rhs) = rhs
+dropInline rhs = rhs
\end{code}
%************************************************************************
mkCallUDs subst f args
| null theta
+ || not (all isClassPred theta)
+ -- Only specialise if all overloading is on class params.
+ -- In ptic, with implicit params, the type args
+ -- *don't* say what the value of the implicit param is!
|| not (spec_tys `lengthIs` n_tyvars)
|| not ( dicts `lengthIs` n_dicts)
|| maybeToBool (lookupRule (\act -> True) (substInScope subst) f args)
spec_tys = [mk_spec_ty tv ty | (tv, Type ty) <- tyvars `zip` args]
dicts = [dict_expr | (_, dict_expr) <- theta `zip` (drop n_tyvars args)]
- 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
------------------------------------------------------------
plusUDs :: UsageDetails -> UsageDetails -> UsageDetails
dump_db (free_dbs, dump_dbs, dump_idset) db@(bind, fvs)
| dump_idset `intersectsVarSet` fvs -- Dump it
= (free_dbs, dump_dbs `snocBag` db,
- dump_idset `unionVarSet` mkVarSet (bindersOf bind))
+ extendVarSetList dump_idset (bindersOf bind))
| otherwise -- Don't dump it
= (free_dbs `snocBag` db, dump_dbs, dump_idset)