summaryrefslogtreecommitdiff
path: root/compiler/specialise
diff options
context:
space:
mode:
authorsimonpj@microsoft.com <unknown>2008-01-23 13:40:12 +0000
committersimonpj@microsoft.com <unknown>2008-01-23 13:40:12 +0000
commitbe9de111a5f9ba0e9716851b30f3b79be370a102 (patch)
tree4231466495d92f26db734c3d9f2d32438c8293d9 /compiler/specialise
parent43a2e4a26175b9dbf29e39b97f7d032ef00f9993 (diff)
downloadhaskell-be9de111a5f9ba0e9716851b30f3b79be370a102.tar.gz
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.
Diffstat (limited to 'compiler/specialise')
-rw-r--r--compiler/specialise/Specialise.lhs30
1 files changed, 29 insertions, 1 deletions
diff --git a/compiler/specialise/Specialise.lhs b/compiler/specialise/Specialise.lhs
index 796c7da0ac..9750bd042c 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