From: simonpj Date: Thu, 29 Dec 2005 09:19:24 +0000 (+0000) Subject: [project @ 2005-12-29 09:19:24 by simonpj] X-Git-Tag: final_switch_to_darcs,_this_repo_is_now_live~77 X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=abd374c9affb2fafd833def8e7d34e285049fe69 [project @ 2005-12-29 09:19:24 by simonpj] Document SPECIALISE INLNE --- diff --git a/ghc/docs/users_guide/glasgow_exts.xml b/ghc/docs/users_guide/glasgow_exts.xml index 1e0e5b9..4d7577d 100644 --- a/ghc/docs/users_guide/glasgow_exts.xml +++ b/ghc/docs/users_guide/glasgow_exts.xml @@ -4907,7 +4907,7 @@ key_function :: Int -> String -> (Bool, Double) for the original function, not its code): 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. +A SPECIALIZE pragma can optionally be followed with a +INLINE or NOINLINE pragma, optionally +followed by a phase, as described in . +The INLINE pragma affects the specialised verison of the +function (only), and applies even if the function is recursive. The motivating +example is this: + +-- 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) + +Here, (!:) is a recursive function that indexes arrays +of type Arr e. Consider a call to (!:) +at type (Int,Int). The second specialisation will fire, and +the specialised function will be inlined. It has two calls to +(!:), +both at type Int. Both these calls fire the first +specialisation, whose body is also inlined. The result is a type-based +unrolling of the indexing function. +Warning: you can make GHC diverge by using SPECIALISE INLINE +on an ordinarily-recursive function. + Note: In earlier versions of GHC, it was possible to provide your own specialised function for a given type: