summaryrefslogtreecommitdiff
path: root/src/passes/Precompute.cpp
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2020-03-05 15:52:44 -0800
committerGitHub <noreply@github.com>2020-03-05 15:52:44 -0800
commit9e3dbb1f668a14341e9aebae479537d4a26095a5 (patch)
tree9857d50c3373c3f6320ca3f2586bd499bc40b224 /src/passes/Precompute.cpp
parent3a275d0627da443cce93631a64d78e7b3f441416 (diff)
downloadbinaryen-9e3dbb1f668a14341e9aebae479537d4a26095a5.tar.gz
binaryen-9e3dbb1f668a14341e9aebae479537d4a26095a5.tar.bz2
binaryen-9e3dbb1f668a14341e9aebae479537d4a26095a5.zip
Initial multivalue support (#2675)
Implements parsing and emitting of tuple creation and extraction and tuple-typed control flow for both the text and binary formats. TODO: - Extend Precompute/interpreter to handle tuple values - C and JS API support/testing - Figure out how to lower in stack IR - Fuzzing
Diffstat (limited to 'src/passes/Precompute.cpp')
-rw-r--r--src/passes/Precompute.cpp45
1 files changed, 26 insertions, 19 deletions
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp
index 3a886166c..197b7bc48 100644
--- a/src/passes/Precompute.cpp
+++ b/src/passes/Precompute.cpp
@@ -188,7 +188,11 @@ struct Precompute
}
// try to evaluate this into a const
Flow flow = precomputeExpression(curr);
- if (flow.value.type.isVector()) {
+ if (flow.values.size() > 1) {
+ // TODO: handle multivalue types
+ return;
+ }
+ if (flow.getSingleValue().type.isVector()) {
return;
}
if (flow.breaking()) {
@@ -199,25 +203,26 @@ struct Precompute
// this expression causes a return. if it's already a return, reuse the
// node
if (auto* ret = curr->dynCast<Return>()) {
- if (flow.value.type != Type::none) {
+ if (flow.getSingleValue().type != Type::none) {
// reuse a const value if there is one
if (ret->value) {
if (auto* value = ret->value->dynCast<Const>()) {
- value->value = flow.value;
+ value->value = flow.getSingleValue();
value->finalize();
return;
}
}
- ret->value = Builder(*getModule()).makeConstExpression(flow.value);
+ ret->value =
+ Builder(*getModule()).makeConstExpression(flow.getSingleValue());
} else {
ret->value = nullptr;
}
} else {
Builder builder(*getModule());
- replaceCurrent(
- builder.makeReturn(flow.value.type != Type::none
- ? builder.makeConstExpression(flow.value)
- : nullptr));
+ replaceCurrent(builder.makeReturn(
+ flow.getSingleValue().type != Type::none
+ ? builder.makeConstExpression(flow.getSingleValue())
+ : nullptr));
}
return;
}
@@ -226,34 +231,36 @@ struct Precompute
if (auto* br = curr->dynCast<Break>()) {
br->name = flow.breakTo;
br->condition = nullptr;
- if (flow.value.type != Type::none) {
+ if (flow.getSingleValue().type != Type::none) {
// reuse a const value if there is one
if (br->value) {
if (auto* value = br->value->dynCast<Const>()) {
- value->value = flow.value;
+ value->value = flow.getSingleValue();
value->finalize();
br->finalize();
return;
}
}
- br->value = Builder(*getModule()).makeConstExpression(flow.value);
+ br->value =
+ Builder(*getModule()).makeConstExpression(flow.getSingleValue());
} else {
br->value = nullptr;
}
br->finalize();
} else {
Builder builder(*getModule());
- replaceCurrent(
- builder.makeBreak(flow.breakTo,
- flow.value.type != Type::none
- ? builder.makeConstExpression(flow.value)
- : nullptr));
+ replaceCurrent(builder.makeBreak(
+ flow.breakTo,
+ flow.getSingleValue().type != Type::none
+ ? builder.makeConstExpression(flow.getSingleValue())
+ : nullptr));
}
return;
}
// this was precomputed
- if (flow.value.type.isConcrete()) {
- replaceCurrent(Builder(*getModule()).makeConstExpression(flow.value));
+ if (flow.getSingleValue().type.isConcrete()) {
+ replaceCurrent(
+ Builder(*getModule()).makeConstExpression(flow.getSingleValue()));
worked = true;
} else {
ExpressionManipulator::nop(curr);
@@ -292,7 +299,7 @@ private:
if (flow.breaking()) {
return Literal();
}
- return flow.value;
+ return flow.getSingleValue();
}
// Propagates values around. Returns whether we propagated.