aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBin Cheng <bin.cheng@arm.com>2017-02-15 17:16:29 +0000
committerBin Cheng <amker@gcc.gnu.org>2017-02-15 17:16:29 +0000
commit25c99850471c3e5d906712711faeeb3e35c03d7d (patch)
tree5fcea889566fedf142ce3dd62039ae6b951bb52f /gcc
parente72028574f776fd5b73de8b974e4ea2d085f1532 (diff)
downloadgcc-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')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr79347.c13
-rw-r--r--gcc/tree-vect-loop-manip.c39
4 files changed, 61 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fa0b01c..b3f4796 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2017-02-15 Bin Cheng <bin.cheng@arm.com>
+
+ PR tree-optimization/79347
+ * tree-vect-loop-manip.c (vect_do_peeling): Maintain profile
+ counters during peeling.
+
2017-02-15 Thomas Schwinge <thomas@codesourcery.com>
* Makefile.in (site.exp): Remove "set ISLVER".
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f749fb7..42ec70d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-02-15 Bin Cheng <bin.cheng@arm.com>
+
+ PR tree-optimization/79347
+ * gcc.dg/vect/pr79347.c: New test.
+
2017-02-15 Jakub Jelinek <jakub@redhat.com>
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 0000000..586c638
--- /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; i<c;i++)
+ a[i]++;
+}
+
+/* { dg-final { scan-tree-dump-times "Invalid sum of " 2 "vect" } } */
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