summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorAustin Seipp <austin@well-typed.com>2013-10-25 11:49:09 -0500
committerAustin Seipp <austin@well-typed.com>2013-10-25 12:18:19 -0500
commit32df429081469a9b928a358be6943744e50b5ff8 (patch)
treea62e26eb40cf2e9420f085ce59b44950d85bc6a4 /compiler
parentd71bbe79e222ea286c2fd465abfde58280450c3a (diff)
downloadhaskell-32df429081469a9b928a358be6943744e50b5ff8.tar.gz
Update documentation regarding SpecConstr.
* Note new SPEC type in release notes. * Document SPEC in the users guide under the documentation for -fspec-constr. * Clean up comments in SpecConstr regarding the forcing of specialisation (see Note [Forcing specialisation].) Signed-off-by: Austin Seipp <austin@well-typed.com>
Diffstat (limited to 'compiler')
-rw-r--r--compiler/specialise/SpecConstr.lhs56
1 files changed, 31 insertions, 25 deletions
diff --git a/compiler/specialise/SpecConstr.lhs b/compiler/specialise/SpecConstr.lhs
index c4b46aa5b2..44dc6f00ef 100644
--- a/compiler/specialise/SpecConstr.lhs
+++ b/compiler/specialise/SpecConstr.lhs
@@ -1,6 +1,6 @@
-ToDo [Nov 2010]
+ToDo [Oct 2013]
~~~~~~~~~~~~~~~
-1. Use a library type rather than an annotation for ForceSpecConstr
+1. Nuke ForceSpecConstr for good (it is subsumed by GHC.Types.SPEC in ghc-prim)
2. Nuke NoSpecConstr
%
@@ -56,7 +56,7 @@ import Data.List
import TyCon ( TyCon, tyConName )
import PrelNames ( specTyConName )
--- See Note [SpecConstrAnnotation]
+-- See Note [Forcing specialisation]
#ifndef GHCI
type SpecConstrAnnotation = ()
#else
@@ -423,28 +423,40 @@ But fspec doesn't have decent strictness info. As it happened,
and hence f. But now f's strictness is less than its arity, which
breaks an invariant.
-Note [SpecConstrAnnotation]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-SpecConstrAnnotation is defined in GHC.Exts, and is only guaranteed to
-be available in stage 2 (well, until the bootstrap compiler can be
-guaranteed to have it)
-
-So we define it to be () in stage1 (ie when GHCI is undefined), and
-'#ifdef' out the code that uses it.
-
-See also Note [Forcing specialisation]
Note [Forcing specialisation]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-With stream fusion and in other similar cases, we want to fully specialise
-some (but not necessarily all!) loops regardless of their size and the
-number of specialisations. We allow a library to specify this by annotating
-a type with ForceSpecConstr and then adding a parameter of that type to the
-loop. Here is a (simplified) example from the vector library:
+
+With stream fusion and in other similar cases, we want to fully
+specialise some (but not necessarily all!) loops regardless of their
+size and the number of specialisations.
+
+We allow a library to do this, in one of two ways (one which is
+deprecated):
+
+ 1) Add a parameter of type GHC.Types.SPEC (from ghc-prim) to the loop body.
+
+ 2) (Deprecated) Annotate a type with ForceSpecConstr from GHC.Exts,
+ and then add *that* type as a parameter to the loop body
+
+The reason #2 is deprecated is because it requires GHCi, which isn't
+available for things like a cross compiler using stage1.
+
+Here's a (simplified) example from the `vector` package. You may bring
+the special 'force specialization' type into scope by saying:
+
+ import GHC.Types (SPEC(..))
+
+or by defining your own type (again, deprecated):
data SPEC = SPEC | SPEC2
{-# ANN type SPEC ForceSpecConstr #-}
+(Note this is the exact same definition of GHC.Types.SPEC, just
+without the annotation.)
+
+After that, you say:
+
foldl :: (a -> b -> a) -> a -> Stream b -> a
{-# INLINE foldl #-}
foldl f z (Stream step s _) = foldl_loop SPEC z s
@@ -494,12 +506,6 @@ can be used in Stream states and (c) some types are fixed by the user
(e.g., the accumulator here) but we still want to specialise as much
as possible.
-ForceSpecConstr is done by way of an annotation:
- data SPEC = SPEC | SPEC2
- {-# ANN type SPEC ForceSpecConstr #-}
-But SPEC is the *only* type so annotated, so it'd be better to
-use a particular library type.
-
Alternatives to ForceSpecConstr
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Instead of giving the loop an extra argument of type SPEC, we
@@ -906,7 +912,7 @@ decreaseSpecCount env n_specs
-- See Note [Avoiding exponential blowup]
---------------------------------------------------
--- See Note [SpecConstrAnnotation]
+-- See Note [Forcing specialisation]
ignoreType :: ScEnv -> Type -> Bool
ignoreDataCon :: ScEnv -> DataCon -> Bool
forceSpecBndr :: ScEnv -> Var -> Bool