summaryrefslogtreecommitdiff
path: root/compiler/hsSyn
diff options
context:
space:
mode:
authorsimonpj@microsoft.com <unknown>2010-10-07 11:10:51 +0000
committersimonpj@microsoft.com <unknown>2010-10-07 11:10:51 +0000
commit92267aa26adb1ab5a6d8004a80fdf6aa06ea4e44 (patch)
tree11ada6374af97f3a65b327221aec17368f3344b0 /compiler/hsSyn
parent861e1d55126391785e93493080d3c7516812675e (diff)
downloadhaskell-92267aa26adb1ab5a6d8004a80fdf6aa06ea4e44.tar.gz
Implement auto-specialisation of imported Ids
This big-ish patch arranges that if an Id 'f' is * Type-class overloaded f :: Ord a => [a] -> [a] * Defined with an INLINABLE pragma {-# INLINABLE f #-} * Exported from its defining module 'D' then in any module 'U' that imports D 1. Any call of 'f' at a fixed type will generate (a) a specialised version of f in U (b) a RULE that rewrites unspecialised calls to the specialised on e.g. if the call is (f Int dOrdInt xs) then the specialiser will generate $sfInt :: [Int] -> [Int] $sfInt = <code for f, imported from D, specialised> {-# RULE forall d. f Int d = $sfInt #-} 2. In addition, you can give an explicit {-# SPECIALISE -#} pragma for the imported Id {-# SPECIALISE f :: [Bool] -> [Bool] #-} This too generates a local specialised definition, and the corresponding RULE The new RULES are exported from module 'U', so that any module importing U will see the specialised versions of 'f', and will not re-specialise them. There's a flag -fwarn-auto-orphan that warns you if the auto-generated RULES are orphan rules. It's not in -Wall, mainly to avoid lots of error messages with existing packages. Main implementation changes - A new flag on a CoreRule to say if it was auto-generated. This is persisted across interface files, so there's a small change in interface file format. - Quite a bit of fiddling with plumbing, to get the {-# SPECIALISE #-} pragmas for imported Ids. In particular, a new field tgc_imp_specs in TcGblEnv, to keep the specialise pragmas for imported Ids between the typechecker and the desugarer. - Some new code (although surprisingly little) in Specialise, to deal with calls of imported Ids
Diffstat (limited to 'compiler/hsSyn')
-rw-r--r--compiler/hsSyn/HsBinds.lhs18
1 files changed, 9 insertions, 9 deletions
diff --git a/compiler/hsSyn/HsBinds.lhs b/compiler/hsSyn/HsBinds.lhs
index 7b4c17cb67..da247c28ed 100644
--- a/compiler/hsSyn/HsBinds.lhs
+++ b/compiler/hsSyn/HsBinds.lhs
@@ -315,7 +315,7 @@ ppr_monobind (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dictvars
where
ppr_exp (tvs, gbl, lcl, prags)
= vcat [ppr gbl <+> ptext (sLit "<=") <+> ppr tvs <+> ppr lcl,
- nest 2 (pprTcSpecPrags gbl prags)]
+ nest 2 (pprTcSpecPrags prags)]
\end{code}
@@ -636,11 +636,14 @@ data FixitySig name = FixitySig (Located name) Fixity
data TcSpecPrags
= IsDefaultMethod -- Super-specialised: a default method should
-- be macro-expanded at every call site
- | SpecPrags [Located TcSpecPrag]
+ | SpecPrags [LTcSpecPrag]
deriving (Data, Typeable)
+type LTcSpecPrag = Located TcSpecPrag
+
data TcSpecPrag
= SpecPrag
+ Id -- The Id to be specialised
HsWrapper -- An wrapper, that specialises the polymorphic function
InlinePragma -- Inlining spec for the specialised function
deriving (Data, Typeable)
@@ -776,14 +779,11 @@ pprSpec var pp_ty inl = ptext (sLit "SPECIALIZE") <+> pp_inl <+> pprVarSig var p
pp_inl | isDefaultInlinePragma inl = empty
| otherwise = ppr inl
-pprTcSpecPrags :: Outputable id => id -> TcSpecPrags -> SDoc
-pprTcSpecPrags _ IsDefaultMethod = ptext (sLit "<default method>")
-pprTcSpecPrags gbl (SpecPrags ps) = vcat (map (pprSpecPrag gbl) ps)
-
-pprSpecPrag :: Outputable id => id -> Located TcSpecPrag -> SDoc
-pprSpecPrag var (L _ (SpecPrag _expr inl)) = pprSpec var (ptext (sLit "<type>")) inl
+pprTcSpecPrags :: TcSpecPrags -> SDoc
+pprTcSpecPrags IsDefaultMethod = ptext (sLit "<default method>")
+pprTcSpecPrags (SpecPrags ps) = vcat (map (ppr . unLoc) ps)
instance Outputable TcSpecPrag where
- ppr (SpecPrag _ p) = ptext (sLit "SpecPrag") <+> ppr p
+ ppr (SpecPrag var _ inl) = pprSpec var (ptext (sLit "<type>")) inl
\end{code}