This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PR42246,39453] Fix pipelining outer loops


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]