Skip to content

Simplifier improvements, esp avoiding unnecessary iteration

This ticket started when I noted that the simplifier was taking two iterations when one would do, but that led me down a long rabbit hole. Here are the things I found:

  • Consider

       case K e of K y{Occ=Once} -> blah

    Since y occurs just once in blah we can do preInlineUnconditionally when we eliminate the case. We weren't doing that.

  • We were repeatedly simplify coercions, some of which were big. This happened when we have

       let f = \x. ...|> co....
       in ...

    and then inline f, where f is big. We don't want to re-simplify co each time we inline f. Once is enough!

  • Suppose we have

    data K a = MkK !a
    
    $WMkK x = case x of y -> K y   -- Wrapper for MkK
    
    ...case $WMkK v of K w -> <rhs>

    We call exprIsConApp_maybe on ($WMkK v); we inline the wrapper and beta-reduce, so we get to

     exprIsConApp_maybe (case v of y -> K y)

    So we may float the case, and end up with

    case v of y -> <rhs>[y/w]

    But if v is already evaluated, the next run of the Simplifier will eliminate the case, and we may then make more progress with <rhs>. Better to do it in one iteration.

  • We make join point that are so small that we immediately inline them again. Silly.

  • There is also a long-running but hard-to-describe saga about how to inline join points. If you are too eager, you get exponential blowup. I ran into more of this when I was in the rabbit hole.

Edited by Simon Peyton Jones
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information