From 9a4bec7e474a310c7f93ff3b84928e0e9ba9cce6 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Mon, 15 Oct 2018 11:52:35 +0200 Subject: Renaming libjulia to libyul --- libyul/optimiser/CommonSubexpressionEliminator.cpp | 71 ++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 libyul/optimiser/CommonSubexpressionEliminator.cpp (limited to 'libyul/optimiser/CommonSubexpressionEliminator.cpp') diff --git a/libyul/optimiser/CommonSubexpressionEliminator.cpp b/libyul/optimiser/CommonSubexpressionEliminator.cpp new file mode 100644 index 00000000..8bb4ca2e --- /dev/null +++ b/libyul/optimiser/CommonSubexpressionEliminator.cpp @@ -0,0 +1,71 @@ +/*( + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +/** + * Optimisation stage that replaces expressions known to be the current value of a variable + * in scope by a reference to that variable. + */ + +#include + +#include +#include +#include + +#include + +using namespace std; +using namespace dev; +using namespace dev::julia; + +void CommonSubexpressionEliminator::visit(Expression& _e) +{ + // We visit the inner expression first to first simplify inner expressions, + // which hopefully allows more matches. + // Note that the DataFlowAnalyzer itself only has code for visiting Statements, + // so this basically invokes the AST walker directly and thus post-visiting + // is also fine with regards to data flow analysis. + DataFlowAnalyzer::visit(_e); + + if (_e.type() == typeid(Identifier)) + { + Identifier& identifier = boost::get(_e); + string const& name = identifier.name; + if (m_value.count(name)) + { + assertThrow(m_value.at(name), OptimizerException, ""); + if (m_value.at(name)->type() == typeid(Identifier)) + { + string const& value = boost::get(*m_value.at(name)).name; + if (inScope(value)) + _e = Identifier{locationOf(_e), value}; + } + } + } + else + { + // TODO this search is rather inefficient. + for (auto const& var: m_value) + { + assertThrow(var.second, OptimizerException, ""); + if (SyntacticalEqualityChecker::equal(_e, *var.second)) + { + _e = Identifier{locationOf(_e), var.first}; + break; + } + } + } +} -- cgit v1.2.3 From 1304361b9c48438d5c55903492b5f11c3dac73e5 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Mon, 15 Oct 2018 11:58:51 +0200 Subject: Renaming namespace dev::julia to dev::yul. --- libyul/optimiser/CommonSubexpressionEliminator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libyul/optimiser/CommonSubexpressionEliminator.cpp') diff --git a/libyul/optimiser/CommonSubexpressionEliminator.cpp b/libyul/optimiser/CommonSubexpressionEliminator.cpp index 8bb4ca2e..23d15cad 100644 --- a/libyul/optimiser/CommonSubexpressionEliminator.cpp +++ b/libyul/optimiser/CommonSubexpressionEliminator.cpp @@ -29,7 +29,7 @@ using namespace std; using namespace dev; -using namespace dev::julia; +using namespace dev::yul; void CommonSubexpressionEliminator::visit(Expression& _e) { -- cgit v1.2.3 From 48749146da6bd335928126855053ea0e3b66aee4 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 18 Oct 2018 14:45:11 +0200 Subject: Fix a bug in CSE where a variable that was already out of scope was used. --- libyul/optimiser/CommonSubexpressionEliminator.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'libyul/optimiser/CommonSubexpressionEliminator.cpp') diff --git a/libyul/optimiser/CommonSubexpressionEliminator.cpp b/libyul/optimiser/CommonSubexpressionEliminator.cpp index 23d15cad..51737097 100644 --- a/libyul/optimiser/CommonSubexpressionEliminator.cpp +++ b/libyul/optimiser/CommonSubexpressionEliminator.cpp @@ -50,8 +50,8 @@ void CommonSubexpressionEliminator::visit(Expression& _e) if (m_value.at(name)->type() == typeid(Identifier)) { string const& value = boost::get(*m_value.at(name)).name; - if (inScope(value)) - _e = Identifier{locationOf(_e), value}; + assertThrow(inScope(value), OptimizerException, ""); + _e = Identifier{locationOf(_e), value}; } } } @@ -61,6 +61,7 @@ void CommonSubexpressionEliminator::visit(Expression& _e) for (auto const& var: m_value) { assertThrow(var.second, OptimizerException, ""); + assertThrow(inScope(var.first), OptimizerException, ""); if (SyntacticalEqualityChecker::equal(_e, *var.second)) { _e = Identifier{locationOf(_e), var.first}; -- cgit v1.2.3 From 674e17c2a895eff6729357d8c10db709ac368b79 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 29 Oct 2018 15:12:02 +0100 Subject: Performance: Replace string by special single-copy YulString class. --- libyul/optimiser/CommonSubexpressionEliminator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libyul/optimiser/CommonSubexpressionEliminator.cpp') diff --git a/libyul/optimiser/CommonSubexpressionEliminator.cpp b/libyul/optimiser/CommonSubexpressionEliminator.cpp index 51737097..64605362 100644 --- a/libyul/optimiser/CommonSubexpressionEliminator.cpp +++ b/libyul/optimiser/CommonSubexpressionEliminator.cpp @@ -43,13 +43,13 @@ void CommonSubexpressionEliminator::visit(Expression& _e) if (_e.type() == typeid(Identifier)) { Identifier& identifier = boost::get(_e); - string const& name = identifier.name; + YulString name = identifier.name; if (m_value.count(name)) { assertThrow(m_value.at(name), OptimizerException, ""); if (m_value.at(name)->type() == typeid(Identifier)) { - string const& value = boost::get(*m_value.at(name)).name; + YulString value = boost::get(*m_value.at(name)).name; assertThrow(inScope(value), OptimizerException, ""); _e = Identifier{locationOf(_e), value}; } -- cgit v1.2.3