diff options
author | Jakub Jelinek <jakub@redhat.com> | 2014-01-07 08:49:10 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-01-07 08:49:10 +0100 |
commit | 41626746d0bd5aaff66a5489e80781917be881da (patch) | |
tree | 071e8492cc75475aa723d80b5247b3945695f667 /gcc | |
parent | cc349a3901254b334d2ab2bf6eadb35eeb8fdb48 (diff) | |
download | gcc-41626746d0bd5aaff66a5489e80781917be881da.zip gcc-41626746d0bd5aaff66a5489e80781917be881da.tar.gz gcc-41626746d0bd5aaff66a5489e80781917be881da.tar.bz2 |
re PR tree-optimization/59643 (Predictive commoning unnecessarily punts on scimark2 SOR)
PR tree-optimization/59643
* tree-predcom.c (split_data_refs_to_components): If one dr is
read and one write, determine_offset fails and the write isn't
in the bad component, just put the read into the bad component.
* gcc.dg/pr59643.c: New test.
* gcc.c-torture/execute/pr59643.c: New test.
From-SVN: r206384
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr59643.c | 39 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr59643.c | 15 | ||||
-rw-r--r-- | gcc/tree-predcom.c | 35 |
5 files changed, 98 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d52cdc3..4760b12 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2014-01-07 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/59643 + * tree-predcom.c (split_data_refs_to_components): If one dr is + read and one write, determine_offset fails and the write isn't + in the bad component, just put the read into the bad component. + 2014-01-07 Mike Stump <mikestump@comcast.net> Jakub Jelinek <jakub@redhat.com> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e6576d4..629d420 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-01-07 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/59643 + * gcc.dg/pr59643.c: New test. + * gcc.c-torture/execute/pr59643.c: New test. + 2014-01-06 Janus Weil <janus@gcc.gnu.org> PR fortran/59589 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr59643.c b/gcc/testsuite/gcc.c-torture/execute/pr59643.c new file mode 100644 index 0000000..e3e8a6a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr59643.c @@ -0,0 +1,39 @@ +/* PR tree-optimization/59643 */ + +#define N 32 + +__attribute__((noinline, noclone)) void +foo (double *a, double *b, double *c, double d, double e, int n) +{ + int i; + for (i = 1; i < n - 1; i++) + a[i] = d * (b[i] + c[i] + a[i - 1] + a[i + 1]) + e * a[i]; +} + +double expected[] = { + 0.0, 10.0, 44.0, 110.0, 232.0, 490.0, 1020.0, 2078.0, 4152.0, 8314.0, + 16652.0, 33326.0, 66664.0, 133354.0, 266748.0, 533534.0, 1067064.0, + 2134138.0, 4268300.0, 8536622.0, 17073256.0, 34146538.0, 68293116.0, + 136586270.0, 273172536.0, 546345082.0, 1092690188.0, 2185380398.0, + 4370760808.0, 8741521642.0, 17483043324.0, 6.0 +}; + +int +main () +{ + int i; + double a[N], b[N], c[N]; + if (__DBL_MANT_DIG__ <= 35) + return 0; + for (i = 0; i < N; i++) + { + a[i] = (i & 3) * 2.0; + b[i] = (i & 7) - 4; + c[i] = i & 7; + } + foo (a, b, c, 2.0, 3.0, N); + for (i = 0; i < N; i++) + if (a[i] != expected[i]) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr59643.c b/gcc/testsuite/gcc.dg/pr59643.c new file mode 100644 index 0000000..f4df5e5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr59643.c @@ -0,0 +1,15 @@ +/* PR tree-optimization/59643 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-pcom-details" } */ + +void +foo (double *a, double *b, double *c, double d, double e, int n) +{ + int i; + for (i = 1; i < n - 1; i++) + a[i] = d * (b[i] + c[i] + a[i - 1] + a[i + 1]) + e * a[i]; +} + +/* { dg-final { scan-tree-dump-times "Before commoning:" 1 "pcom" } } */ +/* { dg-final { scan-tree-dump-times "Unrolling 2 times" 1 "pcom" } } */ +/* { dg-final { cleanup-tree-dump "pcom" } } */ diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index 92cecfa..7169b2f 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -772,10 +772,37 @@ split_data_refs_to_components (struct loop *loop, bad = component_of (comp_father, n); /* If both A and B are reads, we may ignore unsuitable dependences. */ - if (DR_IS_READ (dra) && DR_IS_READ (drb) - && (ia == bad || ib == bad - || !determine_offset (dra, drb, &dummy_off))) - continue; + if (DR_IS_READ (dra) && DR_IS_READ (drb)) + { + if (ia == bad || ib == bad + || !determine_offset (dra, drb, &dummy_off)) + continue; + } + /* If A is read and B write or vice versa and there is unsuitable + dependence, instead of merging both components into a component + that will certainly not pass suitable_component_p, just put the + read into bad component, perhaps at least the write together with + all the other data refs in it's component will be optimizable. */ + else if (DR_IS_READ (dra) && ib != bad) + { + if (ia == bad) + continue; + else if (!determine_offset (dra, drb, &dummy_off)) + { + merge_comps (comp_father, comp_size, bad, ia); + continue; + } + } + else if (DR_IS_READ (drb) && ia != bad) + { + if (ib == bad) + continue; + else if (!determine_offset (dra, drb, &dummy_off)) + { + merge_comps (comp_father, comp_size, bad, ib); + continue; + } + } merge_comps (comp_father, comp_size, ia, ib); } |