Merge pull request #7801 from ethereum/tuneRemat

Tune rematerializer
This commit is contained in:
chriseth
2020-01-08 10:41:32 +01:00
committed by GitHub
16 changed files with 196 additions and 33 deletions
@@ -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
@@ -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
@@ -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)))
// }
@@ -12,7 +12,16 @@
// {
// {
// let y := mload(0x20)
// for { } and(y, 8) { if y { revert(0, 0) } }
// let _1 := iszero(and(y, 8))
// for { }
// iszero(_1)
// {
// if y
// {
// let _2 := 0
// revert(_2, _2)
// }
// }
// {
// if y { continue }
// sstore(1, 0)
@@ -21,10 +21,12 @@
// {
// let _1 := calldataload(0)
// let sum := 0
// let length := calldataload(_1)
// let i := sum
// for { } lt(i, calldataload(_1)) { i := add(i, 1) }
// 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)
// }
@@ -24,10 +24,13 @@
// {
// let _1 := calldataload(0)
// let sum := 0
// let length := calldataload(_1)
// let i := sum
// for { } lt(i, calldataload(_1)) { i := add(i, 1) }
// let _2 := calldataload(7)
// for { } lt(i, length) { i := add(i, 1) }
// {
// sum := add(sum, add(calldataload(add(add(_1, mul(i, 0x20)), 0x20)), calldataload(7)))
// let _3 := 0x20
// sum := add(sum, add(calldataload(add(add(_1, mul(i, _3)), _3)), _2))
// }
// sstore(0, sum)
// }
@@ -12,10 +12,11 @@
// ----
// {
// {
// let _1 := iszero(caller())
// for { }
// 1
// {
// for { } caller() { }
// for { } iszero(_1) { }
// { }
// mstore(192, 0)
// }
@@ -0,0 +1,28 @@
{
// Cost of rematerializating x is 1
let x := 0xff
// Although x has low cost, it is not considered for
// rematerialization because it is referenced more than 5 times
for {} lt(x, 0x100) {}
{
let y := add(x, 1)
let z := mul(x, 1)
let a := div(x, 2)
let b := mod(x, 3)
let c := sdiv(x, 4)
}
}
// ====
// step: rematerialiser
// ----
// {
// let x := 0xff
// for { } lt(x, 0x100) { }
// {
// let y := add(x, 1)
// let z := mul(x, 1)
// let a := div(x, 2)
// let b := mod(x, 3)
// let c := sdiv(x, 4)
// }
// }
@@ -0,0 +1,37 @@
{
// origin has zero cost and thus will be rematerialised,
// calldataload(0) has low cost and will not be rematerialised
let a := origin()
let b := calldataload(0)
let i := 0
let z := calldataload(9)
for {} lt(i, 10) {i := add(a, b)} {
// This will be rematerialised, because it stays inside
// the loop.
let x := calldataload(1)
mstore(9, x)
// No, because again one loop further down.
let y := calldataload(2)
for {} y {} {
// Again no.
mstore(12, z)
}
}
}
// ====
// step: rematerialiser
// ----
// {
// let a := origin()
// let b := calldataload(0)
// let i := 0
// let z := calldataload(9)
// for { } lt(i, 10) { i := add(origin(), b) }
// {
// let x := calldataload(1)
// mstore(9, calldataload(1))
// let y := calldataload(2)
// for { } y { }
// { mstore(12, z) }
// }
// }
@@ -0,0 +1,17 @@
{
// Cost of rematerializating x is 1
let x := 0xff
// Reference to x is not rematerialized because the reference is in a loop
for {} lt(x, 0x100) {}
{
let y := add(x, 1)
}
}
// ====
// step: rematerialiser
// ----
// {
// let x := 0xff
// for { } lt(x, 0x100) { }
// { let y := add(x, 1) }
// }
@@ -0,0 +1,26 @@
{
// Cost of rematerializating x is 1
let x := 0xff
// Although x has a low cost and fewer than 6 references,
// its references in a loop are not rematerialized
for {} lt(x, 0x100) {}
{
let y := add(x, 1)
for {} lt(x, 0x200) {}
{
let z := mul(x, 2)
}
}
}
// ====
// step: rematerialiser
// ----
// {
// let x := 0xff
// for { } lt(x, 0x100) { }
// {
// let y := add(x, 1)
// for { } lt(x, 0x200) { }
// { let z := mul(x, 2) }
// }
// }