Coverage Report

Created: 2026-07-13 07:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/solidity/libyul/backends/evm/EVMMetrics.h
Line
Count
Source
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
 * Module providing metrics for the optimizer.
20
 */
21
22
#pragma once
23
24
#include <libyul/optimiser/ASTWalker.h>
25
#include <liblangutil/EVMVersion.h>
26
#include <libsolutil/Numeric.h>
27
#include <libevmasm/Instruction.h>
28
29
namespace solidity::yul
30
{
31
32
class EVMDialect;
33
34
/**
35
 * Gas meter for expressions only involving literals, identifiers and
36
 * EVM instructions.
37
 *
38
 * Assumes that EXP is not used with exponents larger than a single byte.
39
 * Is not particularly exact for anything apart from arithmetic.
40
 *
41
 * Assumes that Keccak-256 is computed on a single word (rounded up).
42
 */
43
class GasMeter
44
{
45
public:
46
  GasMeter(EVMDialect const& _dialect, bool _isCreation, bigint _runs):
47
190k
    m_dialect(_dialect),
48
190k
    m_isCreation{_isCreation},
49
190k
    m_runs(_isCreation? 1 : _runs)
50
190k
  {}
51
52
  /// @returns the full combined costs of deploying and evaluating the expression.
53
  bigint costs(Expression const& _expression) const;
54
  /// @returns the combined costs of deploying and running the instruction, not including
55
  /// the costs for its arguments.
56
  bigint instructionCosts(evmasm::Instruction _instruction) const;
57
58
private:
59
  bigint combineCosts(std::pair<bigint, bigint> _costs) const;
60
61
  EVMDialect const& m_dialect;
62
  bool m_isCreation = false;
63
  bigint m_runs;
64
};
65
66
class GasMeterVisitor: public ASTWalker
67
{
68
public:
69
  static std::pair<bigint, bigint> costs(
70
    Expression const& _expression,
71
    EVMDialect const& _dialect,
72
    bool _isCreation
73
  );
74
75
  static std::pair<bigint, bigint> instructionCosts(
76
    evmasm::Instruction _instruction,
77
    EVMDialect const& _dialect,
78
    bool _isCreation = false
79
  );
80
81
public:
82
  GasMeterVisitor(EVMDialect const& _dialect, bool _isCreation):
83
3.47M
    m_dialect(_dialect),
84
3.47M
    m_isCreation{_isCreation}
85
3.47M
  {}
86
87
  void operator()(FunctionCall const& _funCall) override;
88
  void operator()(Literal const& _literal) override;
89
  void operator()(Identifier const& _identifier) override;
90
91
private:
92
  bigint singleByteDataGas() const;
93
  /// Computes the cost of storing and executing the single instruction (excluding its arguments).
94
  /// For EXP, it assumes that the exponent is at most 255.
95
  /// Does not work particularly exact for anything apart from arithmetic.
96
  void instructionCostsInternal(evmasm::Instruction _instruction);
97
98
  EVMDialect const& m_dialect;
99
  bool m_isCreation = false;
100
  bigint m_runGas = 0;
101
  bigint m_dataGas = 0;
102
};
103
104
}