aboutsummaryrefslogtreecommitdiffstats
path: root/libyul/optimiser/DataFlowAnalyzer.cpp
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-10-19 00:58:46 +0800
committerGitHub <noreply@github.com>2018-10-19 00:58:46 +0800
commit52ffe5262edb3bd1fcb2477d8f3339f135f85563 (patch)
tree2106f5a23016d73cee12dd81a65ae45fa2400786 /libyul/optimiser/DataFlowAnalyzer.cpp
parent7609e2871e77b623d4c6187b7ebed693ce74cd0e (diff)
parent48749146da6bd335928126855053ea0e3b66aee4 (diff)
downloaddexon-solidity-52ffe5262edb3bd1fcb2477d8f3339f135f85563.tar
dexon-solidity-52ffe5262edb3bd1fcb2477d8f3339f135f85563.tar.gz
dexon-solidity-52ffe5262edb3bd1fcb2477d8f3339f135f85563.tar.bz2
dexon-solidity-52ffe5262edb3bd1fcb2477d8f3339f135f85563.tar.lz
dexon-solidity-52ffe5262edb3bd1fcb2477d8f3339f135f85563.tar.xz
dexon-solidity-52ffe5262edb3bd1fcb2477d8f3339f135f85563.tar.zst
dexon-solidity-52ffe5262edb3bd1fcb2477d8f3339f135f85563.zip
Merge pull request #5269 from ethereum/cseBugfix
Bugfix in common subexpression eliminator related to scopes.
Diffstat (limited to 'libyul/optimiser/DataFlowAnalyzer.cpp')
-rw-r--r--libyul/optimiser/DataFlowAnalyzer.cpp35
1 files changed, 22 insertions, 13 deletions
diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp
index ca1e5153..7ac42c30 100644
--- a/libyul/optimiser/DataFlowAnalyzer.cpp
+++ b/libyul/optimiser/DataFlowAnalyzer.cpp
@@ -84,19 +84,19 @@ void DataFlowAnalyzer::operator()(Switch& _switch)
void DataFlowAnalyzer::operator()(FunctionDefinition& _fun)
{
- m_variableScopes.emplace_back(true);
+ pushScope(true);
for (auto const& parameter: _fun.parameters)
m_variableScopes.back().variables.insert(parameter.name);
for (auto const& var: _fun.returnVariables)
m_variableScopes.back().variables.insert(var.name);
ASTModifier::operator()(_fun);
- m_variableScopes.pop_back();
+ popScope();
}
void DataFlowAnalyzer::operator()(ForLoop& _for)
{
// Special scope handling of the pre block.
- m_variableScopes.emplace_back(false);
+ pushScope(false);
for (auto& statement: _for.pre.statements)
visit(statement);
@@ -110,16 +110,15 @@ void DataFlowAnalyzer::operator()(ForLoop& _for)
(*this)(_for.post);
clearValues(assignments.names());
-
- m_variableScopes.pop_back();
+ popScope();
}
void DataFlowAnalyzer::operator()(Block& _block)
{
size_t numScopes = m_variableScopes.size();
- m_variableScopes.emplace_back(false);
+ pushScope(false);
ASTModifier::operator()(_block);
- m_variableScopes.pop_back();
+ popScope();
assertThrow(numScopes == m_variableScopes.size(), OptimizerException, "");
}
@@ -148,7 +147,18 @@ void DataFlowAnalyzer::handleAssignment(set<string> const& _variables, Expressio
}
}
-void DataFlowAnalyzer::clearValues(set<string> const& _variables)
+void DataFlowAnalyzer::pushScope(bool _functionScope)
+{
+ m_variableScopes.emplace_back(_functionScope);
+}
+
+void DataFlowAnalyzer::popScope()
+{
+ clearValues(std::move(m_variableScopes.back().variables));
+ m_variableScopes.pop_back();
+}
+
+void DataFlowAnalyzer::clearValues(set<string> _variables)
{
// All variables that reference variables to be cleared also have to be
// cleared, but not recursively, since only the value of the original
@@ -163,16 +173,15 @@ void DataFlowAnalyzer::clearValues(set<string> const& _variables)
// This cannot be easily tested since the substitutions will be done
// one by one on the fly, and the last line will just be add(1, 1)
- set<string> variables = _variables;
// Clear variables that reference variables to be cleared.
- for (auto const& name: variables)
+ for (auto const& name: _variables)
for (auto const& ref: m_referencedBy[name])
- variables.insert(ref);
+ _variables.insert(ref);
// Clear the value and update the reference relation.
- for (auto const& name: variables)
+ for (auto const& name: _variables)
m_value.erase(name);
- for (auto const& name: variables)
+ for (auto const& name: _variables)
{
for (auto const& ref: m_references[name])
m_referencedBy[ref].erase(name);