Use map join algorithm for performance.

This commit is contained in:
chriseth
2018-11-12 23:00:37 +01:00
parent 4eaed37b96
commit faa7b61d76
3 changed files with 659 additions and 11 deletions
+34 -9
View File
@@ -163,17 +163,42 @@ void RedundantAssignEliminator::run(Block& _ast)
remover(_ast);
}
template <class K, class V, class F>
void joinMap(std::map<K, V>& _a, std::map<K, V>&& _b, F _conflictSolver)
{
// TODO Perhaps it is better to just create a sorted list
// and then use insert(begin, end)
auto ita = _a.begin();
auto aend = _a.end();
auto itb = _b.begin();
auto bend = _b.end();
for (; itb != bend; ++ita)
{
if (ita == aend)
ita = _a.insert(ita, std::move(*itb++));
else if (ita->first < itb->first)
continue;
else if (itb->first < ita->first)
ita = _a.insert(ita, std::move(*itb++));
else
{
_conflictSolver(ita->second, std::move(itb->second));
++itb;
}
}
}
void RedundantAssignEliminator::join(RedundantAssignEliminator& _other)
{
for (auto& var: _other.m_assignments)
if (m_assignments.count(var.first))
{
map<Assignment const*, State>& assignmentsHere = m_assignments[var.first];
for (auto& assignment: var.second)
assignmentsHere[assignment.first].join(assignment.second);
}
else
m_assignments[var.first] = std::move(var.second);
joinMap(m_assignments, std::move(_other.m_assignments), [](
map<Assignment const*, State>& _assignmentHere,
map<Assignment const*, State>&& _assignmentThere
)
{
return joinMap(_assignmentHere, std::move(_assignmentThere), State::join);
});
}
void RedundantAssignEliminator::changeUndecidedTo(YulString _variable, RedundantAssignEliminator::State _newState)
+2 -2
View File
@@ -127,10 +127,10 @@ private:
State(Value _value = Undecided): m_value(_value) {}
inline bool operator==(State _other) const { return m_value == _other.m_value; }
inline bool operator!=(State _other) const { return !operator==(_other); }
inline void join(State const& _other)
static inline void join(State& _a, State const& _b)
{
// Using "max" works here because of the order of the values in the enum.
m_value = Value(std::max(int(_other.m_value), int(m_value)));
_a.m_value = Value(std::max(int(_a.m_value), int(_b.m_value)));
}
private:
Value m_value = Undecided;