summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-09-07 14:38:41 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-09-07 18:42:48 -0700
commit443d7a8e39c4ccfaeab6066160aae17e1fee8cc8 (patch)
treef0d5a9b48d65edbc5514ba25ff2db2f969f49b2f /src
parentd8af68954309ef2cd34449a50b4d82d3bb96c7e7 (diff)
downloadbinaryen-443d7a8e39c4ccfaeab6066160aae17e1fee8cc8.tar.gz
binaryen-443d7a8e39c4ccfaeab6066160aae17e1fee8cc8.tar.bz2
binaryen-443d7a8e39c4ccfaeab6066160aae17e1fee8cc8.zip
vacuum drops better
Diffstat (limited to 'src')
-rw-r--r--src/passes/Vacuum.cpp29
1 files changed, 21 insertions, 8 deletions
diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp
index db42a994a..53b9eb397 100644
--- a/src/passes/Vacuum.cpp
+++ b/src/passes/Vacuum.cpp
@@ -47,26 +47,31 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum, Visitor<Vacuum>>
case Expression::Id::CallImportId:
case Expression::Id::CallIndirectId:
case Expression::Id::SetLocalId:
- case Expression::Id::LoadId:
case Expression::Id::StoreId:
case Expression::Id::ReturnId:
- case Expression::Id::GetGlobalId:
case Expression::Id::SetGlobalId:
case Expression::Id::HostId:
case Expression::Id::UnreachableId: return curr; // always needed
+ case Expression::Id::LoadId: {
+ if (!resultUsed) {
+ return curr->cast<Load>()->ptr;
+ }
+ return curr;
+ }
case Expression::Id::ConstId:
case Expression::Id::GetLocalId:
+ case Expression::Id::GetGlobalId: {
+ if (!resultUsed) return nullptr;
+ return curr;
+ }
+
case Expression::Id::UnaryId:
case Expression::Id::BinaryId:
case Expression::Id::SelectId: {
if (resultUsed) {
return curr; // used, keep it
}
- // result is not used, perhaps it is dead
- if (curr->is<Const>() || curr->is<GetLocal>()) {
- return nullptr;
- }
// for unary, binary, and select, we need to check their arguments for side effects
if (auto* unary = curr->dynCast<Unary>()) {
if (EffectAnalyzer(unary->value).hasSideEffects()) {
@@ -200,11 +205,19 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum, Visitor<Vacuum>>
}
void visitDrop(Drop* curr) {
- // if the drop input has no side effects, it can be wiped out
- if (!EffectAnalyzer(curr->value).hasSideEffects()) {
+ // optimize the dropped value, maybe leaving nothing
+ curr->value = optimize(curr->value, false);
+ if (curr->value == nullptr) {
ExpressionManipulator::nop(curr);
return;
}
+ // a drop of a tee is a set
+ if (auto* set = curr->value->dynCast<SetLocal>()) {
+ assert(set->isTee());
+ set->setTee(false);
+ replaceCurrent(set);
+ return;
+ }
// sink a drop into an arm of an if-else if the other arm ends in an unreachable, as it if is a branch, this can make that branch optimizable and more vaccuming possible
auto* iff = curr->value->dynCast<If>();
if (iff && iff->ifFalse && isConcreteWasmType(iff->type)) {