This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PR41295] discard post-reload debug var_location referencing pseudos
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 10 Sep 2009 03:49:28 -0300
- Subject: [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