Skip to content

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 becomes tick 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
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information