RFC: https://lists.llvm.org/pipermail/llvm-dev/2021-September/152665.html
This patch implements simple hoisting of instructions from two
single-predecessor blocks to their common predecessor, as a subroutine
in the GVN pass.
The patch pairs two instructions (A and B) with the same value number,
moves A to the predecessor block, replaces all uses of B with A, and
deletes B.
Instructions are paired via sort/merge (could be hashing instead).
Certain instructions act as "hoist barriers" in the sense that they
stop scanning the block for more hoist candidates, thus preventing
instructions to be reordering above them. They themselves can be
hoisted, though, which creates opportunities to hoist other
instructions, which is achieved by consecutive iterations of the
transformation.
Consecutive iterations are also needed to handle loads, which have
unique value numbers.
Initial benchmarking on Neoverse N1 looks good (speedup, higher is
better):
500.perlbench_r 1.13%
502.gcc_r 0.00%
505.mcf_r -1.89%
520.omnetpp_r 0.00%
523.xalancbmk_r 0.00%
525.x264_r 7.67%
531.deepsjeng_r 0.60%
541.leela_r 0.24%
548.exchange2_r 0.00%
557.xz_r 0.75%
(There's that 2% regression in mcf that I've not investigated yet).
clang-format: please reformat the code