mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Introduce global optimiser settings.
This commit is contained in:
committed by
chriseth
parent
0e475438a9
commit
cf5c13f9c7
@@ -108,11 +108,17 @@ void CompilerStack::setLibraries(std::map<std::string, h160> const& _libraries)
|
||||
}
|
||||
|
||||
void CompilerStack::setOptimiserSettings(bool _optimize, unsigned _runs)
|
||||
{
|
||||
OptimiserSettings settings = _optimize ? OptimiserSettings::enabled() : OptimiserSettings::minimal();
|
||||
settings.expectedExecutionsPerDeployment = _runs;
|
||||
setOptimiserSettings(std::move(settings));
|
||||
}
|
||||
|
||||
void CompilerStack::setOptimiserSettings(OptimiserSettings _settings)
|
||||
{
|
||||
if (m_stackState >= ParsingSuccessful)
|
||||
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must set optimiser settings before parsing."));
|
||||
m_optimize = _optimize;
|
||||
m_optimizeRuns = _runs;
|
||||
m_optimiserSettings = std::move(_settings);
|
||||
}
|
||||
|
||||
void CompilerStack::useMetadataLiteralSources(bool _metadataLiteralSources)
|
||||
@@ -146,8 +152,7 @@ void CompilerStack::reset(bool _keepSources)
|
||||
m_unhandledSMTLib2Queries.clear();
|
||||
m_libraries.clear();
|
||||
m_evmVersion = langutil::EVMVersion();
|
||||
m_optimize = false;
|
||||
m_optimizeRuns = 200;
|
||||
m_optimiserSettings = OptimiserSettings::minimal();
|
||||
m_globalContext.reset();
|
||||
m_scopes.clear();
|
||||
m_sourceOrder.clear();
|
||||
@@ -840,7 +845,7 @@ void CompilerStack::compileContract(
|
||||
|
||||
Contract& compiledContract = m_contracts.at(_contract.fullyQualifiedName());
|
||||
|
||||
shared_ptr<Compiler> compiler = make_shared<Compiler>(m_evmVersion, m_optimize, m_optimizeRuns);
|
||||
shared_ptr<Compiler> compiler = make_shared<Compiler>(m_evmVersion, m_optimiserSettings);
|
||||
compiledContract.compiler = compiler;
|
||||
|
||||
string metadata = createMetadata(compiledContract);
|
||||
@@ -953,8 +958,35 @@ string CompilerStack::createMetadata(Contract const& _contract) const
|
||||
meta["sources"][s.first]["urls"].append("bzzr://" + toHex(s.second.swarmHash().asBytes()));
|
||||
}
|
||||
}
|
||||
meta["settings"]["optimizer"]["enabled"] = m_optimize;
|
||||
meta["settings"]["optimizer"]["runs"] = m_optimizeRuns;
|
||||
|
||||
static_assert(sizeof(m_optimiserSettings.expectedExecutionsPerDeployment) <= sizeof(Json::LargestUInt), "Invalid word size.");
|
||||
solAssert(static_cast<Json::LargestUInt>(m_optimiserSettings.expectedExecutionsPerDeployment) < std::numeric_limits<Json::LargestUInt>::max(), "");
|
||||
meta["settings"]["optimizer"]["runs"] = Json::Value(Json::LargestUInt(m_optimiserSettings.expectedExecutionsPerDeployment));
|
||||
|
||||
/// Backwards compatibility: If set to one of the default settings, do not provide details.
|
||||
OptimiserSettings settingsWithoutRuns = m_optimiserSettings;
|
||||
// reset to default
|
||||
settingsWithoutRuns.expectedExecutionsPerDeployment = OptimiserSettings::minimal().expectedExecutionsPerDeployment;
|
||||
if (settingsWithoutRuns == OptimiserSettings::minimal())
|
||||
meta["settings"]["optimizer"]["enabled"] = false;
|
||||
else if (settingsWithoutRuns == OptimiserSettings::enabled())
|
||||
meta["settings"]["optimizer"]["enabled"] = true;
|
||||
else
|
||||
{
|
||||
Json::Value details{Json::objectValue};
|
||||
|
||||
details["orderLiterals"] = m_optimiserSettings.runOrderLiterals;
|
||||
details["jumpdestRemover"] = m_optimiserSettings.runJumpdestRemover;
|
||||
details["peephole"] = m_optimiserSettings.runPeephole;
|
||||
details["deduplicate"] = m_optimiserSettings.runDeduplicate;
|
||||
details["cse"] = m_optimiserSettings.runCSE;
|
||||
details["constantOptimizer"] = m_optimiserSettings.runConstantOptimiser;
|
||||
details["yul"] = m_optimiserSettings.runYulOptimiser;
|
||||
details["yulDetails"] = Json::objectValue;
|
||||
|
||||
meta["settings"]["optimizer"]["details"] = std::move(details);
|
||||
}
|
||||
|
||||
meta["settings"]["evmVersion"] = m_evmVersion.name();
|
||||
meta["settings"]["compilationTarget"][_contract.contract->sourceUnitName()] =
|
||||
_contract.contract->annotation().canonicalName;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <libsolidity/interface/ReadFile.h>
|
||||
#include <libsolidity/interface/OptimiserSettings.h>
|
||||
|
||||
#include <liblangutil/ErrorReporter.h>
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
@@ -128,6 +129,10 @@ public:
|
||||
/// Must be set before parsing.
|
||||
void setOptimiserSettings(bool _optimize, unsigned _runs = 200);
|
||||
|
||||
/// Changes the optimiser settings.
|
||||
/// Must be set before parsing.
|
||||
void setOptimiserSettings(OptimiserSettings _settings);
|
||||
|
||||
/// Set the EVM version used before running compile.
|
||||
/// When called without an argument it will revert to the default version.
|
||||
/// Must be set before parsing.
|
||||
@@ -342,8 +347,7 @@ private:
|
||||
) const;
|
||||
|
||||
ReadCallback::Callback m_readFile;
|
||||
bool m_optimize = false;
|
||||
unsigned m_optimizeRuns = 200;
|
||||
OptimiserSettings m_optimiserSettings;
|
||||
langutil::EVMVersion m_evmVersion;
|
||||
std::set<std::string> m_requestedContractNames;
|
||||
std::map<std::string, h160> m_libraries;
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Alex Beregszaszi
|
||||
* @date 2017
|
||||
* Helper class for optimiser settings.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
|
||||
struct OptimiserSettings
|
||||
{
|
||||
/// No optimisations at all - not recommended.
|
||||
static OptimiserSettings none()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
/// Minimal optimisations: Peephole and jumpdest remover
|
||||
static OptimiserSettings minimal()
|
||||
{
|
||||
OptimiserSettings s = none();
|
||||
s.runJumpdestRemover = true;
|
||||
s.runPeephole = true;
|
||||
return s;
|
||||
}
|
||||
/// Standard optimisations.
|
||||
static OptimiserSettings enabled()
|
||||
{
|
||||
OptimiserSettings s;
|
||||
s.runOrderLiterals = true;
|
||||
s.runJumpdestRemover = true;
|
||||
s.runPeephole = true;
|
||||
s.runDeduplicate = true;
|
||||
s.runCSE = true;
|
||||
s.runConstantOptimiser = true;
|
||||
// The only disabled one
|
||||
s.runYulOptimiser = false;
|
||||
s.expectedExecutionsPerDeployment = 200;
|
||||
return s;
|
||||
}
|
||||
/// Standard optimisations plus yul optimiser.
|
||||
static OptimiserSettings full()
|
||||
{
|
||||
OptimiserSettings s = enabled();
|
||||
s.runYulOptimiser = true;
|
||||
return s;
|
||||
}
|
||||
|
||||
bool operator==(OptimiserSettings const& _other) const
|
||||
{
|
||||
return
|
||||
runOrderLiterals == _other.runOrderLiterals &&
|
||||
runJumpdestRemover == _other.runJumpdestRemover &&
|
||||
runPeephole == _other.runPeephole &&
|
||||
runDeduplicate == _other.runDeduplicate &&
|
||||
runCSE == _other.runCSE &&
|
||||
runConstantOptimiser == _other.runConstantOptimiser &&
|
||||
runYulOptimiser == _other.runYulOptimiser &&
|
||||
expectedExecutionsPerDeployment == _other.expectedExecutionsPerDeployment;
|
||||
}
|
||||
|
||||
/// Move literals to the right of commutative binary operators during code generation.
|
||||
/// This helps exploiting associativity.
|
||||
bool runOrderLiterals = false;
|
||||
/// Non-referenced jump destination remover.
|
||||
bool runJumpdestRemover = false;
|
||||
/// Peephole optimizer
|
||||
bool runPeephole = false;
|
||||
/// Assembly block deduplicator
|
||||
bool runDeduplicate = false;
|
||||
/// Common subexpression eliminator based on assembly items.
|
||||
bool runCSE = false;
|
||||
/// Constant optimizer, which tries to find better representations that satisfy the given
|
||||
/// size/cost-trade-off.
|
||||
bool runConstantOptimiser = false;
|
||||
/// Yul optimiser with default settings. Will only run on certain parts of the code for now.
|
||||
bool runYulOptimiser = false;
|
||||
/// 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;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user