From d49733dfc389362cea944a5f9f1c5606993fe923 Mon Sep 17 00:00:00 2001 From: mingchuan Date: Tue, 9 Apr 2019 17:11:38 +0800 Subject: [PATCH] Fix variable decl scope issue in DeadCodeEliminator FoorLoopInitRewriter needs to be run before DeadCodeEliminator. --- libyul/optimiser/DeadCodeEliminator.h | 4 ++++ libyul/optimiser/Suite.cpp | 2 +- test/libyul/YulOptimizerTest.cpp | 1 + .../deadCodeEliminator/conditional_break.yul | 2 +- .../deadCodeEliminator/early_break.yul | 2 +- .../deadCodeEliminator/early_continue.yul | 2 +- .../deadCodeEliminator/for_loop_init_decl.yul | 12 ++++++++++++ .../deadCodeEliminator/normal_break.yul | 2 +- .../deadCodeEliminator/normal_continue.yul | 2 +- .../deadCodeEliminator/normal_stop.yul | 2 +- 10 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 test/libyul/yulOptimizerTests/deadCodeEliminator/for_loop_init_decl.yul diff --git a/libyul/optimiser/DeadCodeEliminator.h b/libyul/optimiser/DeadCodeEliminator.h index 3009484b5..1d464badd 100644 --- a/libyul/optimiser/DeadCodeEliminator.h +++ b/libyul/optimiser/DeadCodeEliminator.h @@ -38,6 +38,10 @@ namespace yul * Function definitions are retained as they might be called by earlier * code and thus are considered reachable. * + * Because variables declared in a for loop's init block have their scope extended to the loop body, + * we require ForLoopInitRewriter to run before this step. + * + * Prerequisite: ForLoopInitRewriter */ class DeadCodeEliminator: public ASTModifier { diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 855185a65..e0ff847c6 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -71,11 +71,11 @@ void OptimiserSuite::run( VarDeclInitializer{}(ast); FunctionHoister{}(ast); BlockFlattener{}(ast); + ForLoopInitRewriter{}(ast); DeadCodeEliminator{}(ast); FunctionGrouper{}(ast); EquivalentFunctionCombiner::run(ast); UnusedPruner::runUntilStabilised(*_dialect, ast, reservedIdentifiers); - ForLoopInitRewriter{}(ast); BlockFlattener{}(ast); StructuralSimplifier{*_dialect}(ast); BlockFlattener{}(ast); diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index 9b09a33a3..4d34b03cb 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -207,6 +207,7 @@ bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool con else if (m_optimizerStep == "deadCodeEliminator") { disambiguate(); + ForLoopInitRewriter{}(*m_ast); DeadCodeEliminator{}(*m_ast); } else if (m_optimizerStep == "ssaTransform") diff --git a/test/libyul/yulOptimizerTests/deadCodeEliminator/conditional_break.yul b/test/libyul/yulOptimizerTests/deadCodeEliminator/conditional_break.yul index 7c824d8eb..ca36109ea 100644 --- a/test/libyul/yulOptimizerTests/deadCodeEliminator/conditional_break.yul +++ b/test/libyul/yulOptimizerTests/deadCodeEliminator/conditional_break.yul @@ -17,8 +17,8 @@ // step: deadCodeEliminator // ---- // { +// let a := 20 // for { -// let a := 20 // } // lt(a, 40) // { diff --git a/test/libyul/yulOptimizerTests/deadCodeEliminator/early_break.yul b/test/libyul/yulOptimizerTests/deadCodeEliminator/early_break.yul index 1706b60e0..9d08c02ea 100644 --- a/test/libyul/yulOptimizerTests/deadCodeEliminator/early_break.yul +++ b/test/libyul/yulOptimizerTests/deadCodeEliminator/early_break.yul @@ -18,8 +18,8 @@ // step: deadCodeEliminator // ---- // { +// let a := 20 // for { -// let a := 20 // } // lt(a, 40) // { diff --git a/test/libyul/yulOptimizerTests/deadCodeEliminator/early_continue.yul b/test/libyul/yulOptimizerTests/deadCodeEliminator/early_continue.yul index 152221412..dee962c7c 100644 --- a/test/libyul/yulOptimizerTests/deadCodeEliminator/early_continue.yul +++ b/test/libyul/yulOptimizerTests/deadCodeEliminator/early_continue.yul @@ -18,8 +18,8 @@ // step: deadCodeEliminator // ---- // { +// let a := 20 // for { -// let a := 20 // } // lt(a, 40) // { diff --git a/test/libyul/yulOptimizerTests/deadCodeEliminator/for_loop_init_decl.yul b/test/libyul/yulOptimizerTests/deadCodeEliminator/for_loop_init_decl.yul new file mode 100644 index 000000000..30753c9ad --- /dev/null +++ b/test/libyul/yulOptimizerTests/deadCodeEliminator/for_loop_init_decl.yul @@ -0,0 +1,12 @@ +{ + for { stop() let i_0 := 0 } lt(i_0,2) { i_0 := add(i_0,1) } + { + let i_1 := i_0 + } +} +// ==== +// step: deadCodeEliminator +// ---- +// { +// stop() +// } diff --git a/test/libyul/yulOptimizerTests/deadCodeEliminator/normal_break.yul b/test/libyul/yulOptimizerTests/deadCodeEliminator/normal_break.yul index 920f1b511..fadf98981 100644 --- a/test/libyul/yulOptimizerTests/deadCodeEliminator/normal_break.yul +++ b/test/libyul/yulOptimizerTests/deadCodeEliminator/normal_break.yul @@ -16,8 +16,8 @@ // step: deadCodeEliminator // ---- // { +// let a := 20 // for { -// let a := 20 // } // lt(a, 40) // { diff --git a/test/libyul/yulOptimizerTests/deadCodeEliminator/normal_continue.yul b/test/libyul/yulOptimizerTests/deadCodeEliminator/normal_continue.yul index 81165540f..cc4770dc5 100644 --- a/test/libyul/yulOptimizerTests/deadCodeEliminator/normal_continue.yul +++ b/test/libyul/yulOptimizerTests/deadCodeEliminator/normal_continue.yul @@ -16,8 +16,8 @@ // step: deadCodeEliminator // ---- // { +// let a := 20 // for { -// let a := 20 // } // lt(a, 40) // { diff --git a/test/libyul/yulOptimizerTests/deadCodeEliminator/normal_stop.yul b/test/libyul/yulOptimizerTests/deadCodeEliminator/normal_stop.yul index d636e31c1..fa02b2c88 100644 --- a/test/libyul/yulOptimizerTests/deadCodeEliminator/normal_stop.yul +++ b/test/libyul/yulOptimizerTests/deadCodeEliminator/normal_stop.yul @@ -20,8 +20,8 @@ // ---- // { // let b := 20 +// let a := 20 // for { -// let a := 20 // } // lt(a, 40) // {