Prototype of a full SSA transformation.

This commit is contained in:
Daniel Kirchner
2021-01-07 12:50:13 +01:00
parent 591f04e41c
commit dab68e6254
36 changed files with 1263 additions and 3 deletions
+34
View File
@@ -40,6 +40,8 @@
#include <libyul/optimiser/FunctionHoister.h>
#include <libyul/optimiser/ExpressionInliner.h>
#include <libyul/optimiser/FullInliner.h>
#include <libyul/optimiser/FullSSAReverse.h>
#include <libyul/optimiser/FullSSATransform.h>
#include <libyul/optimiser/ForLoopConditionIntoBody.h>
#include <libyul/optimiser/ForLoopConditionOutOfBody.h>
#include <libyul/optimiser/ForLoopInitRewriter.h>
@@ -168,6 +170,38 @@ TestCase::TestResult YulOptimizerTest::run(ostream& _stream, string const& _line
disambiguate();
ForLoopInitRewriter::run(*m_context, *m_object->code);
}
else if (m_optimizerStep == "fullSSATransform")
{
disambiguate();
ForLoopInitRewriter::run(*m_context, *m_object->code);
ForLoopConditionIntoBody::run(*m_context, *m_object->code);
FullSSATransform::run(*m_context, *m_object->code);
}
else if (m_optimizerStep == "fullSSAReverse")
{
disambiguate();
FullSSAReverse::run(*m_context, *m_object->code);
ForLoopConditionOutOfBody::run(*m_context, *m_object->code);
}
else if (m_optimizerStep == "fullSSAandBack")
{
disambiguate();
ForLoopInitRewriter::run(*m_context, *m_object->code);
ForLoopConditionIntoBody::run(*m_context, *m_object->code);
FullSSATransform::run(*m_context, *m_object->code);
UnusedPruner::run(*m_context, *m_object->code);
FullSSAReverse::run(*m_context, *m_object->code);
RedundantAssignEliminator::run(*m_context, *m_object->code);
CommonSubexpressionEliminator::run(*m_context, *m_object->code);
Rematerialiser::run(*m_context, *m_object->code);
UnusedPruner::run(*m_context, *m_object->code);
RedundantAssignEliminator::run(*m_context, *m_object->code);
ForLoopConditionOutOfBody::run(*m_context, *m_object->code);
}
else if (m_optimizerStep == "commonSubexpressionEliminator")
{
disambiguate();
@@ -0,0 +1,13 @@
{
phi_store("a", 23)
let a := 42
sstore(0, phi_load("a"))
}
// ----
// step: fullSSAReverse
//
// {
// let a_1 := 23
// let a := 42
// sstore(0, a_1)
// }
@@ -0,0 +1,13 @@
{
phi_store("a", 42)
let b := 0
phi_store("b", 23)
}
// ----
// step: fullSSAReverse
//
// {
// let a_1 := 42
// let b := 0
// let b_2 := 23
// }
@@ -0,0 +1,28 @@
{
let a := calldataload(42)
for {} a { sstore(1, a) } {
a := sub(a,1)
}
sstore(0, a)
}
// ----
// step: fullSSATransform
//
// {
// let a := calldataload(42)
// phi_store("a", a)
// for { }
// phi_load("a")
// {
// let a_3 := phi_load("a")
// sstore(1, a_3)
// phi_store("a", a_3)
// }
// {
// let a_1 := phi_load("a")
// let a_2 := sub(a_1, 1)
// phi_store("a", a_2)
// }
// let a_4 := phi_load("a")
// sstore(0, a_4)
// }
@@ -0,0 +1,40 @@
{
let a := calldataload(42)
for {} a { sstore(1, a) } {
a := sub(a,1)
if lt(a,4) { continue }
if eq(a,42) { break }
}
sstore(0, a)
}
// ----
// step: fullSSATransform
//
// {
// let a := calldataload(42)
// phi_store("a", a)
// for { }
// phi_load("a")
// {
// let a_3 := phi_load("a")
// sstore(1, a_3)
// phi_store("a", a_3)
// }
// {
// let a_1 := phi_load("a")
// let a_2 := sub(a_1, 1)
// if lt(a_2, 4)
// {
// phi_store("a", a_2)
// continue
// }
// if eq(a_2, 42)
// {
// phi_store("a", a_2)
// break
// }
// phi_store("a", a_2)
// }
// let a_4 := phi_load("a")
// sstore(0, a_4)
// }
@@ -0,0 +1,36 @@
{
let a := 0
for {} lt(a, 10) {
// checked increment
if eq(a, sub(0, 1)) { revert(0, 0) }
a := add(a, 1)
} {
sstore(a, 42)
}
}
// ----
// step: fullSSATransform
//
// {
// let a := 0
// phi_store("a", a)
// for { }
// true
// {
// let a_2 := phi_load("a")
// if eq(a_2, sub(0, 1)) { revert(0, 0) }
// let a_3 := add(a_2, 1)
// phi_store("a", a_3)
// }
// {
// let a_1 := phi_load("a")
// if iszero(lt(a_1, 10))
// {
// phi_store("a", a_1)
// break
// }
// sstore(a_1, 42)
// phi_store("a", a_1)
// }
// let a_4 := phi_load("a")
// }
@@ -0,0 +1,41 @@
{
let a := calldataload(42)
for {} a { for {} a { a := sub(a, 1) } { sstore(1, a) }} {
a := sub(a,1)
}
sstore(0, a)
}
// ----
// step: fullSSATransform
//
// {
// let a := calldataload(42)
// phi_store("a", a)
// for { }
// phi_load("a")
// {
// let a_3 := phi_load("a")
// phi_store("a_3", a_3)
// for { }
// phi_load("a_3")
// {
// let a_5 := phi_load("a_3")
// let a_6 := sub(a_5, 1)
// phi_store("a_3", a_6)
// }
// {
// let a_4 := phi_load("a_3")
// sstore(1, a_4)
// phi_store("a_3", a_4)
// }
// let a_7 := phi_load("a_3")
// phi_store("a", a_7)
// }
// {
// let a_1 := phi_load("a")
// let a_2 := sub(a_1, 1)
// phi_store("a", a_2)
// }
// let a_8 := phi_load("a")
// sstore(0, a_8)
// }
@@ -0,0 +1,25 @@
{
function f(a, b) -> c {
c := calldataload(0)
sstore(0, a)
a := b
sstore(1, b)
c := calldataload(1)
}
sstore(2, f(calldataload(2), calldataload(3)))
}
// ----
// step: fullSSATransform
//
// {
// function f(a, b) -> c
// {
// let c_1 := calldataload(0)
// sstore(0, a)
// let a_2 := b
// sstore(1, b)
// let c_3 := calldataload(1)
// phi_store("c", c_3)
// }
// sstore(2, f(calldataload(2), calldataload(3)))
// }
@@ -0,0 +1,48 @@
{
function f(a, b) -> c {
c := calldataload(0)
for {} gt(a,0) { a := sub(a,b) } {
c := calldataload(a)
}
c := calldataload(c)
}
sstore(2, f(calldataload(2), calldataload(3)))
}
// ----
// step: fullSSATransform
//
// {
// function f(a, b) -> c
// {
// let c_1 := calldataload(0)
// phi_store("c_1", c_1)
// phi_store("a", a)
// for { }
// true
// {
// let c_5 := phi_load("c_1")
// let a_6 := phi_load("a")
// let a_7 := sub(a_6, b)
// phi_store("c_1", c_5)
// phi_store("a", a_7)
// }
// {
// let c_2 := phi_load("c_1")
// let a_3 := phi_load("a")
// if iszero(gt(a_3, 0))
// {
// phi_store("c_1", c_2)
// phi_store("a", a_3)
// break
// }
// let c_4 := calldataload(a_3)
// phi_store("c_1", c_4)
// phi_store("a", a_3)
// }
// let c_8 := phi_load("c_1")
// let a_9 := phi_load("a")
// let c_10 := calldataload(c_8)
// phi_store("c", c_10)
// }
// sstore(2, f(calldataload(2), calldataload(3)))
// }
@@ -0,0 +1,56 @@
{
function f(a, b) -> c {
c := calldataload(0)
for {} gt(a,0) { a := sub(a,b) } {
c := calldataload(a)
if lt(c, add(b, a)) {
leave
}
}
c := calldataload(c)
}
sstore(2, f(calldataload(2), calldataload(3)))
}
// ----
// step: fullSSATransform
//
// {
// function f(a, b) -> c
// {
// let c_1 := calldataload(0)
// phi_store("c_1", c_1)
// phi_store("a", a)
// for { }
// true
// {
// let c_5 := phi_load("c_1")
// let a_6 := phi_load("a")
// let a_7 := sub(a_6, b)
// phi_store("c_1", c_5)
// phi_store("a", a_7)
// }
// {
// let c_2 := phi_load("c_1")
// let a_3 := phi_load("a")
// if iszero(gt(a_3, 0))
// {
// phi_store("c_1", c_2)
// phi_store("a", a_3)
// break
// }
// let c_4 := calldataload(a_3)
// if lt(c_4, add(b, a_3))
// {
// phi_store("c", c_4)
// leave
// }
// phi_store("c_1", c_4)
// phi_store("a", a_3)
// }
// let c_8 := phi_load("c_1")
// let a_9 := phi_load("a")
// let c_10 := calldataload(c_8)
// phi_store("c", c_10)
// }
// sstore(2, f(calldataload(2), calldataload(3)))
// }
@@ -0,0 +1,21 @@
{
let a := 1
if calldataload(42) {
a := 2
}
sstore(0, a)
}
// ----
// step: fullSSATransform
//
// {
// let a := 1
// phi_store("a", a)
// if calldataload(42)
// {
// let a_1 := 2
// phi_store("a", a_1)
// }
// let a_2 := phi_load("a")
// sstore(0, a_2)
// }
@@ -0,0 +1,19 @@
{
let a := 42
if calldataload(42) { a := 23 }
sstore(0, 42)
}
// ----
// step: fullSSATransform
//
// {
// let a := 42
// phi_store("a", a)
// if calldataload(42)
// {
// let a_1 := 23
// phi_store("a", a_1)
// }
// let a_2 := phi_load("a")
// sstore(0, 42)
// }
@@ -0,0 +1,31 @@
{
let a := 1
if calldataload(42) {
a := 2
}
if calldataload(a) {
a := add(a, 4)
}
sstore(0, a)
}
// ----
// step: fullSSATransform
//
// {
// let a := 1
// phi_store("a", a)
// if calldataload(42)
// {
// let a_1 := 2
// phi_store("a", a_1)
// }
// let a_2 := phi_load("a")
// phi_store("a_2", a_2)
// if calldataload(a_2)
// {
// let a_3 := add(a_2, 4)
// phi_store("a_2", a_3)
// }
// let a_4 := phi_load("a_2")
// sstore(0, a_4)
// }
@@ -0,0 +1,13 @@
{
let a := 1
a := 2
sstore(0, a)
}
// ----
// step: fullSSATransform
//
// {
// let a := 1
// let a_1 := 2
// sstore(0, a_1)
// }
@@ -0,0 +1,35 @@
{
let a := 1
switch a
case 1
{
a := calldataload(1)
}
case 2
{
a := calldataload(a)
}
default
{
}
sstore(0, a)
}
// ----
// step: fullSSATransform
//
// {
// let a := 1
// phi_store("a", a)
// switch a
// case 1 {
// let a_1 := calldataload(1)
// phi_store("a", a_1)
// }
// case 2 {
// let a_2 := calldataload(a)
// phi_store("a", a_2)
// }
// default { phi_store("a", a) }
// let a_3 := phi_load("a")
// sstore(0, a_3)
// }
@@ -0,0 +1,16 @@
{
let a := calldataload(42)
for {} a { sstore(1, a) } {
a := sub(a,1)
}
sstore(0, a)
}
// ----
// step: fullSSAandBack
//
// {
// let a_5 := calldataload(42)
// for { } a_5 { sstore(1, a_5) }
// { a_5 := sub(a_5, 1) }
// sstore(0, a_5)
// }
@@ -0,0 +1,31 @@
{
let a := calldataload(42)
for {} a { sstore(1, a) } {
a := sub(a,1)
if lt(a,4) { continue }
if eq(a,42) { break }
}
sstore(0, a)
}
// ----
// step: fullSSAandBack
//
// {
// let a_5 := calldataload(42)
// for { } a_5 { sstore(1, a_5) }
// {
// let a_2 := sub(a_5, 1)
// if lt(a_2, 4)
// {
// a_5 := a_2
// continue
// }
// if eq(a_2, 42)
// {
// a_5 := a_2
// break
// }
// a_5 := a_2
// }
// sstore(0, a_5)
// }
@@ -0,0 +1,23 @@
{
let a := calldataload(42)
for {} a { for {} a { a := sub(a, 1) } { sstore(1, a) }} {
a := sub(a,1)
}
sstore(0, a)
}
// ----
// step: fullSSAandBack
//
// {
// let a_9 := calldataload(42)
// for { }
// a_9
// {
// let a_3_10 := a_9
// for { } a_3_10 { a_3_10 := sub(a_3_10, 1) }
// { sstore(1, a_3_10) }
// a_9 := a_3_10
// }
// { a_9 := sub(a_9, 1) }
// sstore(0, a_9)
// }
@@ -0,0 +1,22 @@
{
function f(a, b) -> c {
c := calldataload(0)
sstore(0, a)
a := b
sstore(1, b)
c := calldataload(1)
}
sstore(2, f(calldataload(2), calldataload(3)))
}
// ----
// step: fullSSAandBack
//
// {
// function f(a, b) -> c_4
// {
// sstore(0, a)
// sstore(1, b)
// c_4 := calldataload(1)
// }
// sstore(2, f(calldataload(2), calldataload(3)))
// }
@@ -0,0 +1,24 @@
{
function f(a, b) -> c {
c := calldataload(0)
for {} gt(a,0) { a := sub(a,b) } {
c := calldataload(a)
}
c := calldataload(c)
}
sstore(2, f(calldataload(2), calldataload(3)))
}
// ----
// step: fullSSAandBack
//
// {
// function f(a, b) -> c_11
// {
// let c_1_12 := calldataload(0)
// let a_13 := a
// for { } gt(a_13, c_11) { a_13 := sub(a_13, b) }
// { c_1_12 := calldataload(a_13) }
// c_11 := calldataload(c_1_12)
// }
// sstore(2, f(calldataload(2), calldataload(3)))
// }
@@ -0,0 +1,35 @@
{
function f(a, b) -> c {
c := calldataload(0)
for {} gt(a,0) { a := sub(a,b) } {
c := calldataload(a)
if lt(c, add(b, a)) {
leave
}
}
c := calldataload(c)
}
sstore(2, f(calldataload(2), calldataload(3)))
}
// ----
// step: fullSSAandBack
//
// {
// function f(a, b) -> c_11
// {
// let c_1_12 := calldataload(0)
// let a_13 := a
// for { } gt(a_13, 0) { a_13 := sub(a_13, b) }
// {
// let c_4 := calldataload(a_13)
// if lt(c_4, add(b, a_13))
// {
// c_11 := c_4
// leave
// }
// c_1_12 := c_4
// }
// c_11 := calldataload(c_1_12)
// }
// sstore(2, f(calldataload(2), calldataload(3)))
// }
@@ -0,0 +1,15 @@
{
let a := 1
if calldataload(42) {
a := 2
}
sstore(0, a)
}
// ----
// step: fullSSAandBack
//
// {
// let a_3 := 1
// if calldataload(42) { a_3 := 2 }
// sstore(0, a_3)
// }
@@ -0,0 +1,20 @@
{
let a := 1
if calldataload(42) {
a := 2
}
if calldataload(a) {
a := add(a, 4)
}
sstore(0, a)
}
// ----
// step: fullSSAandBack
//
// {
// let a_5 := 1
// if calldataload(42) { a_5 := 2 }
// let a_2_6 := a_5
// if calldataload(a_5) { a_2_6 := add(a_5, 4) }
// sstore(0, a_2_6)
// }
@@ -0,0 +1,9 @@
{
let a := calldataload(0)
a := calldataload(1)
sstore(0, a)
}
// ----
// step: fullSSAandBack
//
// { sstore(0, calldataload(1)) }
+1 -1
View File
@@ -138,7 +138,7 @@ BOOST_AUTO_TEST_CASE(output_operator_should_create_concise_and_unambiguous_strin
BOOST_TEST(chromosome.length() == allSteps.size());
BOOST_TEST(chromosome.optimisationSteps() == allSteps);
BOOST_TEST(toString(chromosome) == "flcCUnDvejsxIOoighTLMRrmVatpud");
BOOST_TEST(toString(chromosome) == "flcCUnDvejsxIOoiZzghTLMRrmVatpud");
}
BOOST_AUTO_TEST_CASE(optimisationSteps_should_translate_chromosomes_genes_to_optimisation_step_names)