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]

[PATCH] Fix -fcompare-debug differences caused by loop invariant register pressure code (PR debug/41340)


Hi!

As shown on this testcase, loop-invariant.c calculates higher register
pressure for some loops when DEBUG_INSNs are in the stream.  The liveness
of registers is the same, but some registers in some loops are only ever
mentioned in DEBUG_INSNs and nowhere else.  We shouldn't count them at all
for register pressure computation purposes.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux.  Ok for
trunk?

2009-10-20  Jakub Jelinek  <jakub@redhat.com>

	PR debug/41340
	* loop-invariant.c (calculate_loop_reg_pressure): Don't count regs
	referenced just in DEBUG_INSNs.

	* gcc.dg/pr41340.c: New test.

--- gcc/loop-invariant.c.jj	2009-10-15 22:07:43.000000000 +0200
+++ gcc/loop-invariant.c	2009-10-20 11:27:18.000000000 +0200
@@ -1785,7 +1785,7 @@ calculate_loop_reg_pressure (void)
 
       FOR_BB_INSNS (bb, insn)
 	{
-	  if (! INSN_P (insn))
+	  if (! NONDEBUG_INSN_P (insn))
 	    continue;
 
 	  mark_ref_regs (PATTERN (insn));
--- gcc/testsuite/gcc.dg/pr41340.c.jj	2009-10-20 11:33:03.000000000 +0200
+++ gcc/testsuite/gcc.dg/pr41340.c	2009-10-20 11:34:21.000000000 +0200
@@ -0,0 +1,68 @@
+/* PR debug/41340 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -g -fcompare-debug" } */
+/* { dg-options "-O3 -g -fcompare-debug -march=i686" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+typedef struct { int t; } *T;
+struct S1 { unsigned s1; };
+struct S2 { struct S1 s2; };
+struct S3 { unsigned s3; struct S2 **s4; };
+struct S5 { struct S2 *s5; };
+
+extern void fn0 (void) __attribute__ ((__noreturn__));
+T fn6 (struct S3);
+void fn7 (void);
+
+static inline __attribute__((always_inline)) int
+fn1 (const struct S1 *x)
+{
+  return x->s1;
+}
+
+static inline __attribute__((always_inline)) int
+fn2 (const struct S1 *x, unsigned y)
+{
+  if (y >= x->s1)
+    fn0 ();
+  return 0;
+}
+
+static inline __attribute__((always_inline)) int
+fn3 (struct S3 x)
+{
+  return (x.s3 == fn1 (*x.s4 ? &(*x.s4)->s2 : 0));
+}
+
+static inline __attribute__((always_inline)) int
+fn4 (struct S3 x)
+{
+  return fn2 (&(*x.s4)->s2, x.s3);
+}
+
+int
+fn5 (struct S3 x, T *y)
+{
+  if (!fn3 (x))
+    {
+      *y = (T) (long) fn4 (x);
+      return 1;
+    }
+  return 0;
+}
+
+void
+test (struct S5 *x)
+{
+  struct S3 a;
+  T b;
+  unsigned char c = 0;
+  a.s4 = &x->s5;
+  while (fn5 (a, &b))
+    if (!(b->t & 8))
+      c = 1;
+  a.s4 = &x->s5;
+  while ((b = fn6 (a)))
+    ;
+  if (!c)
+    fn7 ();
+}

	Jakub


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