re PR debug/48203 (ICE in dwarf2out.c while building eglibc.)
authorJakub Jelinek <jakub@redhat.com>
Mon, 28 Mar 2011 23:53:46 +0000 (01:53 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 28 Mar 2011 23:53:46 +0000 (01:53 +0200)
PR debug/48203
* cfgexpand.c (expand_debug_expr) <case SSA_NAME>: Only
create ENTRY_VALUE if incoming or address of incoming's MEM
is a hard REG.
* dwarf2out.c (mem_loc_descriptor): Don't emit
DW_OP_GNU_entry_value of DW_OP_fbreg.
* var-tracking.c (vt_add_function_parameter): Ensure cselib_lookup
on ENTRY_VALUE is able to find the canonical parameter VALUE.
* cselib.c (rtx_equal_for_cselib_1) <case ENTRY_VALUE>: Use
rtx_equal_p instead of rtx_equal_for_cselib_1 to compare
ENTRY_VALUE_EXPs.
(cselib_hash_rtx) <case ENTRY_VALUE>: If ENTRY_VALUE_EXP
is a REG_P or MEM_P with REG_P address, compute hash directly
instead of calling cselib_hash_rtx on ENTRY_VALUE_EXP.
(preserve_only_constants): Don't clear VALUES forwaring
ENTRY_VALUE to some other VALUE.

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

From-SVN: r171640

gcc/ChangeLog
gcc/cfgexpand.c
gcc/cselib.c
gcc/dwarf2out.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr48203.c [new file with mode: 0644]
gcc/var-tracking.c

index eae651961a19c73b38c3e8f03772232ebffbe808..f3ee4b54af9a73aa92ff9835c59745d2763aabb2 100644 (file)
@@ -1,3 +1,22 @@
+2011-03-29  Jakub Jelinek  <jakub@redhat.com>
+
+       PR debug/48203
+       * cfgexpand.c (expand_debug_expr) <case SSA_NAME>: Only
+       create ENTRY_VALUE if incoming or address of incoming's MEM
+       is a hard REG.
+       * dwarf2out.c (mem_loc_descriptor): Don't emit
+       DW_OP_GNU_entry_value of DW_OP_fbreg.
+       * var-tracking.c (vt_add_function_parameter): Ensure cselib_lookup
+       on ENTRY_VALUE is able to find the canonical parameter VALUE.
+       * cselib.c (rtx_equal_for_cselib_1) <case ENTRY_VALUE>: Use
+       rtx_equal_p instead of rtx_equal_for_cselib_1 to compare
+       ENTRY_VALUE_EXPs.
+       (cselib_hash_rtx) <case ENTRY_VALUE>: If ENTRY_VALUE_EXP
+       is a REG_P or MEM_P with REG_P address, compute hash directly
+       instead of calling cselib_hash_rtx on ENTRY_VALUE_EXP.
+       (preserve_only_constants): Don't clear VALUES forwaring
+       ENTRY_VALUE to some other VALUE.
+
 2011-03-28  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * builtins.c (expand_builtin_memset_args): Use gen_int_mode
index da40aaec67560992fe0d290766c37182e9f00974..e075c53a461f98f26ebff57713e252504082dcbb 100644 (file)
@@ -3172,8 +3172,10 @@ expand_debug_expr (tree exp)
                    rtx incoming = DECL_INCOMING_RTL (SSA_NAME_VAR (exp));
                    if (incoming
                        && GET_MODE (incoming) != BLKmode
-                       && (REG_P (incoming)
-                           || (MEM_P (incoming) && REG_P (XEXP (incoming, 0)))))
+                       && ((REG_P (incoming) && HARD_REGISTER_P (incoming))
+                           || (MEM_P (incoming)
+                               && REG_P (XEXP (incoming, 0))
+                               && HARD_REGISTER_P (XEXP (incoming, 0)))))
                      {
                        op0 = gen_rtx_ENTRY_VALUE (GET_MODE (incoming));
                        ENTRY_VALUE_EXP (op0) = incoming;
index f9e13ffffef8902e270181ff6a6743148f956e93..dff096752f5295fba0d4d83a3c6aed9b476a2c11 100644 (file)
@@ -305,7 +305,8 @@ cselib_clear_table (void)
   cselib_reset_table (1);
 }
 
