Terrible loss of optimisation in presence of ticks
Consider
case (error "blah") of BIG
You'd expect that to simplify to error "blah"
, or more precisely to case error "blah" of {}
. And usually it does.
But if there are ticks around it, it does not, and we retain
case (tick x (error "blah")) of BIG
The problem is in Simpify.simplTick
. It calls splitCont
which implements semantics I do not understand.
The Right Thing is surely this.
- Always push the tick onto the continuation
simplTick env tickish expr cont
= simplExprF env expr (mkTickIt tickish cont)
- Implement a suitable
mkTickIt
that pushes a tick past a continuation where possible. For example I think
mkTickIt t (ApplyTo arg cont) = ApplyTo arg (mkTickIt t cont)
That is
(tick t e) a
becomestick t (e a)
. It's probably conditioned on what sort of tick, but that's fine.
- The comments from
7bb0447d
(simonmar) say
-- XXX: we cannot do this, because the simplifier assumes that
-- the context can be pushed into a case with a single branch. e.g.
-- scc<f> case expensive of p -> e
-- becomes
-- case expensive of p -> scc<f> e
--
-- So I'm disabling this for now. It just means we will do more
But that's wrong. All we need to do is to ensure that
prepareCaseCont
always stops at the kind of tick we don't want to push inside.
- Finally, the bottom case of
rebuildCall
should retain ticks from the continuation.
Not too hard, but requires understanding of the semantics of ticks, which I do not have.
Trac metadata
Trac field | Value |
---|---|
Version | 8.0.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |