From 711ed588d7dde79a82faff48d1e3354c117cf45d Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 2 Jul 2020 17:02:26 +0200 Subject: [PATCH] Require for loop init rewriter for SSA. Co-authored-by: Harikrishnan Mulackal --- libyul/optimiser/SSATransform.cpp | 8 ++--- libyul/optimiser/SSATransform.h | 2 +- test/libyul/YulOptimizerTest.cpp | 1 + .../ssaTransform/for_def_in_init.yul | 33 +++++++++++++++++++ .../ssaTransform/for_reassign_body.yul | 3 +- .../ssaTransform/for_reassign_init.yul | 20 +++-------- .../ssaTransform/for_reassign_post.yul | 3 +- .../ssaTransform/for_simple.yul | 7 ++-- 8 files changed, 49 insertions(+), 28 deletions(-) create mode 100644 test/libyul/yulOptimizerTests/ssaTransform/for_def_in_init.yul diff --git a/libyul/optimiser/SSATransform.cpp b/libyul/optimiser/SSATransform.cpp index 948a0e6a6..21165cd47 100644 --- a/libyul/optimiser/SSATransform.cpp +++ b/libyul/optimiser/SSATransform.cpp @@ -194,7 +194,7 @@ void IntroduceControlFlowSSA::operator()(FunctionDefinition& _function) void IntroduceControlFlowSSA::operator()(ForLoop& _for) { - (*this)(_for.pre); + yulAssert(_for.pre.statements.empty(), "For loop init rewriter not run."); Assignments assignments; assignments(_for.body); @@ -357,11 +357,7 @@ void PropagateValues::operator()(Assignment& _assignment) void PropagateValues::operator()(ForLoop& _for) { - // This will clear the current value in case of a reassignment inside the - // init part, although the new variable would still be in scope inside the whole loop. - // This small inefficiency is fine if we move the pre part of all for loops out - // of the for loop. - (*this)(_for.pre); + yulAssert(_for.pre.statements.empty(), "For loop init rewriter not run."); Assignments assignments; assignments(_for.body); diff --git a/libyul/optimiser/SSATransform.h b/libyul/optimiser/SSATransform.h index aa6efb821..201b1981a 100644 --- a/libyul/optimiser/SSATransform.h +++ b/libyul/optimiser/SSATransform.h @@ -85,7 +85,7 @@ class NameDispenser; * * TODO Which transforms are required to keep this idempotent? * - * Prerequisite: Disambiguator. + * Prerequisite: Disambiguator, ForLoopInitRewriter. */ class SSATransform: public ASTModifier { diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index a4507e180..95d7bee64 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -255,6 +255,7 @@ TestCase::TestResult YulOptimizerTest::run(ostream& _stream, string const& _line else if (m_optimizerStep == "ssaTransform") { disambiguate(); + ForLoopInitRewriter::run(*m_context, *m_ast); SSATransform::run(*m_context, *m_ast); } else if (m_optimizerStep == "redundantAssignEliminator") diff --git a/test/libyul/yulOptimizerTests/ssaTransform/for_def_in_init.yul b/test/libyul/yulOptimizerTests/ssaTransform/for_def_in_init.yul new file mode 100644 index 000000000..40fce8613 --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaTransform/for_def_in_init.yul @@ -0,0 +1,33 @@ +{ + for { let x := 0 } 1 { x := 2 } { + for { let y := 0 } 1 { y := 6 } { + } + } +} +// ---- +// step: ssaTransform +// +// { +// let x_1 := 0 +// let x := x_1 +// for { } +// 1 +// { +// let x_7 := x +// let x_2 := 2 +// x := x_2 +// } +// { +// let x_5 := x +// let y_3 := 0 +// let y := y_3 +// for { } +// 1 +// { +// let y_6 := y +// let y_4 := 6 +// y := y_4 +// } +// { } +// } +// } diff --git a/test/libyul/yulOptimizerTests/ssaTransform/for_reassign_body.yul b/test/libyul/yulOptimizerTests/ssaTransform/for_reassign_body.yul index e1e1c13ba..8894a789e 100644 --- a/test/libyul/yulOptimizerTests/ssaTransform/for_reassign_body.yul +++ b/test/libyul/yulOptimizerTests/ssaTransform/for_reassign_body.yul @@ -12,7 +12,8 @@ // { // let a_1 := mload(0) // let a := a_1 -// for { mstore(0, a_1) } +// mstore(0, a_1) +// for { } // a // { // let a_4 := a diff --git a/test/libyul/yulOptimizerTests/ssaTransform/for_reassign_init.yul b/test/libyul/yulOptimizerTests/ssaTransform/for_reassign_init.yul index 284bdbf3d..d3a095285 100644 --- a/test/libyul/yulOptimizerTests/ssaTransform/for_reassign_init.yul +++ b/test/libyul/yulOptimizerTests/ssaTransform/for_reassign_init.yul @@ -12,19 +12,9 @@ // { // let a_1 := mload(0) // let a := a_1 -// for { -// let a_2 := add(a_1, 3) -// a := a_2 -// } -// a -// { -// let a_4 := a -// mstore(0, a_4) -// } -// { -// let a_3 := a -// mstore(0, a_3) -// } -// let a_5 := a -// mstore(0, a_5) +// let a_2 := add(a_1, 3) +// a := a_2 +// for { } a_2 { mstore(0, a_2) } +// { mstore(0, a_2) } +// mstore(0, a_2) // } diff --git a/test/libyul/yulOptimizerTests/ssaTransform/for_reassign_post.yul b/test/libyul/yulOptimizerTests/ssaTransform/for_reassign_post.yul index ac7e426ab..cec17e553 100644 --- a/test/libyul/yulOptimizerTests/ssaTransform/for_reassign_post.yul +++ b/test/libyul/yulOptimizerTests/ssaTransform/for_reassign_post.yul @@ -12,7 +12,8 @@ // { // let a_1 := mload(0) // let a := a_1 -// for { mstore(0, a_1) } +// mstore(0, a_1) +// for { } // a // { // let a_4 := a diff --git a/test/libyul/yulOptimizerTests/ssaTransform/for_simple.yul b/test/libyul/yulOptimizerTests/ssaTransform/for_simple.yul index 77ac89a60..846b22c6c 100644 --- a/test/libyul/yulOptimizerTests/ssaTransform/for_simple.yul +++ b/test/libyul/yulOptimizerTests/ssaTransform/for_simple.yul @@ -32,10 +32,9 @@ // a := a_4 // } // let a_10 := a -// for { -// let a_5 := add(a_10, 3) -// a := a_5 -// } +// let a_5 := add(a_10, 3) +// a := a_5 +// for { } // a // { // let a_12 := a