diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-01-08 09:46:46 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-01-08 09:47:10 -0800 |
commit | f4958962bce2035f9de1ca409672607e68e4b5a3 (patch) | |
tree | 1d4925d04db3ae2d9dcaea33016d575a513c8538 /src | |
parent | 2dc5714c7b80d4d53dbebae2dd851d4b056266ab (diff) | |
download | binaryen-f4958962bce2035f9de1ca409672607e68e4b5a3.tar.gz binaryen-f4958962bce2035f9de1ca409672607e68e4b5a3.tar.bz2 binaryen-f4958962bce2035f9de1ca409672607e68e4b5a3.zip |
optimize if_else in RemoveUnusedBrs
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/RemoveUnusedBrs.cpp | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index 5f3018c5f..0ff48381f 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -27,14 +27,39 @@ struct RemoveUnusedBrs : public Pass { void visitBlock(Block *curr) override { if (curr->name.isNull()) return; if (curr->list.size() == 0) return; - Break* last = curr->list.back()->dyn_cast<Break>(); - if (!last) return; - if (last->condition) return; - if (last->name == curr->name) { - if (!last->value) { - curr->list.pop_back(); - } else { - curr->list[curr->list.size()-1] = last->value; // can replace with the value + Expression* last = curr->list.back(); + if (Break* br = last->dyn_cast<Break>()) { + if (br->condition) return; + if (br->name == curr->name) { + if (!br->value) { + curr->list.pop_back(); + } else { + curr->list[curr->list.size()-1] = br->value; // can replace with the value + } + } + } else if (If* ifelse = curr->list.back()->dyn_cast<If>()) { + if (!ifelse->ifFalse) return; + if (ifelse->type != none) return; + // an if_else that indirectly returns a value by breaking to this block can potentially remove both breaks + auto process = [&curr](Expression *side, bool doIt) { + Block* b = side->dyn_cast<Block>(); + if (!b) return false; + Expression* last = b->list.back(); + Break* br = last->dyn_cast<Break>(); + if (!br) return false; + if (br->condition) return false; + if (!br->value) return false; + if (br->name != curr->name) return false; + if (doIt) { + b->list[b->list.size()-1] = br->value; + } + return true; + }; + // do both, or none + if (process(ifelse->ifTrue, false) && process(ifelse->ifFalse, false)) { + process(ifelse->ifTrue, true); + process(ifelse->ifFalse, true); + ifelse->type = curr->type; // if_else now returns a value } } } |