summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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)) {