diff --git a/libyul/optimiser/Rematerialiser.cpp b/libyul/optimiser/Rematerialiser.cpp index c148778f9..02ac48e96 100644 --- a/libyul/optimiser/Rematerialiser.cpp +++ b/libyul/optimiser/Rematerialiser.cpp @@ -81,7 +81,7 @@ void Rematerialiser::visit(Expression& _e) if ( (refs <= 1 && m_variableLoopDepth.at(name) == m_loopDepth) || cost == 0 || - (refs <= 5 && cost <= 1) || + (refs <= 5 && cost <= 1 && m_loopDepth == 0) || m_varsToAlwaysRematerialize.count(name) ) { diff --git a/libyul/optimiser/Rematerialiser.h b/libyul/optimiser/Rematerialiser.h index 51c5eb4cf..1316f0373 100644 --- a/libyul/optimiser/Rematerialiser.h +++ b/libyul/optimiser/Rematerialiser.h @@ -33,7 +33,7 @@ namespace solidity::yul * - the variable is referenced exactly once (and definition-to-reference does not cross a loop boundary) * - the value is extremely cheap ("cost" of zero like ``caller()``) * - the variable is referenced at most 5 times and the value is rather cheap - * ("cost" of at most 1 like a constant up to 0xff) + * ("cost" of at most 1 like a constant up to 0xff) and we are not in a loop * * Prerequisite: Disambiguator, ForLoopInitRewriter. */ diff --git a/test/libsolidity/gasTests/abiv2_optimised.sol b/test/libsolidity/gasTests/abiv2_optimised.sol index 92323fc68..b1bc1ff5d 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: 605800 +// codeDepositCost: 603000 // executionCost: 638 -// totalCost: 606438 +// totalCost: 603638 // external: // a(): 1029 // b(uint256): 2084 diff --git a/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul b/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul index 0d37cf1b9..4557c1889 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul @@ -492,34 +492,37 @@ // } // function abi_decode_t_array$_t_array$_t_uint256_$2_memory_$dyn_memory_ptr(offset, end) -> array // { -// if iszero(slt(add(offset, 0x1f), end)) { revert(array, array) } +// let _1 := 0x1f +// if iszero(slt(add(offset, _1), 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, 0x40)), _1), end) { revert(0, 0) } +// let _2 := 0x20 +// dst := add(array, _2) +// let src := add(offset, _2) +// let _3 := 0x40 +// if gt(add(add(offset, mul(length, _3)), _2), end) { revert(0, 0) } // let i := 0 // for { } lt(i, length) { i := add(i, 1) } // { -// if iszero(slt(add(src, 0x1f), end)) { revert(0, 0) } -// let dst_1 := allocateMemory(array_allocation_size_t_array$_t_uint256_$2_memory(0x2)) +// if iszero(slt(add(src, _1), end)) { revert(0, 0) } +// let _4 := 0x2 +// let dst_1 := allocateMemory(array_allocation_size_t_array$_t_uint256_$2_memory(_4)) // let dst_2 := dst_1 // let src_1 := src -// let _2 := add(src, 0x40) -// if gt(_2, end) { revert(0, 0) } +// let _5 := add(src, _3) +// if gt(_5, end) { revert(0, 0) } // let i_1 := 0 -// for { } lt(i_1, 0x2) { i_1 := add(i_1, 1) } +// for { } lt(i_1, _4) { i_1 := add(i_1, 1) } // { // mstore(dst_1, calldataload(src_1)) -// dst_1 := add(dst_1, _1) -// src_1 := add(src_1, _1) +// dst_1 := add(dst_1, _2) +// src_1 := add(src_1, _2) // } // mstore(dst, dst_2) -// dst := add(dst, _1) -// src := _2 +// dst := add(dst, _2) +// src := _5 // } // } // function abi_decode_t_array$_t_uint256_$dyn_memory_ptr(offset, end) -> array @@ -548,8 +551,9 @@ // for { } lt(i, 0x3) { i := add(i, 1) } // { // mstore(pos, and(mload(srcPtr), sub(shl(160, 1), 1))) -// srcPtr := add(srcPtr, 0x20) -// pos := add(pos, 0x20) +// let _1 := 0x20 +// srcPtr := add(srcPtr, _1) +// pos := add(pos, _1) // } // } // function allocateMemory(size) -> memPtr diff --git a/test/libyul/yulOptimizerTests/fullSuite/aztec.yul b/test/libyul/yulOptimizerTests/fullSuite/aztec.yul index 35e1bb7b3..635da72d6 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/aztec.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/aztec.yul @@ -375,7 +375,8 @@ // let i := 0 // for { } lt(i, n) { i := add(i, 0x01) } // { -// calldatacopy(add(0x300, mul(i, 0x80)), add(add(notes, mul(i, 0xc0)), 0x60), 0x80) +// let _1 := 0x80 +// calldatacopy(add(0x300, mul(i, _1)), add(add(notes, mul(i, 0xc0)), 0x60), _1) // } // mstore(0, keccak256(0x300, mul(n, 0x80))) // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/clear_after_if_continue.yul b/test/libyul/yulOptimizerTests/fullSuite/clear_after_if_continue.yul index ca6b5fec1..a9cdb84e0 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/clear_after_if_continue.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/clear_after_if_continue.yul @@ -13,7 +13,15 @@ // { // let y := mload(0x20) // let _1 := iszero(and(y, 8)) -// for { } iszero(_1) { if y { revert(0, 0) } } +// for { } +// iszero(_1) +// { +// if y +// { +// let _2 := 0 +// revert(_2, _2) +// } +// } // { // if y { continue } // sstore(1, 0) diff --git a/test/libyul/yulOptimizerTests/fullSuite/devcon_example.yul b/test/libyul/yulOptimizerTests/fullSuite/devcon_example.yul index d215bc728..314f2a363 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/devcon_example.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/devcon_example.yul @@ -25,7 +25,8 @@ // let i := sum // for { } lt(i, length) { i := add(i, 1) } // { -// sum := add(sum, calldataload(add(add(_1, mul(i, 0x20)), 0x20))) +// let _2 := 0x20 +// sum := add(sum, calldataload(add(add(_1, mul(i, _2)), _2))) // } // sstore(0, sum) // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/loopInvariantCodeMotion.yul b/test/libyul/yulOptimizerTests/fullSuite/loopInvariantCodeMotion.yul index 8b69593bb..f8fb81aa8 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/loopInvariantCodeMotion.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/loopInvariantCodeMotion.yul @@ -29,7 +29,8 @@ // let _2 := calldataload(7) // for { } lt(i, length) { i := add(i, 1) } // { -// sum := add(sum, add(calldataload(add(add(_1, mul(i, 0x20)), 0x20)), _2)) +// let _3 := 0x20 +// sum := add(sum, add(calldataload(add(add(_1, mul(i, _3)), _3)), _2)) // } // sstore(0, sum) // } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/some_refs_small_cost_loop.yul b/test/libyul/yulOptimizerTests/rematerialiser/some_refs_small_cost_loop.yul index 6c0c85831..0eeb248a6 100644 --- a/test/libyul/yulOptimizerTests/rematerialiser/some_refs_small_cost_loop.yul +++ b/test/libyul/yulOptimizerTests/rematerialiser/some_refs_small_cost_loop.yul @@ -12,6 +12,6 @@ // ---- // { // let x := 0xff -// for { } lt(0xff, 0x100) { } -// { let y := add(0xff, 1) } +// for { } lt(x, 0x100) { } +// { let y := add(x, 1) } // } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/some_refs_small_cost_nested_loop.yul b/test/libyul/yulOptimizerTests/rematerialiser/some_refs_small_cost_nested_loop.yul index 4b55fe564..c95cf5454 100644 --- a/test/libyul/yulOptimizerTests/rematerialiser/some_refs_small_cost_nested_loop.yul +++ b/test/libyul/yulOptimizerTests/rematerialiser/some_refs_small_cost_nested_loop.yul @@ -17,10 +17,10 @@ // ---- // { // let x := 0xff -// for { } lt(0xff, 0x100) { } +// for { } lt(x, 0x100) { } // { -// let y := add(0xff, 1) -// for { } lt(0xff, 0x200) { } -// { let z := mul(0xff, 2) } +// let y := add(x, 1) +// for { } lt(x, 0x200) { } +// { let z := mul(x, 2) } // } // }