-/* Remove from hash table all VALUEs except constants.  */
+/* Remove from hash table all VALUEs except constants
+   and function invariants.  */
 
 static int
 preserve_only_constants (void **x, void *info ATTRIBUTE_UNUSED)
@@ -329,6 +330,14 @@ preserve_only_constants (void **x, void *info ATTRIBUTE_UNUSED)
            return 1;
        }
     }
+  /* Keep around VALUEs that forward function invariant ENTRY_VALUEs
+     to corresponding parameter VALUEs.  */
+  if (v->locs != NULL
+      && v->locs->next != NULL
+      && v->locs->next->next == NULL
+      && GET_CODE (v->locs->next->loc) == ENTRY_VALUE
+      && GET_CODE (v->locs->loc) == VALUE)
+    return 1;
 
   htab_clear_slot (cselib_hash_table, x);
   return 1;
@@ -804,8 +813,9 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, enum machine_mode memmode)
             == DEBUG_IMPLICIT_PTR_DECL (y);
 
     case ENTRY_VALUE:
-      return rtx_equal_for_cselib_1 (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y),
-                                    memmode);
+      /* ENTRY_VALUEs are function invariant, it is thus undesirable to
+        use rtx_equal_for_cselib_1 to compare the operands.  */
+      return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y));
 
     case LABEL_REF:
       return XEXP (x, 0) == XEXP (y, 0);
@@ -954,7 +964,22 @@ cselib_hash_rtx (rtx x, int create, enum machine_mode memmode)
       return hash ? hash : (unsigned int) DEBUG_IMPLICIT_PTR;
 
     case ENTRY_VALUE:
-      hash += cselib_hash_rtx (ENTRY_VALUE_EXP (x), create, memmode);
+      /* ENTRY_VALUEs are function invariant, thus try to avoid
+        recursing on argument if ENTRY_VALUE is one of the
+        forms emitted by expand_debug_expr, otherwise
+        ENTRY_VALUE hash would depend on the current value
+        in some register or memory.  */
+      if (REG_P (ENTRY_VALUE_EXP (x)))
+       hash += (unsigned int) REG
+               + (unsigned int) GET_MODE (ENTRY_VALUE_EXP (x))
+               + (unsigned int) REGNO (ENTRY_VALUE_EXP (x));
+      else if (MEM_P (ENTRY_VALUE_EXP (x))
+              && REG_P (XEXP (ENTRY_VALUE_EXP (x), 0)))
+       hash += (unsigned int) MEM
+               + (unsigned int) GET_MODE (XEXP (ENTRY_VALUE_EXP (x), 0))
+               + (unsigned int) REGNO (XEXP (ENTRY_VALUE_EXP (x), 0));
+      else
+       hash += cselib_hash_rtx (ENTRY_VALUE_EXP (x), create, memmode);
       return hash ? hash : (unsigned int) ENTRY_VALUE;
 
     case CONST_INT:
index 77d533eb8fbde7f4c6792ab7349ef02b7b88387c..182a894666c8c98e33fe93c5b869bdd7a32acef9 100644 (file)
@@ -13891,7 +13891,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
          dw_loc_descr_ref ref
            = mem_loc_descriptor (ENTRY_VALUE_EXP (rtl), GET_MODE (rtl),
                                  VAR_INIT_STATUS_INITIALIZED);
-         if (ref == NULL)
+         if (ref == NULL || ref->dw_loc_opc == DW_OP_fbreg)
            return NULL;
          mem_loc_result->dw_loc_oprnd1.v.val_loc = ref;
        }
index dec92efca7c507fb6664d5bb3fb016a57d69208d..513805d02082e09acca08f9ca13f8a334ccc5017 100644 (file)
@@ -1,3 +1,8 @@
+2011-03-29  Jakub Jelinek  <jakub@redhat.com>
+
+       PR debug/48203
+       * gcc.dg/pr48203.c: New test.
+
 2011-03-28  Jeff Law <law@redhat.com>
 
        * gcc.dg/tree-ssa/ssa-dom-thread-3.c: New test.
