This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PR42246,39453] Fix pipelining outer loops
- From: Alexander Monakov <amonakov at ispras dot ru>
- To: gcc-patches at gcc dot gnu dot org
- Cc: abel at ispras dot ru, vmakarov at redhat dot com, Alexander Monakov <amonakov at ispras dot ru>
- Date: Wed, 30 Dec 2009 19:33:46 +0300
- Subject: [PR42246,39453] Fix pipelining outer loops
- References: <4B3B7703.1070409@ispras.ru>
Quoting the PR42246 audit trail:
Here, we broke pipelining of outer loops when optimizing the scheduler core.
The problems analyzed by Alexander are simple though. First, when testing
whether a loop is considered for pipelining, I decided to play safe and also
check pipelining_p in addition to the flag in the aux loop data that was
designed specially for this. Naturally, when we then disabled pipelining_p
for rescheduling pipelined loops, this broke, so to fix it we just need to
stop checking for pipelining_p. The second problem is that we use the
last_added_blocks vector when adding blocks to the region, and we failed to
initialize it correctly for the case of moving preheader blocks from an inner
loop to an outer loop when we have added the vector. Also easily fixed via
correctly initializing the vector.
2009-12-30 Alexander Monakov <amonakov@ispras.ru>
PR rtl-optimization/39453
PR rtl-optimization/42246
* sel-sched-ir.c (considered_for_pipelining_p): Do not test
for pipelining_p.
(sel_add_loop_preheaders): Add preheader to last_added_blocks.
* gcc.dg/pr39453.c: New.
* gcc.dg/pr42246.c: New.
---
gcc/sel-sched-ir.c | 5 ++++-
gcc/testsuite/gcc.dg/pr39453.c | 18 ++++++++++++++++++
gcc/testsuite/gcc.dg/pr42246.c | 36 ++++++++++++++++++++++++++++++++++++
3 files changed, 58 insertions(+), 1 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/pr39453.c
create mode 100644 gcc/testsuite/gcc.dg/pr42246.c
diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index 16eacfe..69890dc 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -5864,7 +5864,7 @@ considered_for_pipelining_p (struct loop *loop)
latch. We can't use header here, because this header could be
just removed preheader and it will give us the wrong region number.
Latch can't be used because it could be in the inner loop too. */
- if (LOOP_MARKED_FOR_PIPELINING_P (loop) && pipelining_p)
+ if (LOOP_MARKED_FOR_PIPELINING_P (loop))
{
int rgn = CONTAINING_RGN (loop->latch->index);
@@ -6013,7 +6013,10 @@ sel_add_loop_preheaders (void)
for (i = 0;
VEC_iterate (basic_block, preheader_blocks, i, bb);
i++)
+ {
+ VEC_safe_push (basic_block, heap, last_added_blocks, bb);
sel_add_bb (bb);
+ }
VEC_free (basic_block, heap, preheader_blocks);
}
diff --git a/gcc/testsuite/gcc.dg/pr39453.c b/gcc/testsuite/gcc.dg/pr39453.c
new file mode 100644
index 0000000..66ecc3f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr39453.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target powerpc*-*-* ia64-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -fselective-scheduling2 -fsel-sched-pipelining -fsel-sched-pipelining-outer-loops" } */
+
+int foo(int k, int n)
+{
+ int i;
+ for (i = 0; i < n; i += 8) {
+ int j;
+ for (j = 0; j < n; j += 8) {
+ while (k < n) {
+ k += 8;
+ }
+ }
+ }
+ return k;
+}
+
+
diff --git a/gcc/testsuite/gcc.dg/pr42246.c b/gcc/testsuite/gcc.dg/pr42246.c
new file mode 100644
index 0000000..ee17a21
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr42246.c
@@ -0,0 +1,36 @@
+/* { dg-do compile { target powerpc*-*-* ia64-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -fselective-scheduling -fsel-sched-pipelining -fsel-sched-pipelining-outer-loops" } */
+
+typedef enum
+{
+ empty = 0, pawn = 1, knight = 2, king = 3, bishop = 5, rook = 6, queen = 7
+}
+PIECE;
+extern int p_values[15];
+extern int *last[65];
+int
+Quiesce (int alpha, int beta, int wtm, int ply)
+{
+ register int initial_alpha, value, delta;
+ register int *goodmv, *movep, moves = 0, *sortv, temp;
+ for (movep = last[ply - 1]; movep < last[ply]; movep++)
+ if (p_values[(((*movep) >> 15) & 7) + 7] +
+ p_values[(((*movep) >> 18) & 7) + 7] >= delta)
+ {
+ register int done;
+ register int *end = last[ply - 1] + moves - 1;
+ do
+ {
+ done = 1;
+ movep = last[ply - 1];
+ for (; movep < end; movep++, sortv++)
+ if (*sortv < *(sortv + 1))
+ {
+ *(movep + 1) = temp;
+ done = 0;
+ }
+ }
+ while (!done);
+ }
+}
+
--
1.6.4.3