diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-11-01 17:17:07 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-11-01 17:17:07 -0800 |
commit | a3e712df50f43f6a176a750043c32c752f2dfe2b (patch) | |
tree | e62c0e62f88818d70a2616a29f28c9c94bcf6e7b /src/asm2wasm.h | |
parent | 01fa6454d5b375ea85ba8662306cb0ac30a1de29 (diff) | |
download | binaryen-a3e712df50f43f6a176a750043c32c752f2dfe2b.tar.gz binaryen-a3e712df50f43f6a176a750043c32c752f2dfe2b.tar.bz2 binaryen-a3e712df50f43f6a176a750043c32c752f2dfe2b.zip |
improve unnecessary block removal
Diffstat (limited to 'src/asm2wasm.h')
-rw-r--r-- | src/asm2wasm.h | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 6c14e5757..6cd951dbb 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -1028,26 +1028,24 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { } void Asm2WasmBuilder::optimize() { + // Optimization passes. Note: no effort is made to free nodes that are no longer held on to. + struct BlockBreakOptimizer : public WasmWalker { BlockBreakOptimizer() : WasmWalker(nullptr) {} void visitBlock(Block *curr) override { - if (curr->list.size() > 1) { - // we can't remove the block, but if it ends in a break on this very block, then just put the value there - Break *last = curr->list[curr->list.size()-1]->dyn_cast<Break>(); - if (last && last->value && last->name == curr->name) { - curr->list[curr->list.size()-1] = last->value; - } - return; + // if the block ends in a break on this very block, then just put the value there + Break *last = curr->list[curr->list.size()-1]->dyn_cast<Break>(); + if (last && last->value && last->name == curr->name) { + curr->list[curr->list.size()-1] = last->value; } + if (curr->list.size() > 1) return; // no hope to remove the block // just one element; maybe we can return just the element if (curr->name.isNull()) { - replaceCurrent(curr->list[0]); + replaceCurrent(curr->list[0]); // cannot break into it return; } - // we might be broken to, but if it's a trivial singleton child break, we can optimize here as well - Break *child = curr->list[0]->dyn_cast<Break>(); - if (!child || child->name != curr->name || !child->value) return; + // we might be broken to, but maybe there isn't a break (and we may have removed it, leading to this) struct BreakSeeker : public WasmWalker { IString target; // look for this one @@ -1060,11 +1058,12 @@ void Asm2WasmBuilder::optimize() { } }; - // look in the child's children to see if there are more uses of this name + // look for any breaks to this block BreakSeeker breakSeeker(curr->name); - breakSeeker.walk(child->value); + Expression *child = curr->list[0]; + breakSeeker.walk(child); if (breakSeeker.found == 0) { - replaceCurrent(child->value); + replaceCurrent(child); // no breaks to here, so eliminate the block } } }; |