From 3e907b90563ad90752acf1b318bdac33d546c7f7 Mon Sep 17 00:00:00 2001 From: Bin Cheng Date: Tue, 28 Mar 2017 15:32:29 +0000 Subject: [PATCH] tree-vect-loop-manip.c (slpeel_add_loop_guard): New param and mark new edge's irreducible flag accordign to it. * tree-vect-loop-manip.c (slpeel_add_loop_guard): New param and mark new edge's irreducible flag accordign to it. (vect_do_peeling): Check loop preheader edge's irreducible flag and pass it to function slpeel_add_loop_guard. gcc/testsuite * gcc.c-torture/compile/irreducible-loop.c: New. From-SVN: r246540 --- gcc/ChangeLog | 7 +++++++ gcc/testsuite/ChangeLog | 6 +++++- .../gcc.c-torture/compile/irreducible-loop.c | 21 +++++++++++++++++++++ gcc/tree-vect-loop-manip.c | 18 +++++++++++++----- 4 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/irreducible-loop.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 19b9d57..fa216e9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-03-28 Bin Cheng + + * tree-vect-loop-manip.c (slpeel_add_loop_guard): New param and + mark new edge's irreducible flag accordign to it. + (vect_do_peeling): Check loop preheader edge's irreducible flag + and pass it to function slpeel_add_loop_guard. + 2017-03-28 Richard Sandiford PR tree-optimization/80218 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8cbbc16..44609619 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,10 @@ +2017-03-28 Bin Cheng + + * gcc.c-torture/compile/irreducible-loop.c: New. + 2017-03-28 Richard Sandiford - PR tree-optimization/80218 + PR tree-optimization/80218 * gcc.dg/pr80218.c: New test. 2017-03-28 Richard Biener diff --git a/gcc/testsuite/gcc.c-torture/compile/irreducible-loop.c b/gcc/testsuite/gcc.c-torture/compile/irreducible-loop.c new file mode 100644 index 0000000..e4be667 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/irreducible-loop.c @@ -0,0 +1,21 @@ +void foo (int n, double a, double *b, double *x) +{ + int i, j; + + if(n <= 0) return; + if (a == 0.0e0) return; + + if (a > 5.0) + { + i = 0; + goto sec; + } + for (i = 0; i < 1024; i++) + { + double y = b[i]; +sec: + b[i+1] = y + 5.0; + for (j = 0; j < n; j++) + x[j] = x[j] + a; + } +} diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index 2f82061..f48336b 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -534,12 +534,13 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, /* Given the condition expression COND, put it as the last statement of GUARD_BB; set both edges' probability; set dominator of GUARD_TO to DOM_BB; return the skip edge. GUARD_TO is the target basic block to - skip the loop. PROBABILITY is the skip edge's probability. */ + skip the loop. PROBABILITY is the skip edge's probability. Mark the + new edge as irreducible if IRREDUCIBLE_P is true. */ static edge slpeel_add_loop_guard (basic_block guard_bb, tree cond, basic_block guard_to, basic_block dom_bb, - int probability) + int probability, bool irreducible_p) { gimple_stmt_iterator gsi; edge new_e, enter_e; @@ -566,6 +567,9 @@ slpeel_add_loop_guard (basic_block guard_bb, tree cond, new_e->count = guard_bb->count; new_e->probability = probability; new_e->count = apply_probability (enter_e->count, probability); + if (irreducible_p) + new_e->flags |= EDGE_IRREDUCIBLE_LOOP; + enter_e->count -= new_e->count; enter_e->probability = inverse_probability (probability); set_immediate_dominator (CDI_DOMINATORS, guard_to, dom_bb); @@ -1667,6 +1671,7 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, struct loop *prolog, *epilog = NULL, *loop = LOOP_VINFO_LOOP (loop_vinfo); struct loop *first_loop = loop; + bool irred_flag = loop_preheader_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP; create_lcssa_for_virtual_phi (loop); update_ssa (TODO_update_ssa_only_virtuals); @@ -1748,7 +1753,8 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, guard_to = split_edge (loop_preheader_edge (loop)); guard_e = slpeel_add_loop_guard (guard_bb, guard_cond, guard_to, guard_bb, - inverse_probability (prob_prolog)); + inverse_probability (prob_prolog), + irred_flag); e = EDGE_PRED (guard_to, 0); e = (e != guard_e ? e : EDGE_PRED (guard_to, 1)); slpeel_update_phi_nodes_for_guard1 (prolog, loop, guard_e, e); @@ -1813,7 +1819,8 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, guard_to = split_edge (loop_preheader_edge (epilog)); guard_e = slpeel_add_loop_guard (guard_bb, guard_cond, guard_to, guard_bb, - inverse_probability (prob_vector)); + inverse_probability (prob_vector), + irred_flag); e = EDGE_PRED (guard_to, 0); e = (e != guard_e ? e : EDGE_PRED (guard_to, 1)); slpeel_update_phi_nodes_for_guard1 (first_loop, epilog, guard_e, e); @@ -1853,7 +1860,8 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, guard_to = split_edge (single_exit (epilog)); guard_e = slpeel_add_loop_guard (guard_bb, guard_cond, guard_to, skip_vector ? anchor : guard_bb, - inverse_probability (prob_epilog)); + inverse_probability (prob_epilog), + irred_flag); slpeel_update_phi_nodes_for_guard2 (loop, epilog, guard_e, single_exit (epilog)); /* Only need to handle basic block before epilog loop if it's not -- 2.7.4