diff mbox

Improve debug info for small structures (2)

Message ID 8592328.QliyaZRQOE@polaris
State New
Headers show

Commit Message

Eric Botcazou Oct. 24, 2013, 10:45 a.m. UTC
Hi,

this is a follow-up to http://gcc.gnu.org/ml/gcc-patches/2013-06/msg00895.html 
which fixed the 3. issue partially.  This resulted in gcc.dg/guality/param-2.c 
being compiled with -fno-var-tracking-assignments.

The attached testcase param-3.c is identical to param-2.c but without the 
special option; it fails (at least) for SPARC & PowerPC on the one hand and 
for SPARC64 & x86-64 on the other hand. The first issue is that var-tracking.c 
cannot track values for multiple-part variables; rather than implementing 
this, which looks quite daunting to me, the patch simply reverts to location 
tracking for multiple-part parameters, on the grounds that they are rarely 
modified in practice.  The second issue is that var-tracking.c doesn't handle 
multiple-part parameters coming in a PARALLEL, like on SPARC64 & x86-64.

Tested on x86-64 & PowerPC Linux and SPARC & SPARC64 Solaris, OK for mainline?


2013-10-24  Eric Botcazou  <ebotcazou@adacore.com>

	* var-tracking.c (track_expr_p): Do not track declarations for parts
	of tracked parameters.
	(add_stores): Do not track values for tracked parameters passed in
	multiple locations.
	(vt_get_decl_and_offset): Handle PARALLEL.
	(vt_add_function_parameter): Handle parameters with incoming PARALLEL.


2013-10-24  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.dg/guality/param-3.c: New test.
diff mbox

Patch

Index: var-tracking.c
===================================================================
--- var-tracking.c	(revision 203876)
+++ var-tracking.c	(working copy)
@@ -5065,6 +5065,11 @@  track_expr_p (tree expr, bool need_rtl)
 					   &maxsize);
 	      if (!DECL_P (innerdecl)
 		  || DECL_IGNORED_P (innerdecl)
+		  /* Do not track declarations for parts of tracked parameters
+		     since we want to track them as a whole instead.  */
+		  || (TREE_CODE (innerdecl) == PARM_DECL
+		      && DECL_MODE (innerdecl) != BLKmode
+		      && TREE_CODE (TREE_TYPE (innerdecl)) != UNION_TYPE)
 		  || TREE_STATIC (innerdecl)
 		  || bitsize <= 0
 		  || bitpos + bitsize > 256
@@ -5919,6 +5924,20 @@  add_stores (rtx loc, const_rtx expr, voi
   if (type != MO_VAL_SET)
     goto log_and_return;
 
+  /* We cannot track values for multiple-part variables, so we track only
+     locations for tracked parameters passed either by invisible reference
+     or directly in multiple locations.  */
+  if (track_p
+      && REG_P (loc)
+      && REG_EXPR (loc)
+      && TREE_CODE (REG_EXPR (loc)) == PARM_DECL
+      && DECL_MODE (REG_EXPR (loc)) != BLKmode
+      && ((MEM_P (DECL_INCOMING_RTL (REG_EXPR (loc)))
+	   && XEXP (DECL_INCOMING_RTL (REG_EXPR (loc)), 0) != arg_pointer_rtx)
+          || (GET_CODE (DECL_INCOMING_RTL (REG_EXPR (loc))) == PARALLEL
+	      && XVECLEN (DECL_INCOMING_RTL (REG_EXPR (loc)), 0) > 1)))
+    goto log_and_return;
+
   v = find_use_val (oloc, mode, cui);
 
   if (!v)
@@ -9447,6 +9466,32 @@  vt_get_decl_and_offset (rtx rtl, tree *d
 	  return true;
 	}
     }
+  else if (GET_CODE (rtl) == PARALLEL)
+    {
+      tree decl = NULL_TREE;
+      HOST_WIDE_INT offset = MAX_VAR_PARTS;
+      int len = XVECLEN (rtl, 0), i;
+
+      for (i = 0; i < len; i++)
+	{
+	  rtx reg = XEXP (XVECEXP (rtl, 0, i), 0);
+	  if (!REG_P (reg) || !REG_ATTRS (reg))
+	    break;
+	  if (!decl)
+	    decl = REG_EXPR (reg);
+	  if (REG_EXPR (reg) != decl)
+	    break;
+	  if (REG_OFFSET (reg) < offset)
+	    offset = REG_OFFSET (reg);
+	}
+
+      if (i == len)
+	{
+	  *declp = decl;
+	  *offsetp = offset;
+	  return true;
+	}
+    }
   else if (MEM_P (rtl))
     {
       if (MEM_ATTRS (rtl))
@@ -9532,6 +9577,28 @@  vt_add_function_parameter (tree parm)
 	  p.outgoing = incoming;
 	  vec_safe_push (windowed_parm_regs, p);
 	}
+      else if (GET_CODE (incoming) == PARALLEL)
+	{
+	  rtx outgoing
+	    = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (XVECLEN (incoming, 0)));
+	  int i;
+
+	  for (i = 0; i < XVECLEN (incoming, 0); i++)
+	    {
+	      rtx reg = XEXP (XVECEXP (incoming, 0, i), 0);
+	      parm_reg_t p;
+	      p.incoming = reg;
+	      reg = gen_rtx_REG_offset (reg, GET_MODE (reg),
+					OUTGOING_REGNO (REGNO (reg)), 0);
+	      p.outgoing = reg;
+	      XVECEXP (outgoing, 0, i)
+		= gen_rtx_EXPR_LIST (VOIDmode, reg,
+				     XEXP (XVECEXP (incoming, 0, i), 1));
+	      vec_safe_push (windowed_parm_regs, p);
+	    }
+
+	  incoming = outgoing;
+	}
       else if (MEM_P (incoming)
 	       && REG_P (XEXP (incoming, 0))
 	       && HARD_REGISTER_P (XEXP (incoming, 0)))
@@ -9665,6 +9732,20 @@  vt_add_function_parameter (tree parm)
 	    }
 	}
     }
+  else if (GET_CODE (incoming) == PARALLEL && !dv_onepart_p (dv))
+    {
+      int i;
+
+      for (i = 0; i < XVECLEN (incoming, 0); i++)
+	{
+	  rtx reg = XEXP (XVECEXP (incoming, 0, i), 0);
+	  offset = REG_OFFSET (reg);
+	  gcc_assert (REGNO (reg) < FIRST_PSEUDO_REGISTER);
+	  attrs_list_insert (&out->regs[REGNO (reg)], dv, offset, reg);
+	  set_variable_part (out, reg, dv, offset,
+			     VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
+	}
+    }
   else if (MEM_P (incoming))
     {
       incoming = var_lowpart (mode, incoming);