Harvest left-hand side superoptimization candidates.

Given a clif function, harvest all its integer subexpressions, so that they can
be fed into [Souper](https://github.com/google/souper) as candidates for
superoptimization. For some of these candidates, Souper will successfully
synthesize a right-hand side that is equivalent but has lower cost than the
left-hand side. Then, we can combine these left- and right-hand sides into a
complete optimization, and add it to our peephole passes.

To harvest the expression that produced a given value `x`, we do a post-order
traversal of the dataflow graph starting from `x`. As we do this traversal, we
maintain a map from clif values to their translated Souper values. We stop
traversing when we reach anything that can't be translated into Souper IR: a
memory load, a float-to-int conversion, a block parameter, etc. For values
produced by these instructions, we create a Souper `var`, which is an input
variable to the optimization. For instructions that have a direct mapping into
Souper IR, we get the Souper version of each of its operands and then create the
Souper version of the instruction itself. It should now be clear why we do a
post-order traversal: we need an instruction's translated operands in order to
translate the instruction itself. Once this instruction is translated, we update
the clif-to-souper map with this new translation so that any other instruction
that uses this result as an operand has access to the translated value. When the
traversal is complete we return the translation of `x` as the root of left-hand
side candidate.
This commit is contained in:
Nick Fitzgerald
2020-09-02 15:26:42 -07:00
parent 43d2799fa2
commit 3a6dd832c0
8 changed files with 642 additions and 2 deletions

View File

@@ -38,14 +38,16 @@ wat = { version = "1.0.18", optional = true }
target-lexicon = "0.10"
peepmatic-souper = { path = "./peepmatic/crates/souper", version = "0.66.0", optional = true }
pretty_env_logger = "0.4.0"
rayon = { version = "1", optional = true }
file-per-thread-logger = "0.1.2"
indicatif = "0.13.0"
thiserror = "1.0.15"
walkdir = "2.2"
[features]
default = ["disas", "wasm", "cranelift-codegen/all-arch", "peepmatic-souper"]
default = ["disas", "wasm", "cranelift-codegen/all-arch", "peepmatic-souper", "souper-harvest"]
disas = ["capstone"]
enable-peepmatic = ["cranelift-codegen/enable-peepmatic", "cranelift-filetests/enable-peepmatic"]
wasm = ["wat", "cranelift-wasm"]
experimental_x64 = ["cranelift-codegen/x64"]
souper-harvest = ["cranelift-codegen/souper-harvest", "rayon"]