<para>The Real Truth about what primitive types there are, and what operations
work over those types, is held in the file
-<filename>fptools/ghc/compiler/prelude/primops.txt.pp</filename>.
+<filename>compiler/prelude/primops.txt.pp</filename>.
This file is used directly to generate GHC's primitive-operation definitions, so
it is always correct! It is also intended for processing into text.</para>
-<para> Indeed,
+<para>Indeed,
the result of such processing is part of the description of the
<ulink
url="http://www.haskell.org/ghc/docs/papers/core.ps.gz">External
know and love—usually one instruction.
</para>
+<para> For some primitive types we have special syntax for literals.
+Anything that would be an integer lexeme followed by a
+<literal>#</literal> is an <literal>Int#</literal> literal, e.g.
+<literal>32#</literal> and <literal>-0x3A#</literal>. Likewise,
+any non-negative integer literal followed by
+<literal>##</literal> is a <literal>Word#</literal> literal.
+Likewise, any floating point literal followed by a
+<literal>#</literal> is a <literal>Float#</literal> literal, and
+followed by <literal>##</literal> is a
+<literal>Double#</literal>. Finally, a string literal followed by a
+<literal>#</literal>, e.g. <literal>"foo"#</literal>,
+is a <literal>Addr#</literal> literal.
+</para>
+
<para>
Primitive (unboxed) types cannot be defined in Haskell, and are
therefore built into the language and compiler. Primitive types are
<programlisting>
key_function :: Int -> String -> (Bool, Double)
-
-#ifdef __GLASGOW_HASKELL__
{-# INLINE key_function #-}
-#endif
</programlisting>
- <para>(You don't need to do the C pre-processor carry-on
- unless you're going to stick the code through HBC—it
- doesn't like <literal>INLINE</literal> pragmas.)</para>
-
<para>The major effect of an <literal>INLINE</literal> pragma
is to declare a function's “cost” to be very low.
The normal unfolding machinery will then be very keen to
All of these effects are aimed at ensuring that what gets inlined is
exactly what you asked for, no more and no less.
</para>
+<para>GHC ensures that inlining cannot go on forever: every mutually-recursive
+group is cut by one or more <emphasis>loop breakers</emphasis> that is never inlined
+(see <ulink url="http://research.microsoft.com/%7Esimonpj/Papers/inlining/index.htm">
+Secrets of the GHC inliner, JFP 12(4) July 2002</ulink>).
+GHC tries not to select a function with an INLINE pragma as a loop breaker, but
+when there is no choice even an INLINE function can be selected, in which case
+the INLINE pragma is ignored.
+For example, for a self-recursive function, the loop breaker can only be the function
+itself, so an INLINE pragma is always ignored.</para>
+
<para>Syntactically, an <literal>INLINE</literal> pragma for a
function can be put anywhere its type signature could be
put.</para>
<literal>UniqueSupply</literal> monad code, we have:</para>
<programlisting>
-#ifdef __GLASGOW_HASKELL__
{-# INLINE thenUs #-}
{-# INLINE returnUs #-}
-#endif
</programlisting>
<para>See also the <literal>NOINLINE</literal> pragma (<xref
linkend="noinline-pragma"/>).</para>
+
+ <para>Note: the HBC compiler doesn't like <literal>INLINE</literal> pragmas,
+ so if you want your code to be HBC-compatible you'll have to surround
+ the pragma with C pre-processor directives
+ <literal>#ifdef __GLASGOW_HASKELL__</literal>...<literal>#endif</literal>.</para>
+
</sect3>
<sect3 id="noinline-pragma">
#-}
</programlisting>
</para>
+<para>
+Use the debug flag <option>-ddump-simpl-stats</option> to see what rules fired.
+If you need more information, then <option>-ddump-rule-firings</option> shows you
+each individual rule firing in detail.
+</para>
<sect2>
<title>Syntax</title>
terminating. For example:
<programlisting>
- "loop" forall x,y. f x y = f y x
+ "loop" forall x y. f x y = f y x
</programlisting>
This rule will cause the compiler to go into an infinite loop.
<listitem>
<para>
- In the earlier phases of compilation, GHC inlines <emphasis>nothing
-that appears on the LHS of a rule</emphasis>, because once you have substituted
-for something you can't match against it (given the simple minded
-matching). So if you write the rule
-
+Ordinary inlining happens at the same time as rule rewriting, which may lead to unexpected
+results. Consider this (artificial) example
<programlisting>
- "map/map" forall f,g. map f . map g = map (f.g)
-</programlisting>
+f x = x
+{-# RULES "f" f True = False #-}
-this <emphasis>won't</emphasis> match the expression <literal>map f (map g xs)</literal>.
-It will only match something written with explicit use of ".".
-Well, not quite. It <emphasis>will</emphasis> match the expression
+g y = f y
-<programlisting>
-wibble f g xs
+h z = g True
</programlisting>
-
-where <function>wibble</function> is defined:
-
+Since <literal>f</literal>'s right-hand side is small, it is inlined into <literal>g</literal>,
+to give
<programlisting>
-wibble f g = map f . map g
+g y = y
</programlisting>
-
-because <function>wibble</function> will be inlined (it's small).
-
-Later on in compilation, GHC starts inlining even things on the
-LHS of rules, but still leaves the rules enabled. This inlining
-policy is controlled by the per-simplification-pass flag <option>-finline-phase</option><emphasis>n</emphasis>.
-
+Now <literal>g</literal> is inlined into <literal>h</literal>, but <literal>f</literal>'s RULE has
+no chance to fire.
+If instead GHC had first inlined <literal>g</literal> into <literal>h</literal> then there
+would have been a better chance that <literal>f</literal>'s RULE might fire.
+</para>
+<para>
+The way to get predictable behaviour is to use a NOINLINE
+pragma on <literal>f</literal>, to ensure
+that it is not inlined until its RULEs have had a chance to fire.
</para>
</listitem>
<listitem>