diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2020-03-05 15:52:44 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-05 15:52:44 -0800 |
commit | 9e3dbb1f668a14341e9aebae479537d4a26095a5 (patch) | |
tree | 9857d50c3373c3f6320ca3f2586bd499bc40b224 /src/passes/Precompute.cpp | |
parent | 3a275d0627da443cce93631a64d78e7b3f441416 (diff) | |
download | binaryen-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.cpp | 45 |
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. |