diff --git a/Changelog.md b/Changelog.md index 7c710c3c3..9d6c73c4b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Compiler Features: * SMTChecker: Support shifts. * SMTChecker: Support structs. * Yul Optimizer: Prune unused parameters in functions. + * Yul Optimizer: Inline into functions further down in the call graph first. * Yul Optimizer: Try to simplify function names. diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp index cd17b7aff..ab847e35c 100644 --- a/libyul/optimiser/FullInliner.cpp +++ b/libyul/optimiser/FullInliner.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -74,27 +75,82 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser, Dialect const& void FullInliner::run() { - for (auto& statement: m_ast.statements) - if (holds_alternative(statement)) - handleBlock({}, std::get(statement)); - - // TODO it might be good to determine a visiting order: - // first handle functions that are called from many places. - // Note that the order of inlining can result in very different code. // Since AST IDs and thus function names depend on whether or not a contract // is compiled together with other source files, a change in AST IDs // should have as little an impact as possible. This is the case // if we handle inlining in source (and thus, for the IR generator, // function name) order. + // We use stable_sort below to keep the inlining order of two functions + // with the same depth. + map depths = callDepths(); + vector functions; for (auto& statement: m_ast.statements) + if (holds_alternative(statement)) + functions.emplace_back(&std::get(statement)); + std::stable_sort(functions.begin(), functions.end(), [depths]( + FunctionDefinition const* _a, + FunctionDefinition const* _b + ) { + return depths.at(_a->name) < depths.at(_b->name); + }); + for (FunctionDefinition* fun: functions) { - if (!holds_alternative(statement)) - continue; - FunctionDefinition& fun = std::get(statement); - handleBlock(fun.name, fun.body); - updateCodeSize(fun); + handleBlock(fun->name, fun->body); + updateCodeSize(*fun); } + + for (auto& statement: m_ast.statements) + if (holds_alternative(statement)) + handleBlock({}, std::get(statement)); +} + +map FullInliner::callDepths() const +{ + CallGraph cg = CallGraphGenerator::callGraph(m_ast); + cg.functionCalls.erase(""_yulstring); + + // Remove calls to builtin functions. + for (auto& call: cg.functionCalls) + for (auto it = call.second.begin(); it != call.second.end();) + if (m_dialect.builtin(*it)) + it = call.second.erase(it); + else + ++it; + + map depths; + size_t currentDepth = 0; + + while (true) + { + vector removed; + for (auto it = cg.functionCalls.begin(); it != cg.functionCalls.end();) + { + auto const& [fun, callees] = *it; + if (callees.empty()) + { + removed.emplace_back(fun); + depths[fun] = currentDepth; + it = cg.functionCalls.erase(it); + } + else + ++it; + } + + for (auto& call: cg.functionCalls) + call.second -= removed; + + currentDepth++; + + if (removed.empty()) + break; + } + + // Only recursive functions left here. + for (auto const& fun: cg.functionCalls) + depths[fun.first] = currentDepth; + + return depths; } bool FullInliner::shallInline(FunctionCall const& _funCall, YulString _callSite) diff --git a/libyul/optimiser/FullInliner.h b/libyul/optimiser/FullInliner.h index 8092e478e..a27fdee5b 100644 --- a/libyul/optimiser/FullInliner.h +++ b/libyul/optimiser/FullInliner.h @@ -94,6 +94,10 @@ private: FullInliner(Block& _ast, NameDispenser& _dispenser, Dialect const& _dialect); void run(); + /// @returns a map containing the maximum depths of a call chain starting at each + /// function. For recursive functions, the value is one larger than for all others. + std::map callDepths() const; + void updateCodeSize(FunctionDefinition const& _fun); void handleBlock(YulString _currentFunctionName, Block& _block); bool recursive(FunctionDefinition const& _fun) const; diff --git a/test/cmdlineTests/evm_to_wasm_break/output b/test/cmdlineTests/evm_to_wasm_break/output index ecb9a9ce3..1786ff3bf 100644 --- a/test/cmdlineTests/evm_to_wasm_break/output +++ b/test/cmdlineTests/evm_to_wasm_break/output @@ -31,10 +31,9 @@ object "object" { let x_6 := x_2 let x_7 := x_3 let _2 := 1 - let _3 := i64.or(_1, _1) - let _4:i32 := i32.eqz(i32.eqz(i64.eqz(i64.or(_3, i64.or(_1, _2))))) + let _3:i32 := i32.eqz(i32.eqz(i64.eqz(i64.or(i64.or(_1, _1), i64.or(_1, _2))))) for { } - i32.eqz(_4) + i32.eqz(_3) { let x_8, x_9, x_10, x_11 := add(x_4, x_5, x_6, x_7, _1, _1, _1, _2) x_4 := x_8 @@ -43,10 +42,13 @@ object "object" { x_7 := x_11 } { - let _5, _6, _7, _8 := iszero_170_789(_1, _1, _1, lt_172(x_4, x_5, x_6, x_7, _1, _1, _1, 10)) - if i32.eqz(i64.eqz(i64.or(i64.or(_5, _6), i64.or(_7, _8)))) { break } - if i32.eqz(i64.eqz(i64.or(_3, i64.or(_1, eq(x_4, x_5, x_6, x_7, _1, _1, _1, 2))))) { break } - if i32.eqz(i64.eqz(i64.or(_3, i64.or(_1, eq(x_4, x_5, x_6, x_7, _1, _1, _1, 4))))) { continue } + let _4, _5, _6, _7 := lt_172_762(x_4, x_5, x_6, x_7, _1, _1, _1, 10) + let _8, _9, _10, _11 := iszero_170_760(_4, _5, _6, _7) + if i32.eqz(i64.eqz(i64.or(i64.or(_8, _9), i64.or(_10, _11)))) { break } + let _12, _13, _14, _15 := eq_171_761(x_4, x_5, x_6, x_7, _1, _1, _1, 2) + if i32.eqz(i64.eqz(i64.or(i64.or(_12, _13), i64.or(_14, _15)))) { break } + let _16, _17, _18, _19 := eq_171_761(x_4, x_5, x_6, x_7, _1, _1, _1, 4) + if i32.eqz(i64.eqz(i64.or(i64.or(_16, _17), i64.or(_18, _19)))) { continue } } sstore(_1, _1, _1, _1, x_4, x_5, x_6, x_7) } @@ -67,19 +69,24 @@ object "object" { let r1_1, carry_2 := add_carry(x1, y1, carry_1) r1 := r1_1 } - function iszero_170_789(x1, x2, x3, x4) -> r1, r2, r3, r4 + function iszero_170_760(x1, x2, x3, x4) -> r1, r2, r3, r4 { r4 := i64.extend_i32_u(i64.eqz(i64.or(i64.or(x1, x2), i64.or(x3, x4)))) } - function eq(x1, x2, x3, x4, y1, y2, y3, y4) -> r4 + function eq_171_761(x1, x2, x3, x4, y1, y2, y3, y4) -> r1, r2, r3, r4 { + let r4_1 := 0 if i64.eq(x1, y1) { if i64.eq(x2, y2) { - if i64.eq(x3, y3) { if i64.eq(x4, y4) { r4 := 1 } } + if i64.eq(x3, y3) + { + if i64.eq(x4, y4) { r4_1 := 1 } + } } } + r4 := r4_1 } function cmp(a, b) -> r:i32 { @@ -87,7 +94,7 @@ object "object" { case 1:i32 { r := 0xffffffff:i32 } default { r := i64.ne(a, b) } } - function lt_172(x1, x2, x3, x4, y1, y2, y3, y4) -> z4 + function lt_172_762(x1, x2, x3, x4, y1, y2, y3, y4) -> z1, z2, z3, z4 { let z:i32 := false switch cmp(x1, y1) @@ -152,7 +159,7 @@ object "object" { Binary representation: -0061736d0100000001480a60000060017e017e60027e7e017f60037e7e7e017e60047e7e7e7e017e60087e7e7e7e7e7e7e7e0060087e7e7e7e7e7e7e7e017e60057f7e7e7e7e0060027f7f0060037f7f7f0002310208657468657265756d0c73746f7261676553746f7265000808657468657265756d0c63616c6c44617461436f70790009030e0d0003060406020604010101070505030100010610037e0142000b7e0142000b7e0142000b071102066d656d6f72790200046d61696e00020af0070da302030b7e017f087e02404200210002402000200020002000100921012300210223012103230221040b20012105200221062003210720042108420121092000200084210a200a200020098484504545210b02400340200b45450d01024002402000200020002005200620072008200020002000420a10081005210c2300210d2301210e2302210f0b200c200d84200e200f8484504504400c030b200a20002005200620072008200020002000420210068484504504400c030b200a20002005200620072008200020002000420410068484504504400c010b0b024020052006200720082000200020002009100421102300211123012112230221130b201021052011210620122107201321080c000b0b20002000200020002005200620072008100e0b0b2901037e0240200020017c2105200520027c21032005200054200320055472ad21040b2004240020030b6c010b7e0240200320077c210c200c42007c210b024020022006200c200354200b200c5472ad1003210d2300210e0b200d210a024020012005200e1003210f230021100b200f2109024020002004201010032111230021120b201121080b20092400200a2401200b240220080b2401047e0240200020018420022003848450ad21070b20052400200624012007240220040b2d01017e024020002004510440200120055104402002200651044020032007510440420121080b0b0b0b0b20080b2701027f024002402000200154210320034101460440417f210205200020015221020b0b0b20020b8a0102017e047f0240410021090240200020041007210a200a41004604400240200120051007210b200b41004604400240200220061007210c200c41004604402003200754210905200c41014604404100210905410121090b0b0b05200b41014604404100210905410121090b0b0b05200a41014604404100210905410121090b0b0b2009ad21080b20080b7601087e024042002000200184200284520440000b42002003422088520440000b41002003a7412010014100290000100c2108410041086a290000100c2109410041106a290000100c210a410041186a290000100c210b2008210420092105200a2106200b21070b20052400200624012007240220040b1f01017e024020004208864280fe0383200042088842ff01838421010b20010b1e01027e02402000100a421086210220022000421088100a8421010b20010b1e01027e02402000100b422086210220022000422088100b8421010b20010b3200024020002001100c370000200041086a2002100c370000200041106a2003100c370000200041186a2004100c3700000b0b2300024041002000200120022003100d41202004200520062007100d4100412010000b0b +0061736d0100000001480a60000060017e017e60027e7e017f60037e7e7e017e60047e7e7e7e017e60087e7e7e7e7e7e7e7e0060087e7e7e7e7e7e7e7e017e60057f7e7e7e7e0060027f7f0060037f7f7f0002310208657468657265756d0c73746f7261676553746f7265000808657468657265756d0c63616c6c44617461436f70790009030e0d0003060406020604010101070505030100010610037e0142000b7e0142000b7e0142000b071102066d656d6f72790200046d61696e00020acb080dde02030a7e017f147e02404200210002402000200020002000100921012300210223012103230221040b20012105200221062003210720042108420121092000200084200020098484504545210a02400340200a45450d01024002402005200620072008200020002000420a1008210b2300210c2301210d2302210e0b0240200b200c200d200e1005210f2300211023012111230221120b200f201084201120128484504504400c030b024020052006200720082000200020004202100621132300211423012115230221160b2013201484201520168484504504400c030b0240200520062007200820002000200042041006211723002118230121192302211a0b20172018842019201a8484504504400c010b0b0240200520062007200820002000200020091004211b2300211c2301211d2302211e0b201b2105201c2106201d2107201e21080c000b0b20002000200020002005200620072008100e0b0b2901037e0240200020017c2105200520027c21032005200054200320055472ad21040b2004240020030b6c010b7e0240200320077c210c200c42007c210b024020022006200c200354200b200c5472ad1003210d2300210e0b200d210a024020012005200e1003210f230021100b200f2109024020002004201010032111230021120b201121080b20092400200a2401200b240220080b2401047e0240200020018420022003848450ad21070b20052400200624012007240220040b4101057e02404200210c200020045104402001200551044020022006510440200320075104404201210c0b0b0b0b200c210b0b20092400200a2401200b240220080b2701027f024002402000200154210320034101460440417f210205200020015221020b0b0b20020b960102047e047f02404100210c0240200020041007210d200d41004604400240200120051007210e200e41004604400240200220061007210f200f41004604402003200754210c05200f41014604404100210c054101210c0b0b0b05200e41014604404100210c054101210c0b0b0b05200d41014604404100210c054101210c0b0b0b200cad210b0b20092400200a2401200b240220080b7601087e024042002000200184200284520440000b42002003422088520440000b41002003a7412010014100290000100c2108410041086a290000100c2109410041106a290000100c210a410041186a290000100c210b2008210420092105200a2106200b21070b20052400200624012007240220040b1f01017e024020004208864280fe0383200042088842ff01838421010b20010b1e01027e02402000100a421086210220022000421088100a8421010b20010b1e01027e02402000100b422086210220022000422088100b8421010b20010b3200024020002001100c370000200041086a2002100c370000200041106a2003100c370000200041186a2004100c3700000b0b2300024041002000200120022003100d41202004200520062007100d4100412010000b0b Text representation: (module @@ -175,12 +182,23 @@ Text representation: (local $x_6 i64) (local $x_7 i64) (local $_2 i64) - (local $_3 i64) - (local $_4 i32) + (local $_3 i32) + (local $_4 i64) (local $_5 i64) (local $_6 i64) (local $_7 i64) (local $_8 i64) + (local $_9 i64) + (local $_10 i64) + (local $_11 i64) + (local $_12 i64) + (local $_13 i64) + (local $_14 i64) + (local $_15 i64) + (local $_16 i64) + (local $_17 i64) + (local $_18 i64) + (local $_19 i64) (local $x_8 i64) (local $x_9 i64) (local $x_10 i64) @@ -199,26 +217,46 @@ Text representation: (local.set $x_6 (local.get $x_2)) (local.set $x_7 (local.get $x_3)) (local.set $_2 (i64.const 1)) - (local.set $_3 (i64.or (local.get $_1) (local.get $_1))) - (local.set $_4 (i32.eqz (i32.eqz (i64.eqz (i64.or (local.get $_3) (i64.or (local.get $_1) (local.get $_2))))))) + (local.set $_3 (i32.eqz (i32.eqz (i64.eqz (i64.or (i64.or (local.get $_1) (local.get $_1)) (i64.or (local.get $_1) (local.get $_2))))))) (block $label__3 (loop $label__5 - (br_if $label__3 (i32.eqz (i32.eqz (local.get $_4)))) + (br_if $label__3 (i32.eqz (i32.eqz (local.get $_3)))) (block $label__4 (block - (local.set $_5 (call $iszero_170_789 (local.get $_1) (local.get $_1) (local.get $_1) (call $lt_172 (local.get $x_4) (local.get $x_5) (local.get $x_6) (local.get $x_7) (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 10)))) - (local.set $_6 (global.get $global_)) - (local.set $_7 (global.get $global__1)) - (local.set $_8 (global.get $global__2)) + (local.set $_4 (call $lt_172_762 (local.get $x_4) (local.get $x_5) (local.get $x_6) (local.get $x_7) (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 10))) + (local.set $_5 (global.get $global_)) + (local.set $_6 (global.get $global__1)) + (local.set $_7 (global.get $global__2)) ) - (if (i32.eqz (i64.eqz (i64.or (i64.or (local.get $_5) (local.get $_6)) (i64.or (local.get $_7) (local.get $_8))))) (then + (block + (local.set $_8 (call $iszero_170_760 (local.get $_4) (local.get $_5) (local.get $_6) (local.get $_7))) + (local.set $_9 (global.get $global_)) + (local.set $_10 (global.get $global__1)) + (local.set $_11 (global.get $global__2)) + + ) + (if (i32.eqz (i64.eqz (i64.or (i64.or (local.get $_8) (local.get $_9)) (i64.or (local.get $_10) (local.get $_11))))) (then (br $label__3) )) - (if (i32.eqz (i64.eqz (i64.or (local.get $_3) (i64.or (local.get $_1) (call $eq (local.get $x_4) (local.get $x_5) (local.get $x_6) (local.get $x_7) (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 2)))))) (then + (block + (local.set $_12 (call $eq_171_761 (local.get $x_4) (local.get $x_5) (local.get $x_6) (local.get $x_7) (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 2))) + (local.set $_13 (global.get $global_)) + (local.set $_14 (global.get $global__1)) + (local.set $_15 (global.get $global__2)) + + ) + (if (i32.eqz (i64.eqz (i64.or (i64.or (local.get $_12) (local.get $_13)) (i64.or (local.get $_14) (local.get $_15))))) (then (br $label__3) )) - (if (i32.eqz (i64.eqz (i64.or (local.get $_3) (i64.or (local.get $_1) (call $eq (local.get $x_4) (local.get $x_5) (local.get $x_6) (local.get $x_7) (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 4)))))) (then + (block + (local.set $_16 (call $eq_171_761 (local.get $x_4) (local.get $x_5) (local.get $x_6) (local.get $x_7) (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 4))) + (local.set $_17 (global.get $global_)) + (local.set $_18 (global.get $global__1)) + (local.set $_19 (global.get $global__2)) + + ) + (if (i32.eqz (i64.eqz (i64.or (i64.or (local.get $_16) (local.get $_17)) (i64.or (local.get $_18) (local.get $_19))))) (then (br $label__4) )) @@ -310,7 +348,7 @@ Text representation: (local.get $r1) ) -(func $iszero_170_789 +(func $iszero_170_760 (param $x1 i64) (param $x2 i64) (param $x3 i64) @@ -330,7 +368,7 @@ Text representation: (local.get $r1) ) -(func $eq +(func $eq_171_761 (param $x1 i64) (param $x2 i64) (param $x3 i64) @@ -340,20 +378,29 @@ Text representation: (param $y3 i64) (param $y4 i64) (result i64) + (local $r1 i64) + (local $r2 i64) + (local $r3 i64) (local $r4 i64) + (local $r4_1 i64) (block $label__9 + (local.set $r4_1 (i64.const 0)) (if (i64.eq (local.get $x1) (local.get $y1)) (then (if (i64.eq (local.get $x2) (local.get $y2)) (then (if (i64.eq (local.get $x3) (local.get $y3)) (then (if (i64.eq (local.get $x4) (local.get $y4)) (then - (local.set $r4 (i64.const 1)) + (local.set $r4_1 (i64.const 1)) )) )) )) )) + (local.set $r4 (local.get $r4_1)) ) - (local.get $r4) + (global.set $global_ (local.get $r2)) + (global.set $global__1 (local.get $r3)) + (global.set $global__2 (local.get $r4)) + (local.get $r1) ) (func $cmp @@ -377,7 +424,7 @@ Text representation: (local.get $r) ) -(func $lt_172 +(func $lt_172_762 (param $x1 i64) (param $x2 i64) (param $x3 i64) @@ -387,6 +434,9 @@ Text representation: (param $y3 i64) (param $y4 i64) (result i64) + (local $z1 i64) + (local $z2 i64) + (local $z3 i64) (local $z4 i64) (local $z i32) (local $condition_12 i32) @@ -434,7 +484,10 @@ Text representation: (local.set $z4 (i64.extend_i32_u (local.get $z))) ) - (local.get $z4) + (global.set $global_ (local.get $z2)) + (global.set $global__1 (local.get $z3)) + (global.set $global__2 (local.get $z4)) + (local.get $z1) ) (func $calldataload diff --git a/test/cmdlineTests/name_simplifier/output b/test/cmdlineTests/name_simplifier/output index 5016c1c60..f2ec8e0cc 100644 --- a/test/cmdlineTests/name_simplifier/output +++ b/test/cmdlineTests/name_simplifier/output @@ -26,49 +26,40 @@ object "C_56" { if eq(0xf8eddcc6, shr(224, calldataload(_1))) { if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), 32) { revert(_1, _1) } + let _2 := 32 + if slt(add(calldatasize(), not(3)), _2) { revert(_1, _1) } let offset := calldataload(4) - if gt(offset, 0xffffffffffffffff) { revert(_1, _1) } - let value0 := abi_decode_t_array$_t_struct$_S_$dyn(add(4, offset), calldatasize()) - let value := mload(mload(memory_array_index_access$_t_struct$_S_$dyn(value0, _1))) - let _2, _3 := storage_array_index_access$_t_struct$_S_storage(_1, _1) - sstore(_2, value) - let value_1 := mload(mload(memory_array_index_access$_t_struct$_S_$dyn(value0, 0x01))) - let _4, _5 := storage_array_index_access$_t_struct$_S_storage(0x02, _1) - update_storage_value_t_uint256_to_t_uint256(_4, _5, value_1) - let _6, _7 := storage_array_index_access$_t_struct$_S_storage(0x02, _1) - let vloc := extract_from_storage_value_dynamict_uint256(sload(_6), _7) - let vloc__24_mpos := convert_t_stringliteral_6490_to_t_string() + let _3 := 0xffffffffffffffff + if gt(offset, _3) { revert(_1, _1) } + if iszero(slt(add(offset, 35), calldatasize())) { revert(_1, _1) } + let length := calldataload(add(4, offset)) + if gt(length, _3) { revert(_1, _1) } + let _4 := mul(length, _2) + let dst := allocateMemory(add(_4, _2)) + let dst_1 := dst + mstore(dst, length) + dst := add(dst, _2) + let src := add(offset, 36) + if gt(add(add(offset, _4), 36), calldatasize()) { revert(_1, _1) } + let i := _1 + for { } lt(i, length) { i := add(i, 1) } + { + mstore(dst, abi_decode_t_struct$_S(src, calldatasize())) + dst := add(dst, _2) + src := add(src, _2) + } + let ret, ret_1 := fun_sumArray_55(dst_1) let memPos := allocateMemory(_1) - return(memPos, sub(abi_encode_uint256_t_string(memPos, vloc, vloc__24_mpos), memPos)) + return(memPos, sub(abi_encode_uint256_t_string(memPos, ret, ret_1), memPos)) } } revert(0, 0) } - function abi_decode_t_array$_t_struct$_S_$dyn(offset, end) -> array + function abi_decode_t_struct$_S(headStart, end) -> value { - if iszero(slt(add(offset, 0x1f), end)) { revert(array, array) } - let length := calldataload(offset) - if gt(length, 0xffffffffffffffff) { revert(array, array) } - let _1 := 0x20 - let _2 := mul(length, _1) - array := allocateMemory(add(_2, _1)) - let dst := array - mstore(array, length) - dst := add(array, _1) - let src := add(offset, _1) - if gt(add(add(offset, _2), _1), end) { revert(0, 0) } - let i := 0 - let i_1 := i - for { } lt(i_1, length) { i_1 := add(i_1, 1) } - { - if slt(sub(end, src), _1) { revert(i, i) } - let value := allocateMemory(_1) - mstore(value, calldataload(src)) - mstore(dst, value) - dst := add(dst, _1) - src := add(src, _1) - } + if slt(sub(end, headStart), 0x20) { revert(value, value) } + value := allocateMemory(0x20) + mstore(value, calldataload(headStart)) } function abi_encode_uint256_t_string(headStart, value0, value1) -> tail { @@ -108,10 +99,24 @@ object "C_56" { { value := shr(mul(offset, 8), slot_value) } - function memory_array_index_access$_t_struct$_S_$dyn(baseRef, index) -> addr + function fun_sumArray_55(vloc__s_19_mpos) -> vloc, vloc__24_mpos { - if iszero(lt(index, mload(baseRef))) { invalid() } - addr := add(add(baseRef, mul(index, 32)), 32) + let _1 := mload(vloc__s_19_mpos) + if iszero(lt(vloc, _1)) { invalid() } + let _2 := mload(mload(add(add(vloc__s_19_mpos, mul(vloc, 32)), 32))) + let _3, _4 := storage_array_index_access$_t_struct$_S_storage(vloc, vloc) + sstore(_3, _2) + if iszero(lt(0x01, _1)) { invalid() } + let _5 := mload(mload(add(vloc__s_19_mpos, 64))) + if iszero(lt(vloc, 0x02)) { invalid() } + let slot := add(0x02, vloc) + let _6 := sload(slot) + let shiftBits := mul(vloc, 8) + let mask := shl(shiftBits, not(0)) + sstore(slot, or(and(_6, not(mask)), and(shl(shiftBits, _5), mask))) + let _7, _8 := storage_array_index_access$_t_struct$_S_storage(0x02, vloc) + vloc := extract_from_storage_value_dynamict_uint256(sload(_7), _8) + vloc__24_mpos := convert_t_stringliteral_6490_to_t_string() } function storage_array_index_access$_t_struct$_S_storage(array, index) -> slot, offset { @@ -119,13 +124,6 @@ object "C_56" { slot := add(array, index) offset := offset } - function update_storage_value_t_uint256_to_t_uint256(slot, offset, value) - { - let _1 := sload(slot) - let shiftBits := mul(offset, 8) - let mask := shl(shiftBits, not(0)) - sstore(slot, or(and(_1, not(mask)), and(shl(shiftBits, value), mask))) - } } } } diff --git a/test/cmdlineTests/optimizer_array_sload/output b/test/cmdlineTests/optimizer_array_sload/output index a32246bf3..31c17a0a5 100644 --- a/test/cmdlineTests/optimizer_array_sload/output +++ b/test/cmdlineTests/optimizer_array_sload/output @@ -33,11 +33,14 @@ object "Arraysum_33" { for { } lt(vloc_i, _2) { - vloc_i := increment_t_uint256(vloc_i) + if gt(vloc_i, not(1)) { revert(_1, _1) } + vloc_i := add(vloc_i, 1) } { - let _3, _4 := storage_array_index_access$_t_uint256_$dyn_storage(_1, vloc_i) - vloc_sum := checked_add_t_uint256(vloc_sum, extract_from_storage_value_dynamict_uint256(sload(_3), _4)) + mstore(_1, _1) + let _3 := sload(add(keccak256(_1, 0x20), vloc_i)) + if gt(vloc_sum, not(_3)) { revert(_1, _1) } + vloc_sum := add(vloc_sum, _3) } let memPos := allocateMemory(_1) return(memPos, sub(abi_encode_uint(memPos, _1), memPos)) @@ -57,27 +60,6 @@ object "Arraysum_33" { if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) } mstore(64, newFreePtr) } - function checked_add_t_uint256(x, y) -> sum - { - if gt(x, not(y)) { revert(sum, sum) } - sum := add(x, y) - } - function extract_from_storage_value_dynamict_uint256(slot_value, offset) -> value - { - value := shr(mul(offset, 8), slot_value) - } - function increment_t_uint256(value) -> ret - { - if gt(value, not(1)) { revert(ret, ret) } - ret := add(value, 1) - } - function storage_array_index_access$_t_uint256_$dyn_storage(array, index) -> slot, offset - { - if iszero(lt(index, sload(array))) { invalid() } - mstore(slot, array) - slot := add(keccak256(slot, 0x20), index) - offset := offset - } } } } diff --git a/test/cmdlineTests/standard_eWasm_requested/output.json b/test/cmdlineTests/standard_eWasm_requested/output.json index 7b2af14bf..a3885d128 100644 --- a/test/cmdlineTests/standard_eWasm_requested/output.json +++ b/test/cmdlineTests/standard_eWasm_requested/output.json @@ -6,9 +6,6 @@ (import \"ethereum\" \"finish\" (func $eth.finish (param i32 i32))) (memory $memory (export \"memory\") 1) (export \"main\" (func $main)) - (global $global_ (mut i64) (i64.const 0)) - (global $global__1 (mut i64) (i64.const 0)) - (global $global__2 (mut i64) (i64.const 0)) (func $main (local $_1 i64) @@ -18,7 +15,6 @@ (local $z1 i64) (local $z2 i64) (local $z3 i64) - (local $z4 i64) (local $_3 i64) (block $label_ (local.set $_1 (i64.const 0)) @@ -32,18 +28,14 @@ (i64.store (i32.add (local.get $r) (i32.const 16)) (local.get $_2)) (i64.store (i32.add (local.get $r) (i32.const 24)) (call $endian_swap (i64.const 128))) (call $eth.getCallValue (i32.const 0)) - (block - (local.set $z1 (call $mload_internal (i32.const 0))) - (local.set $z2 (global.get $global_)) - (local.set $z3 (global.get $global__1)) - (local.set $z4 (global.get $global__2)) - - ) - (if (i32.eqz (i64.eqz (i64.or (i64.or (local.get $z1) (local.get $z2)) (i64.or (local.get $z3) (local.get $z4))))) (then - (call $eth.revert (call $to_internal_i32ptr (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1)) (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))))) + (local.set $z1 (call $endian_swap (i64.load (i32.const 0)))) + (local.set $z2 (call $endian_swap (i64.load (i32.add (i32.const 0) (i32.const 8))))) + (local.set $z3 (call $endian_swap (i64.load (i32.add (i32.const 0) (i32.const 16))))) + (if (i32.eqz (i64.eqz (i64.or (i64.or (local.get $z1) (local.get $z2)) (i64.or (local.get $z3) (call $endian_swap (i64.load (i32.add (i32.const 0) (i32.const 24)))))))) (then + (call $revert (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1)))) (local.set $_3 (datasize \"C_2_deployed\")) - (call $eth.codeCopy (call $to_internal_i32ptr (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1)) (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (dataoffset \"C_2_deployed\")) (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3))) - (call $eth.finish (call $to_internal_i32ptr (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1)) (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3))) + (call $codecopy (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (dataoffset \"C_2_deployed\") (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3)) + (call $return (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3)) ) ) @@ -54,7 +46,7 @@ (param $x4 i64) (result i32) (local $v i32) - (block $label__3 + (block $label__1 (if (i64.ne (i64.const 0) (i64.or (i64.or (local.get $x1) (local.get $x2)) (local.get $x3))) (then (unreachable))) (if (i64.ne (i64.const 0) (i64.shr_u (local.get $x4) (i64.const 32))) (then @@ -73,7 +65,7 @@ (result i32) (local $r i32) (local $p i32) - (block $label__4 + (block $label__2 (local.set $p (call $u256_to_i32 (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4))) (local.set $r (i32.add (local.get $p) (i32.const 64))) (if (i32.lt_u (local.get $r) (local.get $p)) (then @@ -83,11 +75,29 @@ (local.get $r) ) +(func $codecopy + (param $x1 i64) + (param $x2 i64) + (param $x3 i64) + (param $x4 i64) + (param $y1 i64) + (param $y2 i64) + (param $y3 i64) + (param $y4 i64) + (param $z1 i64) + (param $z2 i64) + (param $z3 i64) + (param $z4 i64) + (block $label__3 + (call $eth.codeCopy (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)) (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4)) (call $u256_to_i32 (local.get $z1) (local.get $z2) (local.get $z3) (local.get $z4))) + ) +) + (func $endian_swap_16 (param $x i64) (result i64) (local $y i64) - (block $label__5 + (block $label__4 (local.set $y (i64.or (i64.and (i64.shl (local.get $x) (i64.const 8)) (i64.const 65280)) (i64.and (i64.shr_u (local.get $x) (i64.const 8)) (i64.const 255)))) ) @@ -99,7 +109,7 @@ (result i64) (local $y i64) (local $hi i64) - (block $label__6 + (block $label__5 (local.set $hi (i64.shl (call $endian_swap_16 (local.get $x)) (i64.const 16))) (local.set $y (i64.or (local.get $hi) (call $endian_swap_16 (i64.shr_u (local.get $x) (i64.const 16))))) @@ -112,7 +122,7 @@ (result i64) (local $y i64) (local $hi i64) - (block $label__7 + (block $label__6 (local.set $hi (i64.shl (call $endian_swap_32 (local.get $x)) (i64.const 32))) (local.set $y (i64.or (local.get $hi) (call $endian_swap_32 (i64.shr_u (local.get $x) (i64.const 32))))) @@ -120,24 +130,32 @@ (local.get $y) ) -(func $mload_internal - (param $pos i32) - (result i64) - (local $z1 i64) - (local $z2 i64) - (local $z3 i64) - (local $z4 i64) - (block $label__8 - (local.set $z1 (call $endian_swap (i64.load (local.get $pos)))) - (local.set $z2 (call $endian_swap (i64.load (i32.add (local.get $pos) (i32.const 8))))) - (local.set $z3 (call $endian_swap (i64.load (i32.add (local.get $pos) (i32.const 16))))) - (local.set $z4 (call $endian_swap (i64.load (i32.add (local.get $pos) (i32.const 24))))) - +(func $return + (param $x1 i64) + (param $x2 i64) + (param $x3 i64) + (param $x4 i64) + (param $y1 i64) + (param $y2 i64) + (param $y3 i64) + (param $y4 i64) + (block $label__7 + (call $eth.finish (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)) (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4))) + ) +) + +(func $revert + (param $x1 i64) + (param $x2 i64) + (param $x3 i64) + (param $x4 i64) + (param $y1 i64) + (param $y2 i64) + (param $y3 i64) + (param $y4 i64) + (block $label__8 + (call $eth.revert (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)) (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4))) ) - (global.set $global_ (local.get $z2)) - (global.set $global__1 (local.get $z3)) - (global.set $global__2 (local.get $z4)) - (local.get $z1) ) ) diff --git a/test/cmdlineTests/yul_stack_opt/output b/test/cmdlineTests/yul_stack_opt/output index a02859f1e..f2a7dd41e 100644 --- a/test/cmdlineTests/yul_stack_opt/output +++ b/test/cmdlineTests/yul_stack_opt/output @@ -5,55 +5,55 @@ Pretty printed source: object "object" { code { { - let a3, b3, c3, d3, e3, f3, g3, h3, i3, j3, k3, l3, m3, o3, p3 := fun() - let a3_1, b3_1, c3_1, d3_1, e3_1, f3_1, g3_1, h3_1, i3_1, j3_1, k3_1, l3_1, m3_1, o3_1, p3_1 := fun() - sstore(a3, a3_1) + let a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1 := fun_66_345() + let a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2 := fun_66_345() + sstore(a1, a2) } - function fun() -> a3, b3, c3, d3, e3, f3, g3, h3, i3, j3, k3, l3, m3, o3, p3 + function fun_66_345() -> a3, b3, c3, d3, e3, f3, g3, h3, i3, j3, k3, l3, m3, n3, o3, p3 { - let _1 := 1 - sstore(_1, _1) - sstore(2, _1) - sstore(3, _1) - sstore(4, _1) - sstore(5, _1) - sstore(6, _1) - sstore(7, _1) - sstore(8, _1) - sstore(9, _1) - sstore(10, _1) - sstore(11, _1) - sstore(12, _1) - sstore(13, _1) - a3 := _1 - b3 := _1 - c3 := _1 - d3 := _1 - e3 := _1 - f3 := _1 - g3 := _1 - h3 := _1 - i3 := _1 - j3 := _1 - k3 := _1 - l3 := _1 - m3 := _1 - o3 := _1 - p3 := _1 + sstore(1, 1) + sstore(2, 1) + sstore(3, 1) + sstore(4, 1) + sstore(5, 1) + sstore(6, 1) + sstore(7, 1) + sstore(8, 1) + sstore(9, 1) + sstore(10, 1) + sstore(11, 1) + sstore(12, 1) + sstore(13, 1) + a3 := 1 + b3 := a3 + c3 := a3 + d3 := a3 + e3 := a3 + f3 := a3 + g3 := a3 + h3 := a3 + i3 := a3 + j3 := a3 + k3 := a3 + l3 := a3 + m3 := a3 + o3 := a3 + p3 := a3 } } } Binary representation: -60056030565b505050505050505050505050505060196030565b5050505050505050505050505050808255505060c3565b6000600060006000600060006000600060006000600060006000600060006001808155806002558060035580600455806005558060065580600755806008558060095580600a5580600b5580600c5580600d55809f50809e50809d50809c50809b50809a50809950809850809750809650809550809450809350809250809150505b909192939495969798999a9b9c9d9e565b +60056032565b505050505050505050505050505050601a6032565b505050505050505050505050505050808255505060d4565b60006000600060006000600060006000600060006000600060006000600060006001600155600160025560016003556001600455600160055560016006556001600755600160085560016009556001600a556001600b556001600c556001600d5560019f508f9e508f9d508f9c508f9b508f9a508f99508f98508f97508f96508f95508f94508f93508f91508f90505b909192939495969798999a9b9c9d9e9f565b Text representation: - /* "yul_stack_opt/input.sol":3:573 */ + /* "yul_stack_opt/input.sol":645:650 */ tag_1 tag_2 jump // in tag_1: + /* "yul_stack_opt/input.sol":575:650 */ pop pop pop @@ -68,10 +68,14 @@ tag_1: pop pop pop + pop + /* "yul_stack_opt/input.sol":722:727 */ tag_3 tag_2 jump // in tag_3: + /* "yul_stack_opt/input.sol":652:727 */ + pop pop pop pop @@ -111,162 +115,160 @@ tag_2: 0x00 0x00 0x00 + 0x00 0x00 /* "yul_stack_opt/input.sol":98:99 */ 0x01 - dup1 - dup2 + 0x01 /* "yul_stack_opt/input.sol":129:141 */ sstore /* "yul_stack_opt/input.sol":98:99 */ - dup1 + 0x01 /* "yul_stack_opt/input.sol":151:160 */ 0x02 /* "yul_stack_opt/input.sol":144:164 */ sstore /* "yul_stack_opt/input.sol":98:99 */ - dup1 + 0x01 /* "yul_stack_opt/input.sol":174:183 */ 0x03 /* "yul_stack_opt/input.sol":167:187 */ sstore /* "yul_stack_opt/input.sol":98:99 */ - dup1 + 0x01 /* "yul_stack_opt/input.sol":197:206 */ 0x04 /* "yul_stack_opt/input.sol":190:210 */ sstore /* "yul_stack_opt/input.sol":98:99 */ - dup1 + 0x01 /* "yul_stack_opt/input.sol":220:229 */ 0x05 /* "yul_stack_opt/input.sol":213:233 */ sstore /* "yul_stack_opt/input.sol":98:99 */ - dup1 + 0x01 /* "yul_stack_opt/input.sol":243:252 */ 0x06 /* "yul_stack_opt/input.sol":236:256 */ sstore /* "yul_stack_opt/input.sol":98:99 */ - dup1 + 0x01 /* "yul_stack_opt/input.sol":266:275 */ 0x07 /* "yul_stack_opt/input.sol":259:279 */ sstore /* "yul_stack_opt/input.sol":98:99 */ - dup1 + 0x01 /* "yul_stack_opt/input.sol":289:298 */ 0x08 /* "yul_stack_opt/input.sol":282:302 */ sstore /* "yul_stack_opt/input.sol":98:99 */ - dup1 + 0x01 /* "yul_stack_opt/input.sol":312:321 */ 0x09 /* "yul_stack_opt/input.sol":305:325 */ sstore /* "yul_stack_opt/input.sol":98:99 */ - dup1 + 0x01 /* "yul_stack_opt/input.sol":335:344 */ 0x0a /* "yul_stack_opt/input.sol":328:348 */ sstore /* "yul_stack_opt/input.sol":98:99 */ - dup1 + 0x01 /* "yul_stack_opt/input.sol":358:368 */ 0x0b /* "yul_stack_opt/input.sol":351:372 */ sstore /* "yul_stack_opt/input.sol":98:99 */ - dup1 + 0x01 /* "yul_stack_opt/input.sol":382:392 */ 0x0c /* "yul_stack_opt/input.sol":375:396 */ sstore /* "yul_stack_opt/input.sol":98:99 */ - dup1 + 0x01 /* "yul_stack_opt/input.sol":406:416 */ 0x0d /* "yul_stack_opt/input.sol":399:420 */ sstore /* "yul_stack_opt/input.sol":98:99 */ - dup1 - /* "yul_stack_opt/input.sol":423:430 */ + 0x01 + /* "yul_stack_opt/input.sol":3:573 */ swap16 pop /* "yul_stack_opt/input.sol":98:99 */ - dup1 - /* "yul_stack_opt/input.sol":433:440 */ + dup16 + /* "yul_stack_opt/input.sol":3:573 */ swap15 pop /* "yul_stack_opt/input.sol":98:99 */ - dup1 - /* "yul_stack_opt/input.sol":443:450 */ + dup16 + /* "yul_stack_opt/input.sol":3:573 */ swap14 pop /* "yul_stack_opt/input.sol":98:99 */ - dup1 - /* "yul_stack_opt/input.sol":453:460 */ + dup16 + /* "yul_stack_opt/input.sol":3:573 */ swap13 pop /* "yul_stack_opt/input.sol":98:99 */ - dup1 - /* "yul_stack_opt/input.sol":463:470 */ + dup16 + /* "yul_stack_opt/input.sol":3:573 */ swap12 pop /* "yul_stack_opt/input.sol":98:99 */ - dup1 - /* "yul_stack_opt/input.sol":473:480 */ + dup16 + /* "yul_stack_opt/input.sol":3:573 */ swap11 pop /* "yul_stack_opt/input.sol":98:99 */ - dup1 - /* "yul_stack_opt/input.sol":483:490 */ + dup16 + /* "yul_stack_opt/input.sol":3:573 */ swap10 pop /* "yul_stack_opt/input.sol":98:99 */ - dup1 - /* "yul_stack_opt/input.sol":493:500 */ + dup16 + /* "yul_stack_opt/input.sol":3:573 */ swap9 pop /* "yul_stack_opt/input.sol":98:99 */ - dup1 - /* "yul_stack_opt/input.sol":503:510 */ + dup16 + /* "yul_stack_opt/input.sol":3:573 */ swap8 pop /* "yul_stack_opt/input.sol":98:99 */ - dup1 - /* "yul_stack_opt/input.sol":513:520 */ + dup16 + /* "yul_stack_opt/input.sol":3:573 */ swap7 pop /* "yul_stack_opt/input.sol":98:99 */ - dup1 - /* "yul_stack_opt/input.sol":523:530 */ + dup16 + /* "yul_stack_opt/input.sol":3:573 */ swap6 pop /* "yul_stack_opt/input.sol":98:99 */ - dup1 - /* "yul_stack_opt/input.sol":533:540 */ + dup16 + /* "yul_stack_opt/input.sol":3:573 */ swap5 pop /* "yul_stack_opt/input.sol":98:99 */ - dup1 - /* "yul_stack_opt/input.sol":543:550 */ + dup16 + /* "yul_stack_opt/input.sol":3:573 */ swap4 pop /* "yul_stack_opt/input.sol":98:99 */ - dup1 - /* "yul_stack_opt/input.sol":553:560 */ - swap3 - pop - /* "yul_stack_opt/input.sol":98:99 */ - dup1 - /* "yul_stack_opt/input.sol":563:570 */ + dup16 + /* "yul_stack_opt/input.sol":3:573 */ swap2 pop + /* "yul_stack_opt/input.sol":98:99 */ + dup16 + /* "yul_stack_opt/input.sol":3:573 */ + swap1 pop - /* "yul_stack_opt/input.sol":85:573 */ tag_5: swap1 swap2 @@ -283,5 +285,6 @@ tag_5: swap13 swap14 swap15 + swap16 jump // out tag_4: diff --git a/test/libsolidity/gasTests/abiv2_optimised.sol b/test/libsolidity/gasTests/abiv2_optimised.sol index 47eaeaceb..fe3a859b7 100644 --- a/test/libsolidity/gasTests/abiv2_optimised.sol +++ b/test/libsolidity/gasTests/abiv2_optimised.sol @@ -17,9 +17,9 @@ contract C { // optimize-yul: true // ---- // creation: -// codeDepositCost: 614600 -// executionCost: 651 -// totalCost: 615251 +// codeDepositCost: 597000 +// executionCost: 632 +// totalCost: 597632 // external: // a(): 1029 // b(uint256): 2084 diff --git a/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul b/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul index 56cac2704..a5194457a 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul @@ -9,22 +9,25 @@ // { // { // let _1 := 7 -// let a_6 := 3 -// let x_7 := 0 -// x_7 := add(a_6, a_6) -// let b_8 := x_7 -// let c_9 := _1 -// let y_10 := 0 -// y_10 := mul(mload(c_9), f(b_8)) -// let y_1 := y_10 +// let a_8 := 3 +// let x_9 := 0 +// x_9 := add(a_8, a_8) +// let b_10 := x_9 +// let c_11 := _1 +// let y_12 := 0 +// let a_6_13 := b_10 +// let x_7_14 := 0 +// x_7_14 := add(a_6_13, a_6_13) +// y_12 := mul(mload(c_11), x_7_14) +// let y_1 := y_12 // } // function f(a) -> x // { x := add(a, a) } // function g(b, c) -> y // { -// let a_13 := b -// let x_14 := 0 -// x_14 := add(a_13, a_13) -// y := mul(mload(c), x_14) +// let a_6 := b +// let x_7 := 0 +// x_7 := add(a_6, a_6) +// y := mul(mload(c), x_7) // } // } diff --git a/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul b/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul index df3119103..14e977dd3 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul @@ -26,20 +26,14 @@ // step: fullInliner // // { -// { -// let x_8 := 100 -// mstore(0, x_8) -// mstore(7, h()) -// g(10) -// mstore(1, x_8) -// } +// { f(100) } // function f(x) // { // mstore(0, x) -// let t_14 := 0 -// t_14 := 2 -// mstore(7, t_14) -// let x_1_15 := 10 +// let t_8 := 0 +// t_8 := 2 +// mstore(7, t_8) +// let x_1_9 := 10 // f(1) // mstore(1, x) // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul b/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul index 06eae9176..44183b555 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul @@ -473,22 +473,22 @@ // let i := _1 // for { } lt(i, length) { i := add(i, 1) } // { -// abi_encode_t_array$_C_memory(mload(srcPtr), pos) +// let _3 := mload(srcPtr) +// let pos_1 := pos +// let srcPtr_1 := _3 +// let i_1 := _1 +// for { } lt(i_1, 0x3) { i_1 := add(i_1, 1) } +// { +// mstore(pos_1, and(mload(srcPtr_1), sub(shl(160, 1), 1))) +// srcPtr_1 := add(srcPtr_1, 0x20) +// pos_1 := add(pos_1, 0x20) +// } // srcPtr := add(srcPtr, 0x20) // pos := add(pos, 0x60) // } -// let _3 := mload(64) -// let _4 := mload(0x20) -// if slt(sub(_3, _4), 128) { revert(_1, _1) } -// let offset := calldataload(add(_4, 64)) -// let _5 := 0xffffffffffffffff -// if gt(offset, _5) { revert(_1, _1) } -// let value2 := abi_decode_t_array$_t_uint256_$dyn(add(_4, offset), _3) -// let offset_1 := calldataload(add(_4, 0x60)) -// if gt(offset_1, _5) { revert(_1, _1) } -// let value3 := abi_decode_t_array$_t_array$_t_uint256_memory_$dyn(add(_4, offset_1), _3) -// sstore(calldataload(_4), calldataload(add(_4, 0x20))) -// sstore(value2, value3) +// let a, b, c, d := abi_decode_uint256t_uint256t_array$_t_uint256_$dynt_array$_t_array$_t_uint256_memory_$dyn(mload(0x20), mload(64)) +// sstore(a, b) +// sstore(c, d) // sstore(_1, pos) // } // function abi_decode_t_array$_t_array$_t_uint256_memory_$dyn(offset, end) -> array @@ -508,14 +508,13 @@ // for { } lt(i, length) { i := add(i, 1) } // { // if iszero(slt(add(src, _1), end)) { revert(0, 0) } -// let _4 := 0x2 -// let dst_1 := allocateMemory(array_allocation_size_t_array$_t_uint256_memory(_4)) +// let dst_1 := allocateMemory(_3) // let dst_2 := dst_1 // let src_1 := src -// let _5 := add(src, _3) -// if gt(_5, end) { revert(0, 0) } +// let _4 := add(src, _3) +// if gt(_4, end) { revert(0, 0) } // let i_1 := 0 -// for { } lt(i_1, _4) { i_1 := add(i_1, 1) } +// for { } lt(i_1, 0x2) { i_1 := add(i_1, 1) } // { // mstore(dst_1, calldataload(src_1)) // dst_1 := add(dst_1, _2) @@ -523,39 +522,38 @@ // } // mstore(dst, dst_2) // dst := add(dst, _2) -// src := _5 +// src := _4 // } // } -// function abi_decode_t_array$_t_uint256_$dyn(offset, end) -> array +// function abi_decode_uint256t_uint256t_array$_t_uint256_$dynt_array$_t_array$_t_uint256_memory_$dyn(headStart, dataEnd) -> value0, value1, value2, value3 // { -// if iszero(slt(add(offset, 0x1f), end)) { revert(array, array) } -// let length := calldataload(offset) -// array := allocateMemory(array_allocation_size_t_array$_t_address_$dyn_memory(length)) -// let dst := array -// mstore(array, length) -// let _1 := 0x20 -// dst := add(array, _1) -// let src := add(offset, _1) -// if gt(add(add(offset, mul(length, _1)), _1), end) { revert(0, 0) } -// let i := 0 +// if slt(sub(dataEnd, headStart), 128) { revert(value2, value2) } +// value0 := calldataload(headStart) +// let _1 := 32 +// value1 := calldataload(add(headStart, _1)) +// let offset := calldataload(add(headStart, 64)) +// let _2 := 0xffffffffffffffff +// if gt(offset, _2) { revert(value2, value2) } +// let _3 := add(headStart, offset) +// if iszero(slt(add(_3, 0x1f), dataEnd)) { revert(value2, value2) } +// let length := calldataload(_3) +// let dst := allocateMemory(array_allocation_size_t_array$_t_address_$dyn_memory(length)) +// let dst_1 := dst +// mstore(dst, length) +// dst := add(dst, _1) +// let src := add(_3, _1) +// if gt(add(add(_3, mul(length, _1)), _1), dataEnd) { revert(value2, value2) } +// let i := value2 // for { } lt(i, length) { i := add(i, 1) } // { // mstore(dst, calldataload(src)) // dst := add(dst, _1) // src := add(src, _1) // } -// } -// function abi_encode_t_array$_C_memory(value, pos) -// { -// let srcPtr := value -// let i := 0 -// for { } lt(i, 0x3) { i := add(i, 1) } -// { -// mstore(pos, and(mload(srcPtr), sub(shl(160, 1), 1))) -// let _1 := 0x20 -// srcPtr := add(srcPtr, _1) -// pos := add(pos, _1) -// } +// value2 := dst_1 +// let offset_1 := calldataload(add(headStart, 96)) +// if gt(offset_1, _2) { revert(value3, value3) } +// value3 := abi_decode_t_array$_t_array$_t_uint256_memory_$dyn(add(headStart, offset_1), dataEnd) // } // function allocateMemory(size) -> memPtr // { @@ -569,9 +567,4 @@ // if gt(length, 0xffffffffffffffff) { revert(size, size) } // size := add(mul(length, 0x20), 0x20) // } -// function array_allocation_size_t_array$_t_uint256_memory(length) -> size -// { -// if gt(length, 0xffffffffffffffff) { revert(size, size) } -// size := mul(length, 0x20) -// } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul b/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul index b417991c2..fe1ff29eb 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul @@ -49,7 +49,7 @@ // sstore(not(gcd(10, 15)), 1) // sstore(0, 0) // sstore(2, 1) -// extcodecopy(1, msize(), 1, 1) +// pop(foo_singlereturn_1_78_308(calldataload(0), calldataload(3))) // sstore(0, 0) // sstore(3, 1) // } @@ -59,4 +59,6 @@ // case 0 { out := _a } // default { out := gcd(_b, mod(_a, _b)) } // } +// function foo_singlereturn_1_78_308(in, in_1) -> out +// { extcodecopy(1, msize(), 1, 1) } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner.yul b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner.yul index 8fb84fb49..42d5516d8 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner.yul @@ -17,15 +17,18 @@ // // { // { -// let out1, out2 := foo(sload(32)) -// sstore(0, out1) -// sstore(0, out2) -// let out1_1, out2_1 := foo(sload(8)) +// let _1 := sload(32) +// let x, y := foo_21_70(sload(0), _1) +// sstore(0, x) +// sstore(0, y) +// let x_1, y_1 := foo_21_70(_1, sload(8)) // } -// function foo(b) -> out1, out2 +// function foo_21_70(a, b) -> out1, out2 // { -// out1 := sload(mload(32)) -// out2 := add(out1, 1) -// extcodecopy(out1, out2, 1, b) +// let out1_1 := sload(mload(32)) +// let out2_1 := add(out1_1, 1) +// extcodecopy(out1_1, out2_1, 1, b) +// out1 := out1_1 +// out2 := out2_1 // } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul index 47635e415..b51a7ed1c 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul @@ -15,19 +15,15 @@ // // { // { -// f() -// sstore(0, 1) -// f() -// sstore(0, 1) -// f() -// sstore(0, 1) +// sstore(f_23_88(1), 1) +// sstore(f_23_88(2), 1) +// sstore(f_23_88(3), 1) // } -// function f() +// function f_23_88(a) -> x // { // let b := 10 -// let _1 := 0 -// let a := calldataload(_1) +// let a_1 := calldataload(x) // for { } iszero(b) { b := add(b, not(0)) } -// { mstore(a, _1) } +// { mstore(a_1, x) } // } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_return.yul b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_return.yul index aed7406be..c1704921d 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_return.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_return.yul @@ -19,16 +19,18 @@ // // { // { -// let out1, out2 := foo(sload(32)) -// sstore(0, out1) -// sstore(0, out2) -// sstore(0, 0) -// let out1_1, out2_1 := foo(sload(8)) +// let _1 := sload(32) +// let x, y, z := foo_24_75(sload(0), _1) +// sstore(0, x) +// sstore(0, y) +// sstore(0, z) +// let x_1, y_1, z_1 := foo_24_75(_1, sload(8)) // } -// function foo(b) -> out1, out2 +// function foo_24_75(a, b) -> out1, out2, out3 // { -// out1 := sload(mload(32)) -// out2 := add(out1, 1) -// extcodecopy(out1, out1, 1, b) +// let out1_1 := sload(mload(32)) +// extcodecopy(out1_1, out1_1, 1, b) +// out1 := out1_1 +// out2 := add(out1_1, 1) // } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_simple.yul b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_simple.yul index a50257b2b..494c7a291 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_simple.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_simple.yul @@ -18,19 +18,28 @@ // // { // { -// f() -// sstore(0, 1) -// f() -// sstore(0, 1) -// f() -// sstore(0, 1) -// } -// function f() -// { -// mstore(calldataload(0), 0) -// sstore(1, 1) -// sstore(2, 2) -// sstore(3, 3) -// sstore(3, 3) +// let _1 := 0 +// let _2 := calldataload(_1) +// mstore(_2, _1) +// let _3 := 1 +// sstore(_3, _3) +// let _4 := 2 +// sstore(_4, _4) +// let _5 := 3 +// sstore(_5, _5) +// sstore(_5, _5) +// sstore(_1, _3) +// mstore(_2, _1) +// sstore(_3, _3) +// sstore(_4, _4) +// sstore(_5, _5) +// sstore(_5, _5) +// sstore(_1, _3) +// mstore(_2, _1) +// sstore(_3, _3) +// sstore(_4, _4) +// sstore(_5, _5) +// sstore(_5, _5) +// sstore(_1, _3) // } // }