Skip to content
  • Simon Peyton Jones's avatar
    Major improvements to the specialiser · 4291bdda
    Simon Peyton Jones authored and Marge Bot's avatar Marge Bot committed
    This patch is joint work of Alexis King and Simon PJ.  It does some
    significant refactoring of the type-class specialiser.  Main highlights:
    
    * We can specialise functions with types like
         f :: Eq a => a -> Ord b => b => blah
      where the classes aren't all at the front (#16473).  Here we can
      correctly specialise 'f' based on a call like
         f @Int @Bool dEqInt x dOrdBool
      This change really happened in an earlier patch
         commit 2d0cf625
         Author: Sandy Maguire <sandy@sandymaguire.me>
         Date:   Thu May 16 12:12:10 2019 -0400
      work that this new patch builds directly on that work, and refactors
      it a bit.
    
    * We can specialise functions with implicit parameters (#17930)
         g :: (?foo :: Bool, Show a) => a -> String
      Previously we could not, but now they behave just like a non-class
      argument as in 'f' above.
    
    * We can specialise under-saturated calls, where some (but not all of
      the dictionary arguments are provided (#17966).  For example, we can
      specialise the above 'f' based on a call
         map (f @Int dEqInt) xs
      even though we don't (and can't) give Ord dictionary.
    
      This may sound exotic, but #17966 is a program from the wild, and
      showed significant perf loss for functions like f, if you need
      saturation of all dictionaries.
    
    * We fix a buglet in which a floated dictionary had a bogus demand
      (#17810), by using zapIdDemandInfo in the NonRec case of specBind.
    
    * A tiny side benefit: we can drop dead arguments to specialised
      functions; see Note [Drop dead args from specialisations]
    
    * Fixed a bug in deciding what dictionaries are "interesting"; see
      Note [Keep the old dictionaries interesting]
    
    This is all achieved by by building on Sandy Macguire's work in
    defining SpecArg, which mkCallUDs uses to describe the arguments of
    the call. Main changes:
    
    * Main work is in specHeader, which marched down the [InBndr] from the
      function definition and the [SpecArg] from the call site, together.
    
    * specCalls no longer has an arity check; the entire mechanism now
      handles unders-saturated calls fine.
    
    * mkCallUDs decides on an argument-by-argument basis whether to
      specialise a particular dictionary argument; this is new.
      See mk_spec_arg in mkCallUDs.
    
    It looks as if there are many more lines of code, but I think that
    all the extra lines are comments!
    4291bdda