summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast_utils.h31
-rw-r--r--src/pass.cpp2
-rw-r--r--src/passes/Print.cpp5
-rw-r--r--src/passes/Vacuum.cpp8
-rw-r--r--test/unit.fromasm19
-rw-r--r--test/unit.fromasm.imprecise19
6 files changed, 62 insertions, 22 deletions
diff --git a/src/ast_utils.h b/src/ast_utils.h
index f91cfab24..9336d2b3a 100644
--- a/src/ast_utils.h
+++ b/src/ast_utils.h
@@ -117,6 +117,37 @@ struct ExpressionManipulator {
}
};
+struct ExpressionAnalyzer {
+ // Given a stack of expressions, checks if the topmost is used as a result.
+ // For example, if the parent is a block and the node is before the last position,
+ // it is not used.
+ static bool isResultUsed(std::vector<Expression*> stack, Function* func) {
+ for (int i = int(stack.size()) - 2; i >= 0; i--) {
+ auto* curr = stack[i];
+ auto* above = stack[i + 1];
+ // only if and block can drop values
+ if (curr->is<Block>()) {
+ auto* block = curr->cast<Block>();
+ for (size_t j = 0; j < block->list.size() - 1; j++) {
+ if (block->list[j] == above) return false;
+ }
+ assert(block->list.back() == above);
+ // continue down
+ } else if (curr->is<If>()) {
+ auto* iff = curr->cast<If>();
+ if (!iff->ifFalse) return false;
+ if (above == iff->condition) return true;
+ assert(above == iff->ifTrue || above == iff->ifFalse);
+ // continue down
+ } else {
+ return true; // all other node types use the result
+ }
+ }
+ // The value might be used, so it depends on if the function returns
+ return func->result != none;
+ }
+};
+
} // namespace wasm
#endif // wasm_ast_utils_h
diff --git a/src/pass.cpp b/src/pass.cpp
index 1a8aaabc9..7095da71d 100644
--- a/src/pass.cpp
+++ b/src/pass.cpp
@@ -60,9 +60,9 @@ std::string PassRegistry::getPassDescription(std::string name) {
void PassRunner::addDefaultOptimizationPasses() {
add("remove-unused-brs");
add("remove-unused-names");
- add("merge-blocks");
add("optimize-instructions");
add("simplify-locals");
+ add("merge-blocks");
add("reorder-locals");
add("vacuum");
}
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index ddeec3dce..59ade1c76 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -68,7 +68,10 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
}
Name printableLocal(Index index) {
- Name name = currFunction->tryLocalName(index);
+ Name name;
+ if (currFunction) {
+ name = currFunction->tryLocalName(index);
+ }
if (!name.is()) {
name = Name::fromInt(index);
}
diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp
index dfede6d25..863d78f14 100644
--- a/src/passes/Vacuum.cpp
+++ b/src/passes/Vacuum.cpp
@@ -20,6 +20,7 @@
#include <wasm.h>
#include <pass.h>
+#include <ast_utils.h>
namespace wasm {
@@ -41,6 +42,13 @@ struct Vacuum : public WalkerPass<PostWalker<Vacuum, Visitor<Vacuum>>> {
if (skip > 0) {
list.resize(size - skip);
}
+ if (!curr->name.is()) {
+ if (list.size() == 1) {
+ replaceCurrent(list[0]);
+ } else if (list.size() == 0) {
+ ExpressionManipulator::nop(curr);
+ }
+ }
}
};
diff --git a/test/unit.fromasm b/test/unit.fromasm
index 9a142a142..0b43f14fc 100644
--- a/test/unit.fromasm
+++ b/test/unit.fromasm
@@ -272,6 +272,7 @@
)
)
(func $blocker
+ (nop)
)
(func $frem (result f64)
(return
@@ -311,19 +312,17 @@
)
(func $abs
(local $asm2wasm_i32_temp i32)
- (block
- (select
- (i32.sub
+ (select
+ (i32.sub
+ (i32.const 0)
+ (set_local $asm2wasm_i32_temp
(i32.const 0)
- (set_local $asm2wasm_i32_temp
- (i32.const 0)
- )
)
+ )
+ (get_local $asm2wasm_i32_temp)
+ (i32.lt_s
(get_local $asm2wasm_i32_temp)
- (i32.lt_s
- (get_local $asm2wasm_i32_temp)
- (i32.const 0)
- )
+ (i32.const 0)
)
)
(f64.abs
diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise
index e829c7f3c..f5ba55d90 100644
--- a/test/unit.fromasm.imprecise
+++ b/test/unit.fromasm.imprecise
@@ -266,6 +266,7 @@
)
)
(func $blocker
+ (nop)
)
(func $frem (result f64)
(return
@@ -305,19 +306,17 @@
)
(func $abs
(local $asm2wasm_i32_temp i32)
- (block
- (select
- (i32.sub
+ (select
+ (i32.sub
+ (i32.const 0)
+ (set_local $asm2wasm_i32_temp
(i32.const 0)
- (set_local $asm2wasm_i32_temp
- (i32.const 0)
- )
)
+ )
+ (get_local $asm2wasm_i32_temp)
+ (i32.lt_s
(get_local $asm2wasm_i32_temp)
- (i32.lt_s
- (get_local $asm2wasm_i32_temp)
- (i32.const 0)
- )
+ (i32.const 0)
)
)
(f64.abs