Fix redundant assignment removal in combination with break / continue.

This commit is contained in:
chriseth 2019-12-29 14:21:23 +01:00
parent 6a57276fdc
commit 1e50fc61e4
2 changed files with 15 additions and 18 deletions

View File

@ -268,29 +268,28 @@ void RedundantAssignEliminator::changeUndecidedTo(YulString _variable, Redundant
void RedundantAssignEliminator::finalize(YulString _variable, RedundantAssignEliminator::State _finalState) void RedundantAssignEliminator::finalize(YulString _variable, RedundantAssignEliminator::State _finalState)
{ {
finalize(m_assignments, _variable, _finalState); std::map<Assignment const*, State> assignments;
for (auto& assignments: m_forLoopInfo.pendingBreakStmts) joinMap(assignments, std::move(m_assignments[_variable]), State::join);
finalize(assignments, _variable, _finalState); m_assignments.erase(_variable);
for (auto& assignments: m_forLoopInfo.pendingContinueStmts)
finalize(assignments, _variable, _finalState);
}
void RedundantAssignEliminator::finalize( for (auto& breakAssignments: m_forLoopInfo.pendingBreakStmts)
TrackedAssignments& _assignments, {
YulString _variable, joinMap(assignments, std::move(breakAssignments[_variable]), State::join);
RedundantAssignEliminator::State _finalState breakAssignments.erase(_variable);
) }
{ for (auto& continueAssignments: m_forLoopInfo.pendingContinueStmts)
for (auto const& assignment: _assignments[_variable]) {
joinMap(assignments, std::move(continueAssignments[_variable]), State::join);
continueAssignments.erase(_variable);
}
for (auto const& assignment: assignments)
{ {
State const state = assignment.second == State::Undecided ? _finalState : assignment.second; State const state = assignment.second == State::Undecided ? _finalState : assignment.second;
if (state == State::Unused && SideEffectsCollector{*m_dialect, *assignment.first->value}.movable()) if (state == State::Unused && SideEffectsCollector{*m_dialect, *assignment.first->value}.movable())
// TODO the only point where we actually need this
// to be a set is for the for loop
m_pendingRemovals.insert(assignment.first); m_pendingRemovals.insert(assignment.first);
} }
_assignments.erase(_variable);
} }
void AssignmentRemover::operator()(Block& _block) void AssignmentRemover::operator()(Block& _block)

View File

@ -158,8 +158,6 @@ private:
/// assignments to the final state. In this case, this also applies to pending /// assignments to the final state. In this case, this also applies to pending
/// break and continue TrackedAssignments. /// break and continue TrackedAssignments.
void finalize(YulString _variable, State _finalState); void finalize(YulString _variable, State _finalState);
/// Helper function for the above.
void finalize(TrackedAssignments& _assignments, YulString _variable, State _finalState);
Dialect const* m_dialect; Dialect const* m_dialect;
std::set<YulString> m_declaredVariables; std::set<YulString> m_declaredVariables;