solidity/libsolidity/interface/OptimiserSettings.h

161 lines
5.3 KiB
C
Raw Permalink Normal View History

2017-07-17 11:12:00 +00:00
/*
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/>.
*/
// SPDX-License-Identifier: GPL-3.0
2017-07-17 11:12:00 +00:00
/**
* @author Alex Beregszaszi
* @date 2017
* Helper class for optimiser settings.
*/
#pragma once
#include <liblangutil/Exceptions.h>
2017-07-17 11:12:00 +00:00
#include <cstddef>
#include <string>
2017-07-17 11:12:00 +00:00
2019-12-11 16:31:36 +00:00
namespace solidity::frontend
2017-07-17 11:12:00 +00:00
{
enum class OptimisationPreset
{
None,
Minimal,
Standard,
Full,
};
2017-07-17 11:12:00 +00:00
struct OptimiserSettings
{
static char constexpr DefaultYulOptimiserSteps[] =
"dhfoDgvulfnTUtnIf" // None of these can make stack problems worse
"["
2021-11-11 14:54:38 +00:00
"xa[r]EscLM" // Turn into SSA and simplify
"cCTUtTOntnfDIul" // Perform structural simplification
"Lcul" // Simplify again
2021-08-12 13:29:16 +00:00
"Vcul [j]" // Reverse SSA
// should have good "compilability" property here.
"Tpeul" // Run functional expression inliner
2021-08-12 13:29:16 +00:00
"xa[rul]" // Prune a bit more in SSA
"xa[r]cL" // Turn into SSA again and simplify
"gvif" // Run full inliner
2021-05-05 16:02:35 +00:00
"CTUca[r]LSsTFOtfDnca[r]Iulc" // SSA plus simplify
"]"
2021-08-12 13:29:16 +00:00
"jmul[jul] VcTOcul jmul"; // Make source short and pretty
static char constexpr DefaultYulOptimiserCleanupSteps[] = "fDnTOcmu";
2017-07-17 11:12:00 +00:00
/// 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 standard()
2017-07-17 11:12:00 +00:00
{
OptimiserSettings s;
s.runOrderLiterals = true;
2021-01-14 12:02:14 +00:00
s.runInliner = true;
2017-07-17 11:12:00 +00:00
s.runJumpdestRemover = true;
s.runPeephole = true;
s.runDeduplicate = true;
s.runCSE = true;
s.runConstantOptimiser = true;
2019-11-26 15:41:58 +00:00
s.runYulOptimiser = true;
s.optimizeStackAllocation = true;
2017-07-17 11:12:00 +00:00
return s;
}
2019-11-26 15:41:58 +00:00
/// Full optimisations. Currently an alias for standard optimisations.
2017-07-17 11:12:00 +00:00
static OptimiserSettings full()
{
2019-11-26 15:41:58 +00:00
return standard();
2017-07-17 11:12:00 +00:00
}
static OptimiserSettings preset(OptimisationPreset _preset)
{
switch (_preset)
{
case OptimisationPreset::None: return none();
case OptimisationPreset::Minimal: return minimal();
case OptimisationPreset::Standard: return standard();
case OptimisationPreset::Full: return full();
}
util::unreachable();
}
2017-07-17 11:12:00 +00:00
bool operator==(OptimiserSettings const& _other) const
{
return
runOrderLiterals == _other.runOrderLiterals &&
2021-01-14 12:02:14 +00:00
runInliner == _other.runInliner &&
2017-07-17 11:12:00 +00:00
runJumpdestRemover == _other.runJumpdestRemover &&
runPeephole == _other.runPeephole &&
runDeduplicate == _other.runDeduplicate &&
runCSE == _other.runCSE &&
runConstantOptimiser == _other.runConstantOptimiser &&
2019-02-26 18:55:13 +00:00
optimizeStackAllocation == _other.optimizeStackAllocation &&
2017-07-17 11:12:00 +00:00
runYulOptimiser == _other.runYulOptimiser &&
yulOptimiserSteps == _other.yulOptimiserSteps &&
2017-07-17 11:12:00 +00:00
expectedExecutionsPerDeployment == _other.expectedExecutionsPerDeployment;
}
/// Move literals to the right of commutative binary operators during code generation.
/// This helps exploiting associativity.
bool runOrderLiterals = false;
2021-01-14 12:02:14 +00:00
/// Inliner
bool runInliner = false;
2017-07-17 11:12:00 +00:00
/// 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;
2019-02-26 18:55:13 +00:00
/// Perform more efficient stack allocation for variables during code generation from Yul to bytecode.
bool optimizeStackAllocation = false;
2017-07-17 11:12:00 +00:00
/// Yul optimiser with default settings. Will only run on certain parts of the code for now.
bool runYulOptimiser = false;
/// Sequence of optimisation steps to be performed by Yul optimiser.
/// Note that there are some hard-coded steps in the optimiser and you cannot disable
/// them just by setting this to an empty string. Set @a runYulOptimiser to false if you want
/// no optimisations.
std::string yulOptimiserSteps = DefaultYulOptimiserSteps;
2022-08-23 09:58:12 +00:00
/// Sequence of clean-up optimisation steps after yulOptimiserSteps is run. Note that if the string
/// is left empty, there will still be hard-coded optimisation steps that will run regardless.
/// Set @a runYulOptimiser to false if you want no optimisations.
std::string yulOptimiserCleanupSteps = DefaultYulOptimiserCleanupSteps;
2017-07-17 11:12:00 +00:00
/// 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;
};
}