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] ENTRY_VALUE fixes (PR debug/48203)


Hi!

This patch fixes a few problems:
1) on arm bootstrap fails, because expansion creates ENTRY_VALUE
   of a MEM with virtual reg address, which then is changed for
   ap + constant and dwarf2out doesn't expect that.
   As in most passes ENTRY_VALUE is treated like a black box,
   we shouldn't accept anything but hard registers or
   MEMs with hard register addresses
2) DW_OP_GNU_entry_value 2 <DW_OP_fbreg 16> is something we should
   avoid
3) the var-tracking and cselib changes were added to make sure
   var-tracking can easily map ENTRY_VALUEs created by cfgexpand
   back to the canonical VALUEs holding the parameter.  This means
   they can expand even to the original argument registers if they
   haven't been modified or at least in the part of the function
   where they haven't been modified.  E.g. on x86_64-linux
   on the attached testcase we no longer generate any DW_OP_GNU_entry_value
   ops, as the registers aren't clobbered.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2011-03-20  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.

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

--- gcc/cfgexpand.c.jj	2011-03-17 09:37:59.000000000 +0100
+++ gcc/cfgexpand.c	2011-03-19 17:45:32.000000000 +0100
@@ -3182,8 +3182,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;
--- gcc/dwarf2out.c.jj	2011-03-19 17:28:32.000000000 +0100
+++ gcc/dwarf2out.c	2011-03-19 17:48:42.000000000 +0100
@@ -13877,7 +13877,7 @@ mem_loc_descriptor (rtx rtl, enum machin
 	  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;
 	}
--- gcc/var-tracking.c.jj	2011-03-19 16:20:26.000000000 +0100
+++ gcc/var-tracking.c	2011-03-19 18:49:48.000000000 +0100
@@ -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 (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 = val->val_rtx;
+		      el2->setting_insn = get_insns ();
+		      val2->locs = el2;
+		    }
 		}
 	    }
 	}
--- gcc/cselib.c.jj	2011-03-16 18:30:12.000000000 +0100
+++ gcc/cselib.c	2011-03-19 19:58:54.000000000 +0100
@@ -329,6 +329,12 @@ preserve_only_constants (void **x, void 
 	    return 1;
 	}
     }
+  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 +810,7 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, en
 	     == DEBUG_IMPLICIT_PTR_DECL (y);
 
     case ENTRY_VALUE:
-      return rtx_equal_for_cselib_1 (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y),
-				     memmode);
+      return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y));
 
     case LABEL_REF:
       return XEXP (x, 0) == XEXP (y, 0);
@@ -954,7 +959,17 @@ cselib_hash_rtx (rtx x, int create, enum
       return hash ? hash : (unsigned int) DEBUG_IMPLICIT_PTR;
 
     case ENTRY_VALUE:
-      hash += cselib_hash_rtx (ENTRY_VALUE_EXP (x), create, memmode);
+      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:
--- gcc/testsuite/gcc.dg/pr48203.c.jj	2011-03-19 18:06:29.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr48203.c	2011-03-19 18:06:01.000000000 +0100
@@ -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++;
+}

	Jakub


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