Skip to content

Commit f42e3c0

Browse files
authored
Merge pull request #12262 from ethereum/functionGrouper
Keep canonical form of Yul during optimization.
2 parents 19159b9 + 1061818 commit f42e3c0

File tree

169 files changed

+936
-652
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

169 files changed

+936
-652
lines changed

docs/internals/optimizer.rst

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -972,15 +972,19 @@ BlockFlattener
972972
^^^^^^^^^^^^^^
973973

974974
This stage eliminates nested blocks by inserting the statement in the
975-
inner block at the appropriate place in the outer block:
975+
inner block at the appropriate place in the outer block. It depends on the
976+
FunctionGrouper and does not flatten the outermost block to keep the form
977+
produced by the FunctionGrouper.
976978

977979
.. code-block:: yul
978980
979981
{
980-
let x := 2
981982
{
982-
let y := 3
983-
mstore(x, y)
983+
let x := 2
984+
{
985+
let y := 3
986+
mstore(x, y)
987+
}
984988
}
985989
}
986990
@@ -989,9 +993,11 @@ is transformed to
989993
.. code-block:: yul
990994
991995
{
992-
let x := 2
993-
let y := 3
994-
mstore(x, y)
996+
{
997+
let x := 2
998+
let y := 3
999+
mstore(x, y)
1000+
}
9951001
}
9961002
9971003
As long as the code is disambiguated, this does not cause a problem because

libyul/optimiser/BlockFlattener.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,15 @@ void BlockFlattener::operator()(Block& _block)
4343
}
4444
);
4545
}
46+
47+
void BlockFlattener::run(OptimiserStepContext&, Block& _ast)
48+
{
49+
BlockFlattener flattener;
50+
for (auto& statement: _ast.statements)
51+
if (auto* block = get_if<Block>(&statement))
52+
flattener(*block);
53+
else if (auto* function = get_if<FunctionDefinition>(&statement))
54+
flattener(function->body);
55+
else
56+
yulAssert(false, "BlockFlattener requires the FunctionGrouper.");
57+
}

libyul/optimiser/BlockFlattener.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class BlockFlattener: public ASTModifier
2727
{
2828
public:
2929
static constexpr char const* name{"BlockFlattener"};
30-
static void run(OptimiserStepContext&, Block& _ast) { BlockFlattener{}(_ast); }
30+
static void run(OptimiserStepContext&, Block& _ast);
3131

3232
using ASTModifier::operator();
3333
void operator()(Block& _block) override;

libyul/optimiser/CircularReferencesPruner.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <libyul/optimiser/CircularReferencesPruner.h>
1919

2020
#include <libyul/optimiser/CallGraphGenerator.h>
21+
#include <libyul/optimiser/FunctionGrouper.h>
2122
#include <libyul/optimiser/OptimizerUtilities.h>
2223
#include <libyul/AST.h>
2324

@@ -29,6 +30,7 @@ using namespace solidity::yul;
2930
void CircularReferencesPruner::run(OptimiserStepContext& _context, Block& _ast)
3031
{
3132
CircularReferencesPruner{_context.reservedIdentifiers}(_ast);
33+
FunctionGrouper::run(_context, _ast);
3234
}
3335

3436
void CircularReferencesPruner::operator()(Block& _block)

libyul/optimiser/ExpressionJoiner.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <libyul/optimiser/ExpressionJoiner.h>
2424

25+
#include <libyul/optimiser/FunctionGrouper.h>
2526
#include <libyul/optimiser/NameCollector.h>
2627
#include <libyul/optimiser/OptimizerUtilities.h>
2728
#include <libyul/Exceptions.h>
@@ -37,9 +38,10 @@ using namespace std;
3738
using namespace solidity;
3839
using namespace solidity::yul;
3940

40-
void ExpressionJoiner::run(OptimiserStepContext&, Block& _ast)
41+
void ExpressionJoiner::run(OptimiserStepContext& _context, Block& _ast)
4142
{
4243
ExpressionJoiner{_ast}(_ast);
44+
FunctionGrouper::run(_context, _ast);
4345
}
4446

4547

libyul/optimiser/FunctionGrouper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct OptimiserStepContext;
3434
* all function definitions.
3535
*
3636
* After this step, a block is of the form
37-
* { { I...} F... }
37+
* { { I... } F... }
3838
* Where I are (non-function-definition) instructions and F are function definitions.
3939
*/
4040
class FunctionGrouper

libyul/optimiser/OptimizerUtilities.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ namespace solidity::yul
3737
{
3838

3939
/// Removes statements that are just empty blocks (non-recursive).
40+
/// If this is run on the outermost block, the FunctionGrouper should be run afterwards to keep
41+
/// the canonical form.
4042
void removeEmptyBlocks(Block& _block);
4143

4244
/// Returns true if a given literal can not be used as an identifier.

libyul/optimiser/Suite.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ void OptimiserSuite::run(
118118

119119
// Some steps depend on properties ensured by FunctionHoister, BlockFlattener, FunctionGrouper and
120120
// ForLoopInitRewriter. Run them first to be able to run arbitrary sequences safely.
121-
suite.runSequence("hfgo", ast);
121+
suite.runSequence("hgfo", ast);
122122

123123
NameSimplifier::run(suite.m_context, ast);
124124
// Now the user-supplied part

libyul/optimiser/UnusedPruner.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <libyul/optimiser/UnusedPruner.h>
2222

2323
#include <libyul/optimiser/CallGraphGenerator.h>
24+
#include <libyul/optimiser/FunctionGrouper.h>
2425
#include <libyul/optimiser/NameCollector.h>
2526
#include <libyul/optimiser/Semantics.h>
2627
#include <libyul/optimiser/OptimizerUtilities.h>
@@ -33,6 +34,12 @@ using namespace std;
3334
using namespace solidity;
3435
using namespace solidity::yul;
3536

37+
void UnusedPruner::run(OptimiserStepContext& _context, Block& _ast)
38+
{
39+
UnusedPruner::runUntilStabilisedOnFullAST(_context.dialect, _ast, _context.reservedIdentifiers);
40+
FunctionGrouper::run(_context, _ast);
41+
}
42+
3643
UnusedPruner::UnusedPruner(
3744
Dialect const& _dialect,
3845
Block& _ast,

libyul/optimiser/UnusedPruner.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ class UnusedPruner: public ASTModifier
5050
{
5151
public:
5252
static constexpr char const* name{"UnusedPruner"};
53-
static void run(OptimiserStepContext& _context, Block& _ast) {
54-
UnusedPruner::runUntilStabilisedOnFullAST(_context.dialect, _ast, _context.reservedIdentifiers);
55-
}
53+
static void run(OptimiserStepContext& _context, Block& _ast);
5654

5755

5856
using ASTModifier::operator();

0 commit comments

Comments
 (0)