More logic about control flow with continue and about finalize. Remove BlockScope.

This commit is contained in:
chriseth
2019-03-27 22:16:31 +01:00
parent a1ec49409d
commit 91f96c299e
10 changed files with 356 additions and 103 deletions
@@ -1,20 +1,22 @@
{
// Cannot be removed, because we might run the loop only once
let x := 1
for { } calldataload(0) { }
{
if callvalue() {
x := 2 // is preserved because of break stmt below.
break
}
x := 3
}
mstore(x, 0x42)
let x
// Cannot be removed, because we might skip the loop
x := 1
for { } calldataload(0) { }
{
if callvalue() {
x := 2 // is preserved because of break stmt below.
break
}
x := 3
}
mstore(x, 0x42)
}
// ----
// redundantAssignEliminator
// {
// let x := 1
// let x
// x := 1
// for {
// }
// calldataload(0)
@@ -1,21 +1,24 @@
{
// Cannot be removed, because we might run the loop only once
let x := 1
for { } calldataload(0) { }
{
x := 2 // Will not be removed as if-condition can be false.
if callvalue() {
x := 3
continue
}
mstore(x, 2)
}
x := 3
let x
// Can be removed, because x is reassigned after the loop
x := 1
for { } calldataload(0) { }
{
x := 2 // Will not be removed as if-condition can be false.
if callvalue() {
// This can be removed because x is overwritten both after the
// loop at at the start of the next iteration.
x := 3
continue
}
mstore(x, 2)
}
x := 3
}
// ----
// redundantAssignEliminator
// {
// let x := 1
// let x
// for {
// }
// calldataload(0)
@@ -25,7 +28,6 @@
// x := 2
// if callvalue()
// {
// x := 3
// continue
// }
// mstore(x, 2)
@@ -1,20 +1,22 @@
{
// Cannot be removed, because we might run the loop only once
let x := 1
for { } calldataload(0) { }
{
if callvalue() {
x := 2 // is preserved because of continue stmt below.
continue
}
x := 3
}
mstore(x, 0x42)
let x
// Cannot be removed, because we might skip the loop
x := 1
for { } calldataload(0) { }
{
if callvalue() {
x := 2 // is preserved because of continue stmt below.
continue
}
x := 3
}
mstore(x, 0x42)
}
// ----
// redundantAssignEliminator
// {
// let x := 1
// let x
// x := 1
// for {
// }
// calldataload(0)
@@ -1,19 +1,20 @@
{
// Cannot be removed, because we might run the loop only once
let x := 1
for { } calldataload(0) { mstore(x, 0x42) }
{
if callvalue() {
x := 2 // is preserved because of continue stmt below.
continue
}
x := 3
}
let x
// Can be removed, because x is not used after the loop.
x := 1
for { } calldataload(0) { mstore(x, 0x42) }
{
if callvalue() {
x := 2 // is preserved because of continue stmt below.
continue
}
x := 3
}
}
// ----
// redundantAssignEliminator
// {
// let x := 1
// let x
// for {
// }
// calldataload(0)
@@ -0,0 +1,44 @@
{
let x := 1
for { } calldataload(0) { }
{
// This will go out of scope at the end of the block,
// but the continue/break statements still refer to it.
{
let y := 9
if callvalue() {
y := 2 // will be removed
break
}
if eq(callvalue(), 3) {
y := 12 // will be removed
continue
}
}
}
mstore(x, 0x42)
}
// ----
// redundantAssignEliminator
// {
// let x := 1
// for {
// }
// calldataload(0)
// {
// }
// {
// {
// let y := 9
// if callvalue()
// {
// break
// }
// if eq(callvalue(), 3)
// {
// continue
// }
// }
// }
// mstore(x, 0x42)
// }
@@ -0,0 +1,74 @@
{
let x := 1
let y := 1
let z := 1
for { } calldataload(0) { mstore(x, 2) mstore(z, 2) }
{
y := 3
switch callvalue()
case 0 {
x := 2
y := 2
z := 2
break
}
case 1 {
x := 3
y := 3
z := 3
continue
}
case 2 {
x := 4
y := 4
z := 4
break
}
case 3 {
x := 5
y := 5
z := 5
continue
}
mstore(y, 9)
}
mstore(x, 0x42)
}
// ----
// redundantAssignEliminator
// {
// let x := 1
// let y := 1
// let z := 1
// for {
// }
// calldataload(0)
// {
// mstore(x, 2)
// mstore(z, 2)
// }
// {
// y := 3
// switch callvalue()
// case 0 {
// x := 2
// break
// }
// case 1 {
// x := 3
// z := 3
// continue
// }
// case 2 {
// x := 4
// break
// }
// case 3 {
// x := 5
// z := 5
// continue
// }
// mstore(y, 9)
// }
// mstore(x, 0x42)
// }
@@ -0,0 +1,76 @@
{
let x := 1
let y := 1
let a := 7
let b := 9
for { } calldataload(0) { }
{
y := 9
mstore(a, 7)
if callvalue() {
x := 2
for {} calldataload(1) {}
{
a := 2 // can be removed
if eq(x, 3) {
b := 3 // cannot be removed
y := 2 // will be removed
continue
}
}
mstore(b, 2)
break
}
if eq(callvalue(), 3) {
x := 12
y := 12
continue
}
x := 3
mstore(y, 3)
}
mstore(x, 0x42)
}
// ----
// redundantAssignEliminator
// {
// let x := 1
// let y := 1
// let a := 7
// let b := 9
// for {
// }
// calldataload(0)
// {
// }
// {
// y := 9
// mstore(a, 7)
// if callvalue()
// {
// x := 2
// for {
// }
// calldataload(1)
// {
// }
// {
// if eq(x, 3)
// {
// b := 3
// continue
// }
// }
// mstore(b, 2)
// break
// }
// if eq(callvalue(), 3)
// {
// x := 12
// continue
// }
// x := 3
// mstore(y, 3)
// }
// mstore(x, 0x42)
// }
@@ -0,0 +1,52 @@
{
let x := 1
let y := 1
for { } calldataload(0) { }
{
y := 9
if callvalue() {
x := 2
y := 2 // will be removed
break
x := 7 // after break, we start with fresh state.
}
if eq(callvalue(), 3) {
x := 12
y := 12 // will be removed
continue
x := 17 // after continue, we start with fresh state.
y := 9
}
x := 3
mstore(y, 3)
}
mstore(x, 0x42)
}
// ----
// redundantAssignEliminator
// {
// let x := 1
// let y := 1
// for {
// }
// calldataload(0)
// {
// }
// {
// y := 9
// if callvalue()
// {
// x := 2
// break
// }
// if eq(callvalue(), 3)
// {
// x := 12
// continue
// y := 9
// }
// x := 3
// mstore(y, 3)
// }
// mstore(x, 0x42)
// }