From 25c99850471c3e5d906712711faeeb3e35c03d7d Mon Sep 17 00:00:00 2001 From: Bin Cheng Date: Wed, 15 Feb 2017 17:16:29 +0000 Subject: [PATCH] re PR tree-optimization/79347 (vect_do_peeling is messing up profile) PR tree-optimization/79347 * tree-vect-loop-manip.c (vect_do_peeling): Maintain profile counters during peeling. gcc/testsuite * gcc.dg/vect/pr79347.c: New test. From-SVN: r245490 --- gcc/ChangeLog | 6 +++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/vect/pr79347.c | 13 ++++++++++ gcc/tree-vect-loop-manip.c | 39 +++++++++++++++++++++++++++-- 4 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr79347.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fa0b01ce184..b3f479646ed 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-02-15 Bin Cheng + + PR tree-optimization/79347 + * tree-vect-loop-manip.c (vect_do_peeling): Maintain profile + counters during peeling. + 2017-02-15 Thomas Schwinge * Makefile.in (site.exp): Remove "set ISLVER". diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f749fb7dbc9..42ec70d0d3e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-02-15 Bin Cheng + + PR tree-optimization/79347 + * gcc.dg/vect/pr79347.c: New test. + 2017-02-15 Jakub Jelinek PR c++/79301 diff --git a/gcc/testsuite/gcc.dg/vect/pr79347.c b/gcc/testsuite/gcc.dg/vect/pr79347.c new file mode 100644 index 00000000000..586c638c6fa --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr79347.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-additional-options "-fdump-tree-vect-all" } */ + +short *a; +int c; +void n(void) +{ + for (int i = 0; isrc; if (skip_vector) - split_edge (loop_preheader_edge (loop)); + { + split_edge (loop_preheader_edge (loop)); + + /* Due to the order in which we peel prolog and epilog, we first + propagate probability to the whole loop. The purpose is to + avoid adjusting probabilities of both prolog and vector loops + separately. Note in this case, the probability of epilog loop + needs to be scaled back later. */ + basic_block bb_before_loop = loop_preheader_edge (loop)->src; + scale_bbs_frequencies_int (&bb_before_loop, 1, prob_vector, + REG_BR_PROB_BASE); + scale_loop_profile (loop, prob_vector, bound); + } tree niters_prolog = build_int_cst (type, 0); source_location loop_loc = find_loop_location (loop); @@ -1727,6 +1739,7 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, guard_cond = fold_build2 (EQ_EXPR, boolean_type_node, niters_prolog, build_int_cst (type, 0)); guard_bb = loop_preheader_edge (prolog)->src; + basic_block bb_after_prolog = loop_preheader_edge (loop)->src; guard_to = split_edge (loop_preheader_edge (loop)); guard_e = slpeel_add_loop_guard (guard_bb, guard_cond, guard_to, guard_bb, @@ -1734,6 +1747,9 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, 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); + + scale_bbs_frequencies_int (&bb_after_prolog, 1, prob_prolog, + REG_BR_PROB_BASE); scale_loop_profile (prolog, prob_prolog, bound_prolog); } /* Update init address of DRs. */ @@ -1796,9 +1812,18 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, 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); - scale_loop_profile (epilog, prob_vector, bound_scalar); + + /* Simply propagate profile info from guard_bb to guard_to which is + a merge point of control flow. */ + guard_to->frequency = guard_bb->frequency; + guard_to->count = guard_bb->count; + single_succ_edge (guard_to)->count = guard_to->count; + /* Scale probability of epilog loop back. */ + int scale_up = REG_BR_PROB_BASE * REG_BR_PROB_BASE / prob_vector; + scale_loop_frequencies (epilog, scale_up, REG_BR_PROB_BASE); } + basic_block bb_before_epilog = loop_preheader_edge (epilog)->src; tree niters_vector_mult_vf; /* If loop is peeled for non-zero constant times, now niters refers to orig_niters - prolog_peeling, it won't overflow even the orig_niters @@ -1826,6 +1851,16 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, inverse_probability (prob_epilog)); 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 + the guard_bb, which is the case when skip_vector is true. */ + if (guard_bb != bb_before_epilog) + { + prob_epilog = (combine_probabilities (prob_vector, prob_epilog) + + inverse_probability (prob_vector)); + + scale_bbs_frequencies_int (&bb_before_epilog, 1, prob_epilog, + REG_BR_PROB_BASE); + } scale_loop_profile (epilog, prob_epilog, bound); } else -- 2.30.2