summaryrefslogtreecommitdiff
path: root/src/passes/OptimizeInstructions.cpp
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2017-01-31 16:27:50 -0800
committerGitHub <noreply@github.com>2017-01-31 16:27:50 -0800
commit7bc8f14d8699f56777a763f99ad8098fcf7c0583 (patch)
treec838d496b731f846362328076f87a4da364c4065 /src/passes/OptimizeInstructions.cpp
parent64284970344ce5463adada38e348230256b31226 (diff)
downloadbinaryen-7bc8f14d8699f56777a763f99ad8098fcf7c0583.tar.gz
binaryen-7bc8f14d8699f56777a763f99ad8098fcf7c0583.tar.bz2
binaryen-7bc8f14d8699f56777a763f99ad8098fcf7c0583.zip
Make ast_utils into a library (#892)
Split ExpressionAnalyzer and ExpressionManipulator into cpp files, and turn their giant template functions into simple functions which take a callback. More organization, fewer mammoth headers, makes the build a few seconds faster, and the binaries a couple MB smaller.
Diffstat (limited to 'src/passes/OptimizeInstructions.cpp')
-rw-r--r--src/passes/OptimizeInstructions.cpp92
1 files changed, 47 insertions, 45 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 04216f1ee..5c1aa5fc3 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -103,61 +103,63 @@ struct Match {
bool check(Expression* seen) {
// compare seen to the pattern input, doing a special operation for our "wildcards"
assert(wildcards.size() == 0);
- return ExpressionAnalyzer::flexibleEqual(pattern.input, seen, *this);
- }
-
- bool compare(Expression* subInput, Expression* subSeen) {
- CallImport* call = subInput->dynCast<CallImport>();
- if (!call || call->operands.size() != 1 || call->operands[0]->type != i32 || !call->operands[0]->is<Const>()) return false;
- Index index = call->operands[0]->cast<Const>()->value.geti32();
- // handle our special functions
- auto checkMatch = [&](WasmType type) {
- if (type != none && subSeen->type != type) return false;
- while (index >= wildcards.size()) {
- wildcards.push_back(nullptr);
- }
- if (!wildcards[index]) {
- // new wildcard
- wildcards[index] = subSeen; // NB: no need to copy
- return true;
- } else {
- // We are seeing this index for a second or later time, check it matches
- return ExpressionAnalyzer::equal(subSeen, wildcards[index]);
+ auto compare = [this](Expression* subInput, Expression* subSeen) {
+ CallImport* call = subInput->dynCast<CallImport>();
+ if (!call || call->operands.size() != 1 || call->operands[0]->type != i32 || !call->operands[0]->is<Const>()) return false;
+ Index index = call->operands[0]->cast<Const>()->value.geti32();
+ // handle our special functions
+ auto checkMatch = [&](WasmType type) {
+ if (type != none && subSeen->type != type) return false;
+ while (index >= wildcards.size()) {
+ wildcards.push_back(nullptr);
+ }
+ if (!wildcards[index]) {
+ // new wildcard
+ wildcards[index] = subSeen; // NB: no need to copy
+ return true;
+ } else {
+ // We are seeing this index for a second or later time, check it matches
+ return ExpressionAnalyzer::equal(subSeen, wildcards[index]);
+ };
};
+ if (call->target == I32_EXPR) {
+ if (checkMatch(i32)) return true;
+ } else if (call->target == I64_EXPR) {
+ if (checkMatch(i64)) return true;
+ } else if (call->target == F32_EXPR) {
+ if (checkMatch(f32)) return true;
+ } else if (call->target == F64_EXPR) {
+ if (checkMatch(f64)) return true;
+ } else if (call->target == ANY_EXPR) {
+ if (checkMatch(none)) return true;
+ }
+ return false;
};
- if (call->target == I32_EXPR) {
- if (checkMatch(i32)) return true;
- } else if (call->target == I64_EXPR) {
- if (checkMatch(i64)) return true;
- } else if (call->target == F32_EXPR) {
- if (checkMatch(f32)) return true;
- } else if (call->target == F64_EXPR) {
- if (checkMatch(f64)) return true;
- } else if (call->target == ANY_EXPR) {
- if (checkMatch(none)) return true;
- }
- return false;
+
+ return ExpressionAnalyzer::flexibleEqual(pattern.input, seen, compare);
}
+
// Applying/copying
// Apply the match, generate an output expression from the matched input, performing substitutions as necessary
Expression* apply() {
- return ExpressionManipulator::flexibleCopy(pattern.output, wasm, *this);
+ // When copying a wildcard, perform the substitution.
+ // TODO: we can reuse nodes, not copying a wildcard when it appears just once, and we can reuse other individual nodes when they are discarded anyhow.
+ auto copy = [this](Expression* curr) -> Expression* {
+ CallImport* call = curr->dynCast<CallImport>();
+ if (!call || call->operands.size() != 1 || call->operands[0]->type != i32 || !call->operands[0]->is<Const>()) return nullptr;
+ Index index = call->operands[0]->cast<Const>()->value.geti32();
+ // handle our special functions
+ if (call->target == I32_EXPR || call->target == I64_EXPR || call->target == F32_EXPR || call->target == F64_EXPR || call->target == ANY_EXPR) {
+ return ExpressionManipulator::copy(wildcards.at(index), wasm);
+ }
+ return nullptr;
+ };
+ return ExpressionManipulator::flexibleCopy(pattern.output, wasm, copy);
}
- // When copying a wildcard, perform the substitution.
- // TODO: we can reuse nodes, not copying a wildcard when it appears just once, and we can reuse other individual nodes when they are discarded anyhow.
- Expression* copy(Expression* curr) {
- CallImport* call = curr->dynCast<CallImport>();
- if (!call || call->operands.size() != 1 || call->operands[0]->type != i32 || !call->operands[0]->is<Const>()) return nullptr;
- Index index = call->operands[0]->cast<Const>()->value.geti32();
- // handle our special functions
- if (call->target == I32_EXPR || call->target == I64_EXPR || call->target == F32_EXPR || call->target == F64_EXPR || call->target == ANY_EXPR) {
- return ExpressionManipulator::copy(wildcards.at(index), wasm);
- }
- return nullptr;
- }
+
};
// Main pass class