summaryrefslogtreecommitdiff
path: root/compiler/simplCore
Commit message (Collapse)AuthorAgeFilesLines
...
* Minor refactoring in ExitifySimon Peyton Jones2018-04-271-32/+39
| | | | | | No change in behaviour here, just some modest refactoring as I tried to understand the code better.
* Rename a local variableSimon Peyton Jones2018-04-271-2/+2
|
* Refactor in OccurAnalSimon Peyton Jones2018-04-271-28/+29
| | | | | | | | | * (+++) --> andUDs * combineAltsUsageDetails --> orUDs * combineUsageDetailsList --> andUDsList * Change some andUDsList to a fold for efficiency No change in behaviour
* Comments onlySimon Peyton Jones2018-04-272-2/+3
|
* Caching coercion roles in NthCo and coercionKindsRole refactoringTobias Dammers2018-04-201-30/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Minor comments in CSESimon Peyton Jones2018-04-171-8/+8
|
* No need for sortQuantVars in Exitify after allJoachim Breitner2018-04-111-6/+3
| | | | | | | 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.
* In Exitify, zap idInfo of abstracted variables (fixes #15005)Joachim Breitner2018-04-101-1/+8
| | | | | | | | | | | | | | 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
* Discard reflexive casts during SimplifyRichard Eisenberg2018-04-101-41/+48
| | | | | | | | | | | | | | | | | | | | | | | 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
* CSE: Walk past join point lambdas (#15002)Joachim Breitner2018-04-091-2/+32
| | | | | | | | | | | | 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
* Some cleanup of the Exitification codeJoachim Breitner2018-04-092-21/+36
| | | | | | | | | | | | | | | | | | 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
* Comments only, about exitifcationSimon Peyton Jones2018-04-063-15/+28
|
* Deal with join points with RULESSimon Peyton Jones2018-03-272-36/+86
| | | | | | | | | | 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.
* White space onlySimon Peyton Jones2018-03-271-0/+4
|
* Improve shortOutIndirections slightlySimon Peyton Jones2018-03-221-25/+36
| | | | | | | | | | | 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.
* Add -flate-specialise which runs a later specialisation passMatthew Pickering2018-03-191-0/+5
| | | | | | | | | | | | | | | | | | | | | 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
* Also check local rules with -frules-checkMatthew Pickering2018-03-191-2/+5
| | | | | | | | | | Reviewers: bgamari Reviewed By: bgamari Subscribers: rwbarton, thomie, carter Differential Revision: https://phabricator.haskell.org/D4255
* Allow top level ticked string literalsBartosz Nitka2018-03-064-31/+17
| | | | | | | | | | | | | | | | | | | | 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
* doCorePass: Expand catch-allSimon Jakobi2018-03-021-1/+7
| | | | | | | | | | | | | | | 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
* Only load plugins onceMatthew Pickering2018-03-021-27/+7
| | | | | | | | | | | | | | 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>
* Fix utterly bogus TagToEnum rule in caseRulesSimon Peyton Jones2018-02-071-3/+25
| | | | | | | | | | | | | | | | 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!
* Typos in commentsGabor Greif2018-01-172-2/+2
|
* preInlineUnconditionally is ok for INLINEABLESimon Peyton Jones2018-01-092-28/+43
| | | | | | | | | | | | | | | | | 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.
* Fix join-point decisionSimon Peyton Jones2018-01-091-11/+57
| | | | | | | | | | | | | 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.
* Remove a bogus warningSimon Peyton Jones2018-01-091-1/+6
| | | | | | The new comment explains why this warning can legitimately fire, so I've removed it entirely. Lint will cath any bad cases.
* Comments about join point typesSimon Peyton Jones2018-01-031-37/+4
| | | | ...provked by #14620
* Typos in commentsGabor Greif2017-12-212-3/+3
|
* Get rid of some stuttering in comments and docsGabor Greif2017-12-192-2/+2
|
* Typos in commentsGabor Greif2017-12-181-1/+1
|
* Occurrrence analysis improvements for NOINLINE functionsSimon Peyton Jones2017-12-084-34/+43
| | | | | | | | | 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
* Improve LiberateCaseSimon Peyton Jones2017-12-081-36/+54
| | | | | | | | | | | | | | | 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
* Comments only: Trac #14511Simon Peyton Jones2017-11-291-0/+10
|
* Fix in-scope set in simplifierSimon Peyton Jones2017-11-083-25/+56
| | | | | | | | | 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.
* Add Note [Setting the right in-scope set]Simon Peyton Jones2017-10-301-1/+26
|
* Implement a dedicated exitfication pass #14152Joachim Breitner2017-10-295-0/+456
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* simplNonRecJoinPoint: Handle Shadowing correctlyJoachim Breitner2017-10-291-5/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Fix grammaros in commentsGabor Greif2017-10-171-1/+1
|
* Avoid creating dependent types in FloatOutSimon Peyton Jones2017-10-111-20/+61
| | | | | | | | 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.
* Fix nasty bug in w/w for absence analysisSimon Peyton Jones2017-10-031-54/+44
| | | | | | | | | | | | | | | | | | | | 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
* A bunch of typofixesGabor Greif2017-09-262-4/+4
|
* compiler: introduce custom "GhcPrelude" PreludeHerbert Valerio Riedel2017-09-1914-3/+28
| | | | | | | | | | | | | | | | | | 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
* OccurAnal: Ensure SourceNotes don't interfere with join-point analysisBen Gamari2017-09-191-0/+7
| | | | | | | | | | | | | | | | | | | | | 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
* Allow CSE'ing of work-wrapped bindings (#14186)Joachim Breitner2017-09-121-2/+8
| | | | | | | | 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
* Fix typos in diagnostics, testsuite and commentsGabor Greif2017-09-072-2/+2
|
* SetLevels: Substitute in ticks in lvlMFEBen Gamari2017-09-051-1/+2
| | | | | | | | | | | | | | | | | 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
* Add debugPprTypeSimon Peyton Jones2017-08-312-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Don't do the RhsCtxt thing for join pointsSimon Peyton Jones2017-08-251-4/+20
| | | | | | This minor change fixes Trac #14137. It is described in Note [Join point RHSs] in OccurAnal
* Refactor the Mighty SimplifierSimon Peyton Jones2017-08-255-1130/+1127
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Bottoming expressions should not be expandableSimon Peyton Jones2017-08-251-5/+9
| | | | | | | | | | | | | | | | | | | | | | | | 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.
* Restrict exprOkForSpeculation/case to unlifted typesSimon Peyton Jones2017-08-251-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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])