summaryrefslogtreecommitdiff
path: root/compiler/deSugar/DsForeign.lhs
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/deSugar/DsForeign.lhs
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/deSugar/DsForeign.lhs')
-rw-r--r--compiler/deSugar/DsForeign.lhs8
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)