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]

[PR41295] discard post-reload debug var_location referencing pseudos


IRA may split live ranges of pseudos so that a pseudo formerly rewritten
into other loop IVs, but for some reason not removed, is actually dead
within the loop (i.e., dead after the loop, and used only to compute
itself in each iteration).  It will then drop the pseudo, rather than
allocating registers and performing the operations encoded in there.

The pseudo allocated for that live^H^H^H^Hdead range, unfortunately,
might remain in debug insns, which is then detected by failed assertions
in postreload.

This patch reworks the equivalence substitution code used for debug
insns at the end of reload so as to detect the case of an unallocated
pseudo, and discard the entire debug expression.

Ok to install, if it passes regression testing?

for  gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/41295
	* reload1.c (reload): Reset debug insns with pseudos without
	equivalences.

for  gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/41295
	* gcc.dg/pr41295.c: New.

Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c.orig	2009-09-10 01:53:18.000000000 -0300
+++ gcc/reload1.c	2009-09-10 02:32:31.000000000 -0300
@@ -1242,39 +1242,52 @@ reload (rtx first, int global)
 	{
 	  rtx reg = regno_reg_rtx[i];
 	  rtx equiv = 0;
-	  df_ref use;
+	  df_ref use, next;
 
 	  if (reg_equiv_constant[i])
 	    equiv = reg_equiv_constant[i];
 	  else if (reg_equiv_invariant[i])
 	    equiv = reg_equiv_invariant[i];
 	  else if (reg && MEM_P (reg))
-	    {
-	      equiv = targetm.delegitimize_address (reg);
-	      if (equiv == reg)
-		equiv = 0;
-	    }
+	    equiv = targetm.delegitimize_address (reg);
 	  else if (reg && REG_P (reg) && (int)REGNO (reg) != i)
 	    equiv = reg;
 
-	  if (equiv)
-	    for (use = DF_REG_USE_CHAIN (i); use;
-		 use = DF_REF_NEXT_REG (use))
-	      if (DEBUG_INSN_P (DF_REF_INSN (use)))
-		{
-		  rtx *loc = DF_REF_LOC (use);
-		  rtx x = *loc;
-
-		  if (x == reg)
-		    *loc = copy_rtx (equiv);
-		  else if (GET_CODE (x) == SUBREG
-			   && SUBREG_REG (x) == reg)
-		    *loc = simplify_gen_subreg (GET_MODE (x), equiv,
-						GET_MODE (reg),
-						SUBREG_BYTE (x));
+	  if (equiv == reg)
+	    continue;
+
+	  for (use = DF_REG_USE_CHAIN (i); use; use = next)
+	    {
+	      rtx *loc = DF_REF_LOC (use);
+	      rtx x = *loc;
+
+	      insn = DF_REF_INSN (use);
+	      next = DF_REF_NEXT_REG (use);
+
+	      if (DEBUG_INSN_P (insn))
+		{
+		  gcc_assert (x == reg
+			      || (GET_CODE (x) == SUBREG
+				  && SUBREG_REG (x) == reg));
+
+		  if (!equiv)
+		    INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
 		  else
-		    gcc_unreachable ();
+		    {
+		      if (x == reg)
+			*loc = copy_rtx (equiv);
+		      else if (GET_CODE (x) == SUBREG
+			       && SUBREG_REG (x) == reg)
+			*loc = simplify_gen_subreg (GET_MODE (x), equiv,
+						    GET_MODE (reg),
+						    SUBREG_BYTE (x));
+		      else
+			gcc_unreachable ();
+		    }
+
+		  df_insn_rescan_debug_internal (insn);
 		}
+	    }
 	}
     }
 
Index: gcc/testsuite/gcc.dg/pr41295.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.dg/pr41295.c	2009-09-10 02:18:12.000000000 -0300
@@ -0,0 +1,91 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -g" } */
+
+enum reg_class
+{
+  BASE_REGS,
+  GENERAL_REGS,
+  LIM_REG_CLASSES
+};
+
+static __inline__ unsigned char
+hard_reg_set_subset_p (const unsigned long x[4], const unsigned long y[4])
+{
+  return ((x[0] & ~y[0]) == 0
+          && (x[1] & ~y[1]) == 0
+          && (x[2] & ~y[2]) == 0
+	  && (x[3] & ~y[3]) == 0);
+}
+
+static __inline__ unsigned char
+hard_reg_set_equal_p (const unsigned long x[4], const unsigned long y[4])
+{
+  return x[0] == y[0]
+         && x[1] == y[1]
+         && x[2] == y[2]
+         && x[3] == y[3];
+}
+
+extern unsigned long reg_class_contents[(int) LIM_REG_CLASSES][4];
+extern int ira_important_classes_num;
+extern enum reg_class ira_important_classes[(int) LIM_REG_CLASSES];
+extern enum reg_class ira_reg_class_intersect[(int) LIM_REG_CLASSES][(int)
+								     LIM_REG_CLASSES];
+extern unsigned char ira_reg_classes_intersect_p[(int) LIM_REG_CLASSES][(int)
+									LIM_REG_CLASSES];
+extern enum reg_class ira_reg_class_super_classes[(int) LIM_REG_CLASSES][(int)
+									 LIM_REG_CLASSES];
+static unsigned long temp_hard_regset[4];
+
+static void
+setup_reg_class_relations (void)
+{
+  int i, cl1, cl2, cl3;
+  unsigned long temp_set2[4];
+  for (cl1 = 0; cl1 < (int) LIM_REG_CLASSES; cl1++)
+    {
+      ira_reg_class_super_classes[cl1][0] = LIM_REG_CLASSES;
+      for (cl2 = 0; cl2 < (int) LIM_REG_CLASSES; cl2++)
+	{
+	  ira_reg_classes_intersect_p[cl1][cl2] = 0;
+	  {
+	    unsigned long *scan_tp_ = (temp_set2), *scan_fp_ =
+	      (reg_class_contents[cl2]);
+	    scan_tp_[1] = scan_fp_[1];
+	    scan_tp_[2] = scan_fp_[2];
+	    scan_tp_[3] = scan_fp_[3];
+	  }
+	  for (i = 0; i < ira_important_classes_num; i++)
+	    {
+	      cl3 = ira_important_classes[i];
+	      {
+		unsigned long *scan_tp_ = (temp_hard_regset), *scan_fp_ =
+		  (reg_class_contents[cl3]);
+		scan_tp_[0] = scan_fp_[0];
+		scan_tp_[1] = scan_fp_[1];
+		scan_tp_[3] = scan_fp_[3];
+	      }
+	      if (!hard_reg_set_subset_p (temp_hard_regset, temp_set2)
+		  || (hard_reg_set_equal_p (temp_hard_regset, temp_set2)
+		      && hard_reg_set_subset_p (reg_class_contents[cl3],
+						reg_class_contents[(int)
+								   ira_reg_class_intersect
+								   [cl1]
+								   [cl2]])))
+		ira_reg_class_intersect[cl1][cl2] = (enum reg_class) cl3;
+	    }
+	}
+    }
+}
+
+static void
+find_reg_class_closure (void)
+{
+  setup_reg_class_relations ();
+}
+
+void
+ira_init (void)
+{
+  find_reg_class_closure ();
+}
-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist      Red Hat Brazil Compiler Engineer

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