diff options
-rw-r--r-- | libyul/optimiser/README.md | 2 | ||||
-rw-r--r-- | libyul/optimiser/UnusedPruner.cpp | 10 | ||||
-rw-r--r-- | libyul/optimiser/UnusedPruner.h | 6 | ||||
-rw-r--r-- | test/libyul/yulOptimizerTests/fullSuite/medium.yul | 4 | ||||
-rw-r--r-- | test/libyul/yulOptimizerTests/unusedPruner/pop.yul | 8 |
5 files changed, 23 insertions, 7 deletions
diff --git a/libyul/optimiser/README.md b/libyul/optimiser/README.md index faef818b..c2575179 100644 --- a/libyul/optimiser/README.md +++ b/libyul/optimiser/README.md @@ -135,6 +135,8 @@ If there are two assignments to a variable where the first one is a movable expr and the variable is not used between the two assignments (and the second is not inside a loop or conditional, the first one is not inside), the first assignment is removed. +This step also removes movable expression statements. + ## Function Unifier diff --git a/libyul/optimiser/UnusedPruner.cpp b/libyul/optimiser/UnusedPruner.cpp index a7b32873..71e86798 100644 --- a/libyul/optimiser/UnusedPruner.cpp +++ b/libyul/optimiser/UnusedPruner.cpp @@ -85,6 +85,16 @@ void UnusedPruner::operator()(Block& _block) }}; } } + else if (statement.type() == typeid(ExpressionStatement)) + { + ExpressionStatement& exprStmt = boost::get<ExpressionStatement>(statement); + if (MovableChecker(exprStmt.expression).movable()) + { + // pop(x) should be movable! + subtractReferences(ReferencesCounter::countReferences(exprStmt.expression)); + statement = Block{std::move(exprStmt.location), {}}; + } + } removeEmptyBlocks(_block); diff --git a/libyul/optimiser/UnusedPruner.h b/libyul/optimiser/UnusedPruner.h index 2dd74940..b5aea3dd 100644 --- a/libyul/optimiser/UnusedPruner.h +++ b/libyul/optimiser/UnusedPruner.h @@ -32,10 +32,8 @@ namespace yul { /** - * Optimisation stage that removes unused variables and functions. - * - * TODO: Also remove intermediate variable assignments from movable expressions - * which are not referenced until after the next assignment to the same variable. + * Optimisation stage that removes unused variables and functions and also + * removes movable expression statements. * * Note that this does not remove circular references. * diff --git a/test/libyul/yulOptimizerTests/fullSuite/medium.yul b/test/libyul/yulOptimizerTests/fullSuite/medium.yul index 47812fa8..deb02068 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/medium.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/medium.yul @@ -16,9 +16,7 @@ // { // let _18 := 0x20 // let allocate__7 := 0x40 -// let allocate_p_12 := mload(allocate__7) -// mstore(allocate__7, add(allocate_p_12, _18)) -// pop(allocate_p_12) +// mstore(allocate__7, add(mload(allocate__7), _18)) // let allocate_p_12_31 := mload(allocate__7) // mstore(allocate__7, add(allocate_p_12_31, allocate__7)) // mstore(add(allocate_p_12_31, 96), 2) diff --git a/test/libyul/yulOptimizerTests/unusedPruner/pop.yul b/test/libyul/yulOptimizerTests/unusedPruner/pop.yul new file mode 100644 index 00000000..542070f9 --- /dev/null +++ b/test/libyul/yulOptimizerTests/unusedPruner/pop.yul @@ -0,0 +1,8 @@ +{ + let a := 1 + pop(a) +} +// ---- +// unusedPruner +// { +// } |