| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Roman found situations where he had
case (f n) of _ -> e
where he knew that f (which was strict in n) would terminate if n did.
Notice that the result of (f n) is discarded. So it makes sense to
transform to
case n of _ -> e
Rather than attempt some general analysis to support this, I've added
enough support that you can do this using a rewrite rule:
RULE "f/seq" forall n. seq (f n) e = seq n e
You write that rule. When GHC sees a case expression that discards
its result, it mentally transforms it to a call to 'seq' and looks for
a RULE. (This is done in Simplify.rebuildCase.) As usual, the
correctness of the rule is up to you.
This patch implements the extra stuff. I have not documented it explicitly
in the user manual yet... let's see how useful it is first.
The patch looks bigger than it is, because
a) Comments; see esp MkId Note [seqId magic]
b) Some refactoring. Notably, I moved the special desugaring for
seq from MkCore back into DsUtils where it properly belongs.
(It's really a desugaring thing, not a CoreSyn invariant.)
c) Annoyingly, in a RULE left-hand side we need to be careful that
the magical desugaring done in MkId Note [seqId magic] item (c)
is *not* done on the LHS of a rule. Or rather, we arrange to
un-do it, in DsBinds.decomposeRuleLhs.
|
|
|
|
|
|
|
| |
This patch fixes a rather obscure bug, whereby it's possible
for (case C a b of <alts>) to have altenatives that do not inclue
(C a b)! See Note [Unreachable code] in CoreUtils.
|
|
|
|
|
|
|
|
|
| |
It turns out that, as a result of a change I made a few months ago to
the representation of SimplCont, it's easy to solve the optimisation
challenge posed by Trac #3116. Hurrah.
Extensive comments in Note [Duplicating StrictArg].
|
|
|
|
|
|
|
|
| |
This patch makes the specialiser propagate arities a bit more
eagerly, which avoids a spurious warning in the simplifier.
See Note [Arity decrease] in Simplify.lhs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch adds an optional CONLIKE modifier to INLINE/NOINLINE pragmas,
{-# NOINLINE CONLIKE [1] f #-}
The effect is to allow applications of 'f' to be expanded in a potential
rule match. Example
{-# RULE "r/f" forall v. r (f v) = f (v+1) #-}
Consider the term
let x = f v in ..x...x...(r x)...
Normally the (r x) would not match the rule, because GHC would be scared
about duplicating the redex (f v). However the CONLIKE modifier says to
treat 'f' like a constructor in this situation, and "look through" the
unfolding for x. So (r x) fires, yielding (f (v+1)).
The main changes are:
- Syntax
- The inlinePragInfo field of an IdInfo has a RuleMatchInfo
component, which records whether or not the Id is CONLIKE.
Of course, this needs to be serialised in interface files too.
- The occurrence analyser (OccAnal) and simplifier (Simplify) treat
CONLIKE thing like constructors, by ANF-ing them
- New function coreUtils.exprIsExpandable is like exprIsCheap, but
additionally spots applications of CONLIKE functions
- A CoreUnfolding has a field that caches exprIsExpandable
- The rule matcher consults this field. See
Note [Expanding variables] in Rules.lhs.
On the way I fixed a lurking variable bug in the way variables are
expanded. See Note [Do not expand locally-bound variables] in
Rule.lhs. I also did a bit of reformatting and refactoring in
Rules.lhs, so the module has more lines changed than are really
different.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch does two main things
a) Rewrite most of CorePrep to be much easier to understand (I hope!).
The invariants established by CorePrep are now written out, and
the code is more perspicuous. It is surpringly hard to get right,
and the old code had become quite incomprehensible.
b) Rewrite the eta-expander so that it does a bit of simplifying
on-the-fly, and thereby guarantees to maintain the CorePrep
invariants. This make it much easier to use from CorePrep, and
is a generally good thing anyway.
A couple of pieces of re-structuring:
* I moved the eta-expander and arity analysis stuff into a new
module coreSyn/CoreArity.
Max will find that the type CoreArity.EtaInfo looks strangely
familiar.
* I moved a bunch of comments from Simplify to OccurAnal; that's
why it looks as though there's a lot of lines changed in those
modules.
On the way I fixed various things
- Function arguments are eta expanded
f (map g) ===> let s = \x. map g x in f s
- Trac #2368
The result is a modest performance gain, I think mainly due
to the first of these changes:
--------------------------------------------------------------------------------
Program Size Allocs Runtime Elapsed
--------------------------------------------------------------------------------
Min -1.0% -17.4% -19.1% -46.4%
Max +0.3% +0.5% +5.4% +53.8%
Geometric Mean -0.1% -0.3% -7.0% -10.2%
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
rolling back:
Fri Dec 5 10:51:59 GMT 2008 simonpj@microsoft.com
* Add -fpass-case-bndr-to-join-points
See Note [Passing the case binder to join points] in Simplify.lhs
The default now is *not* to pass the case binder. There are some
nofib results with the above note; the effect is almost always
negligible.
I don't expect this flag to be used by users (hence no docs). It's just
there to let me try the performance effects of switching on and off.
M ./compiler/main/StaticFlagParser.hs +1
M ./compiler/main/StaticFlags.hs +4
M ./compiler/simplCore/Simplify.lhs -14 +73
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
rolling back:
Fri Dec 5 16:54:00 GMT 2008 simonpj@microsoft.com
* Completely new treatment of INLINE pragmas (big patch)
This is a major patch, which changes the way INLINE pragmas work.
Although lots of files are touched, the net is only +21 lines of
code -- and I bet that most of those are comments!
HEADS UP: interface file format has changed, so you'll need to
recompile everything.
There is not much effect on overall performance for nofib,
probably because those programs don't make heavy use of INLINE pragmas.
Program Size Allocs Runtime Elapsed
Min -11.3% -6.9% -9.2% -8.2%
Max -0.1% +4.6% +7.5% +8.9%
Geometric Mean -2.2% -0.2% -1.0% -0.8%
(The +4.6% for on allocs is cichelli; see other patch relating to
-fpass-case-bndr-to-join-points.)
The old INLINE system
~~~~~~~~~~~~~~~~~~~~~
The old system worked like this. A function with an INLINE pragam
got a right-hand side which looked like
f = __inline_me__ (\xy. e)
The __inline_me__ part was an InlineNote, and was treated specially
in various ways. Notably, the simplifier didn't inline inside an
__inline_me__ note.
As a result, the code for f itself was pretty crappy. That matters
if you say (map f xs), because then you execute the code for f,
rather than inlining a copy at the call site.
The new story: InlineRules
~~~~~~~~~~~~~~~~~~~~~~~~~~
The new system removes the InlineMe Note altogether. Instead there
is a new constructor InlineRule in CoreSyn.Unfolding. This is a
bit like a RULE, in that it remembers the template to be inlined inside
the InlineRule. No simplification or inlining is done on an InlineRule,
just like RULEs.
An Id can have an InlineRule *or* a CoreUnfolding (since these are two
constructors from Unfolding). The simplifier treats them differently:
- An InlineRule is has the substitution applied (like RULES) but
is otherwise left undisturbed.
- A CoreUnfolding is updated with the new RHS of the definition,
on each iteration of the simplifier.
An InlineRule fires regardless of size, but *only* when the function
is applied to enough arguments. The "arity" of the rule is specified
(by the programmer) as the number of args on the LHS of the "=". So
it makes a difference whether you say
{-# INLINE f #-}
f x = \y -> e or f x y = e
This is one of the big new features that InlineRule gives us, and it
is one that Roman really wanted.
In contrast, a CoreUnfolding can fire when it is applied to fewer
args than than the function has lambdas, provided the result is small
enough.
Consequential stuff
~~~~~~~~~~~~~~~~~~~
* A 'wrapper' no longer has a WrapperInfo in the IdInfo. Instead,
the InlineRule has a field identifying wrappers.
* Of course, IfaceSyn and interface serialisation changes appropriately.
* Making implication constraints inline nicely was a bit fiddly. In
the end I added a var_inline field to HsBInd.VarBind, which is why
this patch affects the type checker slightly
* I made some changes to the way in which eta expansion happens in
CorePrep, mainly to ensure that *arguments* that become let-bound
are also eta-expanded. I'm still not too happy with the clarity
and robustness fo the result.
* We now complain if the programmer gives an INLINE pragma for
a recursive function (prevsiously we just ignored it). Reason for
change: we don't want an InlineRule on a LoopBreaker, because then
we'd have to check for loop-breaker-hood at occurrence sites (which
isn't currenlty done). Some tests need changing as a result.
This patch has been in my tree for quite a while, so there are
probably some other minor changes.
M ./compiler/basicTypes/Id.lhs -11
M ./compiler/basicTypes/IdInfo.lhs -82
M ./compiler/basicTypes/MkId.lhs -2 +2
M ./compiler/coreSyn/CoreFVs.lhs -2 +25
M ./compiler/coreSyn/CoreLint.lhs -5 +1
M ./compiler/coreSyn/CorePrep.lhs -59 +53
M ./compiler/coreSyn/CoreSubst.lhs -22 +31
M ./compiler/coreSyn/CoreSyn.lhs -66 +92
M ./compiler/coreSyn/CoreUnfold.lhs -112 +112
M ./compiler/coreSyn/CoreUtils.lhs -185 +184
M ./compiler/coreSyn/MkExternalCore.lhs -1
M ./compiler/coreSyn/PprCore.lhs -4 +40
M ./compiler/deSugar/DsBinds.lhs -70 +118
M ./compiler/deSugar/DsForeign.lhs -2 +4
M ./compiler/deSugar/DsMeta.hs -4 +3
M ./compiler/hsSyn/HsBinds.lhs -3 +3
M ./compiler/hsSyn/HsUtils.lhs -2 +7
M ./compiler/iface/BinIface.hs -11 +25
M ./compiler/iface/IfaceSyn.lhs -13 +21
M ./compiler/iface/MkIface.lhs -24 +19
M ./compiler/iface/TcIface.lhs -29 +23
M ./compiler/main/TidyPgm.lhs -55 +49
M ./compiler/parser/ParserCore.y -5 +6
M ./compiler/simplCore/CSE.lhs -2 +1
M ./compiler/simplCore/FloatIn.lhs -6 +1
M ./compiler/simplCore/FloatOut.lhs -23
M ./compiler/simplCore/OccurAnal.lhs -36 +5
M ./compiler/simplCore/SetLevels.lhs -59 +54
M ./compiler/simplCore/SimplCore.lhs -48 +52
M ./compiler/simplCore/SimplEnv.lhs -26 +22
M ./compiler/simplCore/SimplUtils.lhs -28 +4
M ./compiler/simplCore/Simplify.lhs -91 +109
M ./compiler/specialise/Specialise.lhs -15 +18
M ./compiler/stranal/WorkWrap.lhs -14 +11
M ./compiler/stranal/WwLib.lhs -2 +2
M ./compiler/typecheck/Inst.lhs -1 +3
M ./compiler/typecheck/TcBinds.lhs -17 +27
M ./compiler/typecheck/TcClassDcl.lhs -1 +2
M ./compiler/typecheck/TcExpr.lhs -4 +6
M ./compiler/typecheck/TcForeign.lhs -1 +1
M ./compiler/typecheck/TcGenDeriv.lhs -14 +13
M ./compiler/typecheck/TcHsSyn.lhs -3 +2
M ./compiler/typecheck/TcInstDcls.lhs -5 +4
M ./compiler/typecheck/TcRnDriver.lhs -2 +11
M ./compiler/typecheck/TcSimplify.lhs -10 +17
M ./compiler/vectorise/VectType.hs +7
Mon Dec 8 12:43:10 GMT 2008 simonpj@microsoft.com
* White space only
M ./compiler/simplCore/Simplify.lhs -2
Mon Dec 8 12:48:40 GMT 2008 simonpj@microsoft.com
* Move simpleOptExpr from CoreUnfold to CoreSubst
M ./compiler/coreSyn/CoreSubst.lhs -1 +87
M ./compiler/coreSyn/CoreUnfold.lhs -72 +1
Mon Dec 8 17:30:18 GMT 2008 simonpj@microsoft.com
* Use CoreSubst.simpleOptExpr in place of the ad-hoc simpleSubst (reduces code too)
M ./compiler/deSugar/DsBinds.lhs -50 +16
Tue Dec 9 17:03:02 GMT 2008 simonpj@microsoft.com
* Fix Trac #2861: bogus eta expansion
Urghlhl! I "tided up" the treatment of the "state hack" in CoreUtils, but
missed an unexpected interaction with the way that a bottoming function
simply swallows excess arguments. There's a long
Note [State hack and bottoming functions]
to explain (which accounts for most of the new lines of code).
M ./compiler/coreSyn/CoreUtils.lhs -16 +53
Mon Dec 15 10:02:21 GMT 2008 Simon Marlow <marlowsd@gmail.com>
* Revert CorePrep part of "Completely new treatment of INLINE pragmas..."
The original patch said:
* I made some changes to the way in which eta expansion happens in
CorePrep, mainly to ensure that *arguments* that become let-bound
are also eta-expanded. I'm still not too happy with the clarity
and robustness fo the result.
Unfortunately this change apparently broke some invariants that were
relied on elsewhere, and in particular lead to panics when compiling
with profiling on.
Will re-investigate in the new year.
M ./compiler/coreSyn/CorePrep.lhs -53 +58
M ./configure.ac -1 +1
Mon Dec 15 12:28:51 GMT 2008 Simon Marlow <marlowsd@gmail.com>
* revert accidental change to configure.ac
M ./configure.ac -1 +1
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is a major patch, which changes the way INLINE pragmas work.
Although lots of files are touched, the net is only +21 lines of
code -- and I bet that most of those are comments!
HEADS UP: interface file format has changed, so you'll need to
recompile everything.
There is not much effect on overall performance for nofib,
probably because those programs don't make heavy use of INLINE pragmas.
Program Size Allocs Runtime Elapsed
Min -11.3% -6.9% -9.2% -8.2%
Max -0.1% +4.6% +7.5% +8.9%
Geometric Mean -2.2% -0.2% -1.0% -0.8%
(The +4.6% for on allocs is cichelli; see other patch relating to
-fpass-case-bndr-to-join-points.)
The old INLINE system
~~~~~~~~~~~~~~~~~~~~~
The old system worked like this. A function with an INLINE pragam
got a right-hand side which looked like
f = __inline_me__ (\xy. e)
The __inline_me__ part was an InlineNote, and was treated specially
in various ways. Notably, the simplifier didn't inline inside an
__inline_me__ note.
As a result, the code for f itself was pretty crappy. That matters
if you say (map f xs), because then you execute the code for f,
rather than inlining a copy at the call site.
The new story: InlineRules
~~~~~~~~~~~~~~~~~~~~~~~~~~
The new system removes the InlineMe Note altogether. Instead there
is a new constructor InlineRule in CoreSyn.Unfolding. This is a
bit like a RULE, in that it remembers the template to be inlined inside
the InlineRule. No simplification or inlining is done on an InlineRule,
just like RULEs.
An Id can have an InlineRule *or* a CoreUnfolding (since these are two
constructors from Unfolding). The simplifier treats them differently:
- An InlineRule is has the substitution applied (like RULES) but
is otherwise left undisturbed.
- A CoreUnfolding is updated with the new RHS of the definition,
on each iteration of the simplifier.
An InlineRule fires regardless of size, but *only* when the function
is applied to enough arguments. The "arity" of the rule is specified
(by the programmer) as the number of args on the LHS of the "=". So
it makes a difference whether you say
{-# INLINE f #-}
f x = \y -> e or f x y = e
This is one of the big new features that InlineRule gives us, and it
is one that Roman really wanted.
In contrast, a CoreUnfolding can fire when it is applied to fewer
args than than the function has lambdas, provided the result is small
enough.
Consequential stuff
~~~~~~~~~~~~~~~~~~~
* A 'wrapper' no longer has a WrapperInfo in the IdInfo. Instead,
the InlineRule has a field identifying wrappers.
* Of course, IfaceSyn and interface serialisation changes appropriately.
* Making implication constraints inline nicely was a bit fiddly. In
the end I added a var_inline field to HsBInd.VarBind, which is why
this patch affects the type checker slightly
* I made some changes to the way in which eta expansion happens in
CorePrep, mainly to ensure that *arguments* that become let-bound
are also eta-expanded. I'm still not too happy with the clarity
and robustness fo the result.
* We now complain if the programmer gives an INLINE pragma for
a recursive function (prevsiously we just ignored it). Reason for
change: we don't want an InlineRule on a LoopBreaker, because then
we'd have to check for loop-breaker-hood at occurrence sites (which
isn't currenlty done). Some tests need changing as a result.
This patch has been in my tree for quite a while, so there are
probably some other minor changes.
|
|
|
|
|
|
|
|
|
|
|
| |
See Note [Passing the case binder to join points] in Simplify.lhs
The default now is *not* to pass the case binder. There are some
nofib results with the above note; the effect is almost always
negligible.
I don't expect this flag to be used by users (hence no docs). It's just
there to let me try the performance effects of switching on and off.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch does a lot of tidying up of the way that dead variables are
handled in Core. Just the sort of thing to do on an aeroplane.
* The tricky "binder-swap" optimisation is moved from the Simplifier
to the Occurrence Analyser. See Note [Binder swap] in OccurAnal.
This is really a nice change. It should reduce the number of
simplifier iteratoins (slightly perhaps). And it means that
we can be much less pessimistic about zapping occurrence info
on binders in a case expression.
* For example:
case x of y { (a,b) -> e }
Previously, each time around, even if y,a,b were all dead, the
Simplifier would pessimistically zap their OccInfo, so that we
can't see they are dead any more. As a result virtually no
case expression ended up with dead binders. This wasn't Bad
in itself, but it always felt wrong.
* I added a check to CoreLint to check that a dead binder really
isn't used. That showed up a couple of bugs in CSE. (Only in
this sense -- they didn't really matter.)
* I've changed the PprCore printer to print "_" for a dead variable.
(Use -dppr-debug to see it again.) This reduces clutter quite a
bit, and of course it's much more useful with the above change.
* Another benefit of the binder-swap change is that I could get rid of
the Simplifier hack (working, but hacky) in which the InScopeSet was
used to map a variable to a *different* variable. That allowed me
to remove VarEnv.modifyInScopeSet, and to simplify lookupInScopeSet
so that it doesn't look for a fixpoint. This fixes no bugs, but
is a useful cleanup.
* Roman pointed out that Id.mkWildId is jolly dangerous, because
of its fixed unique. So I've
- localied it to MkCore, where it is private (not exported)
- renamed it to 'mkWildBinder' to stress that you should only
use it at binding sites, unless you really know what you are
doing
- provided a function MkCore.mkWildCase that emodies the most
common use of mkWildId, and use that elsewhere
So things are much better
* A knock-on change is that I found a common pattern of localising
a potentially global Id, and made a function for it: Id.localiseId
|
| |
|
|
|
|
|
|
|
|
|
|
| |
This warning tests that the arity of a function does not decrease.
And that it's at least as great as the strictness signature.
Failing this test isn't a disater, but it's distinctly odd and
usually indicates that not enough information is getting propagated
around, and hence you may get more simplifier iterations.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
When binding x = e, we now attach an unfolding to 'x' even if
it won't be used because SimplGently is on.
Reason: the specialiser runs right after SimplGently, and it (now)
only gathers call information for calls whose dictionary arguments are
"interesting" -- i.e. have an unfolding of some kind.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch significantly improves the way in which recursive groups
are specialised. This turns out ot be very important when specilising
the bindings that (now) emerge from instance declarations.
Consider
let rec { f x = ...g x'...
; g y = ...f y'.... }
in f 'a'
Here we specialise 'f' at Char; but that is very likely to lead to
a specialisation of 'g' at Char. We must do the latter, else the
whole point of specialisation is lost. This was not happening before.
The whole thing is desribed in
Note [Specialising a recursive group]
Simon
|
| |
|
| |
|
|
|
|
| |
That's 1 line of new code and 38 lines of new comments
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This bug was somehow tickled by the new code for desugaring
polymorphic bindings, but the bug has been there a long time. The
bindings floated out in simplLazyBind, generated by abstractFloats,
were getting processed by postInlineUnconditionally. But that was
wrong because part of their scope has already been processed.
That led to a bit of refactoring in the simplifier. See comments
with Simplify.addPolyBind.
In principle this might happen in 6.8.3, but in practice it doesn't seem
to, so probably not worth merging.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch adds to Core the ability to say
let a = Int in <body>
where 'a' is a type variable. That is: a type-let.
See Note [Type let] in CoreSyn.
* The binding is always non-recursive
* The simplifier immediately eliminates it by substitution
So in effect a type-let is just a delayed substitution. This is convenient
in a couple of places in the desugarer, one existing (see the call to
CoreTyn.mkTyBind in DsUtils), and one that's in the next upcoming patch.
The first use in the desugarer was previously encoded as
(/\a. <body>) Int
rather that eagerly substituting, but that was horrid because Core Lint
had do "know" that a=Int inside <body> else it would bleat. Expressing
it directly as a 'let' seems much nicer.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Trac #2273 showed a case in which 'seq' didn't cure the space leak
it was supposed to. This patch does two things to help
a) It removes a now-redundant special case in Simplify, which
switched off the case-binder-swap in the early stages. This
isn't necessary any more because FloatOut has improved since
the Simplify code was written. And switching off the binder-swap
is harmful for seq.
However fix (a) is a bit fragile, so I did (b) too:
b) Desugar 'seq' specially. See Note [Desugaring seq (2)] in DsUtils
This isn't very robust either, since it's defeated by abstraction,
but that's not something GHC can fix; the programmer should use
a let! instead.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The main change in this patch is this:
* The Stop constructor of SimplCont no longer contains the OutType
of the whole continuation. This is a nice simplification in
lots of places where we build a Stop continuation. For example,
rebuildCall no longer needs to maintain the type of the function.
* Similarly StrictArg no longer needs an OutType
* The consequential complication is that contResultType (not called
much) needs to be given the type of the thing in the middle. No
big deal.
* Lots of other small knock-on effects
Other changes in here
* simplLazyBind does do the type-abstraction thing if there's
a lambda inside. See comments in simplLazyBind
* simplLazyBind reduces simplifier iterations by keeping
unfolding information for stuff for which type abstraction is
done (see add_poly_bind)
All of this came up when implementing System IF, but seems worth applying
to the HEAD
|
|
|
|
| |
Modules that need it import it themselves instead.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This adds back in the patch
* UNDO: Be a little keener to inline
It originally broke the compiler because it tickled a Cmm optimisation bug,
now fixed.
In revisiting this I have also make inlining a bit cleverer, in response to
more examples from Roman. In particular
* CoreUnfold.CallCtxt is a data type that tells something about
the context of a call. The new feature is that if the context is
the argument position of a function call, we record both
- whether the function (or some higher up function) has rules
- what the argument discount in that position is
Either of these make functions keener to inline, even if it's
in a lazy position
* There was conseqential tidying up on the data type of CallCont.
In particular I got rid of the now-unused LetRhsFlag
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The add_evals code in Simplify.simplAlt had bit-rotted. Example:
data T a = T !a
data U a = U !a
foo :: T a -> U a
foo (T x) = U x
Here we should not evaluate x before building the U result, because
the x argument of T is already evaluated.
Thanks to Roman for finding this.
|
|
|
|
|
|
|
|
|
|
|
|
| |
The ru_fn field was wrong when we moved RULES from one Id to another.
The fix is simple enough.
However, looking at this makes me realise that the worker/wrapper stuff
for recursive newtypes isn't very clever: we generate demand info but
then don't properly exploit it.
This patch fixes the crash though.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(No need to merge to 6.8, but no harm if a subsequent patch needs it.)
The proximate cause for this patch is to improve the inlining for INLINE
things that are not functions; this came up in the NDP project. See
Note [Lone variables] in CoreUnfold.
This caused some refactoring that actually made things simpler. In
particular, more of the inlining logic has moved from SimplUtils to
CoreUnfold, where it belongs.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In a typo I'd written env instead of env', and as a result RULES are
practically guaranteed not to work in a recursive group. This pretty
much kills SpecConstr in its tracks!
Well done Kenny Lu for spotting this. The fix is easy.
Merge into 6.8 please.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I got a Core Lint failure when compiling System.Win32.Info in the
Win32 package. It was very delicate: adding or removing a function
definition elsewhere in the module (unrelated to the error) made the
error go away.
Happily, I found it. In SimplUtils.prepareDefault I was comparing an
InId with an OutId. We were getting a spurious hit, and hence doing
a bogus CaseMerge.
This bug has been lurking ever since I re-factored the way that case
expressions were simplified, about 6 months ago!
|
|
|
|
|
|
|
|
|
|
| |
Don't re-add the worker info to a binder until completeBind. It's not
needed in its own RHS, and it may be replaced, via the substitution
following postInlineUnconditionally.
(Fixes build of the stage2 compiler which fell over when Coercion.lhs
was being compiled.)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(Merge to 6.8 branch after testing.)
There were a number of delicate interactions between RULEs and inlining
in GHC 6.6. I've wanted to fix this for a long time, and some perf
problems in the 6.8 release candidate finally forced me over the edge!
The issues are documented extensively in OccurAnal, Note [Loop breaking
and RULES], and I won't duplicate them here. (Many of the extra lines in
OccurAnal are comments!)
This patch resolves Trac bugs #1709, #1794, #1763, I believe.
|
| |
|
|
|
|
| |
MERGE TO STABLE
|
|
|
|
|
|
|
| |
See Note [Float coercions (unlifted)] in Simplify
Test is simpl018
|
| |
|
|
|
|
|
|
|
| |
Older GHCs can't parse OPTIONS_GHC.
This also changes the URL referenced for the -w options from
WorkingConventions#Warnings to CodingStyle#Warnings for the compiler
modules.
|
| |
|
|
|
|
|
|
|
|
| |
See the definition of splitInlineCont for what this is about.
Cures Trac #1627.
Test is simpl017
|
|
|
|
|
| |
See Note [Recursive rules] in OccurAnal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Roman produced programs involving associated types that did not optimise well.
His programs were something like this:
data family T a
data instance T Int = MkT Bool Char
bar :: T Int -> Int
bar t = t `seq` loop 0
where
loop = ...
You'd think that the `seq` should unbox 't' outside the loop, since
a (T Int) is just a MkT pair.
The most robust way to make this happen is for the simplifier to understand
a bit about type-family instances. See
Note [Improving seq]
in Simplify.lhs. We use FamInstEnv.topNormaliseType to do the interesting
work.
To make this happen I did a bit of refactoring to the simplifier
monad.
I'd previously done a very similar transformation in LiberateCase, but it
was happening too late. So this patch takes it out of LiberateCase as
well as adding it to Simplify.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch generalises the let-floating transformation in a way
suggested by Roman and Manuel when doing closure conversion.
There are extensive comments in Note [Floating and type abstraction],
which begins thus. Consider this:
x = /\a. C e1 e2
We'd like to float this to
y1 = /\a. e1
y2 = /\a. e2
x = /\a. C (y1 a) (y2 a)
for the usual reasons: we want to inline x rather vigorously.
(Further commennts follow in SimplUtils.)
The implementation is not hard; indeed it used to be in GHC years ago.
I removed it thinking that full laziness would achieve the same
effect, but I'm not sure it does; and in any case it seems more direct
to do it here.
The transformation should not make anything worse, so yell if
you see anything unexpected happening.
|