[GHC] #14338: Simplifier fails with "Simplifier ticks exhausted"
GHC
ghc-devs at haskell.org
Tue Jan 2 15:51:27 UTC 2018
#14338: Simplifier fails with "Simplifier ticks exhausted"
-------------------------------------+-------------------------------------
Reporter: dredozubov | Owner: bgamari
Type: bug | Status: new
Priority: high | Milestone: 8.4.1
Component: Compiler | Version: 8.2.1
Resolution: | Keywords:
Operating System: Linux | Architecture: x86_64
Type of failure: Compile-time | (amd64)
crash or panic | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by simonpj):
Going from 1,500 to 75,000 ticks is stunning. Thank you for locating the
offenting patch.
I spent some while digging. Here's what I learned
* Discarding `(case e of co -> blah)` is indeed unsound, unless we know
that `e` terminates, so Richard's patch in #11230 is right.
* But his patch does not say why the remaining "optimisation" (which works
for superclass selectors over a `Coercible` dictionary) is sound. And
indeed, it is not; in Core I could produce a bottoming `Coercible`
dictionary. This "optimsation" in `CoreOpt` is all in service of `Note
[Getting the map/coerce RULE to work]`, and I'm not sure how important
that is.
* I was also perplexed that in the case of #11230 the coericon involved
seemed to be dead. The code is
{{{
testPhantom :: Phantom Char -> Phantom Bool
testPhantom x = id x
}}}
which should generate something like
{{{
data Wag x = MkWag ()
type role Wag phantom
testPhantom x = let co :: Wag Char ~ Wag Bool = error "blah"
in id @(PhantomChar) x |> co
}}}
so that coercion `co` certainly isn't dead! But what happens is this.
We actually generate
{{{
testPhantom x = let co :: Char ~# Bool = error "blah"
in id @(PhantomChar) x |> mkSubCo (Wag co)
}}}
where the `mkSubCo` turns a nominal coercion `Char ~# Bool` into a
representational one. Rather than just generate `SubCo` always, it pushes
the sub inwards. Because of the role of `Wag`, we then want to turn the
nominal `co` into a phantom version, via `downgradeRole`. But (currently)
that dicards `co` (retaining only its kind) -- see `Coecion.toPhantomCo`
-- so now `co` appears to be dead. This seems wrong to me; the (nominal-
equality) evidence really is needed and should really still be free in the
result.
That's one set of issues. Now, returning to this ticket:
* The perf changes in this ticket are presumably because of `HEq_sc`
selections, as reported in #13032.
* And here the evidence really is not needed!
* And hence it's really wrong to force the dictionary; that makes the
function stricter (in its dictionary argument) than it should be. (As
well as less efficient.)
Solution: do not generate all these speculative "given" bindings in the
first place. Instead, in the desugarer, figure out which given bindings
are needed, and only emit those ones. That will generate less code --
perhaps a lot less in some exotic programs -- and be better all round.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14338#comment:29>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list