| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
| |
No change in behaviour here, just some modest
refactoring as I tried to understand the code
better.
|
| |
|
|
|
|
|
|
|
|
|
| |
* (+++) --> andUDs
* combineAltsUsageDetails --> orUDs
* combineUsageDetailsList --> andUDsList
* Change some andUDsList to a fold for efficiency
No change in behaviour
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
While addressing nonlinear behavior related to coercion roles,
particularly `NthCo`, we noticed that coercion roles are recalculated
often even though they should be readily at hand already in most cases.
This patch adds a `Role` to the `NthCo` constructor so that we can cache
them rather than having to recalculate them on the fly.
https://ghc.haskell.org/trac/ghc/ticket/11735#comment:23 explains the
approach.
Performance improvement over GHC HEAD, when compiling Grammar.hs (see below):
GHC 8.2.1:
```
ghc Grammar.hs 176.27s user 0.23s system 99% cpu 2:56.81 total
```
before patch (but with other optimizations applied):
```
ghc Grammar.hs -fforce-recomp 175.77s user 0.19s system 100% cpu 2:55.78 total
```
after:
```
../../ghc/inplace/bin/ghc-stage2 Grammar.hs 10.32s user 0.17s system 98% cpu 10.678 total
```
Introduces the following regressions:
- perf/compiler/parsing001 (possibly false positive)
- perf/compiler/T9872
- perf/compiler/haddock.base
Reviewers: goldfire, bgamari, simonpj
Reviewed By: simonpj
Subscribers: rwbarton, thomie, carter
GHC Trac Issues: #11735
Differential Revision: https://phabricator.haskell.org/D4394
|
| |
|
|
|
|
|
|
|
| |
because `captured :: [Var]` is always in dependency order.
I added a comment in the crucial point so that this does not trip us up
again.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
as helpfully outlined by SPJ.
This commit copies a small bit code from `SetLevels` which could
reasonably be put in `Id` as `zapAllIdinfo`; I did not do this to make
merging this commmit into `ghc-8.4` easier.
If this commit gets merged, then presumably after commit
3f59d3802170f495702674b4f8e4e80247803654 (test case) and
ae0cff0a1834d8b041b06d0e1ab6ce969aac44c8 (other fixes to Exitify.hs).
Differential Revision: https://phabricator.haskell.org/D4582
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Trac #14735 (derived from Trac #11735) found that 75% of compile
time was being spent in simplCast. This patch is the first in a series
to deal with that problem.
This particular patch actually has very little effect on performance; it
just refactors simplCast so that it builds Refl coercions less often.
Refl coercions require us to compute the type to put inside them, and
even if that's done lazily it is still work and code. Instead we use
Maybe Coercion with Nothing for Refl. This change also percolates to
pushCoTyArg and pushValArg.
Reviewers: goldfire, bgamari, simonpj
Reviewed By: simonpj
Subscribers: rwbarton, thomie, carter
GHC Trac Issues: #14737
Differential Revision: https://phabricator.haskell.org/D4395
|
|
|
|
|
|
|
|
|
|
|
|
| |
As the CSE transformation traverses the syntax tree, it needs to go past
the lambdas of a join point, and only look for CSE opportunities inside,
as a join point’s lambdas must be preserved. Simple fix; comes with a
Note and a test case.
Thanks to Ryan Scott for an excellently minimized test case, and for
bisecting GHC.
Differential Revision: https://phabricator.haskell.org/D4572
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
based on a thorough review by Simon in comments
https://ghc.haskell.org/trac/ghc/ticket/14152#comment:33
through 37.
The changes are:
* `isExitJoinId` is moved to `SimplUtils`, because
it is only valid when occurrence information is up-to-date.
* Abstracted variables are properly sorted using `sortQuantVars`
* Exitification does not set occ info.
And then minor quibles to notes and avoiding some unhelpful shadowing
of local names.
Differential Revision: https://phabricator.haskell.org/D4576
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Trac #13900 showed that when we have a join point that
has a RULE, we must push the continuation into the RHS
of the RULE.
See Note [Rules and unfolding for join points]
It's hard to tickle this bug, so I have not added a regression test.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
I found (when investigating Trac #14955) a binding looking like
Rec { exported_id = ....big...lcl_id...
; lcl_id = exported_id }
but bizarrely 'lcl_id' was chosen as the loop breaker, and never
inlined. It turned out to be an unintended consequence of the
shortOutIndirections code in SimplCore. Easily fixed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Runs another specialisation pass towards the end of the optimisation
pipeline. This can catch specialisation opportunities which arose from
the previous specialisation pass or other inlining.
You might want to use this if you are you have a type class method
which returns a constrained type. For example, a type class where one
of the methods implements a traversal.
It is not enabled by default or any optimisation level. Only by
manually enabling the flag `-flate-specialise`.
Reviewers: bgamari
Reviewed By: bgamari
Subscribers: rwbarton, thomie, carter
Differential Revision: https://phabricator.haskell.org/D4457
|
|
|
|
|
|
|
|
|
|
| |
Reviewers: bgamari
Reviewed By: bgamari
Subscribers: rwbarton, thomie, carter
Differential Revision: https://phabricator.haskell.org/D4255
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This reverts f5b275a239d2554c4da0b7621211642bf3b10650
and changes the places that looked for `Lit (MachStr _))`
to use `exprIsMbTickedLitString_maybe` to unwrap ticks as
necessary.
Also updated relevant comments.
Test Plan:
I added 3 new tests that previously reproduced.
GHC HEAD now builds with -g
Reviewers: simonpj, simonmar, bgamari, hvr, goldfire
Subscribers: rwbarton, thomie, carter
GHC Trac Issues: #14779
Differential Revision: https://phabricator.haskell.org/D4470
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This doesn't remedy problem, but at least it's more explicit than
the catch-all
Reviewers: bgamari
Reviewed By: bgamari
Subscribers: rwbarton, thomie, carter
GHC Trac Issues: #14544
Differential Revision: https://phabricator.haskell.org/D4435
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Summary: This is part of D4342 which is worthwhile to merge on its own.
Reviewers: nboldi, bgamari
Reviewed By: bgamari
Subscribers: rwbarton, thomie, carter
Differential Revision: https://phabricator.haskell.org/D4410
Co-authored-by: Boldizsar Nemeth <nboldi@elte.hu>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In prelRules we had:
tx_con_tte :: DynFlags -> AltCon -> AltCon
tx_con_tte _ DEFAULT = DEFAULT
tx_con_tte dflags (DataAlt dc)
| tag == 0 = DEFAULT -- See Note [caseRules for tagToEnum]
| otherwise = LitAlt (mkMachInt dflags (toInteger tag))
The tag==0 case is totally wrong, and led directly to Trac #14768.
See "Beware" in Note [caseRules for tagToEnum] (in the patch).
Easily fixed, though!
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When debugging Trac #14650, I found a place where we had
let {-# INLINEABLE f #-}
f = BIG
in f 7
but 'f' wasn't getting inlined at its unique call site.
There's a good reason for that with INLINE things, which
should only inline when saturated, but not for INILNEABLE
things.
This patch narrows the case where preInlineUnconditionally
gives up. It significantly shortens (and improves) the code
for #14650.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch moves the "ok_unfolding" test
from CoreOpt.joinPointBinding_maybe
to OccurAnal.decideJoinPointHood
Previously the occurrence analyser was deciding to make
something a join point, but the simplifier was reversing
that decision, which made the decision about /other/ bindings
invalid.
Fixes Trac #14650.
|
|
|
|
|
|
| |
The new comment explains why this warning can
legitimately fire, so I've removed it entirely.
Lint will cath any bad cases.
|
|
|
|
| |
...provked by #14620
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
| |
This patch fixes #14567. The idea is simple: if a function
is marked NOINLINE then it makes a great candidate for a loop
breaker.
Implementation is easy too, but it needs a little extra plubming,
notably the occ_unf_act field in OccEnv
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch, which fixes Trac #14566, makes LiberateCase a little
more conservative. In particular:
* In libCaseBind, treat a recursive group as a whole, rather than
binding-by-binding, allowing the group to be duplicated only if
- the bindings /considered together/ are smaller than the
liberate-case threshold (which is large by default)
- none of them are thunks
- none of them are guaranteed-diverging
The latter condidtion is new, and happens to apply in the
case of Data/Typeable/Internal.mkTrApp
|
| |
|
|
|
|
|
|
|
|
|
| |
This patch fixes Trac #14408. The problem was that the StaticEnv
field of an ApplyToVar or Select continuation didn't have enough
variables in scope. The fix is simple, and I documented the
invariant in Note [StaticEnv invariant] in SimplUtils.
No change in behaviour: this just stops an ASSERT from tripping.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The idea is described in #14152, and can be summarized: Float the exit
path out of a joinrec, so that the simplifier can do more with it.
See the test case for a nice example.
The floating goes against what the simplifier usually does, hence we
need to be careful not inline them back.
The position of exitification in the pipeline was chosen after a small
amount of experimentation, but may need to be improved. For example,
exitification can allow rewrite rules to fire, but for that it would
have to happen before the `simpl_phases`.
Perf.haskell.org reports these nice performance wins:
Nofib allocations
fannkuch-redux 78446640 - 99.92% 64560
k-nucleotide 109466384 - 91.32% 9502040
simple 72424696 - 5.96% 68109560
Nofib instruction counts
fannkuch-redux 1744331636 - 3.86% 1676999519
k-nucleotide 2318221965 - 6.30% 2172067260
scs 1978470869 - 3.35% 1912263779
simple 669858104 - 3.38% 647206739
spectral-norm 186423292 - 5.37% 176411536
Differential Revision: https://phabricator.haskell.org/D3903
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously, (since 33452df), simplNonRecJoinPoint would do the wrong
thing in the presence of shadowing: It analyzed the RHS of a join
binding with the environment for the body. In particular, with
foo x =
join x = x * x
in x
where there is shadowing, it renames the inner x to x1, and should
produce
foo x =
join x1 = x * x
in x1
but because the substitution (x ↦ x1) is also used on the RHS we get the
bogus
foo x =
join x1 = x1 * x1
in x1
Fixed this by adding a `rhs_se` parameter, analogous to `simplNonRecE`
and `simplLazyBind`.
Differential Revision: https://phabricator.haskell.org/D4130
|
| |
|
|
|
|
|
|
|
|
| |
This bug was exposed by Trac #14270. The problem and its cure
is described in SetLevels, Note [Floating and kind casts].
It's simple and will affect very few programs. But the very
fact that it was so unexpected is discomforting.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This dark corner was exposed by Trac #14285. It involves the
interaction between absence analysis and INLINABLE pragmas.
There is a full explanation in Note [aBSENT_ERROR_ID] in MkCore,
which you can read there. The changes in this patch are
* Make exprIsHNF return True for absentError, treating
absentError like an honorary data constructor.
* Make absentError /not/ be diverging, unlike other error Ids.
This is all a bit horrible.
* While doing this I found that exprOkForSpeculation didn't
have a case for value lambdas so I added one. It's not
really called on lifted types much, but it seems like the
right thing
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This switches the compiler/ component to get compiled with
-XNoImplicitPrelude and a `import GhcPrelude` is inserted in all
modules.
This is motivated by the upcoming "Prelude" re-export of
`Semigroup((<>))` which would cause lots of name clashes in every
modulewhich imports also `Outputable`
Reviewers: austin, goldfire, bgamari, alanz, simonmar
Reviewed By: bgamari
Subscribers: goldfire, rwbarton, thomie, mpickering, bgamari
Differential Revision: https://phabricator.haskell.org/D3989
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In general ticks are problematic for join point analysis as described
in #14242. However, source notes are intended to be a best-effort
annotation which shouldn't interfere with optimization. Special-case
these to ensure that tail-call information is still correct, even in the
presence of source note
ticks.
Test Plan: Validate
Reviewers: simonpj, austin
Reviewed By: simonpj
Subscribers: rwbarton, thomie
GHC Trac Issues: #14242
Differential Revision: https://phabricator.haskell.org/D3978
|
|
|
|
|
|
|
|
| |
the worker/wrapper creates an artificial INLINE pragma, which caused CSE
to not do its work. We now recognize such artificial pragmas by using
`NoUserInline` instead of `Inline` as the `InlineSpec`.
Differential Revision: https://phabricator.haskell.org/D3939
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously SetLevels.lvlMFE would fail to substitute in ticks, unlike
lvlExpr. This lead to #13481. Fix this.
Test Plan: `make test TEST=T12622 WAY=ghci`
Reviewers: austin, simonpj
Reviewed By: simonpj
Subscribers: simonpj, rwbarton, thomie
GHC Trac Issues: #13481
Differential Revision: https://phabricator.haskell.org/D3920
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We pretty-print a type by converting it to an IfaceType and
pretty-printing that. But
(a) that's a bit indirect, and
(b) delibrately loses information about (e.g.) the kind
on the /occurrences/ of a type variable
So this patch implements debugPprType, which pretty prints
the type directly, with no fancy formatting. It's just used
for debugging.
I took the opportunity to refactor the debug-pretty-printing
machinery a little. In particular, define these functions
and use them:
ifPprDeubug :: SDoc -> SDOc -> SDoc
-- Says what to do with and without -dppr-debug
whenPprDebug :: SDoc -> SDoc
-- Says what to do with -dppr-debug; without is empty
getPprDebug :: (Bool -> SDoc) -> SDoc
getPprDebug used to be called sdocPprDebugWith
whenPprDebug used to be called ifPprDebug
So a lot of files get touched in a very mechanical way
|
|
|
|
|
|
| |
This minor change fixes Trac #14137.
It is described in Note [Join point RHSs] in OccurAnal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Triggered by #12150, and the knock-on effects of join points, I did a
major refactoring of the Simplifier. This is a big patch that change
a lot of Simplify.hs: I did a lot of other re-organisation.
The main event
~~~~~~~~~~~~~~
Since the dawn of time we have had
simplExpr :: SimplEnv -> InExpr -> SimplCont
-> SimplM (SimplEnv, OutExpr)
What's that SimplEnv in the result? When simplifying an expression the
simplifier add floated let-bindings to the SimplEnv, extending the
in-scope set appropriately, and hence needs to resturn the SimplEnv at
the end. The mode, flags, substitution in the returned SimplEnv were
all irrelevant: it was just the floating bindings.
It's strange to accumulate part of the /result/ in the /environment/
argument! And indeed its leads to all manner of mysterious calls to
zapFloats and transferring of floats from one SimplEnv to another.
It got worse with join points, so I finally bit the bullet and refactored.
Now we have
simplExpr :: SimplEnv -> InExpr -> SimplCont
-> SimplM (SimplFloats, OutExpr)
-- See Note [The big picture]
and the SimplEnv no longer has floats in it. The code is no shorter,
but it /is/ easier to understand.
Main changes
* Remove seLetFloats field from SimplEnv
* Define new data type SimplFloats, and functions over it
* Change the types of simplExpr, simplBind, and their many variants,
to follow the above plan
Bottoming bindings
~~~~~~~~~~~~~~~~~~
I made one other significant change in SimplUtils (not just refactoring),
related to Trac #12150 comment:16. Given
x = <rhs>
where <rhs> turns out to be a bottoming expression, propagate that
information to x's IdInfo immediately. That's always good, because
it makes x be inlined less (we don't inline bottoming things), and
it allows (case x of ...) to drop the dead alterantives immediately.
Moreover, we are doing the analysis anyway, in tryEtaExpandRhs, which
calls CoreArity.findRhsArity, which already does simple bottom analysis.
So we are generating the information; all we need do is to atach the
bottoming info to the IdInfo.
See Note [Bottoming bindings]
Smaller refactoring
~~~~~~~~~~~~~~~~~~~
* Rename SimplifierMode to SimplMode
* Put DynFlags as a new field in SimplMode, to make fewer
monadic calls to getDynFlags.
* Move the code in addPolyBind into abstractFloats
* Move the "don't eta-expand join points" into tryEtaExpandRhs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch changes isExpandableApp and isWorkFreeApp to respond
False to bottoming applications. I found that if we had
x = undefined <dict-expr>
then prepareRhs was ANF'ing it to
d = <dict-expr>
x = undefined d
which is stupid (no gain); and worse it made the simplifier iterate
indefinitely. It showed up when I started marking 'x' as a bottoming
Id more aggresssively than before; but it's been a lurking bug for
ages.
It was convenient to make isWorkFreeApp also return False for
bottoming applications, and I see no reason not to do so.
That leaves isCheapApp. It currently replies True to bottoming
applications, but I don't see why that's good.. Something to try
later.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Consider
case x of y
DEFAULT -> let v::Int# = case y of
True -> e1
False -> e2
in ...
Previously this would have been ok-for-speculation because
y is evaluated. But the binder-swap done
by SetLevels would transform the inner alternative to
DEFAULT -> let v::Int# = case x of { ... }
in ...)
which does /not/ satisfy the let/app invariant, because x is
not evaluated.
I don't know why this has never bitten us before, but it began
to bite when I did upcoming refactoring of the Simplifier.
So this patch narrows exprOkForSpeculation to only work for
/unlifted/ cases.
To make this work I had to make exprOkForSpeculation non-polymorphic
in the binder type, which has a little knock-on for is use in
SetLevels.
(It's annoying that we need to handle cases at all, but see
Note [exprOkForSpeculation: case expressions])
|