From 83d1382e78b0765e699533185cdf7014331dcfbc Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 21 Feb 2019 18:23:46 +0100 Subject: [PATCH] Take yul optimizer setting into account. --- libsolidity/codegen/CompilerContext.cpp | 67 ++++++++++++++++++------ libsolidity/codegen/CompilerContext.h | 3 +- libsolidity/codegen/ContractCompiler.cpp | 8 ++- 3 files changed, 61 insertions(+), 17 deletions(-) diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 6c090d1fe..3053e3f7c 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -328,12 +329,19 @@ void CompilerContext::resetVisitedNodes(ASTNode const* _node) void CompilerContext::appendInlineAssembly( string const& _assembly, vector const& _localVariables, - set const&, - bool _system + set const& _externallyUsedFunctions, + bool _system, + bool _optimise ) { int startStackHeight = stackHeight(); + set externallyUsedIdentifiers; + for (auto const& fun: _externallyUsedFunctions) + externallyUsedIdentifiers.insert(yul::YulString(fun)); + for (auto const& var: _localVariables) + externallyUsedIdentifiers.insert(yul::YulString(var)); + yul::ExternalIdentifierAccess identifierAccess; identifierAccess.resolve = [&]( yul::Identifier const& _identifier, @@ -380,20 +388,12 @@ void CompilerContext::appendInlineAssembly( #ifdef SOL_OUTPUT_ASM cout << yul::AsmPrinter()(*parserResult) << endl; #endif - yul::AsmAnalysisInfo analysisInfo; - bool analyzerResult = false; - if (parserResult) - analyzerResult = yul::AsmAnalyzer( - analysisInfo, - errorReporter, - boost::none, - yul::EVMDialect::strictAssemblyForEVM(m_evmVersion), - identifierAccess.resolve - ).analyze(*parserResult); - if (!parserResult || !errorReporter.errors().empty() || !analyzerResult) + + auto reportError = [&](string const& _context) { string message = - "Error parsing/analyzing inline assembly block:\n" + "Error parsing/analyzing inline assembly block:\n" + + _context + "\n" "------------------ Input: -----------------\n" + _assembly + "\n" "------------------ Errors: ----------------\n"; @@ -405,10 +405,47 @@ void CompilerContext::appendInlineAssembly( message += "-------------------------------------------\n"; solAssert(false, message); + }; + + yul::AsmAnalysisInfo analysisInfo; + bool analyzerResult = false; + if (parserResult) + analyzerResult = yul::AsmAnalyzer( + analysisInfo, + errorReporter, + boost::none, + yul::EVMDialect::strictAssemblyForEVM(m_evmVersion), + identifierAccess.resolve + ).analyze(*parserResult); + if (!parserResult || !errorReporter.errors().empty() || !analyzerResult) + reportError("Invalid assembly generated by code generator."); + + // Several optimizer steps cannot handle externally supplied stack variables, + // so we essentially only optimize the ABI functions. + if (_optimise && _localVariables.empty()) + { + yul::OptimiserSuite::run( + yul::EVMDialect::strictAssemblyForEVM(m_evmVersion), + *parserResult, + analysisInfo, + externallyUsedIdentifiers + ); + analysisInfo = yul::AsmAnalysisInfo{}; + if (!yul::AsmAnalyzer( + analysisInfo, + errorReporter, + boost::none, + yul::EVMDialect::strictAssemblyForEVM(m_evmVersion), + identifierAccess.resolve + ).analyze(*parserResult)) + reportError("Optimizer introduced error into inline assembly."); } + if (!errorReporter.errors().empty()) + reportError("Failed to analyze inline assembly block."); + solAssert(errorReporter.errors().empty(), "Failed to analyze inline assembly block."); - yul::CodeGenerator::assemble(*parserResult, analysisInfo, *m_asm, m_evmVersion, identifierAccess, _system); + yul::CodeGenerator::assemble(*parserResult, analysisInfo, *m_asm, m_evmVersion, identifierAccess, _system, _optimise); // Reset the source location to the one of the node (instead of the CODEGEN source location) updateSourceLocation(); diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 8a5b89907..0957287a1 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -216,7 +216,8 @@ public: std::string const& _assembly, std::vector const& _localVariables = std::vector(), std::set const& _externallyUsedFunctions = std::set(), - bool _system = false + bool _system = false, + bool _optimise = false ); /// Appends arbitrary data to the end of the bytecode. diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 12da7ebf9..8320d23d5 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -978,7 +978,13 @@ void ContractCompiler::appendMissingFunctions() m_context.appendMissingLowLevelFunctions(); auto abiFunctions = m_context.abiFunctions().requestedFunctions(); if (!abiFunctions.first.empty()) - m_context.appendInlineAssembly("{" + move(abiFunctions.first) + "}", {}, abiFunctions.second, true); + m_context.appendInlineAssembly( + "{" + move(abiFunctions.first) + "}", + {}, + abiFunctions.second, + true, + m_optimiserSettings.runYulOptimiser + ); } void ContractCompiler::appendModifierOrFunctionCode()