mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Take yul optimizer setting into account.
This commit is contained in:
parent
1ff562d28a
commit
83d1382e78
@ -32,6 +32,7 @@
|
|||||||
#include <libyul/AsmAnalysisInfo.h>
|
#include <libyul/AsmAnalysisInfo.h>
|
||||||
#include <libyul/backends/evm/AsmCodeGen.h>
|
#include <libyul/backends/evm/AsmCodeGen.h>
|
||||||
#include <libyul/backends/evm/EVMDialect.h>
|
#include <libyul/backends/evm/EVMDialect.h>
|
||||||
|
#include <libyul/optimiser/Suite.h>
|
||||||
#include <libyul/YulString.h>
|
#include <libyul/YulString.h>
|
||||||
|
|
||||||
#include <liblangutil/ErrorReporter.h>
|
#include <liblangutil/ErrorReporter.h>
|
||||||
@ -328,12 +329,19 @@ void CompilerContext::resetVisitedNodes(ASTNode const* _node)
|
|||||||
void CompilerContext::appendInlineAssembly(
|
void CompilerContext::appendInlineAssembly(
|
||||||
string const& _assembly,
|
string const& _assembly,
|
||||||
vector<string> const& _localVariables,
|
vector<string> const& _localVariables,
|
||||||
set<string> const&,
|
set<string> const& _externallyUsedFunctions,
|
||||||
bool _system
|
bool _system,
|
||||||
|
bool _optimise
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int startStackHeight = stackHeight();
|
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;
|
yul::ExternalIdentifierAccess identifierAccess;
|
||||||
identifierAccess.resolve = [&](
|
identifierAccess.resolve = [&](
|
||||||
yul::Identifier const& _identifier,
|
yul::Identifier const& _identifier,
|
||||||
@ -380,20 +388,12 @@ void CompilerContext::appendInlineAssembly(
|
|||||||
#ifdef SOL_OUTPUT_ASM
|
#ifdef SOL_OUTPUT_ASM
|
||||||
cout << yul::AsmPrinter()(*parserResult) << endl;
|
cout << yul::AsmPrinter()(*parserResult) << endl;
|
||||||
#endif
|
#endif
|
||||||
yul::AsmAnalysisInfo analysisInfo;
|
|
||||||
bool analyzerResult = false;
|
auto reportError = [&](string const& _context)
|
||||||
if (parserResult)
|
|
||||||
analyzerResult = yul::AsmAnalyzer(
|
|
||||||
analysisInfo,
|
|
||||||
errorReporter,
|
|
||||||
boost::none,
|
|
||||||
yul::EVMDialect::strictAssemblyForEVM(m_evmVersion),
|
|
||||||
identifierAccess.resolve
|
|
||||||
).analyze(*parserResult);
|
|
||||||
if (!parserResult || !errorReporter.errors().empty() || !analyzerResult)
|
|
||||||
{
|
{
|
||||||
string message =
|
string message =
|
||||||
"Error parsing/analyzing inline assembly block:\n"
|
"Error parsing/analyzing inline assembly block:\n" +
|
||||||
|
_context + "\n"
|
||||||
"------------------ Input: -----------------\n" +
|
"------------------ Input: -----------------\n" +
|
||||||
_assembly + "\n"
|
_assembly + "\n"
|
||||||
"------------------ Errors: ----------------\n";
|
"------------------ Errors: ----------------\n";
|
||||||
@ -405,10 +405,47 @@ void CompilerContext::appendInlineAssembly(
|
|||||||
message += "-------------------------------------------\n";
|
message += "-------------------------------------------\n";
|
||||||
|
|
||||||
solAssert(false, message);
|
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.");
|
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)
|
// Reset the source location to the one of the node (instead of the CODEGEN source location)
|
||||||
updateSourceLocation();
|
updateSourceLocation();
|
||||||
|
@ -216,7 +216,8 @@ public:
|
|||||||
std::string const& _assembly,
|
std::string const& _assembly,
|
||||||
std::vector<std::string> const& _localVariables = std::vector<std::string>(),
|
std::vector<std::string> const& _localVariables = std::vector<std::string>(),
|
||||||
std::set<std::string> const& _externallyUsedFunctions = std::set<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.
|
/// Appends arbitrary data to the end of the bytecode.
|
||||||
|
@ -978,7 +978,13 @@ void ContractCompiler::appendMissingFunctions()
|
|||||||
m_context.appendMissingLowLevelFunctions();
|
m_context.appendMissingLowLevelFunctions();
|
||||||
auto abiFunctions = m_context.abiFunctions().requestedFunctions();
|
auto abiFunctions = m_context.abiFunctions().requestedFunctions();
|
||||||
if (!abiFunctions.first.empty())
|
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()
|
void ContractCompiler::appendModifierOrFunctionCode()
|
||||||
|
Loading…
Reference in New Issue
Block a user