Coverage Report

Created: 2022-08-24 06:55

/src/solidity/libsolidity/interface/OptimiserSettings.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
  This file is part of solidity.
3
4
  solidity is free software: you can redistribute it and/or modify
5
  it under the terms of the GNU General Public License as published by
6
  the Free Software Foundation, either version 3 of the License, or
7
  (at your option) any later version.
8
9
  solidity is distributed in the hope that it will be useful,
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
  GNU General Public License for more details.
13
14
  You should have received a copy of the GNU General Public License
15
  along with solidity.  If not, see <http://www.gnu.org/licenses/>.
16
*/
17
// SPDX-License-Identifier: GPL-3.0
18
/**
19
 * @author Alex Beregszaszi
20
 * @date 2017
21
 * Helper class for optimiser settings.
22
 */
23
24
#pragma once
25
26
#include <liblangutil/Exceptions.h>
27
28
#include <cstddef>
29
#include <string>
30
31
namespace solidity::frontend
32
{
33
34
enum class OptimisationPreset
35
{
36
  None,
37
  Minimal,
38
  Standard,
39
  Full,
40
};
41
42
struct OptimiserSettings
43
{
44
  static char constexpr DefaultYulOptimiserSteps[] =
45
    "dhfoDgvulfnTUtnIf"            // None of these can make stack problems worse
46
    "["
47
      "xa[r]EscLM"               // Turn into SSA and simplify
48
      "cCTUtTOntnfDIul"          // Perform structural simplification
49
      "Lcul"                     // Simplify again
50
      "Vcul [j]"                 // Reverse SSA
51
52
      // should have good "compilability" property here.
53
54
      "Tpeul"                    // Run functional expression inliner
55
      "xa[rul]"                  // Prune a bit more in SSA
56
      "xa[r]cL"                  // Turn into SSA again and simplify
57
      "gvif"                     // Run full inliner
58
      "CTUca[r]LSsTFOtfDnca[r]Iulc" // SSA plus simplify
59
    "]"
60
    "jmul[jul] VcTOcul jmul";      // Make source short and pretty
61
62
  /// No optimisations at all - not recommended.
63
  static OptimiserSettings none()
64
420k
  {
65
420k
    return {};
66
420k
  }
67
  /// Minimal optimisations: Peephole and jumpdest remover
68
  static OptimiserSettings minimal()
69
95.9k
  {
70
95.9k
    OptimiserSettings s = none();
71
95.9k
    s.runJumpdestRemover = true;
72
95.9k
    s.runPeephole = true;
73
95.9k
    return s;
74
95.9k
  }
75
  /// Standard optimisations.
76
  static OptimiserSettings standard()
77
166k
  {
78
166k
    OptimiserSettings s;
79
166k
    s.runOrderLiterals = true;
80
166k
    s.runInliner = true;
81
166k
    s.runJumpdestRemover = true;
82
166k
    s.runPeephole = true;
83
166k
    s.runDeduplicate = true;
84
166k
    s.runCSE = true;
85
166k
    s.runConstantOptimiser = true;
86
166k
    s.runYulOptimiser = true;
87
166k
    s.optimizeStackAllocation = true;
88
166k
    return s;
89
166k
  }
90
  /// Full optimisations. Currently an alias for standard optimisations.
91
  static OptimiserSettings full()
92
94.9k
  {
93
94.9k
    return standard();
94
94.9k
  }
95
96
  static OptimiserSettings preset(OptimisationPreset _preset)
97
0
  {
98
0
    switch (_preset)
99
0
    {
100
0
      case OptimisationPreset::None: return none();
101
0
      case OptimisationPreset::Minimal: return minimal();
102
0
      case OptimisationPreset::Standard: return standard();
103
0
      case OptimisationPreset::Full: return full();
104
0
      default: solAssert(false, "");
105
0
    }
106
0
  }
107
108
  bool operator==(OptimiserSettings const& _other) const
109
34.9k
  {
110
34.9k
    return
111
34.9k
      runOrderLiterals == _other.runOrderLiterals &&
112
34.9k
      runInliner == _other.runInliner &&
113
34.9k
      runJumpdestRemover == _other.runJumpdestRemover &&
114
34.9k
      runPeephole == _other.runPeephole &&
115
34.9k
      runDeduplicate == _other.runDeduplicate &&
116
34.9k
      runCSE == _other.runCSE &&
117
34.9k
      runConstantOptimiser == _other.runConstantOptimiser &&
118
34.9k
      optimizeStackAllocation == _other.optimizeStackAllocation &&
119
34.9k
      runYulOptimiser == _other.runYulOptimiser &&
120
34.9k
      yulOptimiserSteps == _other.yulOptimiserSteps &&
121
34.9k
      expectedExecutionsPerDeployment == _other.expectedExecutionsPerDeployment;
122
34.9k
  }
123
124
  /// Move literals to the right of commutative binary operators during code generation.
125
  /// This helps exploiting associativity.
126
  bool runOrderLiterals = false;
127
  /// Inliner
128
  bool runInliner = false;
129
  /// Non-referenced jump destination remover.
130
  bool runJumpdestRemover = false;
131
  /// Peephole optimizer
132
  bool runPeephole = false;
133
  /// Assembly block deduplicator
134
  bool runDeduplicate = false;
135
  /// Common subexpression eliminator based on assembly items.
136
  bool runCSE = false;
137
  /// Constant optimizer, which tries to find better representations that satisfy the given
138
  /// size/cost-trade-off.
139
  bool runConstantOptimiser = false;
140
  /// Perform more efficient stack allocation for variables during code generation from Yul to bytecode.
141
  bool optimizeStackAllocation = false;
142
  /// Yul optimiser with default settings. Will only run on certain parts of the code for now.
143
  bool runYulOptimiser = false;
144
  /// Sequence of optimisation steps to be performed by Yul optimiser.
145
  /// Note that there are some hard-coded steps in the optimiser and you cannot disable
146
  /// them just by setting this to an empty string. Set @a runYulOptimiser to false if you want
147
  /// no optimisations.
148
  std::string yulOptimiserSteps = DefaultYulOptimiserSteps;
149
  /// This specifies an estimate on how often each opcode in this assembly will be executed,
150
  /// i.e. use a small value to optimise for size and a large value to optimise for runtime gas usage.
151
  size_t expectedExecutionsPerDeployment = 200;
152
};
153
154
}