diff options
author | simonpj@microsoft.com <unknown> | 2010-10-07 11:10:51 +0000 |
---|---|---|
committer | simonpj@microsoft.com <unknown> | 2010-10-07 11:10:51 +0000 |
commit | 92267aa26adb1ab5a6d8004a80fdf6aa06ea4e44 (patch) | |
tree | 11ada6374af97f3a65b327221aec17368f3344b0 /compiler/deSugar/DsForeign.lhs | |
parent | 861e1d55126391785e93493080d3c7516812675e (diff) | |
download | haskell-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/deSugar/DsForeign.lhs')
-rw-r--r-- | compiler/deSugar/DsForeign.lhs | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/compiler/deSugar/DsForeign.lhs b/compiler/deSugar/DsForeign.lhs index d73cd53044..4d0a148e15 100644 --- a/compiler/deSugar/DsForeign.lhs +++ b/compiler/deSugar/DsForeign.lhs @@ -43,7 +43,7 @@ import Outputable import FastString import Config import Constants - +import OrdList import Data.Maybe import Data.List \end{code} @@ -66,9 +66,9 @@ type Binding = (Id, CoreExpr) -- No rec/nonrec structure; -- the occurrence analyser will sort it all out dsForeigns :: [LForeignDecl Id] - -> DsM (ForeignStubs, [Binding]) + -> DsM (ForeignStubs, OrdList Binding) dsForeigns [] - = return (NoStubs, []) + = return (NoStubs, nilOL) dsForeigns fos = do fives <- mapM do_ldecl fos let @@ -79,7 +79,7 @@ dsForeigns fos = do return (ForeignStubs (vcat hs) (vcat cs $$ vcat fe_init_code), - (concat bindss)) + foldr (appOL . toOL) nilOL bindss) where do_ldecl (L loc decl) = putSrcSpanDs loc (do_decl decl) |