summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/OptimizeInstructions.cpp22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index ebe551d0c..f2ca4e0be 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -1853,10 +1853,6 @@ struct OptimizeInstructions
return;
}
- // What the reference points to does not depend on the type, so casts may be
- // removable.
- skipCast(curr->value);
-
// Optimizating RefIs is not that obvious, since even if we know the result
// evaluates to 0 or 1 then the replacement may not actually save code size,
// since RefIsNull is a single byte (the others are 2), while adding a Const
@@ -1874,6 +1870,21 @@ struct OptimizeInstructions
replaceCurrent(builder.makeSequence(
builder.makeDrop(curr->value),
builder.makeConst(Literal::makeZero(Type::i32))));
+ } else {
+ // What the reference points to does not depend on the type, so casts
+ // may be removable. Do this right before returning because removing a
+ // cast may remove info that we could have used to optimize. For
+ // example:
+ //
+ // (ref.is_func
+ // (ref.as_func
+ // (local.get $anyref)))
+ //
+ // The local has no useful type info. The cast forces it to be a
+ // function, so we can replace the ref.is with 1. But if we removed the
+ // ref.as first then we'd not have the type info we need to optimize
+ // that way.
+ skipCast(curr->value);
}
return;
}
@@ -1913,6 +1924,9 @@ struct OptimizeInstructions
}
}
}
+
+ // See above comment.
+ skipCast(curr->value);
}
void visitRefAs(RefAs* curr) {