Skip to content

Commit

Permalink
Fix a bug preventing repeated parts of optimizer sequence from ever s…
Browse files Browse the repository at this point in the history
…topping after the first cycle
  • Loading branch information
cameel committed Mar 5, 2024
1 parent edc494d commit 5ea8fa2
Show file tree
Hide file tree
Showing 23 changed files with 87 additions and 49 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Expand Up @@ -10,6 +10,7 @@ Compiler Features:
Bugfixes:
* Assembler: Prevent incorrect calculation of tag sizes.
* EVM Assembly Import: Fix handling of missing source locations during import.
* Optimizer: Fix optimizer executing each repeating part of the step sequence at least twice, even if the code size already became stable after the first iteration.
* SMTChecker: Fix internal error caused by not respecting the sign of an integer type when constructing zero-value SMT expressions.
* SMTChecker: Ensure query is properly flushed to a file before calling solver when using SMT-LIB interface.

Expand Down
2 changes: 1 addition & 1 deletion libyul/optimiser/Suite.cpp
Expand Up @@ -472,7 +472,7 @@ void OptimiserSuite::runSequence(std::string_view _stepAbbreviations, Block& _as
subsequences.push_back({subsequence, true});
}

size_t codeSize = 0;
size_t codeSize = (_repeatUntilStable ? CodeSize::codeSizeIncludingFunctions(_ast) : 0);
for (size_t round = 0; round < MaxRounds; ++round)
{
for (auto const& [subsequence, repeat]: subsequences)
Expand Down
13 changes: 11 additions & 2 deletions test/cmdlineTests/optimizer_user_yul/output
Expand Up @@ -42,6 +42,7 @@ tag_5:
/* "optimizer_user_yul/input.sol":263:269 a := 2 */
swap1
pop
0x00
/* "optimizer_user_yul/input.sol":369:370 3 */
0x03
/* "optimizer_user_yul/input.sol":366:367 2 */
Expand All @@ -58,10 +59,18 @@ tag_6:
/* "optimizer_user_yul/input.sol":384:392 sload(5) */
dup1
/* "optimizer_user_yul/input.sol":376:509 for { } sload(5) { } {... */
iszero
tag_6
tag_8
jumpi
/* "optimizer_user_yul/input.sol":495:504 exp(x, y) */
0x01
/* "optimizer_user_yul/input.sol":490:504 z := exp(x, y) */
swap2
pop
/* "optimizer_user_yul/input.sol":376:509 for { } sload(5) { } {... */
jump(tag_6)
tag_8:
/* "optimizer_user_yul/input.sol":380:383 { } */
pop
pop
/* "optimizer_user_yul/input.sol":340:513 {... */
pop
Expand Down
Expand Up @@ -52,7 +52,7 @@ contract C {
}
// ----
// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14
// gas irOptimized: 150004
// gas irOptimized: 150022
// gas legacy: 150745
// gas legacyOptimized: 148678
// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14
Expand Down
Expand Up @@ -37,7 +37,7 @@ contract C {
}
// ----
// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14
// gas irOptimized: 147871
// gas irOptimized: 147889
// gas legacy: 148896
// gas legacyOptimized: 146901
// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14
Expand Down
Expand Up @@ -14,4 +14,4 @@ contract C {
// compileViaYul: true
// ----
// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14
// gas irOptimized: 139683
// gas irOptimized: 139637
Expand Up @@ -31,8 +31,8 @@ contract C {
// compileViaYul: true
// ----
// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29
// gas irOptimized: 327874
// gas irOptimized: 327883
// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13
// gas irOptimized: 140879
// gas irOptimized: 140882
// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13
// gas irOptimized: 188535
// gas irOptimized: 188541
Expand Up @@ -31,8 +31,8 @@ contract C {
// compileViaYul: true
// ----
// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29
// gas irOptimized: 332660
// gas irOptimized: 332687
// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13
// gas irOptimized: 145150
// gas irOptimized: 145159
// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13
// gas irOptimized: 192598
// gas irOptimized: 192616
Expand Up @@ -29,8 +29,8 @@ contract C {
// compileViaYul: true
// ----
// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29
// gas irOptimized: 304747
// gas irOptimized: 304756
// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13
// gas irOptimized: 116464
// gas irOptimized: 116467
// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13
// gas irOptimized: 188024
// gas irOptimized: 188030
Expand Up @@ -29,8 +29,8 @@ contract C {
// compileViaYul: true
// ----
// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29
// gas irOptimized: 309074
// gas irOptimized: 309101
// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13
// gas irOptimized: 118256
// gas irOptimized: 118265
// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13
// gas irOptimized: 190993
// gas irOptimized: 191011
Expand Up @@ -13,6 +13,6 @@ contract C {
}
// ----
// f() -> 2, 3, 4
// gas irOptimized: 109108
// gas irOptimized: 109104
// gas legacy: 122235
// gas legacyOptimized: 118411
Expand Up @@ -176,8 +176,8 @@ contract DepositContract is IDepositContract, ERC165 {
}
// ----
// constructor()
// gas irOptimized: 815686
// gas irOptimized code: 571200
// gas irOptimized: 815994
// gas irOptimized code: 575800
// gas legacy: 925933
// gas legacy code: 1442800
// gas legacyOptimized: 854404
Expand All @@ -187,27 +187,27 @@ contract DepositContract is IDepositContract, ERC165 {
// supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id #
// supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id #
// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e
// gas irOptimized: 115231
// gas irOptimized: 114983
// gas legacy: 148205
// gas legacyOptimized: 122303
// get_deposit_count() -> 0x20, 8, 0 # TODO: check balance and logs after each deposit #
// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0 -> FAILURE # Empty input #
// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e
// gas irOptimized: 115231
// gas irOptimized: 114983
// gas legacy: 148205
// gas legacyOptimized: 122303
// get_deposit_count() -> 0x20, 8, 0
// deposit(bytes,bytes,bytes,bytes32), 1 ether: 0x80, 0xe0, 0x120, 0xaa4a8d0b7d9077248630f1a4701ae9764e42271d7f22b7838778411857fd349e, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0x00f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8 -> # txhash: 0x7085c586686d666e8bb6e9477a0f0b09565b2060a11f1c4209d3a52295033832 #
// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0xf50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x08, 0xca9a3b00000000000000000000000000000000000000000000000000000000, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8, 0x08, 0x00
// get_deposit_root() -> 0x2089653123d9c721215120b6db6738ba273bbc5228ac093b1f983badcdc8a438
// gas irOptimized: 115216
// gas irOptimized: 114978
// gas legacy: 148214
// gas legacyOptimized: 122315
// get_deposit_count() -> 0x20, 8, 0x0100000000000000000000000000000000000000000000000000000000000000
// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0x80, 0xe0, 0x120, 0xdbd986dc85ceb382708cf90a3500f500f0a393c5ece76963ac3ed72eccd2c301, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x00344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d -> # txhash: 0x404d8e109822ce448e68f45216c12cb051b784d068fbe98317ab8e50c58304ac #
// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x08, 0x40597307000000000000000000000000000000000000000000000000000000, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d, 0x08, 0x0100000000000000000000000000000000000000000000000000000000000000
// get_deposit_root() -> 0x40255975859377d912c53aa853245ebd939bdd2b33a28e084babdcc1ed8238ee
// gas irOptimized: 115216
// gas irOptimized: 114978
// gas legacy: 148214
// gas legacyOptimized: 122315
// get_deposit_count() -> 0x20, 8, 0x0200000000000000000000000000000000000000000000000000000000000000
4 changes: 2 additions & 2 deletions test/libsolidity/semanticTests/externalContracts/snark.sol
Expand Up @@ -294,11 +294,11 @@ contract Test {
// f() -> true
// g() -> true
// pair() -> true
// gas irOptimized: 269697
// gas irOptimized: 269701
// gas legacy: 275206
// gas legacyOptimized: 266925
// verifyTx() -> true
// ~ emit Verified(string): 0x20, 0x16, "Successfully verified."
// gas irOptimized: 782210
// gas irOptimized: 782238
// gas legacy: 801868
// gas legacyOptimized: 770942
Expand Up @@ -38,8 +38,8 @@ contract test {
}
// ----
// constructor(), 20 wei ->
// gas irOptimized: 120226
// gas irOptimized code: 132400
// gas irOptimized: 120912
// gas irOptimized code: 140000
// gas legacy: 130568
// gas legacy code: 261000
// gas legacyOptimized: 121069
Expand Down
Expand Up @@ -37,8 +37,8 @@ contract test {
}
// ----
// constructor(), 20 wei ->
// gas irOptimized: 120226
// gas irOptimized code: 132400
// gas irOptimized: 120912
// gas irOptimized code: 140000
// gas legacy: 130568
// gas legacy code: 261000
// gas legacyOptimized: 121069
Expand Down
Expand Up @@ -22,6 +22,6 @@ contract Test {
// ----
// library: Lib
// f() -> 4, 0x11
// gas irOptimized: 111560
// gas irOptimized: 111629
// gas legacy: 132935
// gas legacyOptimized: 118023
Expand Up @@ -44,7 +44,7 @@ contract C {
}
// ----
// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14
// gas irOptimized: 121598
// gas irOptimized: 121586
// gas legacy: 123208
// gas legacyOptimized: 121763
// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14
Expand Down
Expand Up @@ -52,14 +52,14 @@ contract C {
}
// ----
// from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14
// gas irOptimized: 123039
// gas irOptimized: 123010
// gas legacy: 130227
// gas legacyOptimized: 128758
// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14
// gas irOptimized: 121709
// gas irOptimized: 121703
// gas legacy: 123282
// gas legacyOptimized: 121868
// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14
// gas irOptimized: 115130
// gas irOptimized: 115124
// gas legacy: 122516
// gas legacyOptimized: 120804
8 changes: 4 additions & 4 deletions test/libsolidity/semanticTests/structs/copy_to_mapping.sol
Expand Up @@ -45,18 +45,18 @@ contract C {
}
// ----
// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14
// gas irOptimized: 121686
// gas irOptimized: 121680
// gas legacy: 123144
// gas legacyOptimized: 121808
// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14
// gas irOptimized: 121731
// gas irOptimized: 121725
// gas legacy: 123193
// gas legacyOptimized: 121860
// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14
// gas irOptimized: 122947
// gas irOptimized: 122918
// gas legacy: 130088
// gas legacyOptimized: 128754
// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14
// gas irOptimized: 115045
// gas irOptimized: 115039
// gas legacy: 118301
// gas legacyOptimized: 115432
Expand Up @@ -29,6 +29,6 @@ contract C {
}
// ----
// f() -> 0x20, 7, 8, 9, 0xa0, 13, 2, 0x40, 0xa0, 2, 3, 4, 2, 3, 4
// gas irOptimized: 197082
// gas irOptimized: 197116
// gas legacy: 199891
// gas legacyOptimized: 196817
Expand Up @@ -49,11 +49,11 @@ contract C {
}
// ----
// test_f() -> true
// gas irOptimized: 122078
// gas irOptimized: 122094
// gas legacy: 125322
// gas legacyOptimized: 122709
// test_g() -> true
// gas irOptimized: 106215
// gas irOptimized: 106271
// gas legacy: 111120
// gas legacyOptimized: 106964
// addresses(uint256): 0 -> 0x18
Expand Down
Expand Up @@ -19,6 +19,6 @@ contract C {
}
// ----
// g() -> 2, 6
// gas irOptimized: 178475
// gas irOptimized: 178486
// gas legacy: 180839
// gas legacyOptimized: 179374
Expand Up @@ -20,18 +20,46 @@
// {
// {
// f()
// f()
// f()
// f_72()
// f_73()
// sstore(0, 1)
// }
// function f()
// {
// let a := 1
// let b := 10
// let a_1 := calldataload(0)
// let _1 := iszero(a_1)
// for { } iszero(b) { b := add(b, not(0)) }
// {
// a := a_1
// mstore(a_1, 0)
// if _1 { leave }
// }
// }
// function f_72()
// {
// let a := 2
// let b := 10
// let a_1 := calldataload(0)
// let _1 := iszero(a_1)
// for { } iszero(b) { b := add(b, not(0)) }
// {
// a := a_1
// mstore(a_1, 0)
// if _1 { leave }
// }
// }
// function f_73()
// {
// let a := 3
// let b := 10
// let a := calldataload(0)
// let _1 := iszero(a)
// let a_1 := calldataload(0)
// let _1 := iszero(a_1)
// for { } iszero(b) { b := add(b, not(0)) }
// {
// mstore(a, 0)
// a := a_1
// mstore(a_1, 0)
// if _1 { leave }
// }
// }
Expand Down

0 comments on commit 5ea8fa2

Please sign in to comment.