Add optimizer setting for fuzzing.

This commit is contained in:
Daniel Kirchner 2021-08-18 09:58:11 +02:00
parent e3bbc3f18b
commit 4c9fcda641
14 changed files with 30 additions and 16 deletions

View File

@ -521,6 +521,7 @@ void CompilerContext::appendInlineAssembly(
analysisInfo, analysisInfo,
*m_asm, *m_asm,
m_evmVersion, m_evmVersion,
_optimiserSettings.forceOldPipeline,
identifierAccess.generateCode, identifierAccess.generateCode,
_system, _system,
_optimiserSettings.optimizeStackAllocation _optimiserSettings.optimizeStackAllocation
@ -551,6 +552,7 @@ void CompilerContext::optimizeYul(
&meter, &meter,
_object, _object,
_optimiserSettings.optimizeStackAllocation, _optimiserSettings.optimizeStackAllocation,
_optimiserSettings.forceOldPipeline,
_optimiserSettings.yulOptimiserSteps, _optimiserSettings.yulOptimiserSteps,
isCreation? nullopt : make_optional(_optimiserSettings.expectedExecutionsPerDeployment), isCreation? nullopt : make_optional(_optimiserSettings.expectedExecutionsPerDeployment),
_externalIdentifiers, _externalIdentifiers,

View File

@ -915,6 +915,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
*analysisInfo, *analysisInfo,
*m_context.assemblyPtr(), *m_context.assemblyPtr(),
m_context.evmVersion(), m_context.evmVersion(),
m_optimiserSettings.forceOldPipeline,
identifierAccessCodeGen, identifierAccessCodeGen,
false, false,
m_optimiserSettings.optimizeStackAllocation m_optimiserSettings.optimizeStackAllocation

View File

@ -149,6 +149,7 @@ struct OptimiserSettings
/// This specifies an estimate on how often each opcode in this assembly will be executed, /// This specifies an estimate on how often each opcode in this assembly will be executed,
/// i.e. use a small value to optimise for size and a large value to optimise for runtime gas usage. /// i.e. use a small value to optimise for size and a large value to optimise for runtime gas usage.
size_t expectedExecutionsPerDeployment = 200; size_t expectedExecutionsPerDeployment = 200;
bool forceOldPipeline = false;
}; };
} }

View File

@ -168,7 +168,7 @@ bool AssemblyStack::analyzeParsed(Object& _object)
return success; return success;
} }
void AssemblyStack::compileEVM(AbstractAssembly& _assembly, bool _optimize) const void AssemblyStack::compileEVM(AbstractAssembly& _assembly, bool _optimize, bool _forceOldPipeline) const
{ {
EVMDialect const* dialect = nullptr; EVMDialect const* dialect = nullptr;
switch (m_language) switch (m_language)
@ -185,7 +185,7 @@ void AssemblyStack::compileEVM(AbstractAssembly& _assembly, bool _optimize) cons
break; break;
} }
EVMObjectCompiler::compile(*m_parserResult, _assembly, *dialect, _optimize); EVMObjectCompiler::compile(*m_parserResult, _assembly, *dialect, _optimize, _forceOldPipeline);
} }
void AssemblyStack::optimize(Object& _object, bool _isCreation) void AssemblyStack::optimize(Object& _object, bool _isCreation)
@ -205,6 +205,7 @@ void AssemblyStack::optimize(Object& _object, bool _isCreation)
meter.get(), meter.get(),
_object, _object,
m_optimiserSettings.optimizeStackAllocation, m_optimiserSettings.optimizeStackAllocation,
m_optimiserSettings.forceOldPipeline,
m_optimiserSettings.yulOptimiserSteps, m_optimiserSettings.yulOptimiserSteps,
_isCreation ? nullopt : make_optional(m_optimiserSettings.expectedExecutionsPerDeployment), _isCreation ? nullopt : make_optional(m_optimiserSettings.expectedExecutionsPerDeployment),
{} {}
@ -283,7 +284,7 @@ AssemblyStack::assembleEVMWithDeployed(optional<string_view> _deployName) const
evmasm::Assembly assembly; evmasm::Assembly assembly;
EthAssemblyAdapter adapter(assembly); EthAssemblyAdapter adapter(assembly);
compileEVM(adapter, m_optimiserSettings.optimizeStackAllocation); compileEVM(adapter, m_optimiserSettings.optimizeStackAllocation, m_optimiserSettings.forceOldPipeline);
assembly.optimise(translateOptimiserSettings(m_optimiserSettings, m_evmVersion)); assembly.optimise(translateOptimiserSettings(m_optimiserSettings, m_evmVersion));

View File

@ -125,7 +125,7 @@ private:
bool analyzeParsed(); bool analyzeParsed();
bool analyzeParsed(yul::Object& _object); bool analyzeParsed(yul::Object& _object);
public: public:
void compileEVM(yul::AbstractAssembly& _assembly, bool _optimize) const; void compileEVM(yul::AbstractAssembly& _assembly, bool _optimize, bool _forceOldPipeline) const;
private: private:
void optimize(yul::Object& _object, bool _isCreation); void optimize(yul::Object& _object, bool _isCreation);

View File

@ -38,6 +38,7 @@ void CodeGenerator::assemble(
AsmAnalysisInfo& _analysisInfo, AsmAnalysisInfo& _analysisInfo,
evmasm::Assembly& _assembly, evmasm::Assembly& _assembly,
langutil::EVMVersion _evmVersion, langutil::EVMVersion _evmVersion,
bool _forceOldPipeline,
ExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen, ExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen,
bool _system, bool _system,
bool _optimizeStackAllocation bool _optimizeStackAllocation
@ -45,7 +46,7 @@ void CodeGenerator::assemble(
{ {
EthAssemblyAdapter assemblyAdapter(_assembly); EthAssemblyAdapter assemblyAdapter(_assembly);
BuiltinContext builtinContext; BuiltinContext builtinContext;
if (_system && _optimizeStackAllocation && _evmVersion > EVMVersion::homestead()) if (!_forceOldPipeline && _system && _optimizeStackAllocation && _evmVersion > EVMVersion::homestead())
{ {
int oldStackHeight = assemblyAdapter.stackHeight(); int oldStackHeight = assemblyAdapter.stackHeight();
assemblyAdapter.setStackHeight(0); assemblyAdapter.setStackHeight(0);

View File

@ -44,6 +44,7 @@ public:
AsmAnalysisInfo& _analysisInfo, AsmAnalysisInfo& _analysisInfo,
evmasm::Assembly& _assembly, evmasm::Assembly& _assembly,
langutil::EVMVersion _evmVersion, langutil::EVMVersion _evmVersion,
bool _forceOldPipeline,
ExternalIdentifierAccess::CodeGenerator _identifierAccess = {}, ExternalIdentifierAccess::CodeGenerator _identifierAccess = {},
bool _system = false, bool _system = false,
bool _optimizeStackAllocation = false bool _optimizeStackAllocation = false

View File

@ -31,13 +31,13 @@
using namespace solidity::yul; using namespace solidity::yul;
using namespace std; using namespace std;
void EVMObjectCompiler::compile(Object& _object, AbstractAssembly& _assembly, EVMDialect const& _dialect, bool _optimize) void EVMObjectCompiler::compile(Object& _object, AbstractAssembly& _assembly, EVMDialect const& _dialect, bool _optimize, bool _forceOldPipeline)
{ {
EVMObjectCompiler compiler(_assembly, _dialect); EVMObjectCompiler compiler(_assembly, _dialect);
compiler.run(_object, _optimize); compiler.run(_object, _optimize, _forceOldPipeline);
} }
void EVMObjectCompiler::run(Object& _object, bool _optimize) void EVMObjectCompiler::run(Object& _object, bool _optimize, bool _forceOldPipeline)
{ {
BuiltinContext context; BuiltinContext context;
context.currentObject = &_object; context.currentObject = &_object;
@ -49,7 +49,7 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize)
auto subAssemblyAndID = m_assembly.createSubAssembly(subObject->name.str()); auto subAssemblyAndID = m_assembly.createSubAssembly(subObject->name.str());
context.subIDs[subObject->name] = subAssemblyAndID.second; context.subIDs[subObject->name] = subAssemblyAndID.second;
subObject->subId = subAssemblyAndID.second; subObject->subId = subAssemblyAndID.second;
compile(*subObject, *subAssemblyAndID.first, m_dialect, _optimize); compile(*subObject, *subAssemblyAndID.first, m_dialect, _optimize, _forceOldPipeline);
} }
else else
{ {
@ -63,7 +63,7 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize)
yulAssert(_object.analysisInfo, "No analysis info."); yulAssert(_object.analysisInfo, "No analysis info.");
yulAssert(_object.code, "No code."); yulAssert(_object.code, "No code.");
if (_optimize && m_dialect.evmVersion() > langutil::EVMVersion::homestead()) if (!_forceOldPipeline && (_optimize && m_dialect.evmVersion() > langutil::EVMVersion::homestead()))
{ {
auto stackErrors = OptimizedEVMCodeTransform::run(m_assembly, *_object.analysisInfo, *_object.code, m_dialect, context); auto stackErrors = OptimizedEVMCodeTransform::run(m_assembly, *_object.analysisInfo, *_object.code, m_dialect, context);

View File

@ -30,13 +30,13 @@ struct EVMDialect;
class EVMObjectCompiler class EVMObjectCompiler
{ {
public: public:
static void compile(Object& _object, AbstractAssembly& _assembly, EVMDialect const& _dialect, bool _optimize); static void compile(Object& _object, AbstractAssembly& _assembly, EVMDialect const& _dialect, bool _optimize, bool _forceOldPipeline);
private: private:
EVMObjectCompiler(AbstractAssembly& _assembly, EVMDialect const& _dialect): EVMObjectCompiler(AbstractAssembly& _assembly, EVMDialect const& _dialect):
m_assembly(_assembly), m_dialect(_dialect) m_assembly(_assembly), m_dialect(_dialect)
{} {}
void run(Object& _object, bool _optimize); void run(Object& _object, bool _optimize, bool _forceOldPipeline);
AbstractAssembly& m_assembly; AbstractAssembly& m_assembly;
EVMDialect const& m_dialect; EVMDialect const& m_dialect;

View File

@ -87,6 +87,7 @@ void OptimiserSuite::run(
GasMeter const* _meter, GasMeter const* _meter,
Object& _object, Object& _object,
bool _optimizeStackAllocation, bool _optimizeStackAllocation,
bool _forceOldPipeline,
string const& _optimisationSequence, string const& _optimisationSequence,
optional<size_t> _expectedExecutionsPerDeployment, optional<size_t> _expectedExecutionsPerDeployment,
set<YulString> const& _externallyUsedIdentifiers, set<YulString> const& _externallyUsedIdentifiers,
@ -95,6 +96,7 @@ void OptimiserSuite::run(
{ {
EVMDialect const* evmDialect = dynamic_cast<EVMDialect const*>(&_dialect); EVMDialect const* evmDialect = dynamic_cast<EVMDialect const*>(&_dialect);
bool usesOptimizedCodeGenerator = bool usesOptimizedCodeGenerator =
!_forceOldPipeline &&
_optimizeStackAllocation && _optimizeStackAllocation &&
evmDialect && evmDialect &&
evmDialect->evmVersion() > langutil::EVMVersion::homestead(); evmDialect->evmVersion() > langutil::EVMVersion::homestead();

View File

@ -64,6 +64,7 @@ public:
GasMeter const* _meter, GasMeter const* _meter,
Object& _object, Object& _object,
bool _optimizeStackAllocation, bool _optimizeStackAllocation,
bool _forceOldPipeline,
std::string const& _optimisationSequence, std::string const& _optimisationSequence,
std::optional<size_t> _expectedExecutionsPerDeployment, std::optional<size_t> _expectedExecutionsPerDeployment,
std::set<YulString> const& _externallyUsedIdentifiers = {}, std::set<YulString> const& _externallyUsedIdentifiers = {},

View File

@ -61,7 +61,7 @@ TestCase::TestResult EVMCodeTransformTest::run(ostream& _stream, string const& _
evmasm::Assembly assembly; evmasm::Assembly assembly;
EthAssemblyAdapter adapter(assembly); EthAssemblyAdapter adapter(assembly);
stack.compileEVM(adapter, m_stackOpt); stack.compileEVM(adapter, m_stackOpt, settings.forceOldPipeline);
std::ostringstream output; std::ostringstream output;
output << assembly; output << assembly;

View File

@ -79,8 +79,9 @@ using namespace std;
YulOptimizerTestCommon::YulOptimizerTestCommon( YulOptimizerTestCommon::YulOptimizerTestCommon(
shared_ptr<Object> _obj, shared_ptr<Object> _obj,
Dialect const& _dialect Dialect const& _dialect,
) bool _forceOldPipeline
): m_forceOldPipeline(_forceOldPipeline)
{ {
m_object = _obj; m_object = _obj;
m_ast = m_object->code; m_ast = m_object->code;
@ -322,6 +323,7 @@ YulOptimizerTestCommon::YulOptimizerTestCommon(
&meter, &meter,
*m_object, *m_object,
true, true,
m_forceOldPipeline,
frontend::OptimiserSettings::DefaultYulOptimiserSteps, frontend::OptimiserSettings::DefaultYulOptimiserSteps,
frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment
); );

View File

@ -40,7 +40,8 @@ class YulOptimizerTestCommon
public: public:
explicit YulOptimizerTestCommon( explicit YulOptimizerTestCommon(
std::shared_ptr<Object> _obj, std::shared_ptr<Object> _obj,
Dialect const& _dialect Dialect const& _dialect,
bool _forceOldPipeline = false
); );
/// Sets optimiser step to be run to @param /// Sets optimiser step to be run to @param
/// _optimiserStep. /// _optimiserStep.
@ -71,6 +72,7 @@ private:
std::shared_ptr<Block> m_ast; std::shared_ptr<Block> m_ast;
std::shared_ptr<AsmAnalysisInfo> m_analysisInfo; std::shared_ptr<AsmAnalysisInfo> m_analysisInfo;
std::map<std::string, std::function<void(void)>> m_namedSteps; std::map<std::string, std::function<void(void)>> m_namedSteps;
bool m_forceOldPipeline = false;
}; };
} }