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