
#11598: Cache coercion kinds and roles -------------------------------------+------------------------------------- Reporter: goldfire | Owner: goldfire Type: bug | Status: new Priority: normal | Milestone: 8.2.1 Component: Compiler | Version: 7.10.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Compile-time | Unknown/Multiple performance bug | Test Case: Blocked By: | Blocking: Related Tickets: #8095 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by goldfire): * failure: None/Unknown => Compile-time performance bug * milestone: => 8.2.1 Comment: I have made a real solid attempt at this, but I am giving up for now. My work is [https://github.com/goldfirere/ghc/tree/cache-coercion-kind here] (the cache-coercion-kind tag on my github fork). The code there has a roughly 10% slowdown on most of the `perf/compiler` performance tests, along with more drastic slowdowns on the `T9872x` tests. (It has a 16% improvement on `T5030`, though.) It is unclear to me where the slowdown is coming from. I have explored T9872d in some detail, though. It is slowed by the fact that phantom coercions are not always made anymore by `mkPhantomCo`. They can now be `SubCo Phantom`, too. This leads to a ton of work zonking a coercion hole proving a phantom equality. But I suspect phantoms are rare, and so this is not the cause of the general slowdown. Unfortunately, because `PhantomProv` needs a ''kind'' coercion, we are required to have `coercionRepKind` (a function that calculates an uncached kind). This is doable, of course, but I'm wary of sinking more time into this. It's quite possible that savings are realized only in concert with #8095, but the hour is too late for that. Just to record some thoughts on #8095: That ticket proposes looking at every `mkTcXXXCo` call to see if `-dcore-lint` is set and to drop coercions if not. I now think this is the wrong approach. Instead, let's use laziness: we just have to be careful about when `coercionRep`s are forced. As long as we never force them, we'll never have to calculate them. We should, when convenient, replace the thunked coercions with `OmittedCo` or something. For example, during zonking and simplification. And we'll need to write `OmittedCo` to interface files. But it shouldn't be too bad. To pull this off, we'll have to cache a few more things than my work already does: specifically, we'll need to cache the set of tycons mentioned in a coercion and whether or not the coercion is reflexive. I'm also worried about `Rules.match_co` which examines the structure of a coercion, so we may need a bit of re-engineering around that. This is a welcome problem, though, because the fact that `match_co` looks at coercions is just awful. Bottom line: I'm punting to 8.2, and lowering my expectations for performance improvements that will go into 8.0. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11598#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler