Skip to content

Commit 921c4fd

Browse files
authored
Merge pull request #12754 from ethereum/optimizerEqIszero
Some more peephole optimizer rules.
2 parents 2b201f2 + b3fe042 commit 921c4fd

File tree

101 files changed

+312
-253
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+312
-253
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Language Features:
66

77
Compiler Features:
88
* JSON-AST: Added selector field for errors and events.
9+
* Peephole Optimizer: Optimize comparisons in front of conditional jumps and conditional jumps across a single unconditional jump.
910

1011
Bugfixes:
1112
* Yul IR Code Generation: Optimize embedded creation code with correct settings. This fixes potential mismatches between the constructor code of a contract compiled in isolation and the bytecode in ``type(C).creationCode``, resp. the bytecode used for ``new C(...)``.

libevmasm/PeepholeOptimiser.cpp

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,65 @@ struct IsZeroIsZeroJumpI: SimplePeepholeOptimizerMethod<IsZeroIsZeroJumpI>
233233
}
234234
};
235235

236+
struct EqIsZeroJumpI: SimplePeepholeOptimizerMethod<EqIsZeroJumpI>
237+
{
238+
static size_t applySimple(
239+
AssemblyItem const& _eq,
240+
AssemblyItem const& _iszero,
241+
AssemblyItem const& _pushTag,
242+
AssemblyItem const& _jumpi,
243+
std::back_insert_iterator<AssemblyItems> _out
244+
)
245+
{
246+
if (
247+
_eq == Instruction::EQ &&
248+
_iszero == Instruction::ISZERO &&
249+
_pushTag.type() == PushTag &&
250+
_jumpi == Instruction::JUMPI
251+
)
252+
{
253+
*_out = AssemblyItem(Instruction::SUB, _eq.location());
254+
*_out = _pushTag;
255+
*_out = _jumpi;
256+
return true;
257+
}
258+
else
259+
return false;
260+
}
261+
};
262+
263+
// push_tag_1 jumpi push_tag_2 jump tag_1: -> iszero push_tag_2 jumpi tag_1:
264+
struct DoubleJump: SimplePeepholeOptimizerMethod<DoubleJump>
265+
{
266+
static size_t applySimple(
267+
AssemblyItem const& _pushTag1,
268+
AssemblyItem const& _jumpi,
269+
AssemblyItem const& _pushTag2,
270+
AssemblyItem const& _jump,
271+
AssemblyItem const& _tag1,
272+
std::back_insert_iterator<AssemblyItems> _out
273+
)
274+
{
275+
if (
276+
_pushTag1.type() == PushTag &&
277+
_jumpi == Instruction::JUMPI &&
278+
_pushTag2.type() == PushTag &&
279+
_jump == Instruction::JUMP &&
280+
_tag1.type() == Tag &&
281+
_pushTag1.data() == _tag1.data()
282+
)
283+
{
284+
*_out = AssemblyItem(Instruction::ISZERO, _jumpi.location());
285+
*_out = _pushTag2;
286+
*_out = _jumpi;
287+
*_out = _tag1;
288+
return true;
289+
}
290+
else
291+
return false;
292+
}
293+
};
294+
236295
struct JumpToNext: SimplePeepholeOptimizerMethod<JumpToNext>
237296
{
238297
static size_t applySimple(
@@ -372,7 +431,7 @@ bool PeepholeOptimiser::optimise()
372431
applyMethods(
373432
state,
374433
PushPop(), OpPop(), DoublePush(), DoubleSwap(), CommutativeSwap(), SwapComparison(),
375-
DupSwap(), IsZeroIsZeroJumpI(), JumpToNext(), UnreachableCode(),
434+
DupSwap(), IsZeroIsZeroJumpI(), EqIsZeroJumpI(), DoubleJump(), JumpToNext(), UnreachableCode(),
376435
TagConjunctions(), TruthyAnd(), Identity()
377436
);
378437
if (m_optimisedItems.size() < m_items.size() || (

test/cmdlineTests/optimizer_user_yul/output

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,9 @@ tag_6:
5858
/* "optimizer_user_yul/input.sol":384:392 sload(5) */
5959
dup1
6060
/* "optimizer_user_yul/input.sol":376:509 for { } sload(5) { } {... */
61-
tag_8
61+
iszero
62+
tag_6
6263
jumpi
63-
jump(tag_6)
64-
tag_8:
6564
/* "optimizer_user_yul/input.sol":380:383 { } */
6665
pop
6766
/* "optimizer_user_yul/input.sol":340:513 {... */

test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ contract C {
2525
// ----
2626
// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb
2727
// gas irOptimized: 203312
28-
// gas legacy: 206084
29-
// gas legacyOptimized: 203068
28+
// gas legacy: 206075
29+
// gas legacyOptimized: 203059

test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ contract C {
6161
// ----
6262
// test_bytes() ->
6363
// gas irOptimized: 371919
64-
// gas legacy: 418955
65-
// gas legacyOptimized: 326783
64+
// gas legacy: 416585
65+
// gas legacyOptimized: 322043
6666
// test_uint256() ->
6767
// gas irOptimized: 523001
68-
// gas legacy: 586784
69-
// gas legacyOptimized: 451529
68+
// gas legacy: 583100
69+
// gas legacyOptimized: 444161

test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ contract C {
6262
// ----
6363
// test_bytes() ->
6464
// gas irOptimized: 371919
65-
// gas legacy: 418955
66-
// gas legacyOptimized: 326783
65+
// gas legacy: 416585
66+
// gas legacyOptimized: 322043
6767
// test_uint256() ->
6868
// gas irOptimized: 523001
69-
// gas legacy: 586784
70-
// gas legacyOptimized: 451529
69+
// gas legacy: 583100
70+
// gas legacyOptimized: 444161

test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ contract C {
2222
// f(uint256[][1]): 32, 32, 1, 42 -> true
2323
// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true
2424
// gas irOptimized: 171842
25-
// gas legacy: 141644
26-
// gas legacyOptimized: 121532
25+
// gas legacy: 140672
26+
// gas legacyOptimized: 119588

test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ contract C {
1212
// ----
1313
// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg"
1414
// gas irOptimized: 135918
15-
// gas legacy: 137190
16-
// gas legacyOptimized: 136082
15+
// gas legacy: 137181
16+
// gas legacyOptimized: 136073

test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ contract Test {
1414
// compileViaYul: also
1515
// ----
1616
// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06
17-
// gas irOptimized: 189871
17+
// gas irOptimized: 189817
1818
// gas legacy: 211149
1919
// gas legacyOptimized: 206054
2020
// data(uint256,uint256): 0x02, 0x02 -> 0x09

test/libsolidity/semanticTests/array/byte_array_storage_layout.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ contract c {
4848
// storageEmpty -> 0
4949
// test_long() -> 67
5050
// gas irOptimized: 89148
51-
// gas legacy: 103590
52-
// gas legacyOptimized: 101044
51+
// gas legacy: 103039
52+
// gas legacyOptimized: 100493
5353
// storageEmpty -> 0
5454
// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020
5555
// gas legacy: 61930

0 commit comments

Comments
 (0)