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 another dead_debug* df-problems.c issue (PR debug/44023)


Hi!

df_note_bb_compute would apparently record using dead_debug_add just
the first use in a debug stmt that is no longer live, but if the
debug insn contains more than one such register, it would happily
keap that reference in after its REG_DEAD note (which leads to
-fcompare-debug failures in RA and probably a lot of potential problems
elsewhere too).

The following patch fixes that.

Unfortunately just the df_note_bb_compute change wasn't enough,
because Alex' code would immediately df_insn_rescan a debug insn
after updating it in dead_debug_insert_before.  The first such an
update would free all the other uses and thus leaving garbage
in the chains (and not result in updating it for the second etc.
time).  The patch solves it by deferring all debug insn rescans
from dead_debug_insert_before till dead_debug_finish.

Bootstrapped/regtested on x86_64-linux and i686-linux, Uros AFAIK
bootstrapped it on alpha*-linux.

Ok for trunk?

2010-05-10  Jakub Jelinek  <jakub@redhat.com>

	PR debug/44023
	* df-problems.c (struct dead_debug): Add to_rescan field.
	(dead_debug_init): Clear to_rescan field.
	(dead_debug_finish): Rescan all debug insns in to_rescan
	bitmap and free the bitmap.
	(dead_debug_insert_before): Instead of rescanning debug insns
	immediately queue their rescanning until dead_debug_finish.
	(df_note_bb_compute): After dead_debug_add do continue instead
	of break.

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

--- gcc/df-problems.c.jj	2010-05-07 09:17:45.000000000 +0200
+++ gcc/df-problems.c	2010-05-10 11:54:10.000000000 +0200
@@ -3416,6 +3416,7 @@ struct dead_debug
 {
   struct dead_debug_use *head;
   bitmap used;
+  bitmap to_rescan;
 };
 
 /* Initialize DEBUG to an empty list, and clear USED, if given.  */
@@ -3424,6 +3425,7 @@ dead_debug_init (struct dead_debug *debu
 {
   debug->head = NULL;
   debug->used = used;
+  debug->to_rescan = NULL;
   if (used)
     bitmap_clear (used);
 }
@@ -3447,10 +3449,26 @@ dead_debug_finish (struct dead_debug *de
 	{
 	  INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
 	  df_insn_rescan_debug_internal (insn);
+	  if (debug->to_rescan)
+	    bitmap_clear_bit (debug->to_rescan, INSN_UID (insn));
 	}
       debug->head = head->next;
       XDELETE (head);
     }
+
+  if (debug->to_rescan)
+    {
+      bitmap_iterator bi;
+      unsigned int uid;
+
+      EXECUTE_IF_SET_IN_BITMAP (debug->to_rescan, 0, uid, bi)
+	{
+	  struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
+	  if (insn_info)
+	    df_insn_rescan (insn_info->insn);
+	}
+      BITMAP_FREE (debug->to_rescan);
+    }
 }
 
 /* Add USE to DEBUG.  It must be a dead reference to UREGNO in a debug
@@ -3530,7 +3548,9 @@ dead_debug_insert_before (struct dead_de
 	*DF_REF_REAL_LOC (cur->use)
 	  = gen_lowpart_SUBREG (GET_MODE (*DF_REF_REAL_LOC (cur->use)), dval);
       /* ??? Should we simplify subreg of subreg?  */
-      df_insn_rescan (DF_REF_INSN (cur->use));
+      if (debug->to_rescan == NULL)
+	debug->to_rescan = BITMAP_ALLOC (NULL);
+      bitmap_set_bit (debug->to_rescan, INSN_UID (DF_REF_INSN (cur->use)));
       uses = cur->next;
       XDELETE (cur);
     }
@@ -3728,7 +3748,10 @@ df_note_bb_compute (unsigned int bb_inde
 	      if (debug_insn)
 		{
 		  if (debug_insn > 0)
-		    dead_debug_add (&debug, use, uregno);
+		    {
+		      dead_debug_add (&debug, use, uregno);
+		      continue;
+		    }
 		  break;
 		}
 	      else
--- gcc/testsuite/gcc.dg/pr44023.c.jj	2010-05-10 11:55:38.000000000 +0200
+++ gcc/testsuite/gcc.dg/pr44023.c	2010-05-10 11:57:39.000000000 +0200
@@ -0,0 +1,46 @@
+/* PR debug/44023 */
+/* { dg-do compile } */
+/* { dg-options "-fcompare-debug -O2" } */
+/* { dg-options "-fcompare-debug -O2 -mcpu=ev67" { target alpha*-*-* } } */
+
+void
+foo (unsigned f, long v, unsigned *w, unsigned a, unsigned b, unsigned e, unsigned c, unsigned d)
+{
+  unsigned h = v / 4, x[16];
+  while (f < h)
+    {
+      unsigned i;
+      f++;
+      a |= (a >> 30);
+      d = (d << 30) | ((unsigned) d >> 30);
+      c = (c << 30) | ((unsigned) c >> 30);
+      b = 30 | ((unsigned) b >> 30);
+      d += a = (a << 30) | ((unsigned) a >> 2);
+      c += ((d << 5) | (d >> 27)) + ((e & (a ^ b))) + 0x5a827999 + x[12];
+      a += (c & e);
+      c = 30 | ((unsigned) c);
+      i = x[5] ^ x[7] ^ x[8] ^ x[3];
+      x[5] = (i << 1) | ((unsigned) i >> 31);
+      i = x[6] ^ x[2] ^ x[14] ^ x[13];
+      x[6] = (i << 1) | (i >> 31);
+      b += (c | (c >> 5)) + (d ^ e) + 0x6ed9eba1 + (x[7] = (i << 1) | ((unsigned) i >> 31));
+      x[8] = i | 1;
+      e += (a | 5) + b + (i = x[9] ^ x[6], x[10] = (i << (unsigned) i));
+      e = 30 | ((unsigned) e >> 30);
+      i = x[12] ^ x[14] ^ x[12] ^ x[12], (x[12] = 1 | ((unsigned) i));
+      i = x[13] ^ x[5] ^ x[10], (x[13] = (i << (unsigned) 1));
+      i = x[2] ^ x[7] ^ x[12], (x[15] = i | ((unsigned) i >> 1));
+      i = x[2] ^ x[0] ^ x[13], (x[0] = (i << 1) | 31);
+      e = (e << 30) | 2;
+      i = x[14] ^ x[2] ^ x[15], (x[2] = i | 1);
+      x[3] = i | ((unsigned) i);
+      i = x[14] ^ x[12] ^ x[4], (x[4] = 1 | ((unsigned) i >> 1));
+      x[5] = i | 1;
+      e = (e << 30) | 30;
+      b += (5 | ((unsigned) e >> 5)) + 0x8f1bbcdc + (x[9] = (i | ((unsigned) i >> 1)));
+      i = x[2] ^ (x [10] = ((i << 1) | (i >> 1)));
+      x[13] = (i | ((unsigned) i >> 1));
+      (i = x[14] ^ x[0] ^ x[14], (x[14] = ((i << 1) | 31)));
+      a = *w += a;
+    }
+}

	Jakub


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