This commit is contained in:
Alexander Arlt 2022-03-14 09:24:26 -05:00
parent 0c0853e635
commit c097842455
5 changed files with 25 additions and 51 deletions

View File

@ -602,7 +602,7 @@ bool Assembly::loadFromAssemblyJSON(Json::Value const& _json, bool _loadSources
this->m_data[h256(fromHex(key))] = fromHex(code.asString()); this->m_data[h256(fromHex(key))] = fromHex(code.asString());
else else
{ {
shared_ptr<Assembly> subassembly = make_shared<Assembly>(); shared_ptr<Assembly> subassembly = make_shared<Assembly>(false, "");
subassembly->setSources(this->sources()); subassembly->setSources(this->sources());
result &= subassembly->loadFromAssemblyJSON(code, false); result &= subassembly->loadFromAssemblyJSON(code, false);
this->m_subs.emplace_back(subassembly); this->m_subs.emplace_back(subassembly);
@ -646,25 +646,6 @@ AssemblyItem Assembly::newImmutableAssignment(string const& _identifier)
return AssemblyItem{AssignImmutable, h}; return AssemblyItem{AssignImmutable, h};
} }
Assembly& Assembly::optimise(bool _enable, EVMVersion _evmVersion, bool _isCreation, size_t _runs)
{
OptimiserSettings settings;
settings.isCreation = _isCreation;
settings.runInliner = true;
settings.runJumpdestRemover = true;
settings.runPeephole = true;
if (_enable)
{
settings.runDeduplicate = true;
settings.runCSE = true;
settings.runConstantOptimiser = true;
}
settings.evmVersion = _evmVersion;
settings.expectedExecutionsPerDeployment = _runs;
optimise(settings);
return *this;
}
Assembly& Assembly::optimise(OptimiserSettings const& _settings) Assembly& Assembly::optimise(OptimiserSettings const& _settings)
{ {
optimiseInternal(_settings, {}); optimiseInternal(_settings, {});

View File

@ -134,13 +134,6 @@ public:
/// is optimised according to the settings in @a _settings. /// is optimised according to the settings in @a _settings.
Assembly& optimise(OptimiserSettings const& _settings); Assembly& optimise(OptimiserSettings const& _settings);
/// Modify (if @a _enable is set) and return the current assembly such that creation and
/// execution gas usage is optimised. @a _isCreation should be true for the top-level assembly.
/// @a _runs specifes 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.
/// If @a _enable is not set, will perform some simple peephole optimizations.
Assembly& optimise(bool _enable, langutil::EVMVersion _evmVersion, bool _isCreation, size_t _runs);
/// Create a text representation of the assembly. /// Create a text representation of the assembly.
std::string assemblyString( std::string assemblyString(
langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),

View File

@ -692,13 +692,13 @@ bool CompilerStack::compile(State _stopAfter)
optimiserSettings.runJumpdestRemover = m_optimiserSettings.runJumpdestRemover; optimiserSettings.runJumpdestRemover = m_optimiserSettings.runJumpdestRemover;
optimiserSettings.runPeephole = m_optimiserSettings.runPeephole; optimiserSettings.runPeephole = m_optimiserSettings.runPeephole;
m_contracts[evmSourceName].evmAssembly = make_shared<evmasm::Assembly>(evmSourceName); m_contracts[evmSourceName].evmAssembly = make_shared<evmasm::Assembly>(true, evmSourceName);
m_contracts[evmSourceName].evmAssembly->loadFromAssemblyJSON(m_evmAssemblyJson[evmSourceName]); m_contracts[evmSourceName].evmAssembly->loadFromAssemblyJSON(m_evmAssemblyJson[evmSourceName]);
if (m_optimiserSettings.enabled) if (m_optimiserSettings.enabled)
m_contracts[evmSourceName].evmAssembly->optimise(optimiserSettings); m_contracts[evmSourceName].evmAssembly->optimise(optimiserSettings);
m_contracts[evmSourceName].object = m_contracts[evmSourceName].evmAssembly->assemble(); m_contracts[evmSourceName].object = m_contracts[evmSourceName].evmAssembly->assemble();
m_contracts[evmSourceName].evmRuntimeAssembly = make_shared<evmasm::Assembly>(evmSourceName); m_contracts[evmSourceName].evmRuntimeAssembly = make_shared<evmasm::Assembly>(false, evmSourceName);
m_contracts[evmSourceName].evmRuntimeAssembly->setSources(m_contracts[evmSourceName].evmAssembly->sources()); m_contracts[evmSourceName].evmRuntimeAssembly->setSources(m_contracts[evmSourceName].evmAssembly->sources());
m_contracts[evmSourceName].evmRuntimeAssembly->loadFromAssemblyJSON(m_evmAssemblyJson[evmSourceName][".data"]["0"], false); m_contracts[evmSourceName].evmRuntimeAssembly->loadFromAssemblyJSON(m_evmAssemblyJson[evmSourceName][".data"]["0"], false);
if (m_optimiserSettings.enabled) if (m_optimiserSettings.enabled)

View File

@ -168,7 +168,7 @@ ostream& operator<<(ostream& _out, CompilerOutputs const& _selection)
if (_selection.*component) if (_selection.*component)
serializedSelection.push_back(CompilerOutputs::componentName(component)); serializedSelection.push_back(CompilerOutputs::componentName(component));
return _out << joinHumanReadable(serializedSelection, ","); return _out << util::joinHumanReadable(serializedSelection, ",");
} }
string const& CompilerOutputs::componentName(bool CompilerOutputs::* _component) string const& CompilerOutputs::componentName(bool CompilerOutputs::* _component)
@ -199,7 +199,7 @@ ostream& operator<<(ostream& _out, CombinedJsonRequests const& _requests)
if (_requests.*component) if (_requests.*component)
serializedRequests.push_back(CombinedJsonRequests::componentName(component)); serializedRequests.push_back(CombinedJsonRequests::componentName(component));
return _out << joinHumanReadable(serializedRequests, ","); return _out << util::joinHumanReadable(serializedRequests, ",");
} }
string const& CombinedJsonRequests::componentName(bool CombinedJsonRequests::* _component) string const& CombinedJsonRequests::componentName(bool CombinedJsonRequests::* _component)
@ -347,17 +347,17 @@ void CommandLineParser::parseLibraryOption(string const& _input)
try try
{ {
if (fs::is_regular_file(_input)) if (fs::is_regular_file(_input))
data = readFileAsString(_input); data = util::readFileAsString(_input);
} }
catch (fs::filesystem_error const&) catch (fs::filesystem_error const&)
{ {
// Thrown e.g. if path is too long. // Thrown e.g. if path is too long.
} }
catch (FileNotFound const&) catch (util::FileNotFound const&)
{ {
// Should not happen if `fs::is_regular_file` is correct. // Should not happen if `fs::is_regular_file` is correct.
} }
catch (NotAFile const&) catch (util::NotAFile const&)
{ {
// Should not happen if `fs::is_regular_file` is correct. // Should not happen if `fs::is_regular_file` is correct.
} }
@ -422,15 +422,15 @@ void CommandLineParser::parseLibraryOption(string const& _input)
"Invalid length for address for library \"" + libName + "\": " + "Invalid length for address for library \"" + libName + "\": " +
to_string(addrString.length()) + " instead of 40 characters." to_string(addrString.length()) + " instead of 40 characters."
); );
if (!passesAddressChecksum(addrString, false)) if (!util::passesAddressChecksum(addrString, false))
solThrow( solThrow(
CommandLineValidationError, CommandLineValidationError,
"Invalid checksum on address for library \"" + libName + "\": " + addrString + "\n" "Invalid checksum on address for library \"" + libName + "\": " + addrString + "\n"
"The correct checksum is " + getChecksummedAddress(addrString) "The correct checksum is " + util::getChecksummedAddress(addrString)
); );
bytes binAddr = fromHex(addrString); bytes binAddr = util::fromHex(addrString);
h160 address(binAddr, h160::AlignRight); util::h160 address(binAddr, util::h160::AlignRight);
if (binAddr.size() > 20 || address == h160()) if (binAddr.size() > 20 || address == util::h160())
solThrow( solThrow(
CommandLineValidationError, CommandLineValidationError,
"Invalid address for library \"" + libName + "\": " + addrString "Invalid address for library \"" + libName + "\": " + addrString
@ -595,15 +595,15 @@ General Information)").c_str(),
) )
( (
g_strRevertStrings.c_str(), g_strRevertStrings.c_str(),
po::value<string>()->value_name(joinHumanReadable(g_revertStringsArgs, ",")), po::value<string>()->value_name(util::joinHumanReadable(g_revertStringsArgs, ",")),
"Strip revert (and require) reason strings or add additional debugging information." "Strip revert (and require) reason strings or add additional debugging information."
) )
( (
g_strDebugInfo.c_str(), g_strDebugInfo.c_str(),
po::value<string>()->default_value(toString(DebugInfoSelection::Default())), po::value<string>()->default_value(util::toString(DebugInfoSelection::Default())),
("Debug info components to be included in the produced EVM assembly and Yul code. " ("Debug info components to be included in the produced EVM assembly and Yul code. "
"Value can be all, none or a comma-separated list containing one or more of the " "Value can be all, none or a comma-separated list containing one or more of the "
"following components: " + joinHumanReadable(DebugInfoSelection::componentMap() | ranges::views::keys) + ".").c_str() "following components: " + util::joinHumanReadable(DebugInfoSelection::componentMap() | ranges::views::keys) + ".").c_str()
) )
( (
g_strStopAfter.c_str(), g_strStopAfter.c_str(),
@ -665,12 +665,12 @@ General Information)").c_str(),
assemblyModeOptions.add_options() assemblyModeOptions.add_options()
( (
g_strMachine.c_str(), g_strMachine.c_str(),
po::value<string>()->value_name(joinHumanReadable(g_machineArgs, ",")), po::value<string>()->value_name(util::joinHumanReadable(g_machineArgs, ",")),
"Target machine in assembly or Yul mode." "Target machine in assembly or Yul mode."
) )
( (
g_strYulDialect.c_str(), g_strYulDialect.c_str(),
po::value<string>()->value_name(joinHumanReadable(g_yulDialectArgs, ",")), po::value<string>()->value_name(util::joinHumanReadable(g_yulDialectArgs, ",")),
"Input dialect to use in assembly or yul mode." "Input dialect to use in assembly or yul mode."
) )
; ;
@ -743,7 +743,7 @@ General Information)").c_str(),
) )
( (
g_strCombinedJson.c_str(), g_strCombinedJson.c_str(),
po::value<string>()->value_name(joinHumanReadable(CombinedJsonRequests::componentMap() | ranges::views::keys, ",")), po::value<string>()->value_name(util::joinHumanReadable(CombinedJsonRequests::componentMap() | ranges::views::keys, ",")),
"Output a single json document containing the specified information." "Output a single json document containing the specified information."
) )
; ;
@ -753,7 +753,7 @@ General Information)").c_str(),
metadataOptions.add_options() metadataOptions.add_options()
( (
g_strMetadataHash.c_str(), g_strMetadataHash.c_str(),
po::value<string>()->value_name(joinHumanReadable(g_metadataHashArgs, ",")), po::value<string>()->value_name(util::joinHumanReadable(g_metadataHashArgs, ",")),
"Choose hash method for the bytecode metadata or disable it." "Choose hash method for the bytecode metadata or disable it."
) )
( (
@ -1047,11 +1047,11 @@ void CommandLineParser::processArgs()
if (m_args.count(g_strPrettyJson) > 0) if (m_args.count(g_strPrettyJson) > 0)
{ {
m_options.formatting.json.format = JsonFormat::Pretty; m_options.formatting.json.format = util::JsonFormat::Pretty;
} }
if (!m_args[g_strJsonIndent].defaulted()) if (!m_args[g_strJsonIndent].defaulted())
{ {
m_options.formatting.json.format = JsonFormat::Pretty; m_options.formatting.json.format = util::JsonFormat::Pretty;
m_options.formatting.json.indent = m_args[g_strJsonIndent].as<uint32_t>(); m_options.formatting.json.indent = m_args[g_strJsonIndent].as<uint32_t>();
} }
@ -1329,7 +1329,7 @@ size_t CommandLineParser::countEnabledOptions(vector<string> const& _optionNames
string CommandLineParser::joinOptionNames(vector<string> const& _optionNames, string _separator) string CommandLineParser::joinOptionNames(vector<string> const& _optionNames, string _separator)
{ {
return joinHumanReadable( return util::joinHumanReadable(
_optionNames | ranges::views::transform([](string const& _option){ return "--" + _option; }), _optionNames | ranges::views::transform([](string const& _option){ return "--" + _option; }),
_separator _separator
); );

View File

@ -67,7 +67,7 @@ BOOST_AUTO_TEST_CASE(all_assembly_items)
auto sub_asm = make_shared<string>("sub.asm"); auto sub_asm = make_shared<string>("sub.asm");
_subAsm.setSourceLocation({6, 8, sub_asm}); _subAsm.setSourceLocation({6, 8, sub_asm});
Assembly _verbatimAsm; Assembly _verbatimAsm(true, "");
auto verbatim_asm = make_shared<string>("verbatim.asm"); auto verbatim_asm = make_shared<string>("verbatim.asm");
_verbatimAsm.setSourceLocation({8, 18, verbatim_asm}); _verbatimAsm.setSourceLocation({8, 18, verbatim_asm});
@ -202,7 +202,7 @@ BOOST_AUTO_TEST_CASE(all_assembly_items)
BOOST_CHECK(util::jsonParseStrict(json, jsonValue)); BOOST_CHECK(util::jsonParseStrict(json, jsonValue));
BOOST_CHECK_EQUAL(util::jsonCompactPrint(_assembly.assemblyJSON(indices)), util::jsonCompactPrint(jsonValue)); BOOST_CHECK_EQUAL(util::jsonCompactPrint(_assembly.assemblyJSON(indices)), util::jsonCompactPrint(jsonValue));
Assembly _assemblyFromJson; Assembly _assemblyFromJson(true, "");
_assemblyFromJson.loadFromAssemblyJSON(_assembly.assemblyJSON(indices)); _assemblyFromJson.loadFromAssemblyJSON(_assembly.assemblyJSON(indices));
BOOST_CHECK_EQUAL(util::jsonCompactPrint(_assemblyFromJson.assemblyJSON(indices)), util::jsonCompactPrint(jsonValue)); BOOST_CHECK_EQUAL(util::jsonCompactPrint(_assemblyFromJson.assemblyJSON(indices)), util::jsonCompactPrint(jsonValue));
BOOST_CHECK_EQUAL(_assembly.assemble().toHex(), _assemblyFromJson.assemble().toHex()); BOOST_CHECK_EQUAL(_assembly.assemble().toHex(), _assemblyFromJson.assemble().toHex());