diff options
Diffstat (limited to 'src/passes/Precompute.cpp')
-rw-r--r-- | src/passes/Precompute.cpp | 58 |
1 files changed, 27 insertions, 31 deletions
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp index 176642fd6..0a4a691f2 100644 --- a/src/passes/Precompute.cpp +++ b/src/passes/Precompute.cpp @@ -47,7 +47,7 @@ static const Name NOTPRECOMPUTABLE_FLOW("Binaryen|notprecomputable"); // helpful to avoid platform differences in native stack sizes. static const Index MAX_DEPTH = 50; -typedef std::unordered_map<LocalGet*, Literal> GetValues; +typedef std::unordered_map<LocalGet*, Literals> GetValues; // Precomputes an expression. Errors if we hit anything that can't be // precomputed. @@ -89,9 +89,9 @@ public: Flow visitLocalGet(LocalGet* curr) { auto iter = getValues.find(curr); if (iter != getValues.end()) { - auto value = iter->second; - if (value.isConcrete()) { - return Flow(value); + auto values = iter->second; + if (values.isConcrete()) { + return Flow(std::move(values)); } } return Flow(NOTPRECOMPUTABLE_FLOW); @@ -188,10 +188,6 @@ struct Precompute } // try to evaluate this into a const Flow flow = precomputeExpression(curr); - if (flow.values.size() > 1) { - // TODO: handle multivalue types - return; - } if (flow.getType().hasVector()) { return; } @@ -203,7 +199,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.size() > 0) { + 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>()) { @@ -219,8 +215,8 @@ struct Precompute } else { Builder builder(*getModule()); replaceCurrent(builder.makeReturn( - flow.values.size() > 0 ? flow.getConstExpression(*getModule()) - : nullptr)); + flow.values.isConcrete() ? flow.getConstExpression(*getModule()) + : nullptr)); } return; } @@ -229,7 +225,7 @@ struct Precompute if (auto* br = curr->dynCast<Break>()) { br->name = flow.breakTo; br->condition = nullptr; - if (flow.values.size() > 0) { + 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>()) { @@ -248,13 +244,13 @@ struct Precompute Builder builder(*getModule()); replaceCurrent(builder.makeBreak( flow.breakTo, - flow.values.size() > 0 ? flow.getConstExpression(*getModule()) - : nullptr)); + flow.values.isConcrete() ? flow.getConstExpression(*getModule()) + : nullptr)); } return; } // this was precomputed - if (flow.getType().isConcrete()) { + if (flow.values.isConcrete()) { replaceCurrent(flow.getConstExpression(*getModule())); worked = true; } else { @@ -287,14 +283,14 @@ private: // (local.tee (i32.const 1)) // will have value 1 which we can optimize here, but in precomputeExpression // we could not do anything. - Literal precomputeValue(Expression* curr) { + Literals precomputeValue(Expression* curr) { // Note that we set replaceExpression to false, as we just care about // the value here. Flow flow = precomputeExpression(curr, false /* replaceExpression */); if (flow.breaking()) { - return Literal(); + return {}; } - return flow.getSingleValue(); + return flow.values; } // Propagates values around. Returns whether we propagated. @@ -315,7 +311,7 @@ private: work.insert(curr); } // the constant value, or none if not a constant - std::unordered_map<LocalSet*, Literal> setValues; + std::unordered_map<LocalSet*, Literals> setValues; // propagate constant values while (!work.empty()) { auto iter = work.begin(); @@ -328,30 +324,30 @@ private: if (setValues[set].isConcrete()) { continue; // already known constant } - auto value = setValues[set] = + auto values = setValues[set] = precomputeValue(Properties::getFallthrough( set->value, getPassOptions(), getModule()->features)); - if (value.isConcrete()) { + if (values.isConcrete()) { for (auto* get : localGraph.setInfluences[set]) { work.insert(get); } } } else { auto* get = curr->cast<LocalGet>(); - if (getValues[get].isConcrete()) { + if (getValues[get].size() >= 1) { continue; // already known constant } // for this get to have constant value, all sets must agree - Literal value; + Literals values; bool first = true; for (auto* set : localGraph.getSetses[get]) { - Literal curr; + Literals curr; if (set == nullptr) { if (getFunction()->isVar(get->index)) { curr = Literal::makeZero(getFunction()->getLocalType(get->index)); } else { // it's a param, so it's hopeless - value = Literal(); + values = {}; break; } } else { @@ -359,25 +355,25 @@ private: } if (curr.isNone()) { // not a constant, give up - value = Literal(); + values = {}; break; } // we found a concrete value. compare with the current one if (first) { - value = curr; // this is the first + values = curr; // this is the first first = false; } else { - if (value != curr) { + if (values != curr) { // not the same, give up - value = Literal(); + values = {}; break; } } } // we may have found a value - if (value.isConcrete()) { + if (values.isConcrete()) { // we did! - getValues[get] = value; + getValues[get] = values; for (auto* set : localGraph.getInfluences[get]) { work.insert(set); } |