diff options
37 files changed, 249 insertions, 349 deletions
diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 74a5703c..5a86d2a2 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -43,6 +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/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp index 04005847..95360dc3 100644 --- a/libyul/optimiser/FullInliner.cpp +++ b/libyul/optimiser/FullInliner.cpp @@ -168,6 +168,8 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC m_driver.tentativelyUpdateCodeSize(function->name, m_currentFunction); + static Expression const zero{Literal{{}, LiteralKind::Number, YulString{"0"}, {}}}; + // helper function to create a new variable that is supposed to model // an existing variable. auto newVariable = [&](TypedName const& _existingVariable, Expression* _value) { @@ -176,6 +178,8 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC VariableDeclaration varDecl{_funCall.location, {{_funCall.location, newName, _existingVariable.type}}, {}}; if (_value) varDecl.value = make_shared<Expression>(std::move(*_value)); + else + varDecl.value = make_shared<Expression>(zero); newStatements.emplace_back(std::move(varDecl)); }; diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index ad22bfa3..bfba8dfc 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -21,6 +21,7 @@ #include <libyul/optimiser/Suite.h> #include <libyul/optimiser/Disambiguator.h> +#include <libyul/optimiser/VarDeclInitializer.h> #include <libyul/optimiser/FunctionGrouper.h> #include <libyul/optimiser/FunctionHoister.h> #include <libyul/optimiser/ExpressionSplitter.h> @@ -35,7 +36,6 @@ #include <libyul/optimiser/SSATransform.h> #include <libyul/optimiser/StructuralSimplifier.h> #include <libyul/optimiser/RedundantAssignEliminator.h> -#include <libyul/optimiser/VarDeclPropagator.h> #include <libyul/AsmAnalysisInfo.h> #include <libyul/AsmData.h> #include <libyul/AsmPrinter.h> @@ -56,6 +56,7 @@ void OptimiserSuite::run( Block ast = boost::get<Block>(Disambiguator(_analysisInfo, reservedIdentifiers)(_ast)); + (VarDeclInitializer{})(ast); (FunctionHoister{})(ast); (FunctionGrouper{})(ast); (ForLoopInitRewriter{})(ast); @@ -68,7 +69,6 @@ void OptimiserSuite::run( ExpressionSplitter{dispenser}(ast); SSATransform::run(ast, dispenser); RedundantAssignEliminator::run(ast); - VarDeclPropagator{}(ast); RedundantAssignEliminator::run(ast); CommonSubexpressionEliminator{}(ast); @@ -95,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/VarDeclInitializer.cpp b/libyul/optimiser/VarDeclInitializer.cpp new file mode 100644 index 00000000..4a26757f --- /dev/null +++ b/libyul/optimiser/VarDeclInitializer.cpp @@ -0,0 +1,56 @@ +/* + 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 <http://www.gnu.org/licenses/>. +*/ + +#include <libyul/optimiser/VarDeclInitializer.h> +#include <libyul/AsmData.h> + +#include <libdevcore/CommonData.h> +#include <libdevcore/Visitor.h> + +using namespace std; +using namespace dev; +using namespace yul; + +void VarDeclInitializer::operator()(Block& _block) +{ + ASTModifier::operator()(_block); + + static Expression const zero{Literal{{}, LiteralKind::Number, YulString{"0"}, {}}}; + + using OptionalStatements = boost::optional<vector<Statement>>; + GenericFallbackReturnsVisitor<OptionalStatements, VariableDeclaration> visitor{ + [](VariableDeclaration& _varDecl) -> OptionalStatements + { + if (_varDecl.value) + return {}; + else if (_varDecl.variables.size() == 1) + { + _varDecl.value = make_shared<Expression>(zero); + return {}; + } + else + { + OptionalStatements ret{vector<Statement>{}}; + langutil::SourceLocation loc{std::move(_varDecl.location)}; + for (auto& var: _varDecl.variables) + ret->push_back(VariableDeclaration{loc, {std::move(var)}, make_shared<Expression>(zero)}); + return ret; + } + } + }; + iterateReplacing(_block.statements, boost::apply_visitor(visitor)); +} diff --git a/libyul/optimiser/VarDeclInitializer.h b/libyul/optimiser/VarDeclInitializer.h new file mode 100644 index 00000000..41d0917c --- /dev/null +++ b/libyul/optimiser/VarDeclInitializer.h @@ -0,0 +1,38 @@ +/* + 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 <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include <libyul/AsmDataForward.h> +#include <libyul/optimiser/ASTWalker.h> + +namespace yul +{ + +/** + * Rewrites variable declarations so that all of them are initialized. + * Declarations like ``let x, y`` are split into multiple declaration + * statements. + * Only supports initializing with the zero literal for now. + */ +class VarDeclInitializer: public ASTModifier +{ +public: + void operator()(Block& _block) override; +}; + +} diff --git a/libyul/optimiser/VarDeclPropagator.cpp b/libyul/optimiser/VarDeclPropagator.cpp deleted file mode 100644 index bf974f44..00000000 --- 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 <http://www.gnu.org/licenses/>. -*/ - -#include <libyul/optimiser/VarDeclPropagator.h> -#include <libyul/AsmData.h> -#include <libdevcore/CommonData.h> -#include <boost/range/algorithm_ext/erase.hpp> -#include <algorithm> -#include <map> - -using namespace std; -using namespace dev; -using namespace yul; - -void VarDeclPropagator::operator()(Block& _block) -{ - map<YulString, TypedName> outerEmptyVarDecls; - map<YulString, TypedName> outerLazyInitializedVarDecls; - swap(m_emptyVarDecls, outerEmptyVarDecls); - swap(m_lazyInitializedVarDecls, outerLazyInitializedVarDecls); - - ASTModifier::operator()(_block); - - iterateReplacing( - _block.statements, - [this](Statement& _stmt) -> boost::optional<vector<Statement>> - { - if (_stmt.type() == typeid(VariableDeclaration)) - { - VariableDeclaration& varDecl = boost::get<VariableDeclaration>(_stmt); - boost::remove_erase_if( - varDecl.variables, - [&](TypedName const& _typedName) { return m_lazyInitializedVarDecls.count(_typedName.name); } - ); - if (varDecl.variables.empty()) - return vector<Statement>{}; - else - return {}; - } - else if (_stmt.type() == typeid(Assignment)) - { - Assignment& assignment = boost::get<Assignment>(_stmt); - if (isFullyLazyInitialized(assignment.variableNames)) - return vector<Statement>{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<Identifier> const& _variableNames) const -{ - return all_of( - begin(_variableNames), - end(_variableNames), - [&](Identifier const& _ident) -> bool { return m_emptyVarDecls.count(_ident.name); } - ); -} - -bool VarDeclPropagator::isFullyLazyInitialized(vector<Identifier> 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 1908c214..00000000 --- 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 <http://www.gnu.org/licenses/>. -*/ - -#pragma once - -#include <libyul/AsmDataForward.h> -#include <libyul/optimiser/ASTWalker.h> -#include <libyul/Exceptions.h> -#include <libyul/AsmDataForward.h> -#include <vector> -#include <set> -#include <map> - -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<Identifier> const& _variableNames) const; - bool isFullyLazyInitialized(std::vector<Identifier> const& _variableNames) const; - VariableDeclaration recreateVariableDeclaration(Assignment& _assignment); - -private: - /// Holds a list of variables from current Block that have no value assigned yet. - std::map<YulString, TypedName> m_emptyVarDecls; - - /// Holds a list variables (and their TypedName) within the current block. - std::map<YulString, TypedName> m_lazyInitializedVarDecls; -}; - -} diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index 68226e33..9643a1e9 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -22,7 +22,7 @@ #include <test/Options.h> #include <libyul/optimiser/BlockFlattener.h> -#include <libyul/optimiser/VarDeclPropagator.h> +#include <libyul/optimiser/VarDeclInitializer.h> #include <libyul/optimiser/Disambiguator.h> #include <libyul/optimiser/CommonSubexpressionEliminator.h> #include <libyul/optimiser/NameCollector.h> @@ -107,11 +107,8 @@ 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") { disambiguate(); diff --git a/test/libyul/yulOptimizerTests/fullInliner/double_inline.yul b/test/libyul/yulOptimizerTests/fullInliner/double_inline.yul index ee7f5bf5..b3f51593 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/double_inline.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/double_inline.yul @@ -9,14 +9,14 @@ // { // { // let f_a := calldataload(0) -// let f_b -// let f_c +// let f_b := 0 +// let f_c := 0 // f_b := sload(mload(f_a)) // f_c := 3 // let b3 := f_b // let f_a_2 := f_c -// let f_b_3 -// let f_c_4 +// let f_b_3 := 0 +// let f_c_4 := 0 // f_b_3 := sload(mload(f_a_2)) // f_c_4 := 3 // let b4 := f_b_3 diff --git a/test/libyul/yulOptimizerTests/fullInliner/inside_condition.yul b/test/libyul/yulOptimizerTests/fullInliner/inside_condition.yul index 00bb6577..9e6c4e76 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/inside_condition.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/inside_condition.yul @@ -14,7 +14,7 @@ // { // let _2 := mload(0) // let f_a := mload(1) -// let f_r +// let f_r := 0 // f_a := mload(f_a) // f_r := add(f_a, calldatasize()) // if gt(f_r, _2) diff --git a/test/libyul/yulOptimizerTests/fullInliner/large_function_multi_use.yul b/test/libyul/yulOptimizerTests/fullInliner/large_function_multi_use.yul index e0dad8b8..c00b1163 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/large_function_multi_use.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/large_function_multi_use.yul @@ -23,7 +23,7 @@ // let a2 := 2 // let r := f(a_1) // let f_a := a2 -// let f_b +// let f_b := 0 // let f_x := mload(f_a) // f_b := sload(f_x) // let f_y := add(f_a, f_x) @@ -31,7 +31,7 @@ // let t := f_b // let a3 // let f_a_3 := a3 -// let f_b_4 +// let f_b_4 := 0 // let f_x_5 := mload(f_a_3) // f_b_4 := sload(f_x_5) // let f_y_6 := add(f_a_3, f_x_5) diff --git a/test/libyul/yulOptimizerTests/fullInliner/large_function_single_use.yul b/test/libyul/yulOptimizerTests/fullInliner/large_function_single_use.yul index 3302a35c..72beb8b1 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/large_function_single_use.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/large_function_single_use.yul @@ -15,7 +15,7 @@ // { // { // let f_a := mload(1) -// let f_b +// let f_b := 0 // let f_x := mload(f_a) // f_b := sload(f_x) // let f_c := 3 diff --git a/test/libyul/yulOptimizerTests/fullInliner/long_names.yul b/test/libyul/yulOptimizerTests/fullInliner/long_names.yul index 644e9126..869abbc9 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/long_names.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/long_names.yul @@ -13,7 +13,7 @@ // { // let verylongvariablename2_1 := 3 // let verylongfu_verylongvariablename := verylongvariablename2_1 -// let verylongfu_verylongvariablename2 +// let verylongfu_verylongvariablename2 := 0 // verylongfu_verylongvariablename2 := add(verylongfu_verylongvariablename, verylongfu_verylongvariablename) // mstore(0, verylongfu_verylongvariablename2) // mstore(1, verylongvariablename2_1) diff --git a/test/libyul/yulOptimizerTests/fullInliner/move_up_rightwards_argument.yul b/test/libyul/yulOptimizerTests/fullInliner/move_up_rightwards_argument.yul index f3d0b286..0b46a3c6 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/move_up_rightwards_argument.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/move_up_rightwards_argument.yul @@ -15,7 +15,7 @@ // let f_a := mload(2) // let f_b := _6 // let f_c := _4 -// let f_x +// let f_x := 0 // f_x := add(f_a, f_b) // f_x := mul(f_x, f_c) // let _10 := add(f_x, _2) diff --git a/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul b/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul index 8bc6ec58..5d658e96 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul @@ -9,11 +9,11 @@ // { // let _1 := 7 // let f_a := 3 -// let f_x +// let f_x := 0 // f_x := add(f_a, f_a) // let g_b := f_x // let g_c := _1 -// let g_y +// let g_y := 0 // g_y := mul(mload(g_c), f(g_b)) // let y_1 := g_y // } @@ -24,7 +24,7 @@ // function g(b, c) -> y // { // let f_a_6 := b -// let f_x_7 +// let f_x_7 := 0 // f_x_7 := add(f_a_6, f_a_6) // y := mul(mload(c), f_x_7) // } diff --git a/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul b/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul index 19ac945e..6e4acb97 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul @@ -37,7 +37,7 @@ // function f(x) // { // mstore(0, x) -// let h_t +// let h_t := 0 // h_t := 2 // mstore(7, h_t) // let g_x_1 := 10 diff --git a/test/libyul/yulOptimizerTests/fullInliner/multi_return.yul b/test/libyul/yulOptimizerTests/fullInliner/multi_return.yul index eebdec38..a4cbbef0 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/multi_return.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/multi_return.yul @@ -11,8 +11,8 @@ // { // { // let f_a := mload(0) -// let f_x -// let f_y +// let f_x := 0 +// let f_y := 0 // f_x := mul(f_a, f_a) // f_y := add(f_a, f_x) // let r := f_x diff --git a/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul b/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul index 7b1558c0..f59e2c11 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul @@ -19,25 +19,25 @@ // function g() -> x_1 // { // let f_a := 2 -// let f_b +// let f_b := 0 // f_b := sload(mload(f_a)) // let f_a_20 := f_b -// let f_b_21 +// let f_b_21 := 0 // f_b_21 := sload(mload(f_a_20)) // let f_a_23 := f_b_21 -// let f_b_24 +// let f_b_24 := 0 // f_b_24 := sload(mload(f_a_23)) // let f_a_26 := f_b_24 -// let f_b_27 +// let f_b_27 := 0 // f_b_27 := sload(mload(f_a_26)) // let f_a_29 := f_b_27 -// let f_b_30 +// let f_b_30 := 0 // f_b_30 := sload(mload(f_a_29)) // let f_a_32 := f_b_30 -// let f_b_33 +// let f_b_33 := 0 // f_b_33 := sload(mload(f_a_32)) // let f_a_35 := f_b_33 -// let f_b_36 +// let f_b_36 := 0 // f_b_36 := sload(mload(f_a_35)) // x_1 := f(f(f(f(f(f(f(f(f(f(f(f(f_b_36)))))))))))) // } diff --git a/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_global_context.yul b/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_global_context.yul index c8c49d39..f20b7221 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_global_context.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_global_context.yul @@ -12,25 +12,25 @@ // { // { // let f_a := 2 -// let f_b +// let f_b := 0 // f_b := sload(mload(f_a)) // let f_a_20 := f_b -// let f_b_21 +// let f_b_21 := 0 // f_b_21 := sload(mload(f_a_20)) // let f_a_23 := f_b_21 -// let f_b_24 +// let f_b_24 := 0 // f_b_24 := sload(mload(f_a_23)) // let f_a_26 := f_b_24 -// let f_b_27 +// let f_b_27 := 0 // f_b_27 := sload(mload(f_a_26)) // let f_a_29 := f_b_27 -// let f_b_30 +// let f_b_30 := 0 // f_b_30 := sload(mload(f_a_29)) // let f_a_32 := f_b_30 -// let f_b_33 +// let f_b_33 := 0 // f_b_33 := sload(mload(f_a_32)) // let f_a_35 := f_b_33 -// let f_b_36 +// let f_b_36 := 0 // f_b_36 := sload(mload(f_a_35)) // let x_1 := f(f(f(f(f(f(f(f(f(f(f(f(f_b_36)))))))))))) // } diff --git a/test/libyul/yulOptimizerTests/fullInliner/not_inside_for.yul b/test/libyul/yulOptimizerTests/fullInliner/not_inside_for.yul index 9644e6c1..96d806bd 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/not_inside_for.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/not_inside_for.yul @@ -14,7 +14,7 @@ // { // for { // let f_a := 0 -// let f_r +// let f_r := 0 // sstore(f_a, 0) // f_r := f_a // let x := f_r @@ -22,14 +22,14 @@ // f(x) // { // let f_a_3 := x -// let f_r_4 +// let f_r_4 := 0 // sstore(f_a_3, 0) // f_r_4 := f_a_3 // x := f_r_4 // } // { // let f_a_6 := x -// let f_r_7 +// let f_r_7 := 0 // sstore(f_a_6, 0) // f_r_7 := f_a_6 // let t := f_r_7 diff --git a/test/libyul/yulOptimizerTests/fullInliner/pop_result.yul b/test/libyul/yulOptimizerTests/fullInliner/pop_result.yul index cd9e2746..c1bed208 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/pop_result.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/pop_result.yul @@ -14,7 +14,7 @@ // { // let _1 := 2 // let f_a := 7 -// let f_x +// let f_x := 0 // let f_r := mul(f_a, f_a) // f_x := add(f_r, f_r) // pop(add(f_x, _1)) diff --git a/test/libyul/yulOptimizerTests/fullInliner/simple.yul b/test/libyul/yulOptimizerTests/fullInliner/simple.yul index fcdf453b..1ada8f53 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/simple.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/simple.yul @@ -11,7 +11,7 @@ // { // let _2 := mload(7) // let f_a := sload(mload(2)) -// let f_x +// let f_x := 0 // let f_r := mul(f_a, f_a) // f_x := add(f_r, f_r) // let y := add(f_x, _2) diff --git a/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul b/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul index a3d59ff4..efb846f2 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul @@ -463,12 +463,11 @@ // let _2 := 0 // let _485 := mload(_2) // let abi_encode_pos := _1 -// let abi_encode_end_67_610 // let abi_encode_length_68 := mload(_485) // mstore(_1, abi_encode_length_68) // abi_encode_pos := 64 // let abi_encode_srcPtr := add(_485, _1) -// let abi_encode_i_69 := abi_encode_end_67_610 +// let abi_encode_i_69 := _2 // for { // } // lt(abi_encode_i_69, abi_encode_length_68) @@ -476,21 +475,21 @@ // abi_encode_i_69 := add(abi_encode_i_69, 1) // } // { -// let _857 := mload(abi_encode_srcPtr) -// let abi_encode_pos_71_965 := abi_encode_pos -// let abi_encode_length_72_966 := 0x3 -// let abi_encode_srcPtr_73_967 := _857 -// let abi_encode_i_74_968 := _2 +// let _863 := mload(abi_encode_srcPtr) +// let abi_encode_pos_71_971 := abi_encode_pos +// let abi_encode_length_72_972 := 0x3 +// let abi_encode_srcPtr_73_973 := _863 +// let abi_encode_i_74_974 := _2 // for { // } -// lt(abi_encode_i_74_968, abi_encode_length_72_966) +// lt(abi_encode_i_74_974, abi_encode_length_72_972) // { -// abi_encode_i_74_968 := add(abi_encode_i_74_968, 1) +// abi_encode_i_74_974 := add(abi_encode_i_74_974, 1) // } // { -// mstore(abi_encode_pos_71_965, and(mload(abi_encode_srcPtr_73_967), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) -// abi_encode_srcPtr_73_967 := add(abi_encode_srcPtr_73_967, _1) -// abi_encode_pos_71_965 := add(abi_encode_pos_71_965, _1) +// mstore(abi_encode_pos_71_971, and(mload(abi_encode_srcPtr_73_973), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) +// abi_encode_srcPtr_73_973 := add(abi_encode_srcPtr_73_973, _1) +// abi_encode_pos_71_971 := add(abi_encode_pos_71_971, _1) // } // abi_encode_srcPtr := add(abi_encode_srcPtr, _1) // abi_encode_pos := add(abi_encode_pos, 0x60) diff --git a/test/libyul/yulOptimizerTests/varDeclInitializer/ambiguous.yul b/test/libyul/yulOptimizerTests/varDeclInitializer/ambiguous.yul new file mode 100644 index 00000000..5e2d60c2 --- /dev/null +++ b/test/libyul/yulOptimizerTests/varDeclInitializer/ambiguous.yul @@ -0,0 +1,29 @@ +{ + // This component does not need the disambiguator + function f() -> x, y { + let a, b + mstore(a, b) + let d + d := 2 + } + let a + a := 4 + let b := 2 + let x, y := f() +} +// ---- +// varDeclInitializer +// { +// function f() -> x, y +// { +// let a := 0 +// let b := 0 +// mstore(a, b) +// let d := 0 +// d := 2 +// } +// let a := 0 +// a := 4 +// let b := 2 +// let x, y := f() +// } diff --git a/test/libyul/yulOptimizerTests/varDeclInitializer/inside_func.yul b/test/libyul/yulOptimizerTests/varDeclInitializer/inside_func.yul new file mode 100644 index 00000000..16428d7e --- /dev/null +++ b/test/libyul/yulOptimizerTests/varDeclInitializer/inside_func.yul @@ -0,0 +1,24 @@ +{ + function f() -> x, y { + let a, b + mstore(a, b) + let d + d := 2 + } + let r + r := 4 +} +// ---- +// varDeclInitializer +// { +// function f() -> x, y +// { +// let a := 0 +// let b := 0 +// mstore(a, b) +// let d := 0 +// d := 2 +// } +// let r := 0 +// r := 4 +// } diff --git a/test/libyul/yulOptimizerTests/varDeclInitializer/multi.yul b/test/libyul/yulOptimizerTests/varDeclInitializer/multi.yul new file mode 100644 index 00000000..02d731af --- /dev/null +++ b/test/libyul/yulOptimizerTests/varDeclInitializer/multi.yul @@ -0,0 +1,14 @@ +{ + let x, y, z + let a + let b +} +// ---- +// varDeclInitializer +// { +// let x := 0 +// let y := 0 +// let z := 0 +// let a := 0 +// let b := 0 +// } diff --git a/test/libyul/yulOptimizerTests/varDeclInitializer/multi_assign.yul b/test/libyul/yulOptimizerTests/varDeclInitializer/multi_assign.yul new file mode 100644 index 00000000..2e14fe70 --- /dev/null +++ b/test/libyul/yulOptimizerTests/varDeclInitializer/multi_assign.yul @@ -0,0 +1,21 @@ +{ + function f() -> x, y { + let a, b := f() + let u + } + let r + let s := 3 + let t +} +// ---- +// varDeclInitializer +// { +// function f() -> x, y +// { +// let a, b := f() +// let u := 0 +// } +// let r := 0 +// let s := 3 +// let t := 0 +// } diff --git a/test/libyul/yulOptimizerTests/varDeclInitializer/simple.yul b/test/libyul/yulOptimizerTests/varDeclInitializer/simple.yul new file mode 100644 index 00000000..2a9bbe42 --- /dev/null +++ b/test/libyul/yulOptimizerTests/varDeclInitializer/simple.yul @@ -0,0 +1,8 @@ +{ + let a +} +// ---- +// varDeclInitializer +// { +// let a := 0 +// } 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 54fea2fb..00000000 --- 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 ed8d33b4..00000000 --- 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 ca921500..00000000 --- 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 3affcac6..00000000 --- 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 d8959040..00000000 --- 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 e8c91e10..00000000 --- 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 5312112a..00000000 --- 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 e27785dd..00000000 --- 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 3dc35f73..fcbe308f 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -47,7 +47,7 @@ #include <libyul/optimiser/RedundantAssignEliminator.h> #include <libyul/optimiser/SSATransform.h> #include <libyul/optimiser/StructuralSimplifier.h> -#include <libyul/optimiser/VarDeclPropagator.h> +#include <libyul/optimiser/VarDeclInitializer.h> #include <libyul/backends/evm/EVMDialect.h> @@ -125,7 +125,7 @@ public: m_nameDispenser = make_shared<NameDispenser>(*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); |