mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Prototype of a full SSA transformation.
This commit is contained in:
@@ -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)) }
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user