Merge pull request #6172 from ethereum/runYulOptAsLongAsHelpful

[Yul] Run yul optimizer until it has no effect anymore.
This commit is contained in:
chriseth 2019-03-06 11:41:22 +01:00 committed by GitHub
commit 831353c590
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 4 deletions

View File

@ -52,9 +52,16 @@ size_t CodeSize::codeSize(Block const& _block)
return cs.m_size;
}
size_t CodeSize::codeSizeIncludingFunctions(Block const& _block)
{
CodeSize cs(false);
cs(_block);
return cs.m_size;
}
void CodeSize::visit(Statement const& _statement)
{
if (_statement.type() == typeid(FunctionDefinition))
if (_statement.type() == typeid(FunctionDefinition) && m_ignoreFunctions)
return;
else if (!(
_statement.type() == typeid(Block) ||

View File

@ -28,7 +28,7 @@ namespace yul
/**
* Metric for the size of code.
* More specifically, the number of AST nodes.
* Ignores function definitions while traversing the AST.
* Ignores function definitions while traversing the AST by default.
* If you want to know the size of a function, you have to invoke this on its body.
*
* As an exception, the following AST elements have a cost of zero:
@ -44,14 +44,16 @@ public:
static size_t codeSize(Statement const& _statement);
static size_t codeSize(Expression const& _expression);
static size_t codeSize(Block const& _block);
static size_t codeSizeIncludingFunctions(Block const& _block);
private:
CodeSize() {}
CodeSize(bool _ignoreFunctions = true): m_ignoreFunctions(_ignoreFunctions) {}
void visit(Statement const& _statement) override;
void visit(Expression const& _expression) override;
private:
bool m_ignoreFunctions;
size_t m_size = 0;
};

View File

@ -41,6 +41,7 @@
#include <libyul/optimiser/StructuralSimplifier.h>
#include <libyul/optimiser/RedundantAssignEliminator.h>
#include <libyul/optimiser/VarNameCleaner.h>
#include <libyul/optimiser/Metrics.h>
#include <libyul/AsmAnalysis.h>
#include <libyul/AsmAnalysisInfo.h>
#include <libyul/AsmData.h>
@ -80,8 +81,16 @@ void OptimiserSuite::run(
NameDispenser dispenser{*_dialect, ast};
for (size_t i = 0; i < 4; i++)
size_t codeSize = 0;
for (size_t rounds = 0; rounds < 12; ++rounds)
{
{
size_t newSize = CodeSize::codeSizeIncludingFunctions(ast);
if (newSize == codeSize)
break;
codeSize = newSize;
}
{
// Turn into SSA and simplify
ExpressionSplitter{*_dialect, dispenser}(ast);