Implement auto-specialisation of imported Ids
authorsimonpj@microsoft.com <unknown>
Thu, 7 Oct 2010 11:10:51 +0000 (11:10 +0000)
committersimonpj@microsoft.com <unknown>
Thu, 7 Oct 2010 11:10:51 +0000 (11:10 +0000)
commit92267aa26adb1ab5a6d8004a80fdf6aa06ea4e44
tree11ada6374af97f3a65b327221aec17368f3344b0
parent861e1d55126391785e93493080d3c7516812675e
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
27 files changed:
compiler/basicTypes/BasicTypes.lhs
compiler/coreSyn/CoreSyn.lhs
compiler/deSugar/Desugar.lhs
compiler/deSugar/DsBinds.lhs
compiler/deSugar/DsForeign.lhs
compiler/hsSyn/HsBinds.lhs
compiler/iface/BinIface.hs
compiler/iface/IfaceSyn.lhs
compiler/iface/MkIface.lhs
compiler/iface/TcIface.lhs
compiler/main/DynFlags.hs
compiler/rename/RnBinds.lhs
compiler/rename/RnEnv.lhs
compiler/rename/RnExpr.lhs
compiler/rename/RnSource.lhs
compiler/specialise/Rules.lhs
compiler/specialise/SpecConstr.lhs
compiler/specialise/Specialise.lhs
compiler/typecheck/TcBinds.lhs
compiler/typecheck/TcClassDcl.lhs
compiler/typecheck/TcDeriv.lhs
compiler/typecheck/TcHsSyn.lhs
compiler/typecheck/TcInstDcls.lhs
compiler/typecheck/TcRnDriver.lhs
compiler/typecheck/TcRnMonad.lhs
compiler/typecheck/TcRnTypes.lhs
compiler/utils/FiniteMap.lhs