diff options
-rw-r--r-- | libyul/optimiser/FullInliner.cpp | 35 | ||||
-rw-r--r-- | libyul/optimiser/FullInliner.h | 6 | ||||
-rw-r--r-- | test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul | 5 | ||||
-rw-r--r-- | test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul | 52 |
4 files changed, 29 insertions, 69 deletions
diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp index 75cd9d5c..cd0ed52a 100644 --- a/libyul/optimiser/FullInliner.cpp +++ b/libyul/optimiser/FullInliner.cpp @@ -50,7 +50,6 @@ FullInliner::FullInliner(Block& _ast): assertThrow(m_ast.statements.at(i).type() == typeid(FunctionDefinition), OptimizerException, ""); FunctionDefinition& fun = boost::get<FunctionDefinition>(m_ast.statements.at(i)); m_functions[fun.name] = &fun; - m_functionsToVisit.insert(&fun); } } @@ -59,17 +58,8 @@ void FullInliner::run() assertThrow(m_ast.statements[0].type() == typeid(Block), OptimizerException, ""); handleBlock("", boost::get<Block>(m_ast.statements[0])); - while (!m_functionsToVisit.empty()) - handleFunction(**m_functionsToVisit.begin()); -} - -void FullInliner::handleFunction(FunctionDefinition& _fun) -{ - if (!m_functionsToVisit.count(&_fun)) - return; - m_functionsToVisit.erase(&_fun); - - handleBlock(_fun.name, _fun.body); + for (auto const& fun: m_functions) + handleBlock(fun.second->name, fun.second->body); } void FullInliner::handleBlock(string const& _currentFunctionName, Block& _block) @@ -102,28 +92,27 @@ boost::optional<vector<Statement>> InlineModifier::tryInlineStatement(Statement& ), *e); if (funCall) { - FunctionDefinition& fun = m_driver.function(funCall->functionName.name); - m_driver.handleFunction(fun); - // TODO: Insert good heuristic here. Perhaps implement that inside the driver. bool doInline = funCall->functionName.name != m_currentFunction; if (doInline) - return performInline(_statement, *funCall, fun); + return performInline(_statement, *funCall); } } return {}; } -vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionCall& _funCall, FunctionDefinition& _function) +vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionCall& _funCall) { vector<Statement> newStatements; map<string, string> variableReplacements; + FunctionDefinition& function = m_driver.function(_funCall.functionName.name); + // helper function to create a new variable that is supposed to model // an existing variable. auto newVariable = [&](TypedName const& _existingVariable, Expression* _value) { - string newName = m_nameDispenser.newName(_function.name + "_" + _existingVariable.name); + string newName = m_nameDispenser.newName(function.name + "_" + _existingVariable.name); variableReplacements[_existingVariable.name] = newName; VariableDeclaration varDecl{_funCall.location, {{_funCall.location, newName, _existingVariable.type}}, {}}; if (_value) @@ -132,11 +121,11 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC }; for (size_t i = 0; i < _funCall.arguments.size(); ++i) - newVariable(_function.parameters[i], &_funCall.arguments[i]); - for (auto const& var: _function.returnVariables) + newVariable(function.parameters[i], &_funCall.arguments[i]); + for (auto const& var: function.returnVariables) newVariable(var, nullptr); - Statement newBody = BodyCopier(m_nameDispenser, _function.name + "_", variableReplacements)(_function.body); + Statement newBody = BodyCopier(m_nameDispenser, function.name + "_", variableReplacements)(function.body); newStatements += std::move(boost::get<Block>(newBody).statements); boost::apply_visitor(GenericFallbackVisitor<Assignment, VariableDeclaration>{ @@ -148,7 +137,7 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC {_assignment.variableNames[i]}, make_shared<Expression>(Identifier{ _assignment.location, - variableReplacements.at(_function.returnVariables[i].name) + variableReplacements.at(function.returnVariables[i].name) }) }); }, @@ -160,7 +149,7 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC {std::move(_varDecl.variables[i])}, make_shared<Expression>(Identifier{ _varDecl.location, - variableReplacements.at(_function.returnVariables[i].name) + variableReplacements.at(function.returnVariables[i].name) }) }); } diff --git a/libyul/optimiser/FullInliner.h b/libyul/optimiser/FullInliner.h index b69350a6..495286c0 100644 --- a/libyul/optimiser/FullInliner.h +++ b/libyul/optimiser/FullInliner.h @@ -75,9 +75,6 @@ public: void run(); - /// Perform inlining operations inside the given function. - void handleFunction(FunctionDefinition& _function); - FunctionDefinition& function(std::string _name) { return *m_functions.at(_name); } private: @@ -87,7 +84,6 @@ private: /// we store pointers to functions. Block& m_ast; std::map<std::string, FunctionDefinition*> m_functions; - std::set<FunctionDefinition*> m_functionsToVisit; NameDispenser m_nameDispenser; }; @@ -108,7 +104,7 @@ public: private: boost::optional<std::vector<Statement>> tryInlineStatement(Statement& _statement); - std::vector<Statement> performInline(Statement& _statement, FunctionCall& _funCall, FunctionDefinition& _function); + std::vector<Statement> performInline(Statement& _statement, FunctionCall& _funCall); std::string newName(std::string const& _prefix); diff --git a/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul b/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul index 40397a43..c704944d 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul @@ -14,10 +14,7 @@ // let g_b := f_x // let g_c := _1 // let g_y -// let g_f_a_1 := g_b -// let g_f_x_1 -// g_f_x_1 := add(g_f_a_1, g_f_a_1) -// g_y := mul(mload(g_c), g_f_x_1) +// g_y := mul(mload(g_c), f(g_b)) // let y_1 := g_y // } // function f(a) -> x diff --git a/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul b/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul index 7588094f..bcdba8e0 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul @@ -27,23 +27,11 @@ // { // { // { -// let f_x_1 := 100 -// mstore(0, f_x_1) -// let f_h_t -// f_h_t := 2 -// mstore(7, f_h_t) -// let f__5 := 10 -// let f_g_x_1 := f__5 -// let f_g_f_x := 1 -// let -// mstore() -// let f_g_f_ := h() -// let -// mstore() -// let -// g(f__5) -// mstore(1, f_g_f_x) -// mstore(1, f_x_1) +// let f_x := 100 +// mstore(0, f_x) +// mstore(7, h()) +// g(10) +// mstore(1, f_x) // } // } // function f(x) @@ -52,30 +40,20 @@ // let h_t // h_t := 2 // mstore(7, h_t) -// let _5 := 10 -// let g_x_1 := _5 -// let g_f_x := 1 -// let -// mstore() -// let g_f_ := h() -// let -// mstore() -// let -// g(_5) -// mstore(1, g_f_x) +// let g_x_1 := 10 +// f(1) // mstore(1, x) // } // function g(x_1) // { -// let f_x := 1 -// let -// mstore() -// let f_ := h() -// let -// mstore() -// let -// g(_5) -// mstore(1, f_x) +// let f_x_1 := 1 +// mstore(0, f_x_1) +// let f_h_t +// f_h_t := 2 +// mstore(7, f_h_t) +// let f_g_x_1 := 10 +// f(1) +// mstore(1, f_x_1) // } // function h() -> t // { |