Skip to content

Specialiser problems

When I was working on #21286 (closed) I came across some other problems related to specialisation:

  1. In GHC.Core.isEvaldUnfolding we were not treating a DFunUnfolding as evaluated. That's silly: it always is. And that omission in turn weakens SpecConstr, which won't specialise on a DFun. But it will specialise on lambda-values, so we get specialisation if we w/w the dictionary (which we used to do) but not if we don't.

    Anyway, making isEvaldUnfolding and isValueUnfolding return True for DFunUnfolding just seems like the right thing to do.

  2. It turned out (when compiling nofib/spectral/exact-reals that we could get a RULE from the type-class specialiser (actually a user-written SPECIALISE pragma)

      RULE "SPEC:foo"  forall d1 d2. foo @Int @Integer d1 d2 = $sfoo1

    and another rule from SpecConstr like

      RULE "SC:foo"    forall a. foo @Int @a $fNumInteger = $sfoo2 @a

    arising from a call to foo elsewhere. Note that $fNumInteger is a top-level binding for Num Integer. SpecConstr did this because of the fix to item (1).

    These rules overlap, and neither appears to dominate the other.

    Given a call foo @Int @Integer $fNumInteger d, GHC emits a trace message "Rules.findBest: rule overlap (Rule 1 wins)". It happens that SC:foo wins and it specialises less well because it specialises on only one type parameter. Sigh!

    The actual function foo is exponentation ^, but that hard to type and search for! Both RULES are generated when compiling GHC.Real in the libraries.

Edited by Simon Peyton Jones
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information