diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-09-28 11:07:29 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-28 11:07:29 -0700 |
commit | ee9d515581998165c0e573d2b5a468c5b361cfcd (patch) | |
tree | bd5c9694a30188ade1b5805f646de32d249740c9 /src | |
parent | b3d9ad57566c4d30f57626c6a44e2afd664b7459 (diff) | |
download | binaryen-ee9d515581998165c0e573d2b5a468c5b361cfcd.tar.gz binaryen-ee9d515581998165c0e573d2b5a468c5b361cfcd.tar.bz2 binaryen-ee9d515581998165c0e573d2b5a468c5b361cfcd.zip |
Optimize wasm reading (#1202)
* optimize wasm reading: use a set of the breaks we've seen, don't rescan blocks to see if they have breaks to them
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm-binary.h | 1 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 11 |
2 files changed, 10 insertions, 2 deletions
diff --git a/src/wasm-binary.h b/src/wasm-binary.h index b7e614fa5..bf1cb14d6 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -863,6 +863,7 @@ public: BreakTarget(Name name, int arity) : name(name), arity(arity) {} }; std::vector<BreakTarget> breakStack; + std::unordered_set<Name> breakTargetNames; bool breaksToReturn; // whether a break is done to the function scope, which is in effect a return std::vector<Expression*> expressionStack; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 0d142cd8f..f7e10d39b 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1629,6 +1629,7 @@ void WasmBinaryBuilder::readFunctions() { useDebugLocation = false; breaksToReturn = false; // process body + assert(breakTargetNames.size() == 0); assert(breakStack.empty()); breakStack.emplace_back(RETURN_BREAK, func->result != none); // the break target for the function scope assert(expressionStack.empty()); @@ -1637,6 +1638,7 @@ void WasmBinaryBuilder::readFunctions() { assert(depth == 0); assert(breakStack.size() == 1); breakStack.pop_back(); + assert(breakTargetNames.size() == 0); if (!expressionStack.empty()) { throw ParseException("stack not empty on function exit"); } @@ -2222,6 +2224,7 @@ void WasmBinaryBuilder::visitBlock(Block *curr) { pushBlockElements(curr, start, end); curr->finalize(curr->type); breakStack.pop_back(); + breakTargetNames.erase(curr->name); } } @@ -2237,12 +2240,13 @@ Expression* WasmBinaryBuilder::getBlockOrSingleton(WasmType type) { block->name = label; block->finalize(type); // maybe we don't need a block here? - if (!brokenTo(block)) { + if (breakTargetNames.find(block->name) == breakTargetNames.end()) { block->name = Name(); if (block->list.size() == 1) { return block->list[0]; } } + breakTargetNames.erase(block->name); return block; } @@ -2285,6 +2289,7 @@ void WasmBinaryBuilder::visitLoop(Loop *curr) { curr->body = block; } breakStack.pop_back(); + breakTargetNames.erase(curr->name); curr->finalize(curr->type); } @@ -2301,7 +2306,9 @@ WasmBinaryBuilder::BreakTarget WasmBinaryBuilder::getBreakTarget(int32_t offset) breaksToReturn = true; } if (debug) std::cerr << "breaktarget "<< breakStack[index].name << " arity " << breakStack[index].arity << std::endl; - return breakStack[index]; + auto& ret = breakStack[index]; + breakTargetNames.insert(ret.name); + return ret; } void WasmBinaryBuilder::visitBreak(Break *curr, uint8_t code) { |