Take yul optimizer setting into account.

This commit is contained in:
chriseth 2019-02-21 18:23:46 +01:00
parent 1ff562d28a
commit 83d1382e78
3 changed files with 61 additions and 17 deletions

View File

@ -32,6 +32,7 @@
#include <libyul/AsmAnalysisInfo.h>
#include <libyul/backends/evm/AsmCodeGen.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <libyul/optimiser/Suite.h>
#include <libyul/YulString.h>
#include <liblangutil/ErrorReporter.h>
@ -328,12 +329,19 @@ void CompilerContext::resetVisitedNodes(ASTNode const* _node)
void CompilerContext::appendInlineAssembly(
string const& _assembly,
vector<string> const& _localVariables,
set<string> const&,
bool _system
set<string> const& _externallyUsedFunctions,
bool _system,
bool _optimise
)
{
int startStackHeight = stackHeight();
set<yul::YulString> 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();

View File

@ -216,7 +216,8 @@ public:
std::string const& _assembly,
std::vector<std::string> const& _localVariables = std::vector<std::string>(),
std::set<std::string> const& _externallyUsedFunctions = std::set<std::string>(),
bool _system = false
bool _system = false,
bool _optimise = false
);
/// Appends arbitrary data to the end of the bytecode.

View File

@ -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()