summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2011-11-24 12:35:33 +0000
committerSimon Peyton Jones <simonpj@microsoft.com>2011-11-24 12:35:33 +0000
commit814d864125bdd03d8bc6c3fc551f393b21942c6c (patch)
tree51982dc0646852574969a0fd0b581984f7793deb /docs
parentcfcf0a549da1f3d7d74fe4695c56e3763bf44599 (diff)
downloadhaskell-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.xml40
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>