summaryrefslogtreecommitdiff
path: root/compiler/vectorise
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2013-05-30 12:08:39 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2013-05-30 12:08:39 +0100
commit1ed0409010afeaa318676e351b833aea659bf93a (patch)
treeda405ca170cda02dcddbb96426d8a7737c5e7588 /compiler/vectorise
parentcfb9bee7cd3e93bb872cbf6f3fa944d8ad5aabf3 (diff)
downloadhaskell-1ed0409010afeaa318676e351b833aea659bf93a.tar.gz
Make 'SPECIALISE instance' work again
This is a long-standing regression (Trac #7797), which meant that in particular the Eq [Char] instance does not get specialised. (The *methods* do, but the dictionary itself doesn't.) So when you call a function f :: Eq a => blah on a string type (ie a=[Char]), 7.6 passes a dictionary of un-specialised methods. This only matters when calling an overloaded function from a specialised context, but that does matter in some programs. I remember (though I cannot find the details) that Nick Frisby discovered this to be the source of some pretty solid performanc regresisons. Anyway it works now. The key change is that a DFunUnfolding now takes a form that is both simpler than before (the DFunArg type is eliminated) and more general: data Unfolding = ... | DFunUnfolding { -- The Unfolding of a DFunId -- See Note [DFun unfoldings] -- df = /\a1..am. \d1..dn. MkD t1 .. tk -- (op1 a1..am d1..dn) -- (op2 a1..am d1..dn) df_bndrs :: [Var], -- The bound variables [a1..m],[d1..dn] df_con :: DataCon, -- The dictionary data constructor (never a newtype datacon) df_args :: [CoreExpr] -- Args of the data con: types, superclasses and methods, } -- in positional order That in turn allowed me to re-enable the DFunUnfolding specialisation in DsBinds. Lots of details here in TcInstDcls: Note [SPECIALISE instance pragmas] I also did some refactoring, in particular to pass the InScopeSet to exprIsConApp_maybe (which in turn means it has to go to a RuleFun). NB: Interface file format has changed!
Diffstat (limited to 'compiler/vectorise')
-rw-r--r--compiler/vectorise/Vectorise/Generic/PADict.hs24
1 files changed, 11 insertions, 13 deletions
diff --git a/compiler/vectorise/Vectorise/Generic/PADict.hs b/compiler/vectorise/Vectorise/Generic/PADict.hs
index f70e796daa..7e70f2dd11 100644
--- a/compiler/vectorise/Vectorise/Generic/PADict.hs
+++ b/compiler/vectorise/Vectorise/Generic/PADict.hs
@@ -68,37 +68,35 @@ buildPADict vect_tc prepr_ax pdata_tc pdatas_tc repr
; pr_cls <- builtin prClass
; return $ mkClassPred pr_cls [r]
}
- ; super_tys <- sequence [mk_super_ty | not (null tvs)]
+ ; super_tys <- sequence [mk_super_ty | not (null tvs)]
; super_args <- mapM (newLocalVar (fsLit "pr")) super_tys
- ; let all_args = super_args ++ args
+ ; let val_args = super_args ++ args
+ all_args = tvs ++ val_args
-- ...it is constant otherwise
; super_consts <- sequence [prDictOfPReprInstTyCon inst_ty prepr_ax [] | null tvs]
-- Get ids for each of the methods in the dictionary, including superclass
; paMethodBuilders <- buildPAScAndMethods
- ; method_ids <- mapM (method all_args dfun_name) paMethodBuilders
+ ; method_ids <- mapM (method val_args dfun_name) paMethodBuilders
-- Expression to build the dictionary.
; pa_dc <- builtin paDataCon
- ; let dict = mkLams (tvs ++ all_args)
- $ mkConApp pa_dc
- $ Type inst_ty
- : map Var super_args ++ super_consts -- the superclass dictionary is either lambda-bound or constant
- ++ map (method_call all_args) method_ids
+ ; let dict = mkLams all_args (mkConApp pa_dc con_args)
+ con_args = Type inst_ty
+ : map Var super_args -- the superclass dictionary is either
+ ++ super_consts -- lambda-bound or constant
+ ++ map (method_call val_args) method_ids
-- Build the type of the dictionary function.
; pa_cls <- builtin paClass
; let dfun_ty = mkForAllTys tvs
- $ mkFunTys (map varType all_args)
+ $ mkFunTys (map varType val_args)
(mkClassPred pa_cls [inst_ty])
-- Set the unfolding for the inliner.
; raw_dfun <- newExportedVar dfun_name dfun_ty
- ; let dfun_unf = mkDFunUnfolding dfun_ty $
- map (const $ DFunLamArg 0) super_args
- ++ map DFunPolyArg super_consts
- ++ map (DFunPolyArg . Var) method_ids
+ ; let dfun_unf = mkDFunUnfolding all_args pa_dc con_args
dfun = raw_dfun `setIdUnfolding` dfun_unf
`setInlinePragma` dfunInlinePragma