Optimizations to egraph framework (#5391)
* Optimizations to egraph framework: - Save elaborated results by canonical value, not latest value (union value). Previously we were artificially skipping and re-elaborating some values we already had because we were not finding them in the map. - Make some changes to handling of icmp results: when icmp became I8-typed (when bools went away), many uses became `(uextend $I32 (icmp $I8 ...))`, and so patterns in lowering backends were no longer matching. This PR includes an x64-specific change to match `(brz (uextend (icmp ...)))` and similarly for `brnz`, but it also takes advantage of the ability to write rules easily in the egraph mid-end to rewrite selects with icmp inputs appropriately. - Extend constprop to understand selects in the egraph mid-end. With these changes, bz2.wasm sees a ~1% speedup, and spidermonkey.wasm with a fib.js input sees a 16.8% speedup: ``` $ time taskset 1 target/release/wasmtime run --allow-precompiled --dir=. ./spidermonkey.base.cwasm ./fib.js 1346269 taskset 1 target/release/wasmtime run --allow-precompiled --dir=. ./fib.js 2.14s user 0.01s system 99% cpu 2.148 total $ time taskset 1 target/release/wasmtime run --allow-precompiled --dir=. ./spidermonkey.egraphs.cwasm ./fib.js 1346269 taskset 1 target/release/wasmtime run --allow-precompiled --dir=. ./fib.js 1.78s user 0.01s system 99% cpu 1.788 total ``` * Review feedback.
This commit is contained in:
@@ -277,7 +277,7 @@ impl<'a> Elaborator<'a> {
|
||||
let value = self.func.dfg.resolve_aliases(value);
|
||||
|
||||
self.stats.elaborate_visit_node += 1;
|
||||
let canonical_value = self.eclasses.find(value);
|
||||
let canonical_value = self.eclasses.find_and_update(value);
|
||||
debug_assert_ne!(canonical_value, Value::reserved_value());
|
||||
trace!(
|
||||
"elaborate: value {} canonical {} before {}",
|
||||
@@ -518,8 +518,9 @@ impl<'a> Elaborator<'a> {
|
||||
value: new_result,
|
||||
in_block: insert_block,
|
||||
};
|
||||
let canonical_result = self.eclasses.find_and_update(result);
|
||||
self.value_to_elaborated_value.insert_if_absent_with_depth(
|
||||
result,
|
||||
canonical_result,
|
||||
elab_value,
|
||||
scope_depth,
|
||||
);
|
||||
@@ -545,8 +546,9 @@ impl<'a> Elaborator<'a> {
|
||||
value: result,
|
||||
in_block: insert_block,
|
||||
};
|
||||
let canonical_result = self.eclasses.find_and_update(result);
|
||||
self.value_to_elaborated_value.insert_if_absent_with_depth(
|
||||
result,
|
||||
canonical_result,
|
||||
elab_value,
|
||||
scope_depth,
|
||||
);
|
||||
@@ -623,8 +625,9 @@ impl<'a> Elaborator<'a> {
|
||||
// map now.
|
||||
for &result in self.func.dfg.inst_results(inst) {
|
||||
trace!(" -> result {}", result);
|
||||
let canonical_result = self.eclasses.find_and_update(result);
|
||||
self.value_to_elaborated_value.insert_if_absent(
|
||||
result,
|
||||
canonical_result,
|
||||
ElaboratedValue {
|
||||
in_block: block,
|
||||
value: result,
|
||||
|
||||
Reference in New Issue
Block a user