summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/main/DynFlags.hs6
-rw-r--r--compiler/typecheck/TcErrors.lhs77
-rw-r--r--docs/users_guide/flags.xml31
-rw-r--r--docs/users_guide/using.xml564
4 files changed, 376 insertions, 302 deletions
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs
index 4d19519845..4175dc9afb 100644
--- a/compiler/main/DynFlags.hs
+++ b/compiler/main/DynFlags.hs
@@ -580,6 +580,8 @@ data DynFlags = DynFlags {
ruleCheck :: Maybe String,
strictnessBefore :: [Int], -- ^ Additional demand analysis
+ maxRelevantBinds :: Maybe Int, -- ^ Maximum number of bindings from the type envt
+ -- to show in type error messages
simplTickFactor :: Int, -- ^ Multiplier for simplifier ticks
specConstrThreshold :: Maybe Int, -- ^ Threshold for SpecConstr
specConstrCount :: Maybe Int, -- ^ Max number of specialisations for any one function
@@ -1247,6 +1249,7 @@ defaultDynFlags mySettings =
maxSimplIterations = 4,
shouldDumpSimplPhase = Nothing,
ruleCheck = Nothing,
+ maxRelevantBinds = Just 6,
simplTickFactor = 100,
specConstrThreshold = Just 2000,
specConstrCount = Just 3,
@@ -2288,6 +2291,9 @@ dynamic_flags = [
, Flag "O" (optIntSuffixM (\mb_n -> setOptLevel (mb_n `orElse` 1)))
-- If the number is missing, use 1
+
+ , Flag "fmax-relevant-binds" (intSuffix (\n d -> d{ maxRelevantBinds = Just n }))
+ , Flag "fno-max-relevant-binds" (noArg (\d -> d{ maxRelevantBinds = Nothing }))
, Flag "fsimplifier-phases" (intSuffix (\n d -> d{ simplPhases = n }))
, Flag "fmax-simplifier-iterations" (intSuffix (\n d -> d{ maxSimplIterations = n }))
, Flag "fsimpl-tick-factor" (intSuffix (\n d -> d{ simplTickFactor = n }))
diff --git a/compiler/typecheck/TcErrors.lhs b/compiler/typecheck/TcErrors.lhs
index 4023311d3a..307e922633 100644
--- a/compiler/typecheck/TcErrors.lhs
+++ b/compiler/typecheck/TcErrors.lhs
@@ -500,7 +500,7 @@ solve it.
\begin{code}
mkIrredErr :: ReportErrCtxt -> [Ct] -> TcM ErrMsg
mkIrredErr ctxt cts
- = do { (ctxt, binds_msg) <- relevantBindings ctxt ct1
+ = do { (ctxt, binds_msg) <- relevantBindings True ctxt ct1
; mkErrorMsg ctxt ct1 (msg $$ binds_msg) }
where
(ct1:_) = cts
@@ -516,7 +516,8 @@ mkHoleError ctxt ct@(CHoleCan { cc_occ = occ })
msg = vcat [ hang (ptext (sLit "Found hole") <+> quotes (ppr occ))
2 (ptext (sLit "with type:") <+> pprType (ctEvPred (cc_ev ct)))
, ppUnless (null tyvars_msg) (ptext (sLit "Where:") <+> vcat tyvars_msg) ]
- ; (ctxt, binds_doc) <- relevantBindings ctxt ct
+ ; (ctxt, binds_doc) <- relevantBindings False ctxt ct
+ -- The 'False' means "don't filter the bindings; see Trac #8191
; mkErrorMsg ctxt ct (msg $$ binds_doc) }
where
loc_msg tv
@@ -532,7 +533,7 @@ mkHoleError _ ct = pprPanic "mkHoleError" (ppr ct)
----------------
mkIPErr :: ReportErrCtxt -> [Ct] -> TcM ErrMsg
mkIPErr ctxt cts
- = do { (ctxt, bind_msg) <- relevantBindings ctxt ct1
+ = do { (ctxt, bind_msg) <- relevantBindings True ctxt ct1
; mkErrorMsg ctxt ct1 (msg $$ bind_msg) }
where
(ct1:_) = cts
@@ -583,7 +584,7 @@ mkEqErr1 :: ReportErrCtxt -> Ct -> TcM ErrMsg
-- Wanted constraints only!
mkEqErr1 ctxt ct
| isGiven ev
- = do { (ctxt, binds_msg) <- relevantBindings ctxt ct
+ = do { (ctxt, binds_msg) <- relevantBindings True ctxt ct
; let (given_loc, given_msg) = mk_given (cec_encl ctxt)
; dflags <- getDynFlags
; mkEqErr_help dflags ctxt (given_msg $$ binds_msg)
@@ -591,7 +592,7 @@ mkEqErr1 ctxt ct
Nothing ty1 ty2 }
| otherwise -- Wanted or derived
- = do { (ctxt, binds_msg) <- relevantBindings ctxt ct
+ = do { (ctxt, binds_msg) <- relevantBindings True ctxt ct
; (ctxt, tidy_orig) <- zonkTidyOrigin ctxt (ctLocOrigin (cc_loc ct))
; let (is_oriented, wanted_msg) = mk_wanted_extra tidy_orig
; dflags <- getDynFlags
@@ -931,7 +932,7 @@ mk_dict_err :: ReportErrCtxt -> (Ct, ClsInstLookupResult)
mk_dict_err ctxt (ct, (matches, unifiers, safe_haskell))
| null matches -- No matches but perhaps several unifiers
= do { let (is_ambig, ambig_msg) = mkAmbigMsg ct
- ; (ctxt, binds_msg) <- relevantBindings ctxt ct
+ ; (ctxt, binds_msg) <- relevantBindings True ctxt ct
; traceTc "mk_dict_err" (ppr ct $$ ppr is_ambig $$ ambig_msg)
; return (ctxt, cannot_resolve_msg is_ambig binds_msg ambig_msg) }
@@ -1171,17 +1172,25 @@ getSkolemInfo (implic:implics) tv
-- careful to zonk the Id's type first, so it has to be in the monad.
-- We must be careful to pass it a zonked type variable, too.
-relevantBindings :: ReportErrCtxt -> Ct
+relevantBindings :: Bool -- True <=> filter by tyvar; False <=> no filtering
+ -- See Trac #8191
+ -> ReportErrCtxt -> Ct
-> TcM (ReportErrCtxt, SDoc)
-relevantBindings ctxt ct
- = do { (tidy_env', docs) <- go (cec_tidy ctxt) (6, emptyVarSet)
- (reverse (tcl_bndrs lcl_env))
+relevantBindings want_filtering ctxt ct
+ = do { dflags <- getDynFlags
+ ; (tidy_env', docs, discards)
+ <- go (cec_tidy ctxt) (maxRelevantBinds dflags)
+ emptyVarSet [] False
+ (reverse (tcl_bndrs lcl_env))
-- The 'reverse' makes us work from outside in
- -- Blargh; maybe have a flag for this "6"
; traceTc "relevantBindings" (ppr [id | TcIdBndr id _ <- tcl_bndrs lcl_env])
; let doc = hang (ptext (sLit "Relevant bindings include"))
- 2 (vcat docs)
+ 2 (vcat docs $$ max_msg)
+ max_msg | discards
+ = ptext (sLit "(Some bindings suppressed; use -fmax-relevant-binds=N or -fno-max-relevant-binds)")
+ | otherwise = empty
+
; if null docs
then return (ctxt, empty)
else do { traceTc "rb" doc
@@ -1190,28 +1199,38 @@ relevantBindings ctxt ct
lcl_env = ctLocEnv (cc_loc ct)
ct_tvs = tyVarsOfCt ct
- go :: TidyEnv -> (Int, TcTyVarSet)
- -> [TcIdBinder] -> TcM (TidyEnv, [SDoc])
- go tidy_env (_,_) []
- = return (tidy_env, [])
- go tidy_env (n_left,tvs_seen) (TcIdBndr id _ : tc_bndrs)
- | n_left <= 0, ct_tvs `subVarSet` tvs_seen
- = -- We have run out of n_left, and we
- -- already have bindings mentioning all of ct_tvs
- go tidy_env (n_left,tvs_seen) tc_bndrs
- | otherwise
+ run_out :: Maybe Int -> Bool
+ run_out Nothing = False
+ run_out (Just n) = n <= 0
+
+ dec_max :: Maybe Int -> Maybe Int
+ dec_max = fmap (\n -> n - 1)
+
+ go :: TidyEnv -> Maybe Int -> TcTyVarSet -> [SDoc] -> Bool
+ -> [TcIdBinder]
+ -> TcM (TidyEnv, [SDoc], Bool) -- The bool says if we filtered any out
+ -- because of lack of fuel
+ go tidy_env _ _ docs discards []
+ = return (tidy_env, reverse docs, discards)
+ go tidy_env n_left tvs_seen docs discards (TcIdBndr id _ : tc_bndrs)
= do { (tidy_env', tidy_ty) <- zonkTidyTcType tidy_env (idType id)
; let id_tvs = tyVarsOfType tidy_ty
doc = sep [ pprPrefixOcc id <+> dcolon <+> ppr tidy_ty
, nest 2 (parens (ptext (sLit "bound at")
<+> ppr (getSrcLoc id)))]
- ; if id_tvs `intersectsVarSet` ct_tvs
- && (n_left > 0 || not (id_tvs `subVarSet` tvs_seen))
- -- Either we n_left is big enough,
- -- or this binding mentions a new type variable
- then do { (env', docs) <- go tidy_env' (n_left - 1, tvs_seen `unionVarSet` id_tvs) tc_bndrs
- ; return (env', doc:docs) }
- else go tidy_env (n_left, tvs_seen) tc_bndrs }
+ new_seen = tvs_seen `unionVarSet` id_tvs
+
+ ; if (want_filtering && id_tvs `disjointVarSet` ct_tvs)
+ -- We want to filter out this binding anyway
+ then go tidy_env n_left tvs_seen docs discards tc_bndrs
+
+ else if run_out n_left && id_tvs `subVarSet` tvs_seen
+ -- We've run out of n_left fuel and this binding only
+ -- mentions aleady-seen type variables, so discard it
+ then go tidy_env n_left tvs_seen docs True tc_bndrs
+
+ -- Keep this binding, decrement fuel
+ else go tidy_env' (dec_max n_left) new_seen (doc:docs) discards tc_bndrs }
-----------------------
warnDefaulting :: Cts -> Type -> TcM ()
diff --git a/docs/users_guide/flags.xml b/docs/users_guide/flags.xml
index 03252c26a3..18f8beb563 100644
--- a/docs/users_guide/flags.xml
+++ b/docs/users_guide/flags.xml
@@ -1501,7 +1501,7 @@
<sect2>
<title>Optimisation levels</title>
- <para><xref linkend="options-optimise"/></para>
+ <para>These options are described in more detail in <xref linkend="options-optimise"/></para>
<informaltable>
<tgroup cols="4" align="left" colsep="1" rowsep="1">
@@ -1531,10 +1531,10 @@
</informaltable>
</sect2>
- <sect2>
+ <sect2 id="options-f-compact">
<title>Individual optimisations</title>
- <para><xref linkend="options-f"/></para>
+ <para>These options are described in more detail in <xref linkend="options-f"/>.</para>
<informaltable>
<tgroup cols="4" align="left" colsep="1" rowsep="1">
@@ -1558,7 +1558,7 @@
<entry><option>-fcse</option></entry>
<entry>Turn on common sub-expression elimination. Implied by <option>-O</option>.</entry>
<entry>dynamic</entry>
- <entry>-fno-cse</entry>
+ <entry><option>-fno-cse</option></entry>
</row>
<row>
@@ -1634,14 +1634,14 @@
<entry><option>-ffloat-in</option></entry>
<entry>Turn on the float-in transformation. Implied by <option>-O</option>.</entry>
<entry>dynamic</entry>
- <entry>-fno-float-in</entry>
+ <entry><option>-fno-float-in</option></entry>
</row>
<row>
<entry><option>-ffull-laziness</option></entry>
<entry>Turn on full laziness (floating bindings outwards). Implied by <option>-O</option>.</entry>
<entry>dynamic</entry>
- <entry>-fno-full-laziness</entry>
+ <entry><option>-fno-full-laziness</option></entry>
</row>
<row>
@@ -1673,14 +1673,21 @@
</row>
<row>
- <entry><option>-fmax-simplifier-iterations</option></entry>
+ <entry><option>-fmax-relevant-bindings=N</option></entry>
+ <entry>Set the maximum number of bindings to display in type error messages (default 6).</entry>
+ <entry>dynamic</entry>
+ <entry><option>-fno-max-relevant-bindings</option></entry>
+ </row>
+
+ <row>
+ <entry><option>-fmax-simplifier-iterations=N</option></entry>
<entry>Set the max iterations for the simplifier</entry>
<entry>dynamic</entry>
<entry>-</entry>
</row>
<row>
- <entry><option>-fmax-worker-args</option></entry>
+ <entry><option>-fmax-worker-args=N</option></entry>
<entry>If a worker has that many arguments, none will be
unpacked anymore (default: 10)</entry>
<entry>dynamic</entry>
@@ -1744,7 +1751,7 @@
<entry><option>-fspec-constr</option></entry>
<entry>Turn on the SpecConstr transformation. Implied by <option>-O2</option>.</entry>
<entry>dynamic</entry>
- <entry>-fno-spec-constr</entry>
+ <entry><option>-fno-spec-constr</option></entry>
</row>
<row>
@@ -1767,14 +1774,14 @@
<entry><option>-fspecialise</option></entry>
<entry>Turn on specialisation of overloaded functions. Implied by <option>-O</option>.</entry>
<entry>dynamic</entry>
- <entry>-fno-specialise</entry>
+ <entry><option>-fno-specialise</option></entry>
</row>
<row>
<entry><option>-fstrictness</option></entry>
<entry>Turn on strictness analysis. Implied by <option>-O</option>.</entry>
<entry>dynamic</entry>
- <entry>-fno-strictness</entry>
+ <entry><option>-fno-strictness</option></entry>
</row>
<row>
@@ -1789,7 +1796,7 @@
<entry><option>-fstatic-argument-transformation</option></entry>
<entry>Turn on the static argument transformation. Implied by <option>-O2</option>.</entry>
<entry>dynamic</entry>
- <entry>-fno-static-argument-transformation</entry>
+ <entry><option>-fno-static-argument-transformation</option></entry>
</row>
<row>
diff --git a/docs/users_guide/using.xml b/docs/users_guide/using.xml
index 7540279504..4440eec7dd 100644
--- a/docs/users_guide/using.xml
+++ b/docs/users_guide/using.xml
@@ -1885,12 +1885,59 @@ f "2" = 2
them explicitly (indeed, doing so could lead to unexpected
results). A flag <option>-fwombat</option> can be negated by
saying <option>-fno-wombat</option>. The flags below are off
- by default, except where noted below.
+ by default, except where noted below. See <xref linkend="options-f-compact"/>
+ for a compact list.
</para>
<variablelist>
<varlistentry>
<term>
+ <option>-favoid-vect</option>
+ <indexterm><primary><option></option></primary></indexterm>
+ </term>
+ <listitem>
+ <para>Part of <link linkend="dph">Data Parallel Haskell
+ (DPH)</link>.</para>
+
+ <para><emphasis>Off by default.</emphasis> Enable the
+ <emphasis>vectorisation</emphasis> avoidance optimisation. This
+ optimisation only works when used in combination with the
+ <option>-fvectorise</option> transformation.</para>
+
+ <para>While vectorisation of code using DPH is often a big win, it
+ can also produce worse results for some kinds of code. This
+ optimisation modifies the vectorisation transformation to try to
+ determine if a function would be better of unvectorised and if
+ so, do just that.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>-fcase-merge</option>
+ <indexterm><primary><option></option></primary></indexterm>
+ </term>
+ <listitem>
+ <para><emphasis>On by default.</emphasis>
+ Merge immediately-nested case expressions that scrutinse the same variable. Example
+<programlisting>
+ case x of
+ Red -> e1
+ _ -> case x of
+ Blue -> e2
+ Green -> e3
+==>
+ case x of
+ Red -> e1
+ Blue -> e2
+ Green -> e2
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
<option>-fcse</option>
<indexterm><primary><option>-fcse</option></primary></indexterm>
</term>
@@ -1904,170 +1951,88 @@ f "2" = 2
<varlistentry>
<term>
- <option>-fstrictness</option>
+ <option>-fdicts-cheap</option>
<indexterm><primary><option></option></primary></indexterm>
</term>
<listitem>
- <para> <emphasis>On by default.</emphasis>.
- Switch on the strictness analyser. There is a very old paper about GHC's
- strictness analyser, <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/simple-strictnes-analyser.ps.gz">
- Measuring the effectiveness of a simple strictness analyser</ulink>,
- but the current one is quite a bit different.
- </para>
-
- <para>The strictness analyser figures out when arguments and
- variables in a function can be treated 'strictly' (that is they
- are always evaluated in the function at some point). This allow
- GHC to apply certain optimisations such as unboxing that
- otherwise don't apply as they change the semantics of the program
- when applied to lazy arguments.
+ <para>A very experimental flag that makes dictionary-valued
+ expressions seem cheap to the optimiser.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-funbox-strict-fields</option>:
- <indexterm><primary><option>-funbox-strict-fields</option></primary></indexterm>
- <indexterm><primary>strict constructor fields</primary></indexterm>
- <indexterm><primary>constructor fields, strict</primary></indexterm>
+ <option>-fdo-lambda-eta-expansion</option>
+ <indexterm><primary><option></option></primary></indexterm>
</term>
<listitem>
- <para>This option causes all constructor fields which are marked
- strict (i.e. &ldquo;!&rdquo;) to be unpacked if possible. It is
- equivalent to adding an <literal>UNPACK</literal> pragma to every
- strict constructor field (see <xref linkend="unpack-pragma"/>).
+ <para><emphasis>On by default.</emphasis>
+ Eta-expand let-bindings to increase their arity.
</para>
-
- <para>This option is a bit of a sledgehammer: it might sometimes
- make things worse. Selectively unboxing fields by using
- <literal>UNPACK</literal> pragmas might be better. An alternative
- is to use <option>-funbox-strict-fields</option> to turn on
- unboxing by default but disable it for certain constructor
- fields using the <literal>NOUNPACK</literal> pragma (see
- <xref linkend="nounpack-pragma"/>).</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-funbox-small-strict-fields</option>:
- <indexterm><primary><option>-funbox-small-strict-fields</option></primary></indexterm>
- <indexterm><primary>strict constructor fields</primary></indexterm>
- <indexterm><primary>constructor fields, strict</primary></indexterm>
+ <option>-fdo-eta-reduction</option>
+ <indexterm><primary><option></option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>On by default.</emphasis>. This option
- causes all constructor fields which are marked strict
- (i.e. &ldquo;!&rdquo;) and which representation is smaller
- or equal to the size of a pointer to be unpacked, if
- possible. It is equivalent to adding an
- <literal>UNPACK</literal> pragma (see <xref
- linkend="unpack-pragma"/>) to every strict constructor
- field that fulfils the size restriction.
- </para>
-
- <para>For example, the constructor fields in the following
- data types
-<programlisting>
-data A = A !Int
-data B = B !A
-newtype C = C B
-data D = D !C
-</programlisting>
- would all be represented by a single
- <literal>Int#</literal> (see <xref linkend="primitives"/>)
- value with
- <option>-funbox-small-strict-fields</option> enabled.
- </para>
-
- <para>This option is less of a sledgehammer than
- <option>-funbox-strict-fields</option>: it should rarely make things
- worse. If you use <option>-funbox-small-strict-fields</option>
- to turn on unboxing by default you can disable it for certain
- constructor fields using the <literal>NOUNPACK</literal> pragma (see
- <xref linkend="nounpack-pragma"/>).</para>
-
- <para>
- Note that for consistency <literal>Double</literal>,
- <literal>Word64</literal>, and <literal>Int64</literal> constructor
- fields are unpacked on 32-bit platforms, even though they are
- technically larger than a pointer on those platforms.
+ <para><emphasis>On by default.</emphasis>
+ Eta-reduce lambda expressions, if doing so gets rid of a whole
+ group of lambdas.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fspec-constr</option>
- <indexterm><primary><option>-fspec-constr</option></primary></indexterm>
+ <option>-feager-blackholing</option>
+ <indexterm><primary><option></option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>Off by default, but enabled by -O2.</emphasis>
- Turn on call-pattern specialisation; see
- <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/spec-constr/index.htm">
- Call-pattern specialisation for Haskell programs</ulink>.
- </para>
-
- <para>This optimisation specializes recursive functions according to
- their argument "shapes". This is best explained by example so
- consider:
-<programlisting>
-last :: [a] -> a
-last [] = error "last"
-last (x : []) = x
-last (x : xs) = last xs
-</programlisting>
- In this code, once we pass the initial check for an empty list we
- know that in the recursive case this pattern match is redundant. As
- such <option>-fspec-constr</option> will transform the above code
- to:
-<programlisting>
-last :: [a] -> a
-last [] = error "last"
-last (x : xs) = last' x xs
- where
- last' x [] = x
- last' x (y : ys) = last' y ys
-</programlisting>
- </para>
-
- <para>As well avoid unnecessary pattern matching it also helps avoid
- unnecessary allocation. This applies when a argument is strict in
- the recursive call to itself but not on the initial entry. As
- strict recursive branch of the function is created similar to the
- above example.
+ <para>Usually GHC black-holes a thunk only when it switches
+ threads. This flag makes it do so as soon as the thunk is
+ entered. See <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/parallel/">
+ Haskell on a shared-memory multiprocessor</ulink>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fspecialise</option>
- <indexterm><primary><option>-fspecialise</option></primary></indexterm>
+ <option>-fexcess-precision</option>
+ <indexterm><primary><option>-fexcess-precision</option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>On by default.</emphasis>
- Specialise each type-class-overloaded function defined in this
- module for the types at which it is called in this module. Also
- specialise imported functions that have an INLINABLE pragma
- (<xref linkend="inlinable-pragma"/>) for the types at which they
- are called in this module.
+ <para>When this option is given, intermediate floating
+ point values can have a <emphasis>greater</emphasis>
+ precision/range than the final type. Generally this is a
+ good thing, but some programs may rely on the exact
+ precision/range of
+ <literal>Float</literal>/<literal>Double</literal> values
+ and should not use this option for their compilation.</para>
+
+ <para>
+ Note that the 32-bit x86 native code generator only
+ supports excess-precision mode, so neither
+ <option>-fexcess-precision</option> nor
+ <option>-fno-excess-precision</option> has any effect.
+ This is a known bug, see <xref linkend="bugs-ghc" />.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fstatic-argument-transformation</option>
- <indexterm><primary><option>-fstatic-argument-transformation</option></primary></indexterm>
+ <option>-fexpose-all-unfoldings</option>
+ <indexterm><primary><option></option></primary></indexterm>
</term>
<listitem>
- <para>Turn on the static argument transformation, which turns a
- recursive function into a non-recursive one with a local
- recursive loop. See Chapter 7 of
- <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/santos-thesis.ps.gz">
- Andre Santos's PhD thesis</ulink>
+ <para>An experimental flag to expose all unfoldings, even for very
+ large or recursive functions. This allows for all functions to be
+ inlined while usually GHC would avoid inlining larger functions.
</para>
</listitem>
</varlistentry>
@@ -2130,50 +2095,45 @@ last (x : xs) = last' x xs
<varlistentry>
<term>
- <option>-fdo-lambda-eta-expansion</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>--ffun-to-thunk</option>
+ <indexterm><primary><option>-fignore-asserts</option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>On by default.</emphasis>
- Eta-expand let-bindings to increase their arity.
+ <para>Worker-wrapper removes unused arguments, but usually we
+ do not remove them all, lest it turn a function closure into a thunk,
+ thereby perhaps causing extra allocation (since let-no-escape can't happen)
+ and/or a space leak. This flag
+ allows worker/wrapper to remove <emphasis>all</emphasis> value lambdas.
+ Off by default.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fdo-eta-reduction</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>-fignore-asserts</option>
+ <indexterm><primary><option>-fignore-asserts</option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>On by default.</emphasis>
- Eta-reduce lambda expressions, if doing so gets rid of a whole
- group of lambdas.
+ <para>Causes GHC to ignore uses of the function
+ <literal>Exception.assert</literal> in source code (in
+ other words, rewriting <literal>Exception.assert p
+ e</literal> to <literal>e</literal> (see <xref
+ linkend="assertions"/>). This flag is turned on by
+ <option>-O</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fcase-merge</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>-fignore-interface-pragmas</option>
+ <indexterm><primary><option>-fignore-interface-pragmas</option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>On by default.</emphasis>
- Merge immediately-nested case expressions that scrutinse the same variable. Example
-<programlisting>
- case x of
- Red -> e1
- _ -> case x of
- Blue -> e2
- Green -> e3
-==>
- case x of
- Red -> e1
- Blue -> e2
- Green -> e2
-</programlisting>
- </para>
+ <para>Tells GHC to ignore all inessential information when reading interface files.
+ That is, even if <filename>M.hi</filename> contains unfolding or strictness information
+ for a function, GHC will ignore that information.</para>
</listitem>
</varlistentry>
@@ -2195,26 +2155,25 @@ last (x : xs) = last' x xs
<varlistentry>
<term>
- <option>-fdicts-cheap</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>-fliberate-case-threshold=N</option>
+ <indexterm><primary><option>-fliberate-case-threshold</option></primary></indexterm>
</term>
<listitem>
- <para>A very experimental flag that makes dictionary-valued
- expressions seem cheap to the optimiser.
+ <para>Set the size threshold for the liberate-case transformation.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-feager-blackholing</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>-fmax-relevant-bindings=N</option>
+ <indexterm><primary><option>-fmax-relevant-bindings</option></primary></indexterm>
</term>
<listitem>
- <para>Usually GHC black-holes a thunk only when it switches
- threads. This flag makes it do so as soon as the thunk is
- entered. See <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/parallel/">
- Haskell on a shared-memory multiprocessor</ulink>.
+ <para>The type checker sometimes displays a fragment of the type environment
+ in error messages, but only up to some maximum number, set by this flag.
+ The default is 6. Turning it off with <option>-fno-max-relevant-bindings</option>
+ gives an unlimited number.
</para>
</listitem>
</varlistentry>
@@ -2236,6 +2195,42 @@ last (x : xs) = last' x xs
<varlistentry>
<term>
+ <option>-fomit-interface-pragmas</option>
+ <indexterm><primary><option>-fomit-interface-pragmas</option></primary></indexterm>
+ </term>
+ <listitem>
+ <para>Tells GHC to omit all inessential information from the
+ interface file generated for the module being compiled (say M).
+ This means that a module importing M will see only the
+ <emphasis>types</emphasis> of the functions that M exports, but
+ not their unfoldings, strictness info, etc. Hence, for example,
+ no function exported by M will be inlined into an importing module.
+ The benefit is that modules that import M will need to be
+ recompiled less often (only when M's exports change their type, not
+ when they change their implementation).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>-fomit-yields</option>
+ <indexterm><primary><option>-fomit-yields</option></primary></indexterm>
+ </term>
+ <listitem>
+ <para><emphasis>On by default.</emphasis> Tells GHC to omit
+ heap checks when no allocation is being performed. While this improves
+ binary sizes by about 5%, it also means that threads run in
+ tight non-allocating loops will not get preempted in a timely
+ fashion. If it is important to always be able to interrupt such
+ threads, you should turn this optimization off. Consider also
+ recompiling all libraries with this optimization turned off, if you
+ need to guarantee interruptibility.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
<option>-fpedantic-bottoms</option>
<indexterm><primary><option>-fpedantic-bottoms</option></primary></indexterm>
</term>
@@ -2251,6 +2246,38 @@ last (x : xs) = last' x xs
<varlistentry>
<term>
+ <option>-fregs-graph</option>
+ <indexterm><primary><option></option></primary></indexterm>
+ </term>
+ <listitem>
+ <para><emphasis>Off by default, but enabled by -O2. Only applies in
+ combination with the native code generator.</emphasis>
+ Use the graph colouring register allocator for register allocation
+ in the native code generator. By default, GHC uses a simpler,
+ faster linear register allocator. The downside being that the
+ linear register allocator usually generates worse code.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>-fregs-iterative</option>
+ <indexterm><primary><option></option></primary></indexterm>
+ </term>
+ <listitem>
+ <para><emphasis>Off by default, only applies in combination with
+ the native code generator.</emphasis>
+ Use the iterative coalescing graph colouring register allocator for
+ register allocation in the native code generator. This is the same
+ register allocator as the <option>-freg-graph</option> one but also
+ enables iterative coalescing during register allocation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
<option>-fsimpl-tick-factor=<replaceable>n</replaceable></option>
<indexterm><primary><option>-fsimpl-tick-factor</option></primary></indexterm>
</term>
@@ -2332,19 +2359,6 @@ last (x : xs) = last' x xs
<varlistentry>
<term>
- <option>-fexpose-all-unfoldings</option>
- <indexterm><primary><option></option></primary></indexterm>
- </term>
- <listitem>
- <para>An experimental flag to expose all unfoldings, even for very
- large or recursive functions. This allows for all functions to be
- inlined while usually GHC would avoid inlining larger functions.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
<option>-fvectorise</option>
<indexterm><primary><option></option></primary></indexterm>
</term>
@@ -2363,142 +2377,170 @@ last (x : xs) = last' x xs
<varlistentry>
<term>
- <option>-favoid-vect</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>-fspec-constr</option>
+ <indexterm><primary><option>-fspec-constr</option></primary></indexterm>
</term>
<listitem>
- <para>Part of <link linkend="dph">Data Parallel Haskell
- (DPH)</link>.</para>
+ <para><emphasis>Off by default, but enabled by -O2.</emphasis>
+ Turn on call-pattern specialisation; see
+ <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/spec-constr/index.htm">
+ Call-pattern specialisation for Haskell programs</ulink>.
+ </para>
- <para><emphasis>Off by default.</emphasis> Enable the
- <emphasis>vectorisation</emphasis> avoidance optimisation. This
- optimisation only works when used in combination with the
- <option>-fvectorise</option> transformation.</para>
+ <para>This optimisation specializes recursive functions according to
+ their argument "shapes". This is best explained by example so
+ consider:
+<programlisting>
+last :: [a] -> a
+last [] = error "last"
+last (x : []) = x
+last (x : xs) = last xs
+</programlisting>
+ In this code, once we pass the initial check for an empty list we
+ know that in the recursive case this pattern match is redundant. As
+ such <option>-fspec-constr</option> will transform the above code
+ to:
+<programlisting>
+last :: [a] -> a
+last [] = error "last"
+last (x : xs) = last' x xs
+ where
+ last' x [] = x
+ last' x (y : ys) = last' y ys
+</programlisting>
+ </para>
- <para>While vectorisation of code using DPH is often a big win, it
- can also produce worse results for some kinds of code. This
- optimisation modifies the vectorisation transformation to try to
- determine if a function would be better of unvectorised and if
- so, do just that.</para>
+ <para>As well avoid unnecessary pattern matching it also helps avoid
+ unnecessary allocation. This applies when a argument is strict in
+ the recursive call to itself but not on the initial entry. As
+ strict recursive branch of the function is created similar to the
+ above example.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fregs-graph</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>-fspecialise</option>
+ <indexterm><primary><option>-fspecialise</option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>Off by default, but enabled by -O2. Only applies in
- combination with the native code generator.</emphasis>
- Use the graph colouring register allocator for register allocation
- in the native code generator. By default, GHC uses a simpler,
- faster linear register allocator. The downside being that the
- linear register allocator usually generates worse code.
+ <para><emphasis>On by default.</emphasis>
+ Specialise each type-class-overloaded function defined in this
+ module for the types at which it is called in this module. Also
+ specialise imported functions that have an INLINABLE pragma
+ (<xref linkend="inlinable-pragma"/>) for the types at which they
+ are called in this module.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fregs-iterative</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>-fstatic-argument-transformation</option>
+ <indexterm><primary><option>-fstatic-argument-transformation</option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>Off by default, only applies in combination with
- the native code generator.</emphasis>
- Use the iterative coalescing graph colouring register allocator for
- register allocation in the native code generator. This is the same
- register allocator as the <option>-freg-graph</option> one but also
- enables iterative coalescing during register allocation.
+ <para>Turn on the static argument transformation, which turns a
+ recursive function into a non-recursive one with a local
+ recursive loop. See Chapter 7 of
+ <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/santos-thesis.ps.gz">
+ Andre Santos's PhD thesis</ulink>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fexcess-precision</option>
- <indexterm><primary><option>-fexcess-precision</option></primary></indexterm>
+ <option>-fstrictness</option>
+ <indexterm><primary><option></option></primary></indexterm>
</term>
<listitem>
- <para>When this option is given, intermediate floating
- point values can have a <emphasis>greater</emphasis>
- precision/range than the final type. Generally this is a
- good thing, but some programs may rely on the exact
- precision/range of
- <literal>Float</literal>/<literal>Double</literal> values
- and should not use this option for their compilation.</para>
+ <para> <emphasis>On by default.</emphasis>.
+ Switch on the strictness analyser. There is a very old paper about GHC's
+ strictness analyser, <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/simple-strictnes-analyser.ps.gz">
+ Measuring the effectiveness of a simple strictness analyser</ulink>,
+ but the current one is quite a bit different.
+ </para>
- <para>
- Note that the 32-bit x86 native code generator only
- supports excess-precision mode, so neither
- <option>-fexcess-precision</option> nor
- <option>-fno-excess-precision</option> has any effect.
- This is a known bug, see <xref linkend="bugs-ghc" />.
+ <para>The strictness analyser figures out when arguments and
+ variables in a function can be treated 'strictly' (that is they
+ are always evaluated in the function at some point). This allow
+ GHC to apply certain optimisations such as unboxing that
+ otherwise don't apply as they change the semantics of the program
+ when applied to lazy arguments.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fignore-asserts</option>
- <indexterm><primary><option>-fignore-asserts</option></primary></indexterm>
+ <option>-funbox-strict-fields</option>:
+ <indexterm><primary><option>-funbox-strict-fields</option></primary></indexterm>
+ <indexterm><primary>strict constructor fields</primary></indexterm>
+ <indexterm><primary>constructor fields, strict</primary></indexterm>
</term>
<listitem>
- <para>Causes GHC to ignore uses of the function
- <literal>Exception.assert</literal> in source code (in
- other words, rewriting <literal>Exception.assert p
- e</literal> to <literal>e</literal> (see <xref
- linkend="assertions"/>). This flag is turned on by
- <option>-O</option>.
+ <para>This option causes all constructor fields which are marked
+ strict (i.e. &ldquo;!&rdquo;) to be unpacked if possible. It is
+ equivalent to adding an <literal>UNPACK</literal> pragma to every
+ strict constructor field (see <xref linkend="unpack-pragma"/>).
</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>
- <option>-fignore-interface-pragmas</option>
- <indexterm><primary><option>-fignore-interface-pragmas</option></primary></indexterm>
- </term>
- <listitem>
- <para>Tells GHC to ignore all inessential information when reading interface files.
- That is, even if <filename>M.hi</filename> contains unfolding or strictness information
- for a function, GHC will ignore that information.</para>
+ <para>This option is a bit of a sledgehammer: it might sometimes
+ make things worse. Selectively unboxing fields by using
+ <literal>UNPACK</literal> pragmas might be better. An alternative
+ is to use <option>-funbox-strict-fields</option> to turn on
+ unboxing by default but disable it for certain constructor
+ fields using the <literal>NOUNPACK</literal> pragma (see
+ <xref linkend="nounpack-pragma"/>).</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fomit-interface-pragmas</option>
- <indexterm><primary><option>-fomit-interface-pragmas</option></primary></indexterm>
+ <option>-funbox-small-strict-fields</option>:
+ <indexterm><primary><option>-funbox-small-strict-fields</option></primary></indexterm>
+ <indexterm><primary>strict constructor fields</primary></indexterm>
+ <indexterm><primary>constructor fields, strict</primary></indexterm>
</term>
<listitem>
- <para>Tells GHC to omit all inessential information from the
- interface file generated for the module being compiled (say M).
- This means that a module importing M will see only the
- <emphasis>types</emphasis> of the functions that M exports, but
- not their unfoldings, strictness info, etc. Hence, for example,
- no function exported by M will be inlined into an importing module.
- The benefit is that modules that import M will need to be
- recompiled less often (only when M's exports change their type, not
- when they change their implementation).</para>
- </listitem>
- </varlistentry>
+ <para><emphasis>On by default.</emphasis>. This option
+ causes all constructor fields which are marked strict
+ (i.e. &ldquo;!&rdquo;) and which representation is smaller
+ or equal to the size of a pointer to be unpacked, if
+ possible. It is equivalent to adding an
+ <literal>UNPACK</literal> pragma (see <xref
+ linkend="unpack-pragma"/>) to every strict constructor
+ field that fulfils the size restriction.
+ </para>
- <varlistentry>
- <term>
- <option>-fomit-yields</option>
- <indexterm><primary><option>-fomit-yields</option></primary></indexterm>
- </term>
- <listitem>
- <para><emphasis>On by default.</emphasis> Tells GHC to omit
- heap checks when no allocation is being performed. While this improves
- binary sizes by about 5%, it also means that threads run in
- tight non-allocating loops will not get preempted in a timely
- fashion. If it is important to always be able to interrupt such
- threads, you should turn this optimization off. Consider also
- recompiling all libraries with this optimization turned off, if you
- need to guarantee interruptibility.
+ <para>For example, the constructor fields in the following
+ data types
+<programlisting>
+data A = A !Int
+data B = B !A
+newtype C = C B
+data D = D !C
+</programlisting>
+ would all be represented by a single
+ <literal>Int#</literal> (see <xref linkend="primitives"/>)
+ value with
+ <option>-funbox-small-strict-fields</option> enabled.
+ </para>
+
+ <para>This option is less of a sledgehammer than
+ <option>-funbox-strict-fields</option>: it should rarely make things
+ worse. If you use <option>-funbox-small-strict-fields</option>
+ to turn on unboxing by default you can disable it for certain
+ constructor fields using the <literal>NOUNPACK</literal> pragma (see
+ <xref linkend="nounpack-pragma"/>).</para>
+
+ <para>
+ Note that for consistency <literal>Double</literal>,
+ <literal>Word64</literal>, and <literal>Int64</literal> constructor
+ fields are unpacked on 32-bit platforms, even though they are
+ technically larger than a pointer on those platforms.
</para>
</listitem>
</varlistentry>