diff options
-rw-r--r-- | src/tools/wasm-reduce.cpp | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp index fe6e2b22e..094338bea 100644 --- a/src/tools/wasm-reduce.cpp +++ b/src/tools/wasm-reduce.cpp @@ -31,6 +31,7 @@ #include "ir/iteration.h" #include "ir/literal-utils.h" #include "ir/properties.h" +#include "ir/utils.h" #include "pass.h" #include "support/colors.h" #include "support/command-line.h" @@ -42,6 +43,7 @@ #include "wasm-builder.h" #include "wasm-io.h" #include "wasm-validator.h" + #ifdef _WIN32 #ifndef NOMINMAX #define NOMINMAX @@ -71,6 +73,7 @@ std::string GetLastErrorStdStr() { return std::string(); } #endif + using namespace wasm; // A timeout on every execution of the command. @@ -1139,33 +1142,47 @@ struct Reducer return false; } - // try to replace a concrete value with a trivial constant + // Try to replace a concrete value with a trivial constant. bool tryToReduceCurrentToConst() { auto* curr = getCurrent(); - if (curr->is<Const>()) { - return false; - } - // try to replace with a trivial value - if (curr->type.isNullable()) { + + // References. + if (curr->type.isNullable() && !curr->is<RefNull>()) { RefNull* n = builder->makeRefNull(curr->type.getHeapType()); return tryToReplaceCurrent(n); } + + // Tuples. if (curr->type.isTuple() && curr->type.isDefaultable()) { Expression* n = builder->makeConstantExpression(Literal::makeZeros(curr->type)); + if (ExpressionAnalyzer::equal(n, curr)) { + return false; + } return tryToReplaceCurrent(n); } + + // Numbers. We try to replace them with a 0 or a 1. if (!curr->type.isNumber()) { return false; } - // It's a number: try to replace it with a 0 or a 1 (trying more values - // could make sense too, but these handle most cases). + auto* existing = curr->dynCast<Const>(); + if (existing && existing->value.isZero()) { + // It's already a zero. + return false; + } auto* c = builder->makeConst(Literal::makeZero(curr->type)); if (tryToReplaceCurrent(c)) { return true; } + // It's not a zero, and can't be replaced with a zero. Try to make it a one, + // if it isn't already. + if (existing && + existing->value == Literal::makeFromInt32(1, existing->type)) { + // It's already a one. + return false; + } c->value = Literal::makeOne(curr->type); - c->type = curr->type; return tryToReplaceCurrent(c); } |