diff options
author | Bin Cheng <bin.cheng@arm.com> | 2017-02-15 17:16:29 +0000 |
---|---|---|
committer | Bin Cheng <amker@gcc.gnu.org> | 2017-02-15 17:16:29 +0000 |
commit | 25c99850471c3e5d906712711faeeb3e35c03d7d (patch) | |
tree | 5fcea889566fedf142ce3dd62039ae6b951bb52f /gcc/tree-vect-loop-manip.c | |
parent | e72028574f776fd5b73de8b974e4ea2d085f1532 (diff) | |
download | gcc-25c99850471c3e5d906712711faeeb3e35c03d7d.zip gcc-25c99850471c3e5d906712711faeeb3e35c03d7d.tar.gz gcc-25c99850471c3e5d906712711faeeb3e35c03d7d.tar.bz2 |
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
Diffstat (limited to 'gcc/tree-vect-loop-manip.c')
-rw-r--r-- | gcc/tree-vect-loop-manip.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index f29449c..5ee2c38 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -1690,7 +1690,19 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, may be preferred. */ basic_block anchor = loop_preheader_edge (loop)->src; 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 |