summaryrefslogtreecommitdiff
path: root/src/passes/Precompute.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/Precompute.cpp')
-rw-r--r--src/passes/Precompute.cpp61
1 files changed, 33 insertions, 28 deletions
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp
index 0a4a691f2..d809b8b43 100644
--- a/src/passes/Precompute.cpp
+++ b/src/passes/Precompute.cpp
@@ -174,6 +174,37 @@ struct Precompute
} while (propagate && worked);
}
+ template<typename T> void reuseConstantNode(T* curr, Flow flow) {
+ if (flow.values.isConcrete()) {
+ // reuse a const / ref.null / ref.func node if there is one
+ if (curr->value && flow.values.size() == 1) {
+ Literal singleValue = flow.getSingleValue();
+ if (singleValue.type.isNumber()) {
+ if (auto* c = curr->value->template dynCast<Const>()) {
+ c->value = singleValue;
+ c->finalize();
+ curr->finalize();
+ return;
+ }
+ } else if (singleValue.type == Type::nullref &&
+ curr->value->template is<RefNull>()) {
+ return;
+ } else if (singleValue.type == Type::funcref) {
+ if (auto* r = curr->value->template dynCast<RefFunc>()) {
+ r->func = singleValue.getFunc();
+ r->finalize();
+ curr->finalize();
+ return;
+ }
+ }
+ }
+ curr->value = flow.getConstExpression(*getModule());
+ } else {
+ curr->value = nullptr;
+ }
+ curr->finalize();
+ }
+
void visitExpression(Expression* curr) {
// TODO: if local.get, only replace with a constant if we don't care about
// size...?
@@ -199,19 +230,7 @@ struct Precompute
// this expression causes a return. if it's already a return, reuse the
// node
if (auto* ret = curr->dynCast<Return>()) {
- if (flow.values.isConcrete()) {
- // reuse a const value if there is one
- if (ret->value && flow.values.size() == 1) {
- if (auto* value = ret->value->dynCast<Const>()) {
- value->value = flow.getSingleValue();
- value->finalize();
- return;
- }
- }
- ret->value = flow.getConstExpression(*getModule());
- } else {
- ret->value = nullptr;
- }
+ reuseConstantNode(ret, flow);
} else {
Builder builder(*getModule());
replaceCurrent(builder.makeReturn(
@@ -225,21 +244,7 @@ struct Precompute
if (auto* br = curr->dynCast<Break>()) {
br->name = flow.breakTo;
br->condition = nullptr;
- if (flow.values.isConcrete()) {
- // reuse a const value if there is one
- if (br->value && flow.values.size() == 1) {
- if (auto* value = br->value->dynCast<Const>()) {
- value->value = flow.getSingleValue();
- value->finalize();
- br->finalize();
- return;
- }
- }
- br->value = flow.getConstExpression(*getModule());
- } else {
- br->value = nullptr;
- }
- br->finalize();
+ reuseConstantNode(br, flow);
} else {
Builder builder(*getModule());
replaceCurrent(builder.makeBreak(