diff options
Diffstat (limited to 'src/ir')
-rw-r--r-- | src/ir/cost.h | 12 | ||||
-rw-r--r-- | src/ir/properties.h | 30 |
2 files changed, 31 insertions, 11 deletions
diff --git a/src/ir/cost.h b/src/ir/cost.h index 37f2611dd..e89fb9d17 100644 --- a/src/ir/cost.h +++ b/src/ir/cost.h @@ -726,6 +726,18 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> { Index visitDrop(Drop* curr) { return visit(curr->value); } Index visitReturn(Return* curr) { return maybeVisit(curr->value); } Index visitHost(Host* curr) { return 100; } + Index visitRefNull(RefNull* curr) { return 1; } + Index visitRefIsNull(RefIsNull* curr) { return 1; } + Index visitRefFunc(RefFunc* curr) { return 1; } + Index visitTry(Try* curr) { + // We assume no exception will be thrown in most cases + return visit(curr->body); + } + Index visitThrow(Throw* curr) { return 100; } + Index visitRethrow(Rethrow* curr) { return 100; } + Index visitBrOnExn(BrOnExn* curr) { + return 1 + visit(curr->exnref) + curr->sent.size(); + } Index visitNop(Nop* curr) { return 0; } Index visitUnreachable(Unreachable* curr) { return 0; } }; 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 |