aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBin Cheng <bin.cheng@arm.com>2017-02-23 22:02:01 +0000
committerJeff Law <law@gcc.gnu.org>2017-02-23 15:02:01 -0700
commitd822f3d585da1f9be6ab62245073625385a0e34f (patch)
treef2a285c3f42caa72a4e8a86c3183f86f8f56f88b /gcc
parent06b909b07e840d648a425e0ede5947616354f11b (diff)
downloadgcc-d822f3d585da1f9be6ab62245073625385a0e34f.zip
gcc-d822f3d585da1f9be6ab62245073625385a0e34f.tar.gz
gcc-d822f3d585da1f9be6ab62245073625385a0e34f.tar.bz2
re PR tree-optimization/79663 (r244815 causes 10% regression for spec1k/172.mgrid on AArch64)
2017-01-21 Bin Cheng <bin.cheng@arm.com> PR tree-optimization/79663 * tree-predcom.c (combine_chains): Process refs in reverse order only for ZERO length chains, and add explaining comment. From-SVN: r245689
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/tree-predcom.c55
2 files changed, 36 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 37ae06a..906607f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2017-02-23 Bin Cheng <bin.cheng@arm.com>
+
+ PR tree-optimization/79663
+ * tree-predcom.c (combine_chains): Process refs in reverse order
+ only for ZERO length chains, and add explaining comment.
+
2017-02-23 Jeff Law <law@redhat.com>
PR tree-optimization/79578
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index 9723e9c..57d8f7d 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -2283,7 +2283,7 @@ combine_chains (chain_p ch1, chain_p ch2)
enum tree_code op = ERROR_MARK;
bool swap = false;
chain_p new_chain;
- unsigned i;
+ int i, j, num;
gimple *root_stmt;
tree rslt_type = NULL_TREE;
@@ -2305,6 +2305,9 @@ combine_chains (chain_p ch1, chain_p ch2)
return NULL;
}
+ ch1->combined = true;
+ ch2->combined = true;
+
if (swap)
std::swap (ch1, ch2);
@@ -2317,39 +2320,41 @@ combine_chains (chain_p ch1, chain_p ch2)
new_chain->length = ch1->length;
gimple *insert = NULL;
- auto_vec<dref> tmp_refs;
- gcc_assert (ch1->refs.length () == ch2->refs.length ());
- /* Process in reverse order so dominance point is ready when it comes
- to the root ref. */
- for (i = ch1->refs.length (); i > 0; i--)
- {
- r1 = ch1->refs[i - 1];
- r2 = ch2->refs[i - 1];
+ num = ch1->refs.length ();
+ i = (new_chain->length == 0) ? num - 1 : 0;
+ j = (new_chain->length == 0) ? -1 : 1;
+ /* For ZERO length chain, process refs in reverse order so that dominant
+ position is ready when it comes to the root ref.
+ For non-ZERO length chain, process refs in order. See PR79663. */
+ for (; num > 0; num--, i += j)
+ {
+ r1 = ch1->refs[i];
+ r2 = ch2->refs[i];
nw = XCNEW (struct dref_d);
nw->distance = r1->distance;
- nw->stmt = stmt_combining_refs (r1, r2, i == 1 ? insert : NULL);
- /* Record dominance point where root combined stmt should be inserted
- for chains with 0 length. Though all root refs dominate following
- refs, it's possible the combined stmt doesn't. See PR70754. */
- if (ch1->length == 0
+ /* For ZERO length chain, insert combined stmt of root ref at dominant
+ position. */
+ nw->stmt = stmt_combining_refs (r1, r2, i == 0 ? insert : NULL);
+ /* For ZERO length chain, record dominant position where combined stmt
+ of root ref should be inserted. In this case, though all root refs
+ dominate following ones, it's possible that combined stmt doesn't.
+ See PR70754. */
+ if (new_chain->length == 0
&& (insert == NULL || stmt_dominates_stmt_p (nw->stmt, insert)))
insert = nw->stmt;
- tmp_refs.safe_push (nw);
+ new_chain->refs.safe_push (nw);
}
-
- /* Restore the order for new chain's refs. */
- for (i = tmp_refs.length (); i > 0; i--)
- new_chain->refs.safe_push (tmp_refs[i - 1]);
-
- ch1->combined = true;
- ch2->combined = true;
-
- /* For chains with 0 length, has_max_use_after must be true since root
- combined stmt must dominates others. */
if (new_chain->length == 0)
{
+ /* Restore the order for ZERO length chain's refs. */
+ num = new_chain->refs.length () >> 1;
+ for (i = 0, j = new_chain->refs.length () - 1; i < num; i++, j--)
+ std::swap (new_chain->refs[i], new_chain->refs[j]);
+
+ /* For ZERO length chain, has_max_use_after must be true since root
+ combined stmt must dominates others. */
new_chain->has_max_use_after = true;
return new_chain;
}