Refactor the Mighty Simplifier
authorSimon Peyton Jones <simonpj@microsoft.com>
Fri, 25 Aug 2017 08:22:03 +0000 (09:22 +0100)
committerSimon Peyton Jones <simonpj@microsoft.com>
Fri, 25 Aug 2017 11:57:11 +0000 (12:57 +0100)
commit33452dfc6cf891b59d63fa9fe138b18cbce4df81
treee6cc85f4e02d0f792d3e44a28958b7261cf3fb44
parent407c11b880325f4f327982d4f6b9f9cba4564016
Refactor the Mighty Simplifier

Triggered by #12150, and the knock-on effects of join points, I did a
major refactoring of the Simplifier.  This is a big patch that change
a lot of Simplify.hs: I did a lot of other re-organisation.

The main event
~~~~~~~~~~~~~~
Since the dawn of time we have had
  simplExpr :: SimplEnv -> InExpr -> SimplCont
            -> SimplM (SimplEnv, OutExpr)

What's that SimplEnv in the result?  When simplifying an expression the
simplifier add floated let-bindings to the SimplEnv, extending the
in-scope set appropriately, and hence needs to resturn the SimplEnv at
the end.  The mode, flags, substitution in the returned SimplEnv were
all irrelevant: it was just the floating bindings.

It's strange to accumulate part of the /result/ in the /environment/
argument!  And indeed its leads to all manner of mysterious calls to
zapFloats and transferring of floats from one SimplEnv to another.
It got worse with join points, so I finally bit the bullet and refactored.
Now we have
  simplExpr :: SimplEnv -> InExpr -> SimplCont
            -> SimplM (SimplFloats, OutExpr)
  -- See Note [The big picture]
and the SimplEnv no longer has floats in it.  The code is no shorter,
but it /is/ easier to understand.

Main changes

* Remove seLetFloats field from SimplEnv

* Define new data type SimplFloats, and functions over it

* Change the types of simplExpr, simplBind, and their many variants,
  to follow the above plan

Bottoming bindings
~~~~~~~~~~~~~~~~~~
I made one other significant change in SimplUtils (not just refactoring),
related to Trac #12150 comment:16.  Given
  x = <rhs>
where <rhs> turns out to be a bottoming expression, propagate that
information to x's IdInfo immediately.  That's always good, because
it makes x be inlined less (we don't inline bottoming things), and
it allows (case x of ...) to drop the dead alterantives immediately.
Moreover, we are doing the analysis anyway, in tryEtaExpandRhs, which
calls CoreArity.findRhsArity, which already does simple bottom analysis.
So we are generating the information; all we need do is to atach the
bottoming info to the IdInfo.

See Note [Bottoming bindings]

Smaller refactoring
~~~~~~~~~~~~~~~~~~~
* Rename SimplifierMode to SimplMode
* Put DynFlags as a new field in SimplMode, to make fewer
  monadic calls to getDynFlags.
* Move the code in addPolyBind into abstractFloats
* Move the "don't eta-expand join points" into tryEtaExpandRhs
compiler/coreSyn/CoreArity.hs
compiler/simplCore/CoreMonad.hs
compiler/simplCore/SimplCore.hs
compiler/simplCore/SimplEnv.hs
compiler/simplCore/SimplUtils.hs
compiler/simplCore/Simplify.hs
testsuite/tests/perf/compiler/T12150.hs [new file with mode: 0644]
testsuite/tests/perf/compiler/all.T
testsuite/tests/simplCore/should_compile/T3234.stderr
testsuite/tests/simplCore/should_compile/rule2.stderr