mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #11107 from ethereum/extendedLowlevelInliner
Inline ordinary jumps to small blocks and jumps to terminating control flow.
This commit is contained in:
commit
6eac77aea2
@ -4,6 +4,7 @@ Language Features:
|
|||||||
* Possibility to use ``bytes.concat`` with variable number of ``bytes`` and ``bytesNN`` arguments which behaves as a restricted version of `abi.encodePacked` with a more descriptive name.
|
* Possibility to use ``bytes.concat`` with variable number of ``bytes`` and ``bytesNN`` arguments which behaves as a restricted version of `abi.encodePacked` with a more descriptive name.
|
||||||
|
|
||||||
Compiler Features:
|
Compiler Features:
|
||||||
|
* Low-Level Inliner: Inline ordinary jumps to small blocks and jumps to small blocks that terminate.
|
||||||
|
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
@ -82,9 +82,7 @@ bool Inliner::isInlineCandidate(size_t _tag, ranges::span<AssemblyItem const> _i
|
|||||||
{
|
{
|
||||||
assertThrow(_items.size() > 0, OptimizerException, "");
|
assertThrow(_items.size() > 0, OptimizerException, "");
|
||||||
|
|
||||||
// Only consider blocks that end in a JUMP for now. This can e.g. be extended to include transaction terminating
|
if (_items.back() != Instruction::JUMP && !SemanticInformation::terminatesControlFlow(_items.back()))
|
||||||
// instructions as well in the future.
|
|
||||||
if (_items.back() != Instruction::JUMP)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Never inline tags that reference themselves.
|
// Never inline tags that reference themselves.
|
||||||
@ -196,19 +194,38 @@ bool Inliner::shouldInlineFullFunctionBody(size_t _tag, ranges::span<AssemblyIte
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
optional<AssemblyItem> Inliner::shouldInline(size_t _tag, AssemblyItem const& _jump, InlinableBlock const& _block) const
|
||||||
optional<AssemblyItem::JumpType> Inliner::shouldInline(size_t _tag, AssemblyItem const& _jump, InlinableBlock const& _block) const
|
|
||||||
{
|
{
|
||||||
AssemblyItem exitJump = _block.items.back();
|
assertThrow(_jump == Instruction::JUMP, OptimizerException, "");
|
||||||
assertThrow(_jump == Instruction::JUMP && exitJump == Instruction::JUMP, OptimizerException, "");
|
AssemblyItem blockExit = _block.items.back();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
_jump.getJumpType() == AssemblyItem::JumpType::IntoFunction &&
|
_jump.getJumpType() == AssemblyItem::JumpType::IntoFunction &&
|
||||||
exitJump.getJumpType() == AssemblyItem::JumpType::OutOfFunction
|
blockExit == Instruction::JUMP &&
|
||||||
|
blockExit.getJumpType() == AssemblyItem::JumpType::OutOfFunction &&
|
||||||
|
shouldInlineFullFunctionBody(_tag, _block.items, _block.pushTagCount)
|
||||||
)
|
)
|
||||||
return
|
{
|
||||||
shouldInlineFullFunctionBody(_tag, _block.items, _block.pushTagCount) ?
|
blockExit.setJumpType(AssemblyItem::JumpType::Ordinary);
|
||||||
make_optional(AssemblyItem::JumpType::Ordinary) : nullopt;
|
return blockExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inline small blocks, if the jump to it is ordinary or the blockExit is a terminating instruction.
|
||||||
|
if (
|
||||||
|
_jump.getJumpType() == AssemblyItem::JumpType::Ordinary ||
|
||||||
|
SemanticInformation::terminatesControlFlow(blockExit)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
static AssemblyItems const jumpPattern = {
|
||||||
|
AssemblyItem{PushTag},
|
||||||
|
AssemblyItem{Instruction::JUMP},
|
||||||
|
};
|
||||||
|
if (
|
||||||
|
GasMeter::dataGas(codeSize(_block.items), m_isCreation, m_evmVersion) <=
|
||||||
|
GasMeter::dataGas(codeSize(jumpPattern), m_isCreation, m_evmVersion)
|
||||||
|
)
|
||||||
|
return blockExit;
|
||||||
|
}
|
||||||
|
|
||||||
return nullopt;
|
return nullopt;
|
||||||
}
|
}
|
||||||
@ -232,10 +249,10 @@ void Inliner::optimise()
|
|||||||
{
|
{
|
||||||
if (optional<size_t> tag = getLocalTag(item))
|
if (optional<size_t> tag = getLocalTag(item))
|
||||||
if (auto* inlinableBlock = util::valueOrNullptr(inlinableBlocks, *tag))
|
if (auto* inlinableBlock = util::valueOrNullptr(inlinableBlocks, *tag))
|
||||||
if (auto exitJumpType = shouldInline(*tag, nextItem, *inlinableBlock))
|
if (auto exitItem = shouldInline(*tag, nextItem, *inlinableBlock))
|
||||||
{
|
{
|
||||||
newItems += inlinableBlock->items;
|
newItems += inlinableBlock->items | ranges::views::drop_last(1);
|
||||||
newItems.back().setJumpType(*exitJumpType);
|
newItems.emplace_back(move(*exitItem));
|
||||||
|
|
||||||
// We are removing one push tag to the block we inline.
|
// We are removing one push tag to the block we inline.
|
||||||
--inlinableBlock->pushTagCount;
|
--inlinableBlock->pushTagCount;
|
||||||
|
@ -61,8 +61,8 @@ private:
|
|||||||
uint64_t pushTagCount = 0;
|
uint64_t pushTagCount = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @returns the exit jump type for the block to be inlined, if a particular jump to it should be inlined, otherwise nullopt.
|
/// @returns the exit item for the block to be inlined, if a particular jump to it should be inlined, otherwise nullopt.
|
||||||
std::optional<AssemblyItem::JumpType> shouldInline(size_t _tag, AssemblyItem const& _jump, InlinableBlock const& _block) const;
|
std::optional<AssemblyItem> shouldInline(size_t _tag, AssemblyItem const& _jump, InlinableBlock const& _block) const;
|
||||||
/// @returns true, if the full function at tag @a _tag with body @a _block that is referenced @a _pushTagCount times
|
/// @returns true, if the full function at tag @a _tag with body @a _block that is referenced @a _pushTagCount times
|
||||||
/// should be inlined, false otherwise. @a _block should start at the first instruction after the function entry tag
|
/// should be inlined, false otherwise. @a _block should start at the first instruction after the function entry tag
|
||||||
/// up to and including the return jump.
|
/// up to and including the return jump.
|
||||||
|
@ -10,7 +10,7 @@ EVM assembly:
|
|||||||
not(sub(shl(0x40, 0x01), 0x01))
|
not(sub(shl(0x40, 0x01), 0x01))
|
||||||
and
|
and
|
||||||
/* "optimizer_BlockDeDuplicator/input.sol":201:206 fun_x */
|
/* "optimizer_BlockDeDuplicator/input.sol":201:206 fun_x */
|
||||||
or(tag_0_7, shl(0x20, tag_4))
|
or(tag_0_7, shl(0x20, tag_2))
|
||||||
sub(shl(0x40, 0x01), 0x01)
|
sub(shl(0x40, 0x01), 0x01)
|
||||||
/* "optimizer_BlockDeDuplicator/input.sol":179:210 function() r = true ? fun_x : f */
|
/* "optimizer_BlockDeDuplicator/input.sol":179:210 function() r = true ? fun_x : f */
|
||||||
and
|
and
|
||||||
@ -29,8 +29,8 @@ EVM assembly:
|
|||||||
tag_5:
|
tag_5:
|
||||||
pop
|
pop
|
||||||
jump(tag_6)
|
jump(tag_6)
|
||||||
/* "optimizer_BlockDeDuplicator/input.sol":77:103 function fun_x() public {} */
|
/* "optimizer_BlockDeDuplicator/input.sol":138:174 function f() public { true ? 1 : 3;} */
|
||||||
tag_4:
|
tag_2:
|
||||||
jump // out
|
jump // out
|
||||||
/* "optimizer_BlockDeDuplicator/input.sol":60:213 contract C {... */
|
/* "optimizer_BlockDeDuplicator/input.sol":60:213 contract C {... */
|
||||||
tag_6:
|
tag_6:
|
||||||
@ -66,12 +66,12 @@ sub_0: assembly {
|
|||||||
dup1
|
dup1
|
||||||
0x2e1fb2bc
|
0x2e1fb2bc
|
||||||
eq
|
eq
|
||||||
tag_4
|
tag_3
|
||||||
jumpi
|
jumpi
|
||||||
dup1
|
dup1
|
||||||
0x4753a67d
|
0x4753a67d
|
||||||
eq
|
eq
|
||||||
tag_4
|
tag_3
|
||||||
jumpi
|
jumpi
|
||||||
tag_2:
|
tag_2:
|
||||||
0x00
|
0x00
|
||||||
@ -80,10 +80,6 @@ sub_0: assembly {
|
|||||||
/* "optimizer_BlockDeDuplicator/input.sol":138:174 function f() public { true ? 1 : 3;} */
|
/* "optimizer_BlockDeDuplicator/input.sol":138:174 function f() public { true ? 1 : 3;} */
|
||||||
tag_3:
|
tag_3:
|
||||||
stop
|
stop
|
||||||
/* "optimizer_BlockDeDuplicator/input.sol":108:133 function fun_() public {} */
|
|
||||||
tag_4:
|
|
||||||
jump(tag_3)
|
|
||||||
/* "optimizer_BlockDeDuplicator/input.sol":138:174 function f() public { true ? 1 : 3;} */
|
|
||||||
tag_7:
|
tag_7:
|
||||||
jump // out
|
jump // out
|
||||||
|
|
||||||
|
@ -58,9 +58,9 @@ sub_0: assembly {
|
|||||||
revert
|
revert
|
||||||
/* "optimizer_inliner_dynamic_reference/input.sol":160:215 function a() public pure returns (uint) { return f(); } */
|
/* "optimizer_inliner_dynamic_reference/input.sol":160:215 function a() public pure returns (uint) { return f(); } */
|
||||||
tag_3:
|
tag_3:
|
||||||
tag_6
|
/* "optimizer_inliner_dynamic_reference/input.sol":361:362 6 */
|
||||||
tag_7
|
0x06
|
||||||
jump // in
|
/* "optimizer_inliner_dynamic_reference/input.sol":160:215 function a() public pure returns (uint) { return f(); } */
|
||||||
tag_6:
|
tag_6:
|
||||||
mload(0x40)
|
mload(0x40)
|
||||||
/* "#utility.yul":160:185 */
|
/* "#utility.yul":160:185 */
|
||||||
@ -100,12 +100,6 @@ sub_0: assembly {
|
|||||||
sstore
|
sstore
|
||||||
/* "optimizer_inliner_dynamic_reference/input.sol":125:155 function g() public { x = f; } */
|
/* "optimizer_inliner_dynamic_reference/input.sol":125:155 function g() public { x = f; } */
|
||||||
stop
|
stop
|
||||||
/* "optimizer_inliner_dynamic_reference/input.sol":160:215 function a() public pure returns (uint) { return f(); } */
|
|
||||||
tag_7:
|
|
||||||
/* "optimizer_inliner_dynamic_reference/input.sol":194:198 uint */
|
|
||||||
0x00
|
|
||||||
/* "optimizer_inliner_dynamic_reference/input.sol":361:362 6 */
|
|
||||||
0x06
|
|
||||||
/* "optimizer_inliner_dynamic_reference/input.sol":209:212 f() */
|
/* "optimizer_inliner_dynamic_reference/input.sol":209:212 f() */
|
||||||
tag_16:
|
tag_16:
|
||||||
/* "optimizer_inliner_dynamic_reference/input.sol":202:212 return f() */
|
/* "optimizer_inliner_dynamic_reference/input.sol":202:212 return f() */
|
||||||
@ -147,8 +141,8 @@ sub_0: assembly {
|
|||||||
tag_17:
|
tag_17:
|
||||||
/* "optimizer_inliner_dynamic_reference/input.sol":361:362 6 */
|
/* "optimizer_inliner_dynamic_reference/input.sol":361:362 6 */
|
||||||
0x06
|
0x06
|
||||||
/* "optimizer_inliner_dynamic_reference/input.sol":310:365 function f() internal pure returns (uint) { return 6; } */
|
|
||||||
swap1
|
swap1
|
||||||
|
/* "optimizer_inliner_dynamic_reference/input.sol":310:365 function f() internal pure returns (uint) { return 6; } */
|
||||||
jump // out
|
jump // out
|
||||||
tag_20:
|
tag_20:
|
||||||
mstore(0x00, shl(0xe0, 0x4e487b71))
|
mstore(0x00, shl(0xe0, 0x4e487b71))
|
||||||
|
@ -35,8 +35,8 @@ tag_1:
|
|||||||
tag_4:
|
tag_4:
|
||||||
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":355:356 6 */
|
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":355:356 6 */
|
||||||
0x06
|
0x06
|
||||||
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":304:359 function f() internal pure returns (uint) { return 6; } */
|
|
||||||
swap1
|
swap1
|
||||||
|
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":304:359 function f() internal pure returns (uint) { return 6; } */
|
||||||
jump // out
|
jump // out
|
||||||
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":60:361 contract C {... */
|
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":60:361 contract C {... */
|
||||||
tag_5:
|
tag_5:
|
||||||
@ -80,9 +80,9 @@ sub_0: assembly {
|
|||||||
revert
|
revert
|
||||||
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":154:209 function a() public pure returns (uint) { return f(); } */
|
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":154:209 function a() public pure returns (uint) { return f(); } */
|
||||||
tag_3:
|
tag_3:
|
||||||
tag_5
|
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":355:356 6 */
|
||||||
tag_6
|
0x06
|
||||||
jump // in
|
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":154:209 function a() public pure returns (uint) { return f(); } */
|
||||||
tag_5:
|
tag_5:
|
||||||
mload(0x40)
|
mload(0x40)
|
||||||
/* "#utility.yul":160:185 */
|
/* "#utility.yul":160:185 */
|
||||||
@ -105,12 +105,6 @@ sub_0: assembly {
|
|||||||
tag_5
|
tag_5
|
||||||
tag_10
|
tag_10
|
||||||
jump // in
|
jump // in
|
||||||
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":154:209 function a() public pure returns (uint) { return f(); } */
|
|
||||||
tag_6:
|
|
||||||
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":188:192 uint */
|
|
||||||
0x00
|
|
||||||
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":355:356 6 */
|
|
||||||
0x06
|
|
||||||
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":203:206 f() */
|
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":203:206 f() */
|
||||||
tag_14:
|
tag_14:
|
||||||
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":196:206 return f() */
|
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":196:206 return f() */
|
||||||
@ -152,8 +146,8 @@ sub_0: assembly {
|
|||||||
tag_12:
|
tag_12:
|
||||||
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":355:356 6 */
|
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":355:356 6 */
|
||||||
0x06
|
0x06
|
||||||
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":304:359 function f() internal pure returns (uint) { return 6; } */
|
|
||||||
swap1
|
swap1
|
||||||
|
/* "optimizer_inliner_dynamic_reference_constructor/input.sol":304:359 function f() internal pure returns (uint) { return 6; } */
|
||||||
jump // out
|
jump // out
|
||||||
tag_17:
|
tag_17:
|
||||||
mstore(0x00, shl(0xe0, 0x4e487b71))
|
mstore(0x00, shl(0xe0, 0x4e487b71))
|
||||||
|
@ -1637,6 +1637,113 @@ BOOST_AUTO_TEST_CASE(inliner_cse_break)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(inliner_stop)
|
||||||
|
{
|
||||||
|
AssemblyItems items{
|
||||||
|
AssemblyItem(PushTag, 1),
|
||||||
|
Instruction::JUMP,
|
||||||
|
AssemblyItem(Tag, 1),
|
||||||
|
Instruction::STOP
|
||||||
|
};
|
||||||
|
AssemblyItems expectation{
|
||||||
|
Instruction::STOP,
|
||||||
|
AssemblyItem(Tag, 1),
|
||||||
|
Instruction::STOP
|
||||||
|
};
|
||||||
|
Inliner{items, {}, 200, false, {}}.optimise();
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||||
|
items.begin(), items.end(),
|
||||||
|
expectation.begin(), expectation.end()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(inliner_stop_jumpi)
|
||||||
|
{
|
||||||
|
// Because of `jumpi`, will not be inlined.
|
||||||
|
AssemblyItems items{
|
||||||
|
u256(1),
|
||||||
|
AssemblyItem(PushTag, 1),
|
||||||
|
Instruction::JUMPI,
|
||||||
|
AssemblyItem(Tag, 1),
|
||||||
|
Instruction::STOP
|
||||||
|
};
|
||||||
|
AssemblyItems expectation = items;
|
||||||
|
Inliner{items, {}, 200, false, {}}.optimise();
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||||
|
items.begin(), items.end(),
|
||||||
|
expectation.begin(), expectation.end()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(inliner_revert)
|
||||||
|
{
|
||||||
|
AssemblyItems items{
|
||||||
|
AssemblyItem(PushTag, 1),
|
||||||
|
Instruction::JUMP,
|
||||||
|
AssemblyItem(Tag, 1),
|
||||||
|
u256(0),
|
||||||
|
Instruction::DUP1,
|
||||||
|
Instruction::REVERT
|
||||||
|
};
|
||||||
|
AssemblyItems expectation{
|
||||||
|
u256(0),
|
||||||
|
Instruction::DUP1,
|
||||||
|
Instruction::REVERT,
|
||||||
|
AssemblyItem(Tag, 1),
|
||||||
|
u256(0),
|
||||||
|
Instruction::DUP1,
|
||||||
|
Instruction::REVERT
|
||||||
|
};
|
||||||
|
|
||||||
|
Inliner{items, {}, 200, false, {}}.optimise();
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||||
|
items.begin(), items.end(),
|
||||||
|
expectation.begin(), expectation.end()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(inliner_revert_increased_datagas)
|
||||||
|
{
|
||||||
|
// Inlining this would increase data gas (5 bytes v/s 4 bytes), therefore, skipped.
|
||||||
|
AssemblyItems items{
|
||||||
|
AssemblyItem(PushTag, 1),
|
||||||
|
Instruction::JUMP,
|
||||||
|
AssemblyItem(Tag, 1),
|
||||||
|
u256(0),
|
||||||
|
u256(0),
|
||||||
|
Instruction::REVERT
|
||||||
|
};
|
||||||
|
|
||||||
|
AssemblyItems expectation = items;
|
||||||
|
Inliner{items, {}, 200, false, {}}.optimise();
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||||
|
items.begin(), items.end(),
|
||||||
|
expectation.begin(), expectation.end()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(inliner_invalid)
|
||||||
|
{
|
||||||
|
AssemblyItems items{
|
||||||
|
AssemblyItem(PushTag, 1),
|
||||||
|
Instruction::JUMP,
|
||||||
|
AssemblyItem(Tag, 1),
|
||||||
|
Instruction::INVALID
|
||||||
|
};
|
||||||
|
|
||||||
|
AssemblyItems expectation = {
|
||||||
|
Instruction::INVALID,
|
||||||
|
AssemblyItem(Tag, 1),
|
||||||
|
Instruction::INVALID
|
||||||
|
};
|
||||||
|
Inliner{items, {}, 200, false, {}}.optimise();
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||||
|
items.begin(), items.end(),
|
||||||
|
expectation.begin(), expectation.end()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
} // end namespaces
|
} // end namespaces
|
||||||
|
@ -210,7 +210,7 @@ BOOST_AUTO_TEST_CASE(jump_type)
|
|||||||
jumpTypes += item.getJumpTypeAsString() + "\n";
|
jumpTypes += item.getJumpTypeAsString() + "\n";
|
||||||
|
|
||||||
if (solidity::test::CommonOptions::get().optimize)
|
if (solidity::test::CommonOptions::get().optimize)
|
||||||
BOOST_CHECK_EQUAL(jumpTypes, "[in]\n[out]\n[in]\n[out]\n");
|
BOOST_CHECK_EQUAL(jumpTypes, "[in]\n[out]\n[out]\n[in]\n[out]\n");
|
||||||
else
|
else
|
||||||
BOOST_CHECK_EQUAL(jumpTypes, "[in]\n[out]\n[in]\n[out]\n");
|
BOOST_CHECK_EQUAL(jumpTypes, "[in]\n[out]\n[in]\n[out]\n");
|
||||||
}
|
}
|
||||||
|
@ -21,4 +21,4 @@ contract c {
|
|||||||
// test() -> 0
|
// test() -> 0
|
||||||
// gas irOptimized: 312322
|
// gas irOptimized: 312322
|
||||||
// gas legacy: 483915
|
// gas legacy: 483915
|
||||||
// gas legacyOptimized: 478673
|
// gas legacyOptimized: 478672
|
||||||
|
@ -14,7 +14,7 @@ contract Test {
|
|||||||
// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18
|
// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18
|
||||||
// gas irOptimized: 121109
|
// gas irOptimized: 121109
|
||||||
// gas legacy: 125815
|
// gas legacy: 125815
|
||||||
// gas legacyOptimized: 123615
|
// gas legacyOptimized: 123614
|
||||||
// data(uint256): 7 -> 8
|
// data(uint256): 7 -> 8
|
||||||
// data(uint256): 15 -> 16
|
// data(uint256): 15 -> 16
|
||||||
// data(uint256): 18 -> FAILURE
|
// data(uint256): 18 -> FAILURE
|
||||||
|
@ -50,4 +50,4 @@ contract C {
|
|||||||
// f() -> 0xff
|
// f() -> 0xff
|
||||||
// gas irOptimized: 137415
|
// gas irOptimized: 137415
|
||||||
// gas legacy: 137645
|
// gas legacy: 137645
|
||||||
// gas legacyOptimized: 134377
|
// gas legacyOptimized: 134376
|
||||||
|
@ -19,4 +19,4 @@ contract c {
|
|||||||
// test() -> 0
|
// test() -> 0
|
||||||
// gas irOptimized: 397892
|
// gas irOptimized: 397892
|
||||||
// gas legacy: 565428
|
// gas legacy: 565428
|
||||||
// gas legacyOptimized: 552525
|
// gas legacyOptimized: 552524
|
||||||
|
@ -28,4 +28,4 @@ contract Creator {
|
|||||||
// 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: 472714
|
// gas irOptimized: 472714
|
||||||
// gas legacy: 570900
|
// gas legacy: 570900
|
||||||
// gas legacyOptimized: 436360
|
// gas legacyOptimized: 435524
|
||||||
|
@ -298,4 +298,4 @@ contract Test {
|
|||||||
// verifyTx() -> true
|
// verifyTx() -> true
|
||||||
// gas irOptimized: 145824
|
// gas irOptimized: 145824
|
||||||
// gas legacy: 130571
|
// gas legacy: 130571
|
||||||
// gas legacyOptimized: 100187
|
// gas legacyOptimized: 100147
|
||||||
|
@ -24,4 +24,4 @@ contract A {
|
|||||||
// same_salt() -> true
|
// same_salt() -> true
|
||||||
// gas irOptimized: 98439083
|
// gas irOptimized: 98439083
|
||||||
// gas legacy: 98439116
|
// gas legacy: 98439116
|
||||||
// gas legacyOptimized: 98438982
|
// gas legacyOptimized: 98438970
|
||||||
|
@ -38,4 +38,4 @@ contract C {
|
|||||||
// f(bytes): 0x20, 0x5, "abcde" -> 0
|
// f(bytes): 0x20, 0x5, "abcde" -> 0
|
||||||
// gas irOptimized: 248997
|
// gas irOptimized: 248997
|
||||||
// gas legacy: 239258
|
// gas legacy: 239258
|
||||||
// gas legacyOptimized: 238578
|
// gas legacyOptimized: 238577
|
||||||
|
@ -30,7 +30,7 @@ contract C {
|
|||||||
// index(uint256): 0xFF -> true
|
// index(uint256): 0xFF -> true
|
||||||
// gas irOptimized: 167533
|
// gas irOptimized: 167533
|
||||||
// gas legacy: 248854
|
// gas legacy: 248854
|
||||||
// gas legacyOptimized: 152640
|
// gas legacyOptimized: 152638
|
||||||
// accessIndex(uint256,int256): 10, 1 -> 2
|
// accessIndex(uint256,int256): 10, 1 -> 2
|
||||||
// accessIndex(uint256,int256): 10, 0 -> 1
|
// accessIndex(uint256,int256): 10, 0 -> 1
|
||||||
// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex"4e487b71", 0x32
|
// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex"4e487b71", 0x32
|
||||||
|
Loading…
Reference in New Issue
Block a user