re PR debug/41295 (gfortran.dg/loc_2.f90 -O3 -g fails on SH with orphaned debug_insn)
authorAlexandre Oliva <aoliva@redhat.com>
Tue, 22 Sep 2009 18:31:26 +0000 (18:31 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Tue, 22 Sep 2009 18:31:26 +0000 (18:31 +0000)
gcc/ChangeLog:
PR debug/41295
* reload1.c (reload): Reset debug insns with pseudos without
equivalences.
gcc/testsuite/ChangeLog:
PR debug/41295
* gcc.dg/pr41295.c: New.

From-SVN: r152040

gcc/ChangeLog
gcc/reload1.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr41295.c [new file with mode: 0644]

index 254de0b..2565cb9 100644 (file)
@@ -1,3 +1,9 @@
+2009-09-22  Alexandre Oliva  <aoliva@redhat.com>
+
+       PR debug/41295
+       * reload1.c (reload): Reset debug insns with pseudos without
+       equivalences.
+
 2009-09-22  Neil Vachharajani  <nvachhar@google.com>
 
        * testsuite/gcc.dg/pr40209.c: Add test case.
index fae95d6..5581cd6 100644 (file)
@@ -1241,40 +1241,54 @@ 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)))
+         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))
                {
-                 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));
+                 gcc_assert (x == reg
+                             || (GET_CODE (x) == SUBREG
+                                 && SUBREG_REG (x) == reg));
+
+                 if (!equiv)
+                   {
+                     INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
+                     df_insn_rescan_debug_internal (insn);
+                   }
                  else
-                   gcc_unreachable ();
-                 *loc = wrap_constant (GET_MODE (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));
+                     else
+                       gcc_unreachable ();
+                   *loc = wrap_constant (GET_MODE (x), *loc);
+                   }
                }
+           }
        }
     }
 
index e32300b..fd26fb2 100644 (file)
@@ -1,3 +1,8 @@
+2009-09-22  Alexandre Oliva  <aoliva@redhat.com>
+
+       PR debug/41295
+       * gcc.dg/pr41295.c: New.
+
 2009-09-22  Adam Nemet  <anemet@caviumnetworks.com>
 
        * gcc.target/mips/code-readable-1.c: Change \. to \\. when
diff --git a/gcc/testsuite/gcc.dg/pr41295.c b/gcc/testsuite/gcc.dg/pr41295.c
new file mode 100644 (file)
index 0000000..fabff63
--- /dev/null
@@ -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 ();
+}