Keep canonical form of Yul code at all times.

This commit is contained in:
Daniel Kirchner 2021-11-09 13:25:00 +01:00
parent fc41083027
commit 9fb77b139c
9 changed files with 30 additions and 7 deletions

View File

@ -43,3 +43,15 @@ void BlockFlattener::operator()(Block& _block)
}
);
}
void BlockFlattener::run(OptimiserStepContext&, Block& _ast)
{
BlockFlattener flattener;
for (auto& statement: _ast.statements)
if (auto* block = get_if<Block>(&statement))
flattener(*block);
else if (auto* function = get_if<FunctionDefinition>(&statement))
flattener(function->body);
else
yulAssert(false, "BlockFlattener requires the FunctionGrouper.");
}

View File

@ -27,7 +27,7 @@ class BlockFlattener: public ASTModifier
{
public:
static constexpr char const* name{"BlockFlattener"};
static void run(OptimiserStepContext&, Block& _ast) { BlockFlattener{}(_ast); }
static void run(OptimiserStepContext&, Block& _ast);
using ASTModifier::operator();
void operator()(Block& _block) override;

View File

@ -18,6 +18,7 @@
#include <libyul/optimiser/CircularReferencesPruner.h>
#include <libyul/optimiser/CallGraphGenerator.h>
#include <libyul/optimiser/FunctionGrouper.h>
#include <libyul/optimiser/OptimizerUtilities.h>
#include <libyul/AST.h>
@ -29,6 +30,7 @@ using namespace solidity::yul;
void CircularReferencesPruner::run(OptimiserStepContext& _context, Block& _ast)
{
CircularReferencesPruner{_context.reservedIdentifiers}(_ast);
FunctionGrouper::run(_context, _ast);
}
void CircularReferencesPruner::operator()(Block& _block)

View File

@ -22,6 +22,7 @@
#include <libyul/optimiser/ExpressionJoiner.h>
#include <libyul/optimiser/FunctionGrouper.h>
#include <libyul/optimiser/NameCollector.h>
#include <libyul/optimiser/OptimizerUtilities.h>
#include <libyul/Exceptions.h>
@ -37,9 +38,10 @@ using namespace std;
using namespace solidity;
using namespace solidity::yul;
void ExpressionJoiner::run(OptimiserStepContext&, Block& _ast)
void ExpressionJoiner::run(OptimiserStepContext& _context, Block& _ast)
{
ExpressionJoiner{_ast}(_ast);
FunctionGrouper::run(_context, _ast);
}

View File

@ -37,6 +37,8 @@ namespace solidity::yul
{
/// Removes statements that are just empty blocks (non-recursive).
/// If this is run on the outermost block, the FunctionGrouper should be run afterwards to keep
/// the canonical form.
void removeEmptyBlocks(Block& _block);
/// Returns true if a given literal can not be used as an identifier.

View File

@ -118,7 +118,7 @@ void OptimiserSuite::run(
// Some steps depend on properties ensured by FunctionHoister, BlockFlattener, FunctionGrouper and
// ForLoopInitRewriter. Run them first to be able to run arbitrary sequences safely.
suite.runSequence("hfgo", ast);
suite.runSequence("hgfo", ast);
NameSimplifier::run(suite.m_context, ast);
// Now the user-supplied part

View File

@ -21,6 +21,7 @@
#include <libyul/optimiser/UnusedPruner.h>
#include <libyul/optimiser/CallGraphGenerator.h>
#include <libyul/optimiser/FunctionGrouper.h>
#include <libyul/optimiser/NameCollector.h>
#include <libyul/optimiser/Semantics.h>
#include <libyul/optimiser/OptimizerUtilities.h>
@ -33,6 +34,12 @@ using namespace std;
using namespace solidity;
using namespace solidity::yul;
void UnusedPruner::run(OptimiserStepContext& _context, Block& _ast)
{
UnusedPruner::runUntilStabilisedOnFullAST(_context.dialect, _ast, _context.reservedIdentifiers);
FunctionGrouper::run(_context, _ast);
}
UnusedPruner::UnusedPruner(
Dialect const& _dialect,
Block& _ast,

View File

@ -50,9 +50,7 @@ class UnusedPruner: public ASTModifier
{
public:
static constexpr char const* name{"UnusedPruner"};
static void run(OptimiserStepContext& _context, Block& _ast) {
UnusedPruner::runUntilStabilisedOnFullAST(_context.dialect, _ast, _context.reservedIdentifiers);
}
static void run(OptimiserStepContext& _context, Block& _ast);
using ASTModifier::operator();