• simonpj@microsoft.com's avatar
    Implement auto-specialisation of imported Ids · 92267aa2
    simonpj@microsoft.com authored
    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
RnBinds.lhs 30.5 KB