diff options
Diffstat (limited to 'src/ir/properties.h')
-rw-r--r-- | src/ir/properties.h | 30 |
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 |