From f5b24a38b8006b66f5e5bed37e8041d87998eddf Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 8 Jan 2019 15:03:40 +0100 Subject: Make function grouper idempotent. --- libyul/optimiser/FunctionGrouper.cpp | 15 +++++++++++++++ libyul/optimiser/FunctionGrouper.h | 3 +++ .../fullInliner/multi_fun_callback.yul | 12 +++++------- .../functionGrouper/already_grouped.yul | 17 +++++++++++++++++ .../functionGrouper/grouped_but_not_ordered.yul | 19 +++++++++++++++++++ 5 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 test/libyul/yulOptimizerTests/functionGrouper/already_grouped.yul create mode 100644 test/libyul/yulOptimizerTests/functionGrouper/grouped_but_not_ordered.yul diff --git a/libyul/optimiser/FunctionGrouper.cpp b/libyul/optimiser/FunctionGrouper.cpp index 02ce22cd..b9852fcd 100644 --- a/libyul/optimiser/FunctionGrouper.cpp +++ b/libyul/optimiser/FunctionGrouper.cpp @@ -33,6 +33,9 @@ using namespace dev::solidity; void FunctionGrouper::operator()(Block& _block) { + if (alreadyGrouped(_block)) + return; + vector reordered; reordered.emplace_back(Block{_block.location, {}}); @@ -45,3 +48,15 @@ void FunctionGrouper::operator()(Block& _block) } _block.statements = std::move(reordered); } + +bool FunctionGrouper::alreadyGrouped(Block const& _block) +{ + if (_block.statements.empty()) + return false; + if (_block.statements.front().type() != typeid(Block)) + return false; + for (size_t i = 1; i < _block.statements.size(); ++i) + if (_block.statements.at(i).type() != typeid(FunctionDefinition)) + return false; + return true; +} diff --git a/libyul/optimiser/FunctionGrouper.h b/libyul/optimiser/FunctionGrouper.h index 3b3f48a7..4b6abf76 100644 --- a/libyul/optimiser/FunctionGrouper.h +++ b/libyul/optimiser/FunctionGrouper.h @@ -38,6 +38,9 @@ class FunctionGrouper { public: void operator()(Block& _block); + +private: + bool alreadyGrouped(Block const& _block); }; } diff --git a/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul b/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul index 6e4acb97..dbbc5422 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul @@ -26,13 +26,11 @@ // fullInliner // { // { -// { -// let f_x := 100 -// mstore(0, f_x) -// mstore(7, h()) -// g(10) -// mstore(1, f_x) -// } +// let f_x := 100 +// mstore(0, f_x) +// mstore(7, h()) +// g(10) +// mstore(1, f_x) // } // function f(x) // { diff --git a/test/libyul/yulOptimizerTests/functionGrouper/already_grouped.yul b/test/libyul/yulOptimizerTests/functionGrouper/already_grouped.yul new file mode 100644 index 00000000..42e8a48e --- /dev/null +++ b/test/libyul/yulOptimizerTests/functionGrouper/already_grouped.yul @@ -0,0 +1,17 @@ +{ + { + let x := 2 + } + function f() -> y { y := 8 } +} +// ---- +// functionGrouper +// { +// { +// let x := 2 +// } +// function f() -> y +// { +// y := 8 +// } +// } diff --git a/test/libyul/yulOptimizerTests/functionGrouper/grouped_but_not_ordered.yul b/test/libyul/yulOptimizerTests/functionGrouper/grouped_but_not_ordered.yul new file mode 100644 index 00000000..0abb5d87 --- /dev/null +++ b/test/libyul/yulOptimizerTests/functionGrouper/grouped_but_not_ordered.yul @@ -0,0 +1,19 @@ +{ + function f() -> y { y := 8 } + { + let x := 2 + } +} +// ---- +// functionGrouper +// { +// { +// { +// let x := 2 +// } +// } +// function f() -> y +// { +// y := 8 +// } +// } -- cgit