diff --git a/gcc/testsuite/gcc.dg/pr48203.c b/gcc/testsuite/gcc.dg/pr48203.c
new file mode 100644 (file)
index 0000000..b4b2b08
--- /dev/null
@@ -0,0 +1,51 @@
+/* PR debug/48203 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -g" } */
+
+volatile int v;
+
+void
+foo (long a, long b, long c, long d, long e, long f, long g, long h,
+     long i, long j, long k, long l, long m, long n, long o, long p)
+{
+  long a2 = a;
+  long b2 = b;
+  long c2 = c;
+  long d2 = d;
+  long e2 = e;
+  long f2 = f;
+  long g2 = g;
+  long h2 = h;
+  long i2 = i;
+  long j2 = j;
+  long k2 = k;
+  long l2 = l;
+  long m2 = m;
+  long n2 = n;
+  long o2 = o;
+  long p2 = p;
+  v++;
+}
+
+void
+bar (int a, int b, int c, int d, int e, int f, int g, int h,
+     int i, int j, int k, int l, int m, int n, int o, int p)
+{
+  int a2 = a;
+  int b2 = b;
+  int c2 = c;
+  int d2 = d;
+  int e2 = e;
+  int f2 = f;
+  int g2 = g;
+  int h2 = h;
+  int i2 = i;
+  int j2 = j;
+  int k2 = k;
+  int l2 = l;
+  int m2 = m;
+  int n2 = n;
+  int o2 = o;
+  int p2 = p;
+  v++;
+}
index ef0293790492b97dd219f9ce4f5f951672a3e23d..972995644aec9a1ec40c154127b9c35a6ca703d8 100644 (file)
@@ -8472,7 +8472,7 @@ vt_add_function_parameter (tree parm)
                         VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
       if (dv_is_value_p (dv))
        {
-         cselib_val *val = CSELIB_VAL_PTR (dv_as_value (dv));
+         cselib_val *val = CSELIB_VAL_PTR (dv_as_value (dv)), *val2;
          struct elt_loc_list *el;
          el = (struct elt_loc_list *)
            ggc_alloc_cleared_atomic (sizeof (*el));
@@ -8481,6 +8481,23 @@ vt_add_function_parameter (tree parm)
          ENTRY_VALUE_EXP (el->loc) = incoming;
          el->setting_insn = get_insns ();
          val->locs = el;
+         val2 = cselib_lookup_from_insn (el->loc, GET_MODE (incoming),
+                                         true, VOIDmode, get_insns ());
+         if (val2
+             && val2 != val
+             && val2->locs
+             && rtx_equal_p (val2->locs->loc, el->loc))
+           {
+             struct elt_loc_list *el2;
+
+             preserve_value (val2);
+             el2 = (struct elt_loc_list *)
+               ggc_alloc_cleared_atomic (sizeof (*el2));
+             el2->next = val2->locs;
+             el2->loc = dv_as_value (dv);
+             el2->setting_insn = get_insns ();
+             val2->locs = el2;
+           }
          if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE
              && INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (parm))))
            {
@@ -8499,6 +8516,24 @@ vt_add_function_parameter (tree parm)
                  ENTRY_VALUE_EXP (el->loc) = mem;
                  el->setting_insn = get_insns ();
                  val->locs = el;
+                 val2 = cselib_lookup_from_insn (el->loc, GET_MODE (mem),
+                                                 true, VOIDmode,
+                                                 get_insns ());
+                 if (val2
+                     && val2 != val
+                     && val2->locs
+                     && rtx_equal_p (val2->locs->loc, el->loc))
+                   {
+                     struct elt_loc_list *el2;
+
+                     preserve_value (val2);
+                     el2 = (struct elt_loc_list *)
+                       ggc_alloc_cleared_atomic (sizeof (*el2));
+                     el2->next = val2->locs;
+                     el2->loc = val->val_rtx;
+                     el2->setting_insn = get_insns ();
+                     val2->locs = el2;
+                   }
                }
            }
        }