diff options
author | Alon Zakai <azakai@google.com> | 2023-08-08 16:04:10 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-08 16:04:10 -0700 |
commit | ef17febfd7106ee5330c01c66fbf8d3f6fdc0e03 (patch) | |
tree | 887e86c4d4fc1d8deaa1093d7ea00e2ed67408e5 | |
parent | 6537640f95a08aaf5f4829e34adc1f9755892af8 (diff) | |
download | binaryen-ef17febfd7106ee5330c01c66fbf8d3f6fdc0e03.tar.gz binaryen-ef17febfd7106ee5330c01c66fbf8d3f6fdc0e03.tar.bz2 binaryen-ef17febfd7106ee5330c01c66fbf8d3f6fdc0e03.zip |
LocalCSE: Connect adjacent blocks in LinearExecutionWalker (#5867)
Followup to #5860, this does the same for LocalCSE.
As there, this is valid because it's ok if we branch away. This pass adds a local.tee of
a reused value and then gets it later, and it's ok to add a tee even if we branch away
and do not use it.
-rw-r--r-- | src/passes/LocalCSE.cpp | 11 | ||||
-rw-r--r-- | test/lit/passes/inlining-optimizing_optimize-level=3.wast | 8 | ||||
-rw-r--r-- | test/lit/passes/local-cse.wast | 49 |
3 files changed, 64 insertions, 4 deletions
diff --git a/src/passes/LocalCSE.cpp b/src/passes/LocalCSE.cpp index 2b9b26f0e..9e92093e1 100644 --- a/src/passes/LocalCSE.cpp +++ b/src/passes/LocalCSE.cpp @@ -232,6 +232,11 @@ struct Scanner // information, leaving the things we need later. } + // It is ok to look at adjacent blocks together, as if a later part of a block + // is not reached that is fine - changes we make there would not be reached in + // that case. + bool connectAdjacentBlocks = true; + void visitExpression(Expression* curr) { // Compute the hash, using the pre-computed hashes of the children, which // are saved. This allows us to hash everything in linear time. @@ -465,6 +470,9 @@ struct Checker assert(self->activeOriginals.empty()); } + // See the same code above. + bool connectAdjacentBlocks = true; + void visitFunction(Function* curr) { // At the end of the function there can be no active originals. assert(activeOriginals.empty()); @@ -516,6 +524,9 @@ struct Applier // Clear the state between blocks. self->originalLocalMap.clear(); } + + // See the same code above. + bool connectAdjacentBlocks = true; }; } // anonymous namespace diff --git a/test/lit/passes/inlining-optimizing_optimize-level=3.wast b/test/lit/passes/inlining-optimizing_optimize-level=3.wast index c6c4f389c..659a6e04d 100644 --- a/test/lit/passes/inlining-optimizing_optimize-level=3.wast +++ b/test/lit/passes/inlining-optimizing_optimize-level=3.wast @@ -1342,14 +1342,14 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_fflush + ;; CHECK-NEXT: (local.tee $0 ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (i32.const 12) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $_fflush + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/local-cse.wast b/test/lit/passes/local-cse.wast index a2e728548..b3f32fddc 100644 --- a/test/lit/passes/local-cse.wast +++ b/test/lit/passes/local-cse.wast @@ -386,6 +386,55 @@ ) ) ) + + ;; CHECK: (func $dominance + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $dominance + (drop + (i32.add + (i32.const 2) + (i32.const 3) + ) + ) + (if + (i32.const 0) + ;; This add is dominated by the above, so we can use a tee of it. + (drop + (i32.add + (i32.const 2) + (i32.const 3) + ) + ) + ;; We could optimize this add as well, but do not yet. TODO + (drop + (i32.add + (i32.const 2) + (i32.const 3) + ) + ) + ) + ) ) (module |