mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Take termination into account for data flow analyzer.
This commit is contained in:
parent
04c8a7f0c6
commit
ca29136348
@ -43,10 +43,12 @@ using namespace solidity::yul;
|
|||||||
|
|
||||||
DataFlowAnalyzer::DataFlowAnalyzer(
|
DataFlowAnalyzer::DataFlowAnalyzer(
|
||||||
Dialect const& _dialect,
|
Dialect const& _dialect,
|
||||||
map<YulString, SideEffects> _functionSideEffects
|
map<YulString, SideEffects> _functionSideEffects,
|
||||||
|
map<YulString, ControlFlowSideEffects> _controlFlowSideEffects
|
||||||
):
|
):
|
||||||
m_dialect(_dialect),
|
m_dialect(_dialect),
|
||||||
m_functionSideEffects(std::move(_functionSideEffects)),
|
m_functionSideEffects(std::move(_functionSideEffects)),
|
||||||
|
m_controlFlowSideEffects(std::move(_controlFlowSideEffects)),
|
||||||
m_knowledgeBase(_dialect, m_value)
|
m_knowledgeBase(_dialect, m_value)
|
||||||
{
|
{
|
||||||
if (auto const* builtin = _dialect.memoryStoreFunction(YulString{}))
|
if (auto const* builtin = _dialect.memoryStoreFunction(YulString{}))
|
||||||
@ -120,9 +122,10 @@ void DataFlowAnalyzer::operator()(If& _if)
|
|||||||
unordered_map<YulString, YulString> memory = m_memory;
|
unordered_map<YulString, YulString> memory = m_memory;
|
||||||
|
|
||||||
ASTModifier::operator()(_if);
|
ASTModifier::operator()(_if);
|
||||||
|
joinKnowledge(storage, memory, _if.body);
|
||||||
|
|
||||||
joinKnowledge(storage, memory);
|
// TODO we can do the same optimization here, but maybe this is already done in the ssa
|
||||||
|
// transform or some other step?
|
||||||
clearValues(assignedVariableNames(_if.body));
|
clearValues(assignedVariableNames(_if.body));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,8 +139,8 @@ void DataFlowAnalyzer::operator()(Switch& _switch)
|
|||||||
unordered_map<YulString, YulString> storage = m_storage;
|
unordered_map<YulString, YulString> storage = m_storage;
|
||||||
unordered_map<YulString, YulString> memory = m_memory;
|
unordered_map<YulString, YulString> memory = m_memory;
|
||||||
(*this)(_case.body);
|
(*this)(_case.body);
|
||||||
//TODO throw away knowledge if it is terminating
|
|
||||||
joinKnowledge(storage, memory);
|
joinKnowledge(storage, memory, _case.body);
|
||||||
|
|
||||||
set<YulString> variables = assignedVariableNames(_case.body);
|
set<YulString> variables = assignedVariableNames(_case.body);
|
||||||
assignedVariables += variables;
|
assignedVariables += variables;
|
||||||
@ -343,7 +346,8 @@ void DataFlowAnalyzer::clearKnowledgeIfInvalidated(Block const& _block)
|
|||||||
|
|
||||||
void DataFlowAnalyzer::clearKnowledgeIfInvalidated(Expression const& _expr)
|
void DataFlowAnalyzer::clearKnowledgeIfInvalidated(Expression const& _expr)
|
||||||
{
|
{
|
||||||
// TODO with the extended side-effects, this could also be more precise now.
|
// TODO with the extended side-effects, this could also be more precise now,
|
||||||
|
// I.e. we should check collisions like we do for sstore and mstore
|
||||||
SideEffectsCollector sideEffects(m_dialect, _expr, &m_functionSideEffects);
|
SideEffectsCollector sideEffects(m_dialect, _expr, &m_functionSideEffects);
|
||||||
if (sideEffects.invalidatesStorage())
|
if (sideEffects.invalidatesStorage())
|
||||||
m_storage.clear();
|
m_storage.clear();
|
||||||
@ -353,11 +357,25 @@ void DataFlowAnalyzer::clearKnowledgeIfInvalidated(Expression const& _expr)
|
|||||||
|
|
||||||
void DataFlowAnalyzer::joinKnowledge(
|
void DataFlowAnalyzer::joinKnowledge(
|
||||||
unordered_map<YulString, YulString> const& _olderStorage,
|
unordered_map<YulString, YulString> const& _olderStorage,
|
||||||
unordered_map<YulString, YulString> const& _olderMemory
|
unordered_map<YulString, YulString> const& _olderMemory,
|
||||||
|
Block const& _branch
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
joinKnowledgeHelper(m_storage, _olderStorage);
|
if (
|
||||||
joinKnowledgeHelper(m_memory, _olderMemory);
|
_branch.statements.empty() ||
|
||||||
|
TerminationFinder(m_dialect, &m_controlFlowSideEffects).controlFlowKind(_branch.statements.back()) ==
|
||||||
|
TerminationFinder::ControlFlow::FlowOut
|
||||||
|
)
|
||||||
|
{
|
||||||
|
joinKnowledgeHelper(m_storage, _olderStorage);
|
||||||
|
joinKnowledgeHelper(m_memory, _olderMemory);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TOOD test that this works with 'break' and 'continue'
|
||||||
|
m_storage = _olderStorage;
|
||||||
|
m_memory = _olderMemory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFlowAnalyzer::joinKnowledgeHelper(
|
void DataFlowAnalyzer::joinKnowledgeHelper(
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <libyul/YulString.h>
|
#include <libyul/YulString.h>
|
||||||
#include <libyul/AST.h> // Needed for m_zero below.
|
#include <libyul/AST.h> // Needed for m_zero below.
|
||||||
#include <libyul/SideEffects.h>
|
#include <libyul/SideEffects.h>
|
||||||
|
#include <libyul/ControlFlowSideEffects.h>
|
||||||
|
|
||||||
#include <libsolutil/Common.h>
|
#include <libsolutil/Common.h>
|
||||||
|
|
||||||
@ -85,7 +86,8 @@ public:
|
|||||||
/// The parameter is mostly used to determine movability of expressions.
|
/// The parameter is mostly used to determine movability of expressions.
|
||||||
explicit DataFlowAnalyzer(
|
explicit DataFlowAnalyzer(
|
||||||
Dialect const& _dialect,
|
Dialect const& _dialect,
|
||||||
std::map<YulString, SideEffects> _functionSideEffects = {}
|
std::map<YulString, SideEffects> _functionSideEffects = {},
|
||||||
|
std::map<YulString, ControlFlowSideEffects> _controlFlowSideEffects = {}
|
||||||
);
|
);
|
||||||
|
|
||||||
using ASTModifier::operator();
|
using ASTModifier::operator();
|
||||||
@ -123,9 +125,12 @@ protected:
|
|||||||
/// Joins knowledge about storage and memory with an older point in the control-flow.
|
/// Joins knowledge about storage and memory with an older point in the control-flow.
|
||||||
/// This only works if the current state is a direct successor of the older point,
|
/// This only works if the current state is a direct successor of the older point,
|
||||||
/// i.e. `_otherStorage` and `_otherMemory` cannot have additional changes.
|
/// i.e. `_otherStorage` and `_otherMemory` cannot have additional changes.
|
||||||
|
/// If the last statement in the vector is not continuing, replace the current knowledge
|
||||||
|
/// with the old instead.
|
||||||
void joinKnowledge(
|
void joinKnowledge(
|
||||||
std::unordered_map<YulString, YulString> const& _olderStorage,
|
std::unordered_map<YulString, YulString> const& _olderStorage,
|
||||||
std::unordered_map<YulString, YulString> const& _olderMemory
|
std::unordered_map<YulString, YulString> const& _olderMemory,
|
||||||
|
Block const& _branch
|
||||||
);
|
);
|
||||||
|
|
||||||
static void joinKnowledgeHelper(
|
static void joinKnowledgeHelper(
|
||||||
@ -163,6 +168,7 @@ protected:
|
|||||||
/// Side-effects of user-defined functions. Worst-case side-effects are assumed
|
/// Side-effects of user-defined functions. Worst-case side-effects are assumed
|
||||||
/// if this is not provided or the function is not found.
|
/// if this is not provided or the function is not found.
|
||||||
std::map<YulString, SideEffects> m_functionSideEffects;
|
std::map<YulString, SideEffects> m_functionSideEffects;
|
||||||
|
std::map<YulString, ControlFlowSideEffects> m_controlFlowSideEffects;
|
||||||
|
|
||||||
/// Current values of variables, always movable.
|
/// Current values of variables, always movable.
|
||||||
std::map<YulString, AssignedValue> m_value;
|
std::map<YulString, AssignedValue> m_value;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <libyul/backends/evm/EVMMetrics.h>
|
#include <libyul/backends/evm/EVMMetrics.h>
|
||||||
#include <libyul/optimiser/Semantics.h>
|
#include <libyul/optimiser/Semantics.h>
|
||||||
#include <libyul/optimiser/CallGraphGenerator.h>
|
#include <libyul/optimiser/CallGraphGenerator.h>
|
||||||
|
#include <libyul/ControlFlowSideEffectsCollector.h>
|
||||||
#include <libyul/SideEffects.h>
|
#include <libyul/SideEffects.h>
|
||||||
#include <libyul/AST.h>
|
#include <libyul/AST.h>
|
||||||
#include <libyul/Utilities.h>
|
#include <libyul/Utilities.h>
|
||||||
@ -47,6 +48,7 @@ void LoadResolver::run(OptimiserStepContext& _context, Block& _ast)
|
|||||||
LoadResolver{
|
LoadResolver{
|
||||||
_context.dialect,
|
_context.dialect,
|
||||||
SideEffectsPropagator::sideEffects(_context.dialect, CallGraphGenerator::callGraph(_ast)),
|
SideEffectsPropagator::sideEffects(_context.dialect, CallGraphGenerator::callGraph(_ast)),
|
||||||
|
ControlFlowSideEffectsCollector{_context.dialect, _ast}.functionSideEffectsNamed(),
|
||||||
containsMSize,
|
containsMSize,
|
||||||
_context.expectedExecutionsPerDeployment
|
_context.expectedExecutionsPerDeployment
|
||||||
}(_ast);
|
}(_ast);
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <libyul/optimiser/DataFlowAnalyzer.h>
|
#include <libyul/optimiser/DataFlowAnalyzer.h>
|
||||||
#include <libyul/optimiser/OptimiserStep.h>
|
#include <libyul/optimiser/OptimiserStep.h>
|
||||||
|
#include <libyul/ControlFlowSideEffects.h>
|
||||||
|
|
||||||
namespace solidity::yul
|
namespace solidity::yul
|
||||||
{
|
{
|
||||||
@ -50,10 +51,11 @@ private:
|
|||||||
LoadResolver(
|
LoadResolver(
|
||||||
Dialect const& _dialect,
|
Dialect const& _dialect,
|
||||||
std::map<YulString, SideEffects> _functionSideEffects,
|
std::map<YulString, SideEffects> _functionSideEffects,
|
||||||
|
std::map<YulString, ControlFlowSideEffects> _controlFlowSideEffects,
|
||||||
bool _containsMSize,
|
bool _containsMSize,
|
||||||
std::optional<size_t> _expectedExecutionsPerDeployment
|
std::optional<size_t> _expectedExecutionsPerDeployment
|
||||||
):
|
):
|
||||||
DataFlowAnalyzer(_dialect, std::move(_functionSideEffects)),
|
DataFlowAnalyzer(_dialect, std::move(_functionSideEffects), std::move(_controlFlowSideEffects)),
|
||||||
m_containsMSize(_containsMSize),
|
m_containsMSize(_containsMSize),
|
||||||
m_expectedExecutionsPerDeployment(std::move(_expectedExecutionsPerDeployment))
|
m_expectedExecutionsPerDeployment(std::move(_expectedExecutionsPerDeployment))
|
||||||
{}
|
{}
|
||||||
|
@ -14,6 +14,6 @@ contract c {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// test() -> 9, 4
|
// test() -> 9, 4
|
||||||
// gas irOptimized: 123162
|
// gas irOptimized: 123195
|
||||||
// gas legacy: 123579
|
// gas legacy: 123579
|
||||||
// gas legacyOptimized: 123208
|
// gas legacyOptimized: 123208
|
||||||
|
@ -18,6 +18,6 @@ contract C {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// test() -> 7
|
// test() -> 7
|
||||||
// gas irOptimized: 124041
|
// gas irOptimized: 124024
|
||||||
// gas legacy: 205196
|
// gas legacy: 205196
|
||||||
// gas legacyOptimized: 204987
|
// gas legacyOptimized: 204987
|
||||||
|
@ -11,7 +11,7 @@ contract Creator {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// constructor(): 1, 2, 3, 4 ->
|
// constructor(): 1, 2, 3, 4 ->
|
||||||
// gas irOptimized: 129908
|
// gas irOptimized: 127748
|
||||||
// gas legacy: 176789
|
// gas legacy: 176789
|
||||||
// gas legacyOptimized: 129585
|
// gas legacyOptimized: 129585
|
||||||
// r() -> 4
|
// r() -> 4
|
||||||
|
@ -45,6 +45,6 @@ contract C {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// test() -> 5, 6, 7
|
// test() -> 5, 6, 7
|
||||||
// gas irOptimized: 298983
|
// gas irOptimized: 298177
|
||||||
// gas legacy: 452172
|
// gas legacy: 452172
|
||||||
// gas legacyOptimized: 285017
|
// gas legacyOptimized: 285017
|
||||||
|
@ -26,6 +26,6 @@ contract Creator {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8
|
// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8
|
||||||
// gas irOptimized: 443960
|
// gas irOptimized: 446570
|
||||||
// gas legacy: 590683
|
// gas legacy: 590683
|
||||||
// gas legacyOptimized: 448326
|
// gas legacyOptimized: 448326
|
||||||
|
@ -26,6 +26,6 @@ contract Creator {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h"
|
// f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h"
|
||||||
// gas irOptimized: 300804
|
// gas irOptimized: 299178
|
||||||
// gas legacy: 428917
|
// gas legacy: 428917
|
||||||
// gas legacyOptimized: 298128
|
// gas legacyOptimized: 298128
|
||||||
|
@ -19,7 +19,7 @@ contract Main {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// constructor(): "abc", true
|
// constructor(): "abc", true
|
||||||
// gas irOptimized: 107175
|
// gas irOptimized: 105225
|
||||||
// gas legacy: 145838
|
// gas legacy: 145838
|
||||||
// gas legacyOptimized: 104017
|
// gas legacyOptimized: 104017
|
||||||
// getFlag() -> true
|
// getFlag() -> true
|
||||||
|
@ -12,7 +12,7 @@ contract C {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// constructor(): 1, 2, 3, 4 ->
|
// constructor(): 1, 2, 3, 4 ->
|
||||||
// gas irOptimized: 174905
|
// gas irOptimized: 175559
|
||||||
// gas legacy: 221377
|
// gas legacy: 221377
|
||||||
// gas legacyOptimized: 177671
|
// gas legacyOptimized: 177671
|
||||||
// a() -> 1
|
// a() -> 1
|
||||||
|
@ -15,5 +15,5 @@ contract B is A {
|
|||||||
// compileViaYul: true
|
// compileViaYul: true
|
||||||
// ----
|
// ----
|
||||||
// constructor() ->
|
// constructor() ->
|
||||||
// gas irOptimized: 122017
|
// gas irOptimized: 120289
|
||||||
// y() -> 42
|
// y() -> 42
|
||||||
|
@ -12,7 +12,7 @@ contract B is A {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// constructor() ->
|
// constructor() ->
|
||||||
// gas irOptimized: 122017
|
// gas irOptimized: 120289
|
||||||
// gas legacy: 135046
|
// gas legacy: 135046
|
||||||
// gas legacyOptimized: 116176
|
// gas legacyOptimized: 116176
|
||||||
// y() -> 42
|
// y() -> 42
|
||||||
|
@ -11,7 +11,7 @@ contract C {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// constructor(): 2, 0 ->
|
// constructor(): 2, 0 ->
|
||||||
// gas irOptimized: 104227
|
// gas irOptimized: 102283
|
||||||
// gas legacy: 117158
|
// gas legacy: 117158
|
||||||
// i() -> 2
|
// i() -> 2
|
||||||
// k() -> 0
|
// k() -> 0
|
||||||
|
@ -23,7 +23,7 @@ contract D is B, C {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// constructor(): 2, 0 ->
|
// constructor(): 2, 0 ->
|
||||||
// gas irOptimized: 160166
|
// gas irOptimized: 159086
|
||||||
// gas legacy: 170665
|
// gas legacy: 170665
|
||||||
// gas legacyOptimized: 145396
|
// gas legacyOptimized: 145396
|
||||||
// i() -> 2
|
// i() -> 2
|
||||||
|
@ -14,7 +14,7 @@ contract D is C {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// constructor(): 2, 0 ->
|
// constructor(): 2, 0 ->
|
||||||
// gas irOptimized: 124844
|
// gas irOptimized: 122900
|
||||||
// gas legacy: 139250
|
// gas legacy: 139250
|
||||||
// gas legacyOptimized: 119367
|
// gas legacyOptimized: 119367
|
||||||
// i() -> 2
|
// i() -> 2
|
||||||
|
@ -51,7 +51,7 @@ contract test {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// constructor()
|
// constructor()
|
||||||
// gas irOptimized: 707330
|
// gas irOptimized: 708410
|
||||||
// gas legacy: 1130761
|
// gas legacy: 1130761
|
||||||
// gas legacyOptimized: 750416
|
// gas legacyOptimized: 750416
|
||||||
// toSlice(string): 0x20, 11, "hello world" -> 11, 0xa0
|
// toSlice(string): 0x20, 11, "hello world" -> 11, 0xa0
|
||||||
@ -71,6 +71,6 @@ contract test {
|
|||||||
// gas legacy: 31621
|
// gas legacy: 31621
|
||||||
// gas legacyOptimized: 27914
|
// gas legacyOptimized: 27914
|
||||||
// benchmark(string,bytes32): 0x40, 0x0842021, 8, "solidity" -> 0x2020
|
// benchmark(string,bytes32): 0x40, 0x0842021, 8, "solidity" -> 0x2020
|
||||||
// gas irOptimized: 2040045
|
// gas irOptimized: 2040061
|
||||||
// gas legacy: 4381235
|
// gas legacy: 4381235
|
||||||
// gas legacyOptimized: 2317529
|
// gas legacyOptimized: 2317529
|
||||||
|
@ -18,7 +18,7 @@ contract C {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// constructor(), 20 wei
|
// constructor(), 20 wei
|
||||||
// gas irOptimized: 219285
|
// gas irOptimized: 218415
|
||||||
// gas legacy: 294569
|
// gas legacy: 294569
|
||||||
// gas legacyOptimized: 174699
|
// gas legacyOptimized: 174699
|
||||||
// f(uint256): 20 -> 1370859564726510389319704988634906228201275401179
|
// f(uint256): 20 -> 1370859564726510389319704988634906228201275401179
|
||||||
|
@ -41,7 +41,7 @@ contract test {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// constructor(), 20 wei ->
|
// constructor(), 20 wei ->
|
||||||
// gas irOptimized: 283040
|
// gas irOptimized: 281960
|
||||||
// gas legacy: 402654
|
// gas legacy: 402654
|
||||||
// gas legacyOptimized: 274470
|
// gas legacyOptimized: 274470
|
||||||
// sendAmount(uint256): 5 -> 5
|
// sendAmount(uint256): 5 -> 5
|
||||||
|
@ -40,7 +40,7 @@ contract test {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// constructor(), 20 wei ->
|
// constructor(), 20 wei ->
|
||||||
// gas irOptimized: 283040
|
// gas irOptimized: 281960
|
||||||
// gas legacy: 402654
|
// gas legacy: 402654
|
||||||
// gas legacyOptimized: 274470
|
// gas legacyOptimized: 274470
|
||||||
// sendAmount(uint256): 5 -> 5
|
// sendAmount(uint256): 5 -> 5
|
||||||
|
@ -29,7 +29,7 @@ contract C {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f() -> 3, 7, 5
|
// f() -> 3, 7, 5
|
||||||
// gas irOptimized: 127347
|
// gas irOptimized: 127321
|
||||||
// gas legacy: 151334
|
// gas legacy: 151334
|
||||||
// gas legacyOptimized: 125166
|
// gas legacyOptimized: 125166
|
||||||
// x() -> 7
|
// x() -> 7
|
||||||
|
@ -25,6 +25,6 @@ contract B {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// g() -> 42
|
// g() -> 42
|
||||||
// gas irOptimized: 111794
|
// gas irOptimized: 112591
|
||||||
// gas legacy: 185053
|
// gas legacy: 185053
|
||||||
// gas legacyOptimized: 114598
|
// gas legacyOptimized: 114598
|
||||||
|
@ -42,7 +42,7 @@ contract Main {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// constructor(), 22 wei ->
|
// constructor(), 22 wei ->
|
||||||
// gas irOptimized: 284287
|
// gas irOptimized: 281653
|
||||||
// gas legacy: 402045
|
// gas legacy: 402045
|
||||||
// gas legacyOptimized: 266772
|
// gas legacyOptimized: 266772
|
||||||
// getFlag() -> true
|
// getFlag() -> true
|
||||||
|
@ -22,6 +22,6 @@ contract A {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f(), 10 ether -> 3007, 3008, 3009
|
// f(), 10 ether -> 3007, 3008, 3009
|
||||||
// gas irOptimized: 272413
|
// gas irOptimized: 273010
|
||||||
// gas legacy: 422501
|
// gas legacy: 422501
|
||||||
// gas legacyOptimized: 287472
|
// gas legacyOptimized: 287472
|
||||||
|
@ -14,7 +14,7 @@ contract C {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// constructor()
|
// constructor()
|
||||||
// gas irOptimized: 115297
|
// gas irOptimized: 114001
|
||||||
// gas legacy: 155081
|
// gas legacy: 155081
|
||||||
// gas legacyOptimized: 107997
|
// gas legacyOptimized: 107997
|
||||||
// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737
|
// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737
|
||||||
|
@ -17,7 +17,7 @@ contract C {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// constructor() ->
|
// constructor() ->
|
||||||
// gas irOptimized: 199723
|
// gas irOptimized: 199084
|
||||||
// gas legacy: 241124
|
// gas legacy: 241124
|
||||||
// gas legacyOptimized: 155549
|
// gas legacyOptimized: 155549
|
||||||
// initCode() -> 0x20, 0
|
// initCode() -> 0x20, 0
|
||||||
|
@ -36,6 +36,6 @@ contract C {
|
|||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f(bytes): 0x20, 0x5, "abcde" -> 0
|
// f(bytes): 0x20, 0x5, "abcde" -> 0
|
||||||
// gas irOptimized: 240691
|
// gas irOptimized: 240688
|
||||||
// gas legacy: 240358
|
// gas legacy: 240358
|
||||||
// gas legacyOptimized: 239682
|
// gas legacyOptimized: 239682
|
||||||
|
@ -23,6 +23,6 @@
|
|||||||
// mstore(_1, sload(0))
|
// mstore(_1, sload(0))
|
||||||
// return(_1, 32)
|
// return(_1, 32)
|
||||||
// }
|
// }
|
||||||
// case 0xc2985578 { return(mload(64), 0) }
|
// case 0xc2985578 { return(_1, 0) }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
Loading…
Reference in New Issue
Block a user