summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/effects.h8
-rw-r--r--src/passes/MinifyImportsAndExports.cpp1
-rw-r--r--src/passes/OptimizeInstructions.cpp21
-rw-r--r--test/passes/optimize-instructions.txt25
-rw-r--r--test/passes/optimize-instructions.wast28
5 files changed, 80 insertions, 3 deletions
diff --git a/src/ir/effects.h b/src/ir/effects.h
index 8919c6da4..8c95f463d 100644
--- a/src/ir/effects.h
+++ b/src/ir/effects.h
@@ -283,6 +283,14 @@ struct EffectAnalyzer : public PostWalker<EffectAnalyzer> {
isAtomic = true;
}
void visitUnreachable(Unreachable *curr) { branches = true; }
+
+ // Helpers
+
+ static bool canReorder(PassOptions& passOptions, Expression* a, Expression* b) {
+ EffectAnalyzer aEffects(passOptions, a);
+ EffectAnalyzer bEffects(passOptions, b);
+ return !aEffects.invalidates(bEffects);
+ }
};
} // namespace wasm
diff --git a/src/passes/MinifyImportsAndExports.cpp b/src/passes/MinifyImportsAndExports.cpp
index 9cbc3b19a..f32859384 100644
--- a/src/passes/MinifyImportsAndExports.cpp
+++ b/src/passes/MinifyImportsAndExports.cpp
@@ -64,7 +64,6 @@ struct MinifyImportsAndExports : public Pass {
reserved.insert("enum");
reserved.insert("void");
reserved.insert("this");
- reserved.insert("void");
reserved.insert("with");
validInitialChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$";
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 255ff4cbd..7cdc048f7 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -380,16 +380,32 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions,
// Y
// X
// )
+ // Note that this reorders X and Y, so we need to be careful about that.
if (auto* sub = binary->left->dynCast<Binary>()) {
if (sub->op == SubInt32) {
if (auto* subZero = sub->left->dynCast<Const>()) {
if (subZero->value.geti32() == 0) {
- sub->left = binary->right;
- return sub;
+ if (EffectAnalyzer::canReorder(getPassOptions(), sub->right, binary->right)) {
+ sub->left = binary->right;
+ return sub;
+ }
}
}
}
}
+ // The flip case is even easier, as no reordering occurs:
+ // (i32.add
+ // Y
+ // (i32.sub
+ // (i32.const 0)
+ // X
+ // )
+ // )
+ // =>
+ // (i32.sub
+ // Y
+ // X
+ // )
if (auto* sub = binary->right->dynCast<Binary>()) {
if (sub->op == SubInt32) {
if (auto* subZero = sub->left->dynCast<Const>()) {
@@ -761,6 +777,7 @@ private:
constant += value * mul;
constants.push_back(c);
}
+ return;
} else if (auto* binary = curr->dynCast<Binary>()) {
if (binary->op == AddInt32) {
seek(binary->left, mul);
diff --git a/test/passes/optimize-instructions.txt b/test/passes/optimize-instructions.txt
index 5a0a45e3d..51a5113b1 100644
--- a/test/passes/optimize-instructions.txt
+++ b/test/passes/optimize-instructions.txt
@@ -2997,6 +2997,31 @@
)
)
)
+ (func $add-sub-zero-reorder-1 (; 73 ;) (type $3) (param $temp i32) (result i32)
+ (i32.add
+ (i32.add
+ (i32.sub
+ (i32.const 0)
+ (get_local $temp)
+ )
+ (tee_local $temp
+ (i32.const 1)
+ )
+ )
+ (i32.const 2)
+ )
+ )
+ (func $add-sub-zero-reorder-2 (; 74 ;) (type $3) (param $temp i32) (result i32)
+ (i32.add
+ (i32.sub
+ (tee_local $temp
+ (i32.const 1)
+ )
+ (get_local $temp)
+ )
+ (i32.const 2)
+ )
+ )
)
(module
(type $0 (func))
diff --git a/test/passes/optimize-instructions.wast b/test/passes/optimize-instructions.wast
index aa979c62a..53ed761d8 100644
--- a/test/passes/optimize-instructions.wast
+++ b/test/passes/optimize-instructions.wast
@@ -3526,6 +3526,34 @@
)
)
)
+ (func $add-sub-zero-reorder-1 (param $temp i32) (result i32)
+ (i32.add
+ (i32.add
+ (i32.sub
+ (i32.const 0) ;; this zero looks like we could remove it by subtracting the get of $temp from the parent, but that would reorder it *after* the tee :(
+ (get_local $temp)
+ )
+ (tee_local $temp ;; cannot move this tee before the get
+ (i32.const 1)
+ )
+ )
+ (i32.const 2)
+ )
+ )
+ (func $add-sub-zero-reorder-2 (param $temp i32) (result i32)
+ (i32.add
+ (i32.add
+ (tee_local $temp ;; in this order, the tee already comes first, so all is good for the optimization
+ (i32.const 1)
+ )
+ (i32.sub
+ (i32.const 0)
+ (get_local $temp)
+ )
+ )
+ (i32.const 2)
+ )
+ )
)
(module
(import "env" "memory" (memory $0 (shared 256 256)))