Skip to content

Simplifier doing multiple iterations unnecessarily

When looking at the Simplifier, I came across a couple of places in which we were doing multiple Simplifier iterations where one would do.

I'm describing them here by quoting the Notes that I added when fixing them.

Strict data constructors

Note [Case elim in exprIsConApp_maybe]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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.  Hence the `do_case_elim`
check in `exprIsConApp_maybe`.

Used-one variables

Note [Post-inline for single-use things]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If we have

   let x = rhs in ...x...

and `x` is used exactly once, and not inside a lambda, then we will usually
preInlineUnconditinally. But we can still get this situation in
postInlineUnconditionally:

  case K rhs of K x -> ...x....

Here we'll use `simplAuxBind` to bind `x` to (the already-simplified) `rhs`;
and `x` is used exactly once.  It's beneficial to inline right away; otherwise
we risk creating

   let x = rhs in ...x...

which will take another iteration of the Simplifier to eliminate.  What a waste!

We take advantage of the used-once info in two places

1. In the full `postInlineUnconditionally` look for the special case
   of "one occurrence, not under a lambda", and inline unconditionally then.

2. `simplAuxBind` does a kind of poor-man's `postInlineUnconditionally`.  It
   does not need to account for many of the cases (e.g. top level) that the
   full `postInlineUnconditionally` does.  Moreover, we don't have an
   OutId, which `postInlineUnconditionally` needs.  I got a slight improvement
   in compiler performance when I added this test.
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information