Yul] RedundantAssignEliminator: Implements break/continue handling within ForLoop.

This commit is contained in:
Christian Parpart
2019-03-26 17:36:43 +01:00
committed by chriseth
parent d8c42a0270
commit a1ec49409d
6 changed files with 160 additions and 2 deletions
+20 -2
View File
@@ -133,9 +133,14 @@ void RedundantAssignEliminator::operator()(ForLoop const& _forLoop)
visit(*_forLoop.condition);
ForLoopInfo outerForLoopInfo;
swap(outerForLoopInfo, m_forLoopInfo);
TrackedAssignments zeroRuns{m_assignments};
(*this)(_forLoop.body);
merge(m_assignments, move(m_forLoopInfo.pendingContinueStmts));
m_forLoopInfo.pendingContinueStmts = {};
(*this)(_forLoop.post);
visit(*_forLoop.condition);
@@ -143,6 +148,8 @@ void RedundantAssignEliminator::operator()(ForLoop const& _forLoop)
TrackedAssignments oneRun{m_assignments};
(*this)(_forLoop.body);
merge(m_assignments, move(m_forLoopInfo.pendingContinueStmts));
(*this)(_forLoop.post);
visit(*_forLoop.condition);
@@ -150,16 +157,20 @@ void RedundantAssignEliminator::operator()(ForLoop const& _forLoop)
// Order does not matter because "max" is commutative and associative.
merge(m_assignments, move(oneRun));
merge(m_assignments, move(zeroRuns));
merge(m_assignments, move(m_forLoopInfo.pendingBreakStmts));
// Oestore potential outer for-loop states.
swap(m_forLoopInfo, outerForLoopInfo);
}
void RedundantAssignEliminator::operator()(Break const&)
{
yulAssert(false, "Not implemented yet.");
m_forLoopInfo.pendingBreakStmts.push_back(m_assignments);
}
void RedundantAssignEliminator::operator()(Continue const&)
{
yulAssert(false, "Not implemented yet.");
m_forLoopInfo.pendingContinueStmts.push_back(m_assignments);
}
void RedundantAssignEliminator::operator()(Block const& _block)
@@ -218,6 +229,13 @@ void RedundantAssignEliminator::merge(TrackedAssignments& _target, TrackedAssign
});
}
void RedundantAssignEliminator::merge(TrackedAssignments& _target, vector<TrackedAssignments>&& _source)
{
for (TrackedAssignments& ts: _source)
merge(_target, move(ts));
_source.clear();
}
void RedundantAssignEliminator::changeUndecidedTo(YulString _variable, RedundantAssignEliminator::State _newState)
{
for (auto& assignment: m_assignments[_variable])