[project @ 2005-12-29 09:19:24 by simonpj]
authorsimonpj <unknown>
Thu, 29 Dec 2005 09:19:24 +0000 (09:19 +0000)
committersimonpj <unknown>
Thu, 29 Dec 2005 09:19:24 +0000 (09:19 +0000)
Document SPECIALISE INLNE

ghc/docs/users_guide/glasgow_exts.xml

index 1e0e5b9..4d7577d 100644 (file)
@@ -4907,7 +4907,7 @@ key_function :: Int -> String -> (Bool, Double)
       for the original function, not its code):
 <programlisting>
   f :: Eq a => a -> b -> b
-  {-# SPECIALISE g :: Int -> b -> b #-}
+  {-# SPECIALISE f :: Int -> b -> b #-}
 
   g :: (Eq a, Ix b) => a -> b -> b
   {-# SPECIALISE g :: (Eq a) => a -> Int -> Int #-}
@@ -4920,6 +4920,35 @@ RULE with a somewhat-complex left-hand side (try it yourself), so it might not f
 well.  If you use this kind of specialisation, let us know how well it works.
 </para>
 
+<para>A <literal>SPECIALIZE</literal> pragma can optionally be followed with a
+<literal>INLINE</literal> or <literal>NOINLINE</literal> pragma, optionally 
+followed by a phase, as described in <xref linkend="inline-noinline-pragma"/>.
+The <literal>INLINE</literal> pragma affects the specialised verison of the
+function (only), and applies even if the function is recursive.  The motivating
+example is this:
+<programlisting>
+-- A GADT for arrays with type-indexed representation
+data Arr e where
+  ArrInt :: !Int -> ByteArray# -> Arr Int
+  ArrPair :: !Int -> Arr e1 -> Arr e2 -> Arr (e1, e2)
+
+(!:) :: Arr e -> Int -> e
+{-# SPECIALISE INLINE (!:) :: Arr Int -> Int -> Int #-}
+{-# SPECIALISE INLINE (!:) :: Arr (a, b) -> Int -> (a, b) #-}
+(ArrInt _ ba)     !: (I# i) = I# (indexIntArray# ba i)
+(ArrPair _ a1 a2) !: i      = (a1 !: i, a2 !: i)
+</programlisting>
+Here, <literal>(!:)</literal> is a recursive function that indexes arrays
+of type <literal>Arr e</literal>.  Consider a call to  <literal>(!:)</literal>
+at type <literal>(Int,Int)</literal>.  The second specialisation will fire, and
+the specialised function will be inlined.  It has two calls to
+<literal>(!:)</literal>,
+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>Warning: you can make GHC diverge by using <literal>SPECIALISE INLINE</literal>
+on an ordinarily-recursive function.</para>
+
       <para>Note: In earlier versions of GHC, it was possible to provide your own
       specialised function for a given type: