Actually implement binary operation rebalancing

This uses a fairly simple algorithm to rebalance binary trees.
Essentially it just walks the input set of each connected component
and replaces each output node with a balanced representation of that
node.

The big implementation wrinkle is that this pass leaves in all the
intermediate nodes in the competation as we have no idea if they're
being used for anything else.  This may seem like a hacky way to do
this, but I think it's actually correct: it just relies on dead code
elimination to work correctly.

Note that it may actually be correct to treat every node as an output
node, but I'm not going to bother with that for now.  This will
perform better in the common case (where there's no oddness with using
internal AND tree nodes) and in the worst case (where you're using a
bunch of those internal nodes so things go nuts when you try to build
a log-input tree for every one), so I think it's fine for now.

Note that this is actually a good example of an optimization that's
pretty machine-specific: this optimization is bad on a CPU and isn't
necessarily good on DREAMER (as we only want to split stuff up until
there's enough parallelism).  At least it's an example of an
optimization pass, though!
Run all the tests under valgrind

This is pretty standard: I don't want any memory corruption ever.