diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2011-11-24 12:35:33 +0000 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2011-11-24 12:35:33 +0000 |
commit | 814d864125bdd03d8bc6c3fc551f393b21942c6c (patch) | |
tree | 51982dc0646852574969a0fd0b581984f7793deb /docs | |
parent | cfcf0a549da1f3d7d74fe4695c56e3763bf44599 (diff) | |
download | haskell-814d864125bdd03d8bc6c3fc551f393b21942c6c.tar.gz |
Support "phase control" for SPECIALISE pragmas
This featurelet allows Trac #5237 to be fixed.
The idea is to allow SPECIALISE pragmas to specify
the phases in which the RULE is active, just as you can
do with RULES themselves.
{-# SPECIALISE [1] foo :: Int -> Int #-}
This feature is so obvious that not having it is really a bug.
There are, needless to say, a few wrinkles. See
Note [Activation pragmas for SPECIALISE]
in DsBinds
Diffstat (limited to 'docs')
-rw-r--r-- | docs/users_guide/glasgow_exts.xml | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index 7779b0dcc7..0d7ea5cc38 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -8302,12 +8302,16 @@ happen. {-# SPECIALIZE hammeredLookup :: [(Widget, value)] -> Widget -> value #-} </programlisting> +<itemizedlist> +<listitem> <para>A <literal>SPECIALIZE</literal> pragma for a function can be put anywhere its type signature could be put. Moreover, you can also <literal>SPECIALIZE</literal> an <emphasis>imported</emphasis> function provided it was given an <literal>INLINABLE</literal> pragma at its definition site (<xref linkend="inlinable-pragma"/>).</para> +</listitem> +<listitem> <para>A <literal>SPECIALIZE</literal> has the effect of generating (a) a specialised version of the function and (b) a rewrite rule (see <xref linkend="rewrite-rules"/>) that rewrites a call to @@ -8318,7 +8322,36 @@ happen. by <literal>f</literal>, if they are in the same module as the <literal>SPECIALIZE</literal> pragma, or if they are <literal>INLINABLE</literal>; and so on, transitively.</para> +</listitem> +<listitem> + <para>You can add phase control (<xref linkend="phase-control"/>) + to the RULE generated by a <literal>SPECIALIZE</literal> pragma, + just as you can if you writ a RULE directly. For exxample: +<programlisting> + {-# SPECIALIZE [0] hammeredLookup :: [(Widget, value)] -> Widget -> value #-} +</programlisting> + generates a specialisation rule that only fires in Phase 0 (the final phase). + If you do not specify any phase control in the <literal>SPECIALIZE</literal> pragma, + the phase control is inherited from the inline pragma (if any) of the function. + For example: +<programlisting> + foo :: Num a => a -> a + foo = ...blah... + {-# NOINLINE [0] foo #-} + {-# SPECIALIZE foo :: Int -> Int #-} +</programlisting> + The <literal>NOINLINE</literal> pragma tells GHC not to inline <literal>foo</literal> + until Phase 0; and this property is inherited by the specialiation RULE, which will + therefore only fire in Phase 0.</para> + <para>The main reason for using phase control on specialisations is so that you can + write optimisation RULES that fire early in the compilation pipeline, and only + <emphasis>then</emphasis> specialise the calls to the function. If specialisation is + done too early, the optimsation rules might fail to fire. + </para> +</listitem> + +<listitem> <para>The type in a SPECIALIZE pragma can be any type that is less polymorphic than the type of the original function. In concrete terms, if the original function is <literal>f</literal> then the pragma @@ -8346,6 +8379,8 @@ The last of these examples will generate a RULE with a somewhat-complex left-hand side (try it yourself), so it might not fire very well. If you use this kind of specialisation, let us know how well it works. </para> +</listitem> +</itemizedlist> <sect3 id="specialize-inline"> <title>SPECIALIZE INLINE</title> @@ -8376,6 +8411,11 @@ the specialised function will be inlined. It has two calls to both at type <literal>Int</literal>. Both these calls fire the first specialisation, whose body is also inlined. The result is a type-based unrolling of the indexing function.</para> +<para>You can add explicit phase control (<xref linkend="phase-control"/>) +to <literal>SPECIALISE INLINE</literal> pragma, +just like on an <literal>INLINE</literal> pragma; if you do so, the same phase +is used for the rewrite rule and the INLINE control of the specialised function. + <para>Warning: you can make GHC diverge by using <literal>SPECIALISE INLINE</literal> on an ordinarily-recursive function.</para> </sect3> |