From 4c9fcda641f02bd60188786e952c009edf16ed5d Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 18 Aug 2021 09:58:11 +0200 Subject: [PATCH] Add optimizer setting for fuzzing. --- libsolidity/codegen/CompilerContext.cpp | 2 ++ libsolidity/codegen/ContractCompiler.cpp | 1 + libsolidity/interface/OptimiserSettings.h | 1 + libyul/AssemblyStack.cpp | 7 ++++--- libyul/AssemblyStack.h | 2 +- libyul/backends/evm/AsmCodeGen.cpp | 3 ++- libyul/backends/evm/AsmCodeGen.h | 1 + libyul/backends/evm/EVMObjectCompiler.cpp | 10 +++++----- libyul/backends/evm/EVMObjectCompiler.h | 4 ++-- libyul/optimiser/Suite.cpp | 2 ++ libyul/optimiser/Suite.h | 1 + test/libyul/EVMCodeTransformTest.cpp | 2 +- test/libyul/YulOptimizerTestCommon.cpp | 6 ++++-- test/libyul/YulOptimizerTestCommon.h | 4 +++- 14 files changed, 30 insertions(+), 16 deletions(-) diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 7d87fa08e..00efbe5bc 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -521,6 +521,7 @@ void CompilerContext::appendInlineAssembly( analysisInfo, *m_asm, m_evmVersion, + _optimiserSettings.forceOldPipeline, identifierAccess.generateCode, _system, _optimiserSettings.optimizeStackAllocation @@ -551,6 +552,7 @@ void CompilerContext::optimizeYul( &meter, _object, _optimiserSettings.optimizeStackAllocation, + _optimiserSettings.forceOldPipeline, _optimiserSettings.yulOptimiserSteps, isCreation? nullopt : make_optional(_optimiserSettings.expectedExecutionsPerDeployment), _externalIdentifiers, diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 6c5a0abe0..f46c9553a 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -915,6 +915,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) *analysisInfo, *m_context.assemblyPtr(), m_context.evmVersion(), + m_optimiserSettings.forceOldPipeline, identifierAccessCodeGen, false, m_optimiserSettings.optimizeStackAllocation diff --git a/libsolidity/interface/OptimiserSettings.h b/libsolidity/interface/OptimiserSettings.h index 578a5519a..55eaa0ade 100644 --- a/libsolidity/interface/OptimiserSettings.h +++ b/libsolidity/interface/OptimiserSettings.h @@ -149,6 +149,7 @@ struct OptimiserSettings /// 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. size_t expectedExecutionsPerDeployment = 200; + bool forceOldPipeline = false; }; } diff --git a/libyul/AssemblyStack.cpp b/libyul/AssemblyStack.cpp index 8a00608cf..2981a1da1 100644 --- a/libyul/AssemblyStack.cpp +++ b/libyul/AssemblyStack.cpp @@ -168,7 +168,7 @@ bool AssemblyStack::analyzeParsed(Object& _object) return success; } -void AssemblyStack::compileEVM(AbstractAssembly& _assembly, bool _optimize) const +void AssemblyStack::compileEVM(AbstractAssembly& _assembly, bool _optimize, bool _forceOldPipeline) const { EVMDialect const* dialect = nullptr; switch (m_language) @@ -185,7 +185,7 @@ void AssemblyStack::compileEVM(AbstractAssembly& _assembly, bool _optimize) cons break; } - EVMObjectCompiler::compile(*m_parserResult, _assembly, *dialect, _optimize); + EVMObjectCompiler::compile(*m_parserResult, _assembly, *dialect, _optimize, _forceOldPipeline); } void AssemblyStack::optimize(Object& _object, bool _isCreation) @@ -205,6 +205,7 @@ void AssemblyStack::optimize(Object& _object, bool _isCreation) meter.get(), _object, m_optimiserSettings.optimizeStackAllocation, + m_optimiserSettings.forceOldPipeline, m_optimiserSettings.yulOptimiserSteps, _isCreation ? nullopt : make_optional(m_optimiserSettings.expectedExecutionsPerDeployment), {} @@ -283,7 +284,7 @@ AssemblyStack::assembleEVMWithDeployed(optional _deployName) const evmasm::Assembly assembly; EthAssemblyAdapter adapter(assembly); - compileEVM(adapter, m_optimiserSettings.optimizeStackAllocation); + compileEVM(adapter, m_optimiserSettings.optimizeStackAllocation, m_optimiserSettings.forceOldPipeline); assembly.optimise(translateOptimiserSettings(m_optimiserSettings, m_evmVersion)); diff --git a/libyul/AssemblyStack.h b/libyul/AssemblyStack.h index 768d21b33..00557d2f2 100644 --- a/libyul/AssemblyStack.h +++ b/libyul/AssemblyStack.h @@ -125,7 +125,7 @@ private: bool analyzeParsed(); bool analyzeParsed(yul::Object& _object); public: - void compileEVM(yul::AbstractAssembly& _assembly, bool _optimize) const; + void compileEVM(yul::AbstractAssembly& _assembly, bool _optimize, bool _forceOldPipeline) const; private: void optimize(yul::Object& _object, bool _isCreation); diff --git a/libyul/backends/evm/AsmCodeGen.cpp b/libyul/backends/evm/AsmCodeGen.cpp index b18d49936..637e6edff 100644 --- a/libyul/backends/evm/AsmCodeGen.cpp +++ b/libyul/backends/evm/AsmCodeGen.cpp @@ -38,6 +38,7 @@ void CodeGenerator::assemble( AsmAnalysisInfo& _analysisInfo, evmasm::Assembly& _assembly, langutil::EVMVersion _evmVersion, + bool _forceOldPipeline, ExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen, bool _system, bool _optimizeStackAllocation @@ -45,7 +46,7 @@ void CodeGenerator::assemble( { EthAssemblyAdapter assemblyAdapter(_assembly); BuiltinContext builtinContext; - if (_system && _optimizeStackAllocation && _evmVersion > EVMVersion::homestead()) + if (!_forceOldPipeline && _system && _optimizeStackAllocation && _evmVersion > EVMVersion::homestead()) { int oldStackHeight = assemblyAdapter.stackHeight(); assemblyAdapter.setStackHeight(0); diff --git a/libyul/backends/evm/AsmCodeGen.h b/libyul/backends/evm/AsmCodeGen.h index 215435b50..5daf288c5 100644 --- a/libyul/backends/evm/AsmCodeGen.h +++ b/libyul/backends/evm/AsmCodeGen.h @@ -44,6 +44,7 @@ public: AsmAnalysisInfo& _analysisInfo, evmasm::Assembly& _assembly, langutil::EVMVersion _evmVersion, + bool _forceOldPipeline, ExternalIdentifierAccess::CodeGenerator _identifierAccess = {}, bool _system = false, bool _optimizeStackAllocation = false diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index d0d1d99c2..f12cd9579 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -31,13 +31,13 @@ using namespace solidity::yul; 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); - 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; context.currentObject = &_object; @@ -49,7 +49,7 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) auto subAssemblyAndID = m_assembly.createSubAssembly(subObject->name.str()); context.subIDs[subObject->name] = subAssemblyAndID.second; subObject->subId = subAssemblyAndID.second; - compile(*subObject, *subAssemblyAndID.first, m_dialect, _optimize); + compile(*subObject, *subAssemblyAndID.first, m_dialect, _optimize, _forceOldPipeline); } else { @@ -63,7 +63,7 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) yulAssert(_object.analysisInfo, "No analysis info."); 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); diff --git a/libyul/backends/evm/EVMObjectCompiler.h b/libyul/backends/evm/EVMObjectCompiler.h index 02ccc9181..3b70bd2f8 100644 --- a/libyul/backends/evm/EVMObjectCompiler.h +++ b/libyul/backends/evm/EVMObjectCompiler.h @@ -30,13 +30,13 @@ struct EVMDialect; class EVMObjectCompiler { 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: EVMObjectCompiler(AbstractAssembly& _assembly, EVMDialect const& _dialect): m_assembly(_assembly), m_dialect(_dialect) {} - void run(Object& _object, bool _optimize); + void run(Object& _object, bool _optimize, bool _forceOldPipeline); AbstractAssembly& m_assembly; EVMDialect const& m_dialect; diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 83ec8b6df..1c7c36032 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -87,6 +87,7 @@ void OptimiserSuite::run( GasMeter const* _meter, Object& _object, bool _optimizeStackAllocation, + bool _forceOldPipeline, string const& _optimisationSequence, optional _expectedExecutionsPerDeployment, set const& _externallyUsedIdentifiers, @@ -95,6 +96,7 @@ void OptimiserSuite::run( { EVMDialect const* evmDialect = dynamic_cast(&_dialect); bool usesOptimizedCodeGenerator = + !_forceOldPipeline && _optimizeStackAllocation && evmDialect && evmDialect->evmVersion() > langutil::EVMVersion::homestead(); diff --git a/libyul/optimiser/Suite.h b/libyul/optimiser/Suite.h index 817ffe755..0ca0f9fcd 100644 --- a/libyul/optimiser/Suite.h +++ b/libyul/optimiser/Suite.h @@ -64,6 +64,7 @@ public: GasMeter const* _meter, Object& _object, bool _optimizeStackAllocation, + bool _forceOldPipeline, std::string const& _optimisationSequence, std::optional _expectedExecutionsPerDeployment, std::set const& _externallyUsedIdentifiers = {}, diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index da51e501f..b7556c60a 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -61,7 +61,7 @@ TestCase::TestResult EVMCodeTransformTest::run(ostream& _stream, string const& _ evmasm::Assembly assembly; EthAssemblyAdapter adapter(assembly); - stack.compileEVM(adapter, m_stackOpt); + stack.compileEVM(adapter, m_stackOpt, settings.forceOldPipeline); std::ostringstream output; output << assembly; diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index 00aba3c79..55bd186c1 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -79,8 +79,9 @@ using namespace std; YulOptimizerTestCommon::YulOptimizerTestCommon( shared_ptr _obj, - Dialect const& _dialect -) + Dialect const& _dialect, + bool _forceOldPipeline +): m_forceOldPipeline(_forceOldPipeline) { m_object = _obj; m_ast = m_object->code; @@ -322,6 +323,7 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( &meter, *m_object, true, + m_forceOldPipeline, frontend::OptimiserSettings::DefaultYulOptimiserSteps, frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment ); diff --git a/test/libyul/YulOptimizerTestCommon.h b/test/libyul/YulOptimizerTestCommon.h index 3dce998c5..2a55a4e53 100644 --- a/test/libyul/YulOptimizerTestCommon.h +++ b/test/libyul/YulOptimizerTestCommon.h @@ -40,7 +40,8 @@ class YulOptimizerTestCommon public: explicit YulOptimizerTestCommon( std::shared_ptr _obj, - Dialect const& _dialect + Dialect const& _dialect, + bool _forceOldPipeline = false ); /// Sets optimiser step to be run to @param /// _optimiserStep. @@ -71,6 +72,7 @@ private: std::shared_ptr m_ast; std::shared_ptr m_analysisInfo; std::map> m_namedSteps; + bool m_forceOldPipeline = false; }; }