diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 9dee5348a..5a86d2a23 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -43,7 +43,6 @@ add_library(yul optimiser/SyntacticalEquality.cpp optimiser/UnusedPruner.cpp optimiser/Utilities.cpp - optimiser/VarDeclPropagator.cpp optimiser/VarDeclInitializer.cpp ) target_link_libraries(yul PUBLIC evmasm devcore langutil) diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 16df6d3ca..bfba8dfca 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -70,7 +69,6 @@ void OptimiserSuite::run( ExpressionSplitter{dispenser}(ast); SSATransform::run(ast, dispenser); RedundantAssignEliminator::run(ast); - VarDeclPropagator{}(ast); RedundantAssignEliminator::run(ast); CommonSubexpressionEliminator{}(ast); @@ -97,27 +95,22 @@ void OptimiserSuite::run( RedundantAssignEliminator::run(ast); CommonSubexpressionEliminator{}(ast); FullInliner{ast, dispenser}.run(); - VarDeclPropagator{}(ast); SSATransform::run(ast, dispenser); RedundantAssignEliminator::run(ast); - VarDeclPropagator{}(ast); RedundantAssignEliminator::run(ast); ExpressionSimplifier::run(ast); StructuralSimplifier{}(ast); CommonSubexpressionEliminator{}(ast); SSATransform::run(ast, dispenser); RedundantAssignEliminator::run(ast); - VarDeclPropagator{}(ast); RedundantAssignEliminator::run(ast); UnusedPruner::runUntilStabilised(ast, reservedIdentifiers); } ExpressionJoiner::run(ast); - VarDeclPropagator{}(ast); UnusedPruner::runUntilStabilised(ast); ExpressionJoiner::run(ast); UnusedPruner::runUntilStabilised(ast); ExpressionJoiner::run(ast); - VarDeclPropagator{}(ast); UnusedPruner::runUntilStabilised(ast); ExpressionJoiner::run(ast); UnusedPruner::runUntilStabilised(ast); diff --git a/libyul/optimiser/VarDeclPropagator.cpp b/libyul/optimiser/VarDeclPropagator.cpp deleted file mode 100644 index bf974f44c..000000000 --- a/libyul/optimiser/VarDeclPropagator.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - 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 . -*/ - -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace dev; -using namespace yul; - -void VarDeclPropagator::operator()(Block& _block) -{ - map outerEmptyVarDecls; - map outerLazyInitializedVarDecls; - swap(m_emptyVarDecls, outerEmptyVarDecls); - swap(m_lazyInitializedVarDecls, outerLazyInitializedVarDecls); - - ASTModifier::operator()(_block); - - iterateReplacing( - _block.statements, - [this](Statement& _stmt) -> boost::optional> - { - if (_stmt.type() == typeid(VariableDeclaration)) - { - VariableDeclaration& varDecl = boost::get(_stmt); - boost::remove_erase_if( - varDecl.variables, - [&](TypedName const& _typedName) { return m_lazyInitializedVarDecls.count(_typedName.name); } - ); - if (varDecl.variables.empty()) - return vector{}; - else - return {}; - } - else if (_stmt.type() == typeid(Assignment)) - { - Assignment& assignment = boost::get(_stmt); - if (isFullyLazyInitialized(assignment.variableNames)) - return vector{recreateVariableDeclaration(assignment)}; - else - return {}; - } - else - return {}; - } - ); - - swap(m_emptyVarDecls, outerEmptyVarDecls); - swap(m_lazyInitializedVarDecls, outerLazyInitializedVarDecls); -} - -void VarDeclPropagator::operator()(VariableDeclaration& _varDecl) -{ - if (_varDecl.value) - visit(*_varDecl.value); - else - for (TypedName const& typedName: _varDecl.variables) - m_emptyVarDecls[typedName.name] = typedName; -} - -void VarDeclPropagator::operator()(Assignment& _assignment) -{ - visit(*_assignment.value); - - if (allVarNamesUninitialized(_assignment.variableNames)) - for (Identifier const& ident: _assignment.variableNames) - m_lazyInitializedVarDecls[ident.name] = m_emptyVarDecls[ident.name]; - - for (Identifier& name: _assignment.variableNames) - (*this)(name); -} - -void VarDeclPropagator::operator()(Identifier& _ident) -{ - m_emptyVarDecls.erase(_ident.name); -} - -bool VarDeclPropagator::allVarNamesUninitialized(vector const& _variableNames) const -{ - return all_of( - begin(_variableNames), - end(_variableNames), - [&](Identifier const& _ident) -> bool { return m_emptyVarDecls.count(_ident.name); } - ); -} - -bool VarDeclPropagator::isFullyLazyInitialized(vector const& _variableNames) const -{ - return all_of( - begin(_variableNames), - end(_variableNames), - [&](Identifier const& ident) -> bool { return m_lazyInitializedVarDecls.count(ident.name); } - ); -} - -VariableDeclaration VarDeclPropagator::recreateVariableDeclaration(Assignment& _assignment) -{ - TypedNameList variables; - - for (Identifier const& varName: _assignment.variableNames) - { - variables.emplace_back(move(m_lazyInitializedVarDecls.at(varName.name))); - m_lazyInitializedVarDecls.erase(varName.name); - } - - return VariableDeclaration{move(_assignment.location), move(variables), std::move(_assignment.value)}; -} diff --git a/libyul/optimiser/VarDeclPropagator.h b/libyul/optimiser/VarDeclPropagator.h deleted file mode 100644 index 1908c2142..000000000 --- a/libyul/optimiser/VarDeclPropagator.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - 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 . -*/ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace yul -{ - -/** - * Rewrites Assignment statements into VariableDeclaration when the assignment's LHS - * variables had no value yet. - * - * It recursively walks through the AST and moves each declaration of variables to - * the first assignment within the same block (if possible).. - */ -class VarDeclPropagator: public ASTModifier -{ -public: - using ASTModifier::operator(); - void operator()(Block& _block) override; - void operator()(VariableDeclaration& _varDecl) override; - void operator()(Assignment& _assignment) override; - void operator()(Identifier& _ident) override; - -private: - bool allVarNamesUninitialized(std::vector const& _variableNames) const; - bool isFullyLazyInitialized(std::vector const& _variableNames) const; - VariableDeclaration recreateVariableDeclaration(Assignment& _assignment); - -private: - /// Holds a list of variables from current Block that have no value assigned yet. - std::map m_emptyVarDecls; - - /// Holds a list variables (and their TypedName) within the current block. - std::map m_lazyInitializedVarDecls; -}; - -} diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index 68de563df..9643a1e9f 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -108,11 +107,6 @@ bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool con disambiguate(); BlockFlattener{}(*m_ast); } - else if (m_optimizerStep == "varDeclPropagator") - { - disambiguate(); - VarDeclPropagator{}(*m_ast); - } else if (m_optimizerStep == "varDeclInitializer") VarDeclInitializer{}(*m_ast); else if (m_optimizerStep == "forLoopInitRewriter") diff --git a/test/libyul/yulOptimizerTests/varDeclPropagator/init_assignment_inside_if.yul b/test/libyul/yulOptimizerTests/varDeclPropagator/init_assignment_inside_if.yul deleted file mode 100644 index 54fea2fbe..000000000 --- a/test/libyul/yulOptimizerTests/varDeclPropagator/init_assignment_inside_if.yul +++ /dev/null @@ -1,17 +0,0 @@ -{ - let a := 4 - let x - if a { - x := 2 - } -} -// ---- -// varDeclPropagator -// { -// let a := 4 -// let x -// if a -// { -// x := 2 -// } -// } diff --git a/test/libyul/yulOptimizerTests/varDeclPropagator/multi_assignment_vardecl.yul b/test/libyul/yulOptimizerTests/varDeclPropagator/multi_assignment_vardecl.yul deleted file mode 100644 index ed8d33b46..000000000 --- a/test/libyul/yulOptimizerTests/varDeclPropagator/multi_assignment_vardecl.yul +++ /dev/null @@ -1,13 +0,0 @@ -{ - function f() -> a, b, c {} - let x, y, z - z, x, y := f() -} -// ---- -// varDeclPropagator -// { -// function f() -> a, b, c -// { -// } -// let z, x, y := f() -// } diff --git a/test/libyul/yulOptimizerTests/varDeclPropagator/overwrite.yul b/test/libyul/yulOptimizerTests/varDeclPropagator/overwrite.yul deleted file mode 100644 index ca9215000..000000000 --- a/test/libyul/yulOptimizerTests/varDeclPropagator/overwrite.yul +++ /dev/null @@ -1,11 +0,0 @@ -{ - let a - a := 4 - a := 5 -} -// ---- -// varDeclPropagator -// { -// let a := 4 -// a := 5 -// } diff --git a/test/libyul/yulOptimizerTests/varDeclPropagator/rewrite_removes_unused_var.yul b/test/libyul/yulOptimizerTests/varDeclPropagator/rewrite_removes_unused_var.yul deleted file mode 100644 index 3affcac69..000000000 --- a/test/libyul/yulOptimizerTests/varDeclPropagator/rewrite_removes_unused_var.yul +++ /dev/null @@ -1,10 +0,0 @@ -{ - let a, b - a := mload(0) -} -// ---- -// varDeclPropagator -// { -// let b -// let a := mload(0) -// } diff --git a/test/libyul/yulOptimizerTests/varDeclPropagator/simple1.yul b/test/libyul/yulOptimizerTests/varDeclPropagator/simple1.yul deleted file mode 100644 index d89590406..000000000 --- a/test/libyul/yulOptimizerTests/varDeclPropagator/simple1.yul +++ /dev/null @@ -1,9 +0,0 @@ -{ - let f - f := mload(0) -} -// ---- -// varDeclPropagator -// { -// let f := mload(0) -// } diff --git a/test/libyul/yulOptimizerTests/varDeclPropagator/split_assign_splits_vardecl.yul b/test/libyul/yulOptimizerTests/varDeclPropagator/split_assign_splits_vardecl.yul deleted file mode 100644 index e8c91e109..000000000 --- a/test/libyul/yulOptimizerTests/varDeclPropagator/split_assign_splits_vardecl.yul +++ /dev/null @@ -1,11 +0,0 @@ -{ - let a, b - a := mload(0) - b := mload(1) -} -// ---- -// varDeclPropagator -// { -// let a := mload(0) -// let b := mload(1) -// } diff --git a/test/libyul/yulOptimizerTests/varDeclPropagator/use_before_init.yul b/test/libyul/yulOptimizerTests/varDeclPropagator/use_before_init.yul deleted file mode 100644 index 5312112a4..000000000 --- a/test/libyul/yulOptimizerTests/varDeclPropagator/use_before_init.yul +++ /dev/null @@ -1,12 +0,0 @@ -{ - let b - let a := b - b := 1 -} -// ---- -// varDeclPropagator -// { -// let b -// let a := b -// b := 1 -// } diff --git a/test/libyul/yulOptimizerTests/varDeclPropagator/use_doesnt_rewrite.yul b/test/libyul/yulOptimizerTests/varDeclPropagator/use_doesnt_rewrite.yul deleted file mode 100644 index e27785dd5..000000000 --- a/test/libyul/yulOptimizerTests/varDeclPropagator/use_doesnt_rewrite.yul +++ /dev/null @@ -1,16 +0,0 @@ -{ - function f(x) {} - let a - f(a) - a := 4 -} -// ---- -// varDeclPropagator -// { -// function f(x) -// { -// } -// let a -// f(a) -// a := 4 -// } diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index 3dc35f73f..fcbe308f5 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include @@ -125,7 +125,7 @@ public: m_nameDispenser = make_shared(*m_ast); disambiguated = true; } - cout << "(q)quit/(f)flatten/(c)se/propagate var(d)ecls/(x)plit/(j)oin/(g)rouper/(h)oister/" << endl; + cout << "(q)quit/(f)flatten/(c)se/initialize var(d)ecls/(x)plit/(j)oin/(g)rouper/(h)oister/" << endl; cout << " (e)xpr inline/(i)nline/(s)implify/(u)nusedprune/ss(a) transform/" << endl; cout << " (r)edundant assign elim./re(m)aterializer/f(o)r-loop-pre-rewriter/" << endl; cout << " s(t)ructural simplifier? " << endl; @@ -146,7 +146,7 @@ public: (CommonSubexpressionEliminator{})(*m_ast); break; case 'd': - (VarDeclPropagator{})(*m_ast); + (VarDeclInitializer{})(*m_ast); break; case 'x': ExpressionSplitter{*m_nameDispenser}(*m_ast);