From 622d8b69482a3c8f2a0df0324033719a771932fd Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 17 Aug 2016 08:11:32 +0000 Subject: [PATCH] re PR tree-optimization/23855 (loop header should also be pulled out of the inner loop too) 2016-08-17 Richard Biener PR tree-optimization/23855 * tree-ssa-loop-unswitch.c: Include tree-ssa-loop-manip.h. (tree_unswitch_outer_loop): Iterate find_loop_guard as long as we find guards to hoist. Do not update SSA form but rewrite virtuals into loop closed SSA. (find_loop_guard): Adjust to skip already hoisted guards. Do not mark virtuals for renaming or update SSA form. * gcc.dg/loop-unswitch-2.c: Adjust. From-SVN: r239523 --- gcc/ChangeLog | 10 ++++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/loop-unswitch-2.c | 2 +- gcc/tree-ssa-loop-unswitch.c | 45 +++++++++++++++++--------- 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index edbac57728b..467f016514b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-08-17 Richard Biener + + PR tree-optimization/23855 + * tree-ssa-loop-unswitch.c: Include tree-ssa-loop-manip.h. + (tree_unswitch_outer_loop): Iterate find_loop_guard as long as we + find guards to hoist. Do not update SSA form but rewrite virtuals + into loop closed SSA. + (find_loop_guard): Adjust to skip already hoisted guards. Do + not mark virtuals for renaming or update SSA form. + 2016-08-17 Martin Liska * coverage.c (get_gcov_type): Replace GCOV_TYPE_SIZE with diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cd0463f4d43..ffa81389d16 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-08-17 Richard Biener + + PR tree-optimization/23855 + * gcc.dg/loop-unswitch-2.c: Adjust. + 2016-08-16 Jakub Jelinek PR tree-optimization/72817 diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-2.c b/gcc/testsuite/gcc.dg/loop-unswitch-2.c index 5ebf6087fcd..77900f9e955 100644 --- a/gcc/testsuite/gcc.dg/loop-unswitch-2.c +++ b/gcc/testsuite/gcc.dg/loop-unswitch-2.c @@ -11,5 +11,5 @@ void foo (float **a, float **b, float *c, int n, int m, int l) c[i] += a[i][k] * b[k][j]; } -/* { dg-final { scan-tree-dump-times "guard hoisted" 2 "unswitch" } } */ +/* { dg-final { scan-tree-dump-times "guard hoisted" 3 "unswitch" } } */ diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c index 73bdc6eab7d..40905af45eb 100644 --- a/gcc/tree-ssa-loop-unswitch.c +++ b/gcc/tree-ssa-loop-unswitch.c @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-inline.h" #include "gimple-iterator.h" #include "cfghooks.h" +#include "tree-ssa-loop-manip.h" /* This file implements the loop unswitching, i.e. transformation of loops like @@ -451,14 +452,15 @@ tree_unswitch_outer_loop (struct loop *loop) return false; } - guard = find_loop_guard (loop); - if (guard) + bool changed = false; + while ((guard = find_loop_guard (loop))) { + if (! changed) + rewrite_virtuals_into_loop_closed_ssa (loop); hoist_guard (loop, guard); - update_ssa (TODO_update_ssa); - return true; + changed = true; } - return false; + return changed; } /* Checks if the body of the LOOP is within an invariant guard. If this @@ -501,13 +503,28 @@ find_loop_guard (struct loop *loop) b) anything defined in something1, something2 and something3 is not used outside of the loop. */ - while (single_succ_p (header)) - header = single_succ (header); - if (!last_stmt (header) - || gimple_code (last_stmt (header)) != GIMPLE_COND) - return NULL; - - extract_true_false_edges_from_block (header, &te, &fe); + gcond *cond; + do + { + if (single_succ_p (header)) + header = single_succ (header); + else + { + cond = dyn_cast (last_stmt (header)); + if (! cond) + return NULL; + extract_true_false_edges_from_block (header, &te, &fe); + /* Make sure to skip earlier hoisted guards that are left + in place as if (true). */ + if (gimple_cond_true_p (cond)) + header = te->dest; + else if (gimple_cond_false_p (cond)) + header = fe->dest; + else + break; + } + } + while (1); if (!flow_bb_inside_loop_p (loop, te->dest) || !flow_bb_inside_loop_p (loop, fe->dest)) return NULL; @@ -549,7 +566,7 @@ find_loop_guard (struct loop *loop) guard_edge->src->index, guard_edge->dest->index, loop->num); /* Check if condition operands do not have definitions inside loop since any bb copying is not performed. */ - FOR_EACH_SSA_TREE_OPERAND (use, last_stmt (header), iter, SSA_OP_USE) + FOR_EACH_SSA_TREE_OPERAND (use, cond, iter, SSA_OP_USE) { gimple *def = SSA_NAME_DEF_STMT (use); basic_block def_bb = gimple_bb (def); @@ -762,8 +779,6 @@ hoist_guard (struct loop *loop, edge guard) } } - mark_virtual_operands_for_renaming (cfun); - update_ssa (TODO_update_ssa); if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, " guard hoisted.\n"); } -- 2.30.2