summaryrefslogtreecommitdiff
path: root/src/ir/properties.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir/properties.h')
-rw-r--r--src/ir/properties.h30
1 files changed, 19 insertions, 11 deletions
diff --git a/src/ir/properties.h b/src/ir/properties.h
index 01e78563d..1dbb0e096 100644
--- a/src/ir/properties.h
+++ b/src/ir/properties.h
@@ -18,6 +18,8 @@
#define wasm_ir_properties_h
#include "ir/bits.h"
+#include "ir/effects.h"
+#include "ir/iteration.h"
#include "wasm.h"
namespace wasm {
@@ -68,6 +70,10 @@ inline bool isNamedControlFlow(Expression* curr) {
return false;
}
+inline bool isConstantExpression(const Expression* curr) {
+ return curr->is<Const>() || curr->is<RefNull>() || curr->is<RefFunc>();
+}
+
// Check if an expression is a sign-extend, and if so, returns the value
// that is extended, otherwise nullptr
inline Expression* getSignExtValue(Expression* curr) {
@@ -153,7 +159,9 @@ inline Index getZeroExtBits(Expression* curr) {
// Returns a falling-through value, that is, it looks through a local.tee
// and other operations that receive a value and let it flow through them.
-inline Expression* getFallthrough(Expression* curr) {
+inline Expression* getFallthrough(Expression* curr,
+ const PassOptions& passOptions,
+ FeatureSet features) {
// If the current node is unreachable, there is no value
// falling through.
if (curr->type == Type::unreachable) {
@@ -161,36 +169,36 @@ inline Expression* getFallthrough(Expression* curr) {
}
if (auto* set = curr->dynCast<LocalSet>()) {
if (set->isTee()) {
- return getFallthrough(set->value);
+ return getFallthrough(set->value, passOptions, features);
}
} else if (auto* block = curr->dynCast<Block>()) {
// if no name, we can't be broken to, and then can look at the fallthrough
if (!block->name.is() && block->list.size() > 0) {
- return getFallthrough(block->list.back());
+ return getFallthrough(block->list.back(), passOptions, features);
}
} else if (auto* loop = curr->dynCast<Loop>()) {
- return getFallthrough(loop->body);
+ return getFallthrough(loop->body, passOptions, features);
} else if (auto* iff = curr->dynCast<If>()) {
if (iff->ifFalse) {
// Perhaps just one of the two actually returns.
if (iff->ifTrue->type == Type::unreachable) {
- return getFallthrough(iff->ifFalse);
+ return getFallthrough(iff->ifFalse, passOptions, features);
} else if (iff->ifFalse->type == Type::unreachable) {
- return getFallthrough(iff->ifTrue);
+ return getFallthrough(iff->ifTrue, passOptions, features);
}
}
} else if (auto* br = curr->dynCast<Break>()) {
if (br->condition && br->value) {
- return getFallthrough(br->value);
+ return getFallthrough(br->value, passOptions, features);
+ }
+ } else if (auto* tryy = curr->dynCast<Try>()) {
+ if (!EffectAnalyzer(passOptions, features, tryy->body).throws) {
+ return getFallthrough(tryy->body, passOptions, features);
}
}
return curr;
}
-inline bool isConstantExpression(const Expression* curr) {
- return curr->is<Const>() || curr->is<RefNull>() || curr->is<RefFunc>();
-}
-
} // namespace Properties
} // namespace wasm