/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 | | } |