how and where to {-# specialize #-} ?
Simon Peyton-Jones
simonpj@microsoft.com
Thu, 19 Jun 2003 15:38:05 +0100
| I am looking for some advice on
| where to place specialize-pragmas for ghc
| (to optimize speed - and heap usage)
|=20
| Typically I have some module A (containing polymorphic functions A.f,
..)
| and a module B uses this. The interesting case is
| when I want to specialize A.f (which is NOT exported)
| to some types that are only defined in B
| (but normally A should not know about B).
|=20
| Is there some kind of `deep specialisation' where one would say,
| `specialize ALL the functions that are reachable from here'? -
| or how can one get a similar effect?
There are two questions here
a) If module B=20
defines a type B.T, and=20
imports function A.f from module A
can we specialise f at type B.T?
b) If we specialise f at T, and f calls g, how can we specialise g at T?
Unfortunately, GHC has no good way to do (a). It only specialises
functions in the module being compiled, so
it can't specialise f when compiling A because it can't see B.T
it can't specialise f when compiling B because it can't see (all
of) f
It's not obvious how best to address this. Putting all of A's code in
its interface file (not only f, but the things f calls), so that B can
specialise it, seems a bit brutal; and f might then be specialised to
the same type many times. But we can't specialise it in module A,
because A can't see T.
Maybe the Right Thing is some kind of whole-program specialisation, but
GHC isn't set up to do that. The only workaround is to define T early,
import it into A, and specialise A.f there.
Relating to (b), GHC automatically does this specialisation propagation
within one module, but if A.f calls A2.g (where A imports A2), then A2.g
won't get automatically specialised; you'll have to add your own
specialisation pragma in A2. Again this is far from ideal. One
possible plan (totally unimplemented) is this:
when compiling a module, dump specialisation guidance of the
form
A.f needs A2.g @ T
or, more generally something like
A.f @ t needs A2.g at [t]
Now do a global analysis of all the specialization guidance info
to=20
generate SPECIALISE pragamas. =20
Now recompile everything
Simon
=09