From: simonpj@microsoft.com Date: Wed, 23 Jan 2008 13:40:12 +0000 (+0000) Subject: Attach the INLINE Activation pragma to any automatically-generated specialisations X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=be9de111a5f9ba0e9716851b30f3b79be370a102;p=ghc-hetmet.git Attach the INLINE Activation pragma to any automatically-generated specialisations Another idea suggested by Roman, happily involving a one-line change. Here's the new Note in Specialise: Note [Auto-specialisation and RULES] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider: g :: Num a => a -> a g = ... f :: (Int -> Int) -> Int f w = ... {-# RULE f g = 0 #-} Suppose that auto-specialisation makes a specialised version of g::Int->Int That version won't appear in the LHS of the RULE for f. So if the specialisation rule fires too early, the rule for f may never fire. It might be possible to add new rules, to "complete" the rewrite system. Thus when adding RULE forall d. g Int d = g_spec also add RULE f g_spec = 0 But that's a bit complicated. For now we ask the programmer's help, by *copying the INLINE activation pragma* to the auto-specialised rule. So if g says {-# NOINLINE[2] g #-}, then the auto-spec rule will also not be active until phase 2. --- diff --git a/compiler/specialise/Specialise.lhs b/compiler/specialise/Specialise.lhs index 796c7da..9750bd0 100644 --- a/compiler/specialise/Specialise.lhs +++ b/compiler/specialise/Specialise.lhs @@ -892,7 +892,8 @@ specDefn subst calls (fn, rhs) -- The rule to put in the function's specialisation is: -- forall b,d, d1',d2'. f t1 b t3 d d1' d2' = f1 b d spec_env_rule = mkLocalRule (mkFastString ("SPEC " ++ showSDoc (ppr fn))) - AlwaysActive (idName fn) + inline_prag -- Note [Auto-specialisation and RULES] + (idName fn) (poly_tyvars ++ rhs_dicts') inst_args (mkVarApps (Var spec_f) app_args) @@ -918,6 +919,33 @@ specDefn subst calls (fn, rhs) | otherwise = zipEqual doc xs ys \end{code} +Note [Auto-specialisation and RULES] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider: + g :: Num a => a -> a + g = ... + + f :: (Int -> Int) -> Int + f w = ... + {-# RULE f g = 0 #-} + +Suppose that auto-specialisation makes a specialised version of +g::Int->Int That version won't appear in the LHS of the RULE for f. +So if the specialisation rule fires too early, the rule for f may +never fire. + +It might be possible to add new rules, to "complete" the rewrite system. +Thus when adding + RULE forall d. g Int d = g_spec +also add + RULE f g_spec = 0 + +But that's a bit complicated. For now we ask the programmer's help, +by *copying the INLINE activation pragma* to the auto-specialised rule. +So if g says {-# NOINLINE[2] g #-}, then the auto-spec rule will also +not be active until phase 2. + + Note [Specialisation shape] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ We only specialise a function if it has visible top-level lambdas