Commit 622d8b69 by Richard Biener Committed by Richard Biener

re PR tree-optimization/23855 (loop header should also be pulled out of the inner loop too)

2016-08-17  Richard Biener  <rguenther@suse.de>

	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
parent 892a653c
2016-08-17 Richard Biener <rguenther@suse.de>
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 <mliska@suse.cz> 2016-08-17 Martin Liska <mliska@suse.cz>
* coverage.c (get_gcov_type): Replace GCOV_TYPE_SIZE with * coverage.c (get_gcov_type): Replace GCOV_TYPE_SIZE with
......
2016-08-17 Richard Biener <rguenther@suse.de>
PR tree-optimization/23855
* gcc.dg/loop-unswitch-2.c: Adjust.
2016-08-16 Jakub Jelinek <jakub@redhat.com> 2016-08-16 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/72817 PR tree-optimization/72817
......
...@@ -11,5 +11,5 @@ void foo (float **a, float **b, float *c, int n, int m, int l) ...@@ -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]; 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" } } */
...@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-inline.h" #include "tree-inline.h"
#include "gimple-iterator.h" #include "gimple-iterator.h"
#include "cfghooks.h" #include "cfghooks.h"
#include "tree-ssa-loop-manip.h"
/* This file implements the loop unswitching, i.e. transformation of loops like /* This file implements the loop unswitching, i.e. transformation of loops like
...@@ -451,14 +452,15 @@ tree_unswitch_outer_loop (struct loop *loop) ...@@ -451,14 +452,15 @@ tree_unswitch_outer_loop (struct loop *loop)
return false; return false;
} }
guard = find_loop_guard (loop); bool changed = false;
if (guard) while ((guard = find_loop_guard (loop)))
{ {
if (! changed)
rewrite_virtuals_into_loop_closed_ssa (loop);
hoist_guard (loop, guard); hoist_guard (loop, guard);
update_ssa (TODO_update_ssa); changed = true;
return true;
} }
return false; return changed;
} }
/* Checks if the body of the LOOP is within an invariant guard. If this /* Checks if the body of the LOOP is within an invariant guard. If this
...@@ -501,13 +503,28 @@ find_loop_guard (struct loop *loop) ...@@ -501,13 +503,28 @@ find_loop_guard (struct loop *loop)
b) anything defined in something1, something2 and something3 b) anything defined in something1, something2 and something3
is not used outside of the loop. */ is not used outside of the loop. */
while (single_succ_p (header)) gcond *cond;
header = single_succ (header); do
if (!last_stmt (header) {
|| gimple_code (last_stmt (header)) != GIMPLE_COND) if (single_succ_p (header))
return NULL; header = single_succ (header);
else
extract_true_false_edges_from_block (header, &te, &fe); {
cond = dyn_cast <gcond *> (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) if (!flow_bb_inside_loop_p (loop, te->dest)
|| !flow_bb_inside_loop_p (loop, fe->dest)) || !flow_bb_inside_loop_p (loop, fe->dest))
return NULL; return NULL;
...@@ -549,7 +566,7 @@ find_loop_guard (struct loop *loop) ...@@ -549,7 +566,7 @@ find_loop_guard (struct loop *loop)
guard_edge->src->index, guard_edge->dest->index, loop->num); guard_edge->src->index, guard_edge->dest->index, loop->num);
/* Check if condition operands do not have definitions inside loop since /* Check if condition operands do not have definitions inside loop since
any bb copying is not performed. */ 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); gimple *def = SSA_NAME_DEF_STMT (use);
basic_block def_bb = gimple_bb (def); basic_block def_bb = gimple_bb (def);
...@@ -762,8 +779,6 @@ hoist_guard (struct loop *loop, edge guard) ...@@ -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)) if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " guard hoisted.\n"); fprintf (dump_file, " guard hoisted.\n");
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment