public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PR debug/46724] var-track address of RESULT_DECL
@ 2010-12-21 10:32 Alexandre Oliva
  2010-12-21 18:32 ` Richard Henderson
  0 siblings, 1 reply; 5+ messages in thread
From: Alexandre Oliva @ 2010-12-21 10:32 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 954 bytes --]

We curently don't emit debug info for RESULT_DECLs, but after NVR, we
use the debug info we'd have emitted for them for VAR_DECLs mapped to
the result, so we'd better make sure they're accurate.

Unfortunately, the incoming address of the RESULT_DECL does not undergo
var-tracking, and the address of the RESULT_DECL is permanently set to
that of a copy of the incoming parameter, even though the copy may be
optimized away within the function.

This patch arranges for us to var-track (not necessarily at assignments)
the nameless VAR_DECL that holds the address of the result, and sets the
DECL_VALUE_EXPR of the RESULT_DECL so that the relationship between the
RESULT_DECL and the nameless VAR_DECL is in the tree level, so that we
use its var-tracked locations to emit debug info for any variable NVRed
to the RESULT_DECL.

It also introduces the needed support for DECL_VALUE_EXPR in
RESULT_DECLs.

Regstrapped on x86_64-linux-gnu.  Ok to install?


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: result-decl-value-pr46724.patch --]
[-- Type: text/x-diff, Size: 11427 bytes --]

for gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/46724
	* function.c (assign_parms_augmented_arg_list): Name and mark
	DECL of result address as NAMELESS rather than IGNORED.
	(assign_parms): Set DECL_VALUE_EXPR for indirect result.
	* tree.h (tree_decl_common::decl_flag_2): Document RESULT_DECL.
	(DECL_HAS_VALUE_EXPR_P): Accept RESULT_DECL.
	* dwarf2out.c (loc_list_from_tree) <RESULT_DECL>: Use
	DECL_VALUE_EXPR.
	* dbxout.c (dbxout_expand_expr) <RESULT_DECL>: Likewise.
	* var-tracking.c (vt_add_function_parameter): New, split out of...
	(vt_add_function_parameters): ... this.  Handle incoming
	pointer to hold result.

Index: gcc/function.c
===================================================================
--- gcc/function.c.orig	2010-12-18 05:10:06.824255797 -0200
+++ gcc/function.c	2010-12-18 05:24:35.581505785 -0200
@@ -2253,10 +2253,11 @@ assign_parms_augmented_arg_list (struct 
       tree decl;
 
       decl = build_decl (DECL_SOURCE_LOCATION (fndecl),
-			 PARM_DECL, NULL_TREE, type);
+			 PARM_DECL, get_identifier (".result_ptr"), type);
       DECL_ARG_TYPE (decl) = type;
       DECL_ARTIFICIAL (decl) = 1;
-      DECL_IGNORED_P (decl) = 1;
+      DECL_NAMELESS (decl) = 1;
+      TREE_CONSTANT (decl) = 1;
 
       DECL_CHAIN (decl) = all->orig_fnargs;
       all->orig_fnargs = decl;
@@ -3418,13 +3419,22 @@ assign_parms (tree fndecl)
       rtx x;
 
       if (DECL_BY_REFERENCE (result))
-	x = addr;
+	{
+	  SET_DECL_VALUE_EXPR (result, all.function_result_decl);
+	  x = addr;
+	}
       else
 	{
+	  SET_DECL_VALUE_EXPR (result,
+			       build1 (INDIRECT_REF, TREE_TYPE (result),
+				       all.function_result_decl));
 	  addr = convert_memory_address (Pmode, addr);
 	  x = gen_rtx_MEM (DECL_MODE (result), addr);
 	  set_mem_attributes (x, result, 1);
 	}
+
+      DECL_HAS_VALUE_EXPR_P (result) = 1;
+
       SET_DECL_RTL (result, x);
     }
 
Index: gcc/tree.h
===================================================================
--- gcc/tree.h.orig	2010-12-18 05:10:06.953255983 -0200
+++ gcc/tree.h	2010-12-18 05:20:29.812257147 -0200
@@ -2773,7 +2773,8 @@ struct GTY(()) tree_decl_common {
      In TYPE_DECL, this is TYPE_DECL_SUPPRESS_DEBUG.  */
   unsigned decl_flag_1 : 1;
   /* In FIELD_DECL, this is DECL_NONADDRESSABLE_P
-     In VAR_DECL and PARM_DECL, this is DECL_HAS_VALUE_EXPR_P.  */
+     In VAR_DECL, PARM_DECL and RESULT_DECL, this is
+     DECL_HAS_VALUE_EXPR_P.  */
   unsigned decl_flag_2 : 1;
   /* Logically, these two would go in a theoretical base shared by var and
      parm decl. */
@@ -2818,7 +2819,8 @@ extern void decl_value_expr_insert (tree
    decl itself.  This should only be used for debugging; once this field has
    been set, the decl itself may not legitimately appear in the function.  */
 #define DECL_HAS_VALUE_EXPR_P(NODE) \
-  (TREE_CHECK2 (NODE, VAR_DECL, PARM_DECL)->decl_common.decl_flag_2)
+  (TREE_CHECK3 (NODE, VAR_DECL, PARM_DECL, RESULT_DECL) \
+   ->decl_common.decl_flag_2)
 #define DECL_VALUE_EXPR(NODE) \
   (decl_value_expr_lookup (DECL_WRTL_CHECK (NODE)))
 #define SET_DECL_VALUE_EXPR(NODE, VAL) \
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c.orig	2010-12-18 05:10:07.352256670 -0200
+++ gcc/dwarf2out.c	2010-12-18 05:20:29.989282017 -0200
@@ -15446,12 +15446,12 @@ loc_list_from_tree (tree loc, int want_a
       /* FALLTHRU */
 
     case PARM_DECL:
+    case RESULT_DECL:
       if (DECL_HAS_VALUE_EXPR_P (loc))
 	return loc_list_from_tree (DECL_VALUE_EXPR (loc),
 				   want_address);
       /* FALLTHRU */
 
-    case RESULT_DECL:
     case FUNCTION_DECL:
       {
 	rtx rtl;
Index: gcc/dbxout.c
===================================================================
--- gcc/dbxout.c.orig	2010-12-18 05:10:07.196562031 -0200
+++ gcc/dbxout.c	2010-12-18 05:20:30.095271325 -0200
@@ -2396,12 +2396,12 @@ dbxout_expand_expr (tree expr)
       /* FALLTHRU */
 
     case PARM_DECL:
+    case RESULT_DECL:
       if (DECL_HAS_VALUE_EXPR_P (expr))
 	return dbxout_expand_expr (DECL_VALUE_EXPR (expr));
       /* FALLTHRU */
 
     case CONST_DECL:
-    case RESULT_DECL:
       return DECL_RTL_IF_SET (expr);
 
     case INTEGER_CST:
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c.orig	2010-12-18 05:10:07.073509808 -0200
+++ gcc/var-tracking.c	2010-12-18 05:44:50.633258275 -0200
@@ -7999,121 +7999,136 @@ vt_get_decl_and_offset (rtx rtl, tree *d
   return false;
 }
 
-/* Insert function parameters to IN and OUT sets of ENTRY_BLOCK.  */
-
 static void
-vt_add_function_parameters (void)
+vt_add_function_parameter (tree parm)
 {
-  tree parm;
+  rtx decl_rtl = DECL_RTL_IF_SET (parm);
+  rtx incoming = DECL_INCOMING_RTL (parm);
+  tree decl;
+  enum machine_mode mode;
+  HOST_WIDE_INT offset;
+  dataflow_set *out;
+  decl_or_value dv;
 
-  for (parm = DECL_ARGUMENTS (current_function_decl);
-       parm; parm = DECL_CHAIN (parm))
-    {
-      rtx decl_rtl = DECL_RTL_IF_SET (parm);
-      rtx incoming = DECL_INCOMING_RTL (parm);
-      tree decl;
-      enum machine_mode mode;
-      HOST_WIDE_INT offset;
-      dataflow_set *out;
-      decl_or_value dv;
-
-      if (TREE_CODE (parm) != PARM_DECL)
-	continue;
-
-      if (!DECL_NAME (parm))
-	continue;
+  if (TREE_CODE (parm) != PARM_DECL)
+    return;
 
-      if (!decl_rtl || !incoming)
-	continue;
+  if (!decl_rtl || !incoming)
+    return;
 
-      if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
-	continue;
+  if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
+    return;
 
-      if (!vt_get_decl_and_offset (incoming, &decl, &offset))
+  if (!vt_get_decl_and_offset (incoming, &decl, &offset))
+    {
+      if (REG_P (incoming) || MEM_P (incoming))
 	{
-	  if (REG_P (incoming) || MEM_P (incoming))
-	    {
-	      /* This means argument is passed by invisible reference.  */
-	      offset = 0;
-	      decl = parm;
-	      incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
-	    }
-	  else
-	    {
-	      if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
-		continue;
-	      offset += byte_lowpart_offset (GET_MODE (incoming),
-					     GET_MODE (decl_rtl));
-	    }
+	  /* This means argument is passed by invisible reference.  */
+	  offset = 0;
+	  decl = parm;
+	  incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
 	}
-
-      if (!decl)
-	continue;
-
-      if (parm != decl)
+      else
 	{
-	  /* Assume that DECL_RTL was a pseudo that got spilled to
-	     memory.  The spill slot sharing code will force the
-	     memory to reference spill_slot_decl (%sfp), so we don't
-	     match above.  That's ok, the pseudo must have referenced
-	     the entire parameter, so just reset OFFSET.  */
-	  gcc_assert (decl == get_spill_slot_decl (false));
-	  offset = 0;
+	  if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
+	    return;
+	  offset += byte_lowpart_offset (GET_MODE (incoming),
+					 GET_MODE (decl_rtl));
 	}
+    }
 
-      if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
-	continue;
+  if (!decl)
+    return;
 
-      out = &VTI (ENTRY_BLOCK_PTR)->out;
+  if (parm != decl)
+    {
+      /* Assume that DECL_RTL was a pseudo that got spilled to
+	 memory.  The spill slot sharing code will force the
+	 memory to reference spill_slot_decl (%sfp), so we don't
+	 match above.  That's ok, the pseudo must have referenced
+	 the entire parameter, so just reset OFFSET.  */
+      gcc_assert (decl == get_spill_slot_decl (false));
+      offset = 0;
+    }
 
-      dv = dv_from_decl (parm);
+  if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
+    return;
 
-      if (target_for_debug_bind (parm)
-	  /* We can't deal with these right now, because this kind of
-	     variable is single-part.  ??? We could handle parallels
-	     that describe multiple locations for the same single
-	     value, but ATM we don't.  */
-	  && GET_CODE (incoming) != PARALLEL)
-	{
-	  cselib_val *val;
+  out = &VTI (ENTRY_BLOCK_PTR)->out;
 
-	  /* ??? We shouldn't ever hit this, but it may happen because
-	     arguments passed by invisible reference aren't dealt with
-	     above: incoming-rtl will have Pmode rather than the
-	     expected mode for the type.  */
-	  if (offset)
-	    continue;
-
-	  val = cselib_lookup (var_lowpart (mode, incoming), mode, true);
-
-	  /* ??? Float-typed values in memory are not handled by
-	     cselib.  */
-	  if (val)
-	    {
-	      preserve_value (val);
-	      set_variable_part (out, val->val_rtx, dv, offset,
-				 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
-	      dv = dv_from_value (val->val_rtx);
-	    }
-	}
+  dv = dv_from_decl (parm);
 
-      if (REG_P (incoming))
+  if (target_for_debug_bind (parm)
+      /* We can't deal with these right now, because this kind of
+	 variable is single-part.  ??? We could handle parallels
+	 that describe multiple locations for the same single
+	 value, but ATM we don't.  */
+      && GET_CODE (incoming) != PARALLEL)
+    {
+      cselib_val *val;
+
+      /* ??? We shouldn't ever hit this, but it may happen because
+	 arguments passed by invisible reference aren't dealt with
+	 above: incoming-rtl will have Pmode rather than the
+	 expected mode for the type.  */
+      if (offset)
+	return;
+
+      val = cselib_lookup (var_lowpart (mode, incoming), mode, true);
+
+      /* ??? Float-typed values in memory are not handled by
+	 cselib.  */
+      if (val)
 	{
-	  incoming = var_lowpart (mode, incoming);
-	  gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
-	  attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
-			     incoming);
-	  set_variable_part (out, incoming, dv, offset,
-			     VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
-	}
-      else if (MEM_P (incoming))
-	{
-	  incoming = var_lowpart (mode, incoming);
-	  set_variable_part (out, incoming, dv, offset,
+	  preserve_value (val);
+	  set_variable_part (out, val->val_rtx, dv, offset,
 			     VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
+	  dv = dv_from_value (val->val_rtx);
 	}
     }
 
+  if (REG_P (incoming))
+    {
+      incoming = var_lowpart (mode, incoming);
+      gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
+      attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
+			 incoming);
+      set_variable_part (out, incoming, dv, offset,
+			 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
+    }
+  else if (MEM_P (incoming))
+    {
+      incoming = var_lowpart (mode, incoming);
+      set_variable_part (out, incoming, dv, offset,
+			 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
+    }
+}
+
+/* Insert function parameters to IN and OUT sets of ENTRY_BLOCK.  */
+
+static void
+vt_add_function_parameters (void)
+{
+  tree parm;
+
+  for (parm = DECL_ARGUMENTS (current_function_decl);
+       parm; parm = DECL_CHAIN (parm))
+    vt_add_function_parameter (parm);
+
+  if (DECL_HAS_VALUE_EXPR_P (DECL_RESULT (current_function_decl)))
+    {
+      tree vexpr = DECL_VALUE_EXPR (DECL_RESULT (current_function_decl));
+
+      if (TREE_CODE (vexpr) == INDIRECT_REF)
+	vexpr = TREE_OPERAND (vexpr, 0);
+
+      if (TREE_CODE (vexpr) == PARM_DECL
+	  && DECL_ARTIFICIAL (vexpr)
+	  && !DECL_IGNORED_P (vexpr)
+	  && DECL_NAMELESS (vexpr))
+	vt_add_function_parameter (vexpr);
+    }
+
   if (MAY_HAVE_DEBUG_INSNS)
     {
       cselib_preserve_only_values ();

[-- Attachment #3: Type: text/plain, Size: 257 bytes --]


-- 
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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PR debug/46724] var-track address of RESULT_DECL
  2010-12-21 10:32 [PR debug/46724] var-track address of RESULT_DECL Alexandre Oliva
@ 2010-12-21 18:32 ` Richard Henderson
  2010-12-22  6:37   ` Alexandre Oliva
  0 siblings, 1 reply; 5+ messages in thread
From: Richard Henderson @ 2010-12-21 18:32 UTC (permalink / raw)
  To: Alexandre Oliva; +Cc: gcc-patches

On 12/20/2010 11:30 PM, Alexandre Oliva wrote:
> 	PR debug/46724
> 	* function.c (assign_parms_augmented_arg_list): Name and mark
> 	DECL of result address as NAMELESS rather than IGNORED.
> 	(assign_parms): Set DECL_VALUE_EXPR for indirect result.
> 	* tree.h (tree_decl_common::decl_flag_2): Document RESULT_DECL.
> 	(DECL_HAS_VALUE_EXPR_P): Accept RESULT_DECL.
> 	* dwarf2out.c (loc_list_from_tree) <RESULT_DECL>: Use
> 	DECL_VALUE_EXPR.
> 	* dbxout.c (dbxout_expand_expr) <RESULT_DECL>: Likewise.
> 	* var-tracking.c (vt_add_function_parameter): New, split out of...
> 	(vt_add_function_parameters): ... this.  Handle incoming
> 	pointer to hold result.

Ok, with a function comment for vt_add_function_parameter.


r~

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PR debug/46724] var-track address of RESULT_DECL
  2010-12-21 18:32 ` Richard Henderson
@ 2010-12-22  6:37   ` Alexandre Oliva
  2010-12-28 20:26     ` H.J. Lu
  0 siblings, 1 reply; 5+ messages in thread
From: Alexandre Oliva @ 2010-12-22  6:37 UTC (permalink / raw)
  To: Richard Henderson; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 156 bytes --]

On Dec 21, 2010, Richard Henderson <rth@redhat.com> wrote:

> Ok, with a function comment for vt_add_function_parameter.

Thanks, here's what I installed.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: result-decl-value-pr46724.patch --]
[-- Type: text/x-diff, Size: 11501 bytes --]

for gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/46724
	* function.c (assign_parms_augmented_arg_list): Name and mark
	DECL of result address as NAMELESS rather than IGNORED.
	(assign_parms): Set DECL_VALUE_EXPR for indirect result.
	* tree.h (tree_decl_common::decl_flag_2): Document RESULT_DECL.
	(DECL_HAS_VALUE_EXPR_P): Accept RESULT_DECL.
	* dwarf2out.c (loc_list_from_tree) <RESULT_DECL>: Use
	DECL_VALUE_EXPR.
	* dbxout.c (dbxout_expand_expr) <RESULT_DECL>: Likewise.
	* var-tracking.c (vt_add_function_parameter): New, split out of...
	(vt_add_function_parameters): ... this.  Handle incoming
	pointer to hold result.

Index: gcc/function.c
===================================================================
--- gcc/function.c.orig	2010-12-22 01:37:41.590793383 -0200
+++ gcc/function.c	2010-12-22 01:46:17.286791902 -0200
@@ -2253,10 +2253,11 @@ assign_parms_augmented_arg_list (struct 
       tree decl;
 
       decl = build_decl (DECL_SOURCE_LOCATION (fndecl),
-			 PARM_DECL, NULL_TREE, type);
+			 PARM_DECL, get_identifier (".result_ptr"), type);
       DECL_ARG_TYPE (decl) = type;
       DECL_ARTIFICIAL (decl) = 1;
-      DECL_IGNORED_P (decl) = 1;
+      DECL_NAMELESS (decl) = 1;
+      TREE_CONSTANT (decl) = 1;
 
       DECL_CHAIN (decl) = all->orig_fnargs;
       all->orig_fnargs = decl;
@@ -3418,13 +3419,22 @@ assign_parms (tree fndecl)
       rtx x;
 
       if (DECL_BY_REFERENCE (result))
-	x = addr;
+	{
+	  SET_DECL_VALUE_EXPR (result, all.function_result_decl);
+	  x = addr;
+	}
       else
 	{
+	  SET_DECL_VALUE_EXPR (result,
+			       build1 (INDIRECT_REF, TREE_TYPE (result),
+				       all.function_result_decl));
 	  addr = convert_memory_address (Pmode, addr);
 	  x = gen_rtx_MEM (DECL_MODE (result), addr);
 	  set_mem_attributes (x, result, 1);
 	}
+
+      DECL_HAS_VALUE_EXPR_P (result) = 1;
+
       SET_DECL_RTL (result, x);
     }
 
Index: gcc/tree.h
===================================================================
--- gcc/tree.h.orig	2010-12-22 01:37:41.704788669 -0200
+++ gcc/tree.h	2010-12-22 01:46:17.333791271 -0200
@@ -2773,7 +2773,8 @@ struct GTY(()) tree_decl_common {
      In TYPE_DECL, this is TYPE_DECL_SUPPRESS_DEBUG.  */
   unsigned decl_flag_1 : 1;
   /* In FIELD_DECL, this is DECL_NONADDRESSABLE_P
-     In VAR_DECL and PARM_DECL, this is DECL_HAS_VALUE_EXPR_P.  */
+     In VAR_DECL, PARM_DECL and RESULT_DECL, this is
+     DECL_HAS_VALUE_EXPR_P.  */
   unsigned decl_flag_2 : 1;
   /* Logically, these two would go in a theoretical base shared by var and
      parm decl. */
@@ -2818,7 +2819,8 @@ extern void decl_value_expr_insert (tree
    decl itself.  This should only be used for debugging; once this field has
    been set, the decl itself may not legitimately appear in the function.  */
 #define DECL_HAS_VALUE_EXPR_P(NODE) \
-  (TREE_CHECK2 (NODE, VAR_DECL, PARM_DECL)->decl_common.decl_flag_2)
+  (TREE_CHECK3 (NODE, VAR_DECL, PARM_DECL, RESULT_DECL) \
+   ->decl_common.decl_flag_2)
 #define DECL_VALUE_EXPR(NODE) \
   (decl_value_expr_lookup (DECL_WRTL_CHECK (NODE)))
 #define SET_DECL_VALUE_EXPR(NODE, VAL) \
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c.orig	2010-12-22 01:37:42.132800981 -0200
+++ gcc/dwarf2out.c	2010-12-22 01:46:17.364792666 -0200
@@ -15446,12 +15446,12 @@ loc_list_from_tree (tree loc, int want_a
       /* FALLTHRU */
 
     case PARM_DECL:
+    case RESULT_DECL:
       if (DECL_HAS_VALUE_EXPR_P (loc))
 	return loc_list_from_tree (DECL_VALUE_EXPR (loc),
 				   want_address);
       /* FALLTHRU */
 
-    case RESULT_DECL:
     case FUNCTION_DECL:
       {
 	rtx rtl;
Index: gcc/dbxout.c
===================================================================
--- gcc/dbxout.c.orig	2010-12-22 01:37:41.964037950 -0200
+++ gcc/dbxout.c	2010-12-22 01:46:17.388791720 -0200
@@ -2396,12 +2396,12 @@ dbxout_expand_expr (tree expr)
       /* FALLTHRU */
 
     case PARM_DECL:
+    case RESULT_DECL:
       if (DECL_HAS_VALUE_EXPR_P (expr))
 	return dbxout_expand_expr (DECL_VALUE_EXPR (expr));
       /* FALLTHRU */
 
     case CONST_DECL:
-    case RESULT_DECL:
       return DECL_RTL_IF_SET (expr);
 
     case INTEGER_CST:
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c.orig	2010-12-22 01:37:41.833789063 -0200
+++ gcc/var-tracking.c	2010-12-22 01:47:45.166793025 -0200
@@ -7999,121 +7999,138 @@ vt_get_decl_and_offset (rtx rtl, tree *d
   return false;
 }
 
-/* Insert function parameters to IN and OUT sets of ENTRY_BLOCK.  */
+/* Insert function parameter PARM in IN and OUT sets of ENTRY_BLOCK.  */
 
 static void
-vt_add_function_parameters (void)
+vt_add_function_parameter (tree parm)
 {
-  tree parm;
+  rtx decl_rtl = DECL_RTL_IF_SET (parm);
+  rtx incoming = DECL_INCOMING_RTL (parm);
+  tree decl;
+  enum machine_mode mode;
+  HOST_WIDE_INT offset;
+  dataflow_set *out;
+  decl_or_value dv;
 
-  for (parm = DECL_ARGUMENTS (current_function_decl);
-       parm; parm = DECL_CHAIN (parm))
-    {
-      rtx decl_rtl = DECL_RTL_IF_SET (parm);
-      rtx incoming = DECL_INCOMING_RTL (parm);
-      tree decl;
-      enum machine_mode mode;
-      HOST_WIDE_INT offset;
-      dataflow_set *out;
-      decl_or_value dv;
-
-      if (TREE_CODE (parm) != PARM_DECL)
-	continue;
-
-      if (!DECL_NAME (parm))
-	continue;
+  if (TREE_CODE (parm) != PARM_DECL)
+    return;
 
-      if (!decl_rtl || !incoming)
-	continue;
+  if (!decl_rtl || !incoming)
+    return;
 
-      if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
-	continue;
+  if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
+    return;
 
-      if (!vt_get_decl_and_offset (incoming, &decl, &offset))
+  if (!vt_get_decl_and_offset (incoming, &decl, &offset))
+    {
+      if (REG_P (incoming) || MEM_P (incoming))
 	{
-	  if (REG_P (incoming) || MEM_P (incoming))
-	    {
-	      /* This means argument is passed by invisible reference.  */
-	      offset = 0;
-	      decl = parm;
-	      incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
-	    }
-	  else
-	    {
-	      if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
-		continue;
-	      offset += byte_lowpart_offset (GET_MODE (incoming),
-					     GET_MODE (decl_rtl));
-	    }
+	  /* This means argument is passed by invisible reference.  */
+	  offset = 0;
+	  decl = parm;
+	  incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
 	}
-
-      if (!decl)
-	continue;
-
-      if (parm != decl)
+      else
 	{
-	  /* Assume that DECL_RTL was a pseudo that got spilled to
-	     memory.  The spill slot sharing code will force the
-	     memory to reference spill_slot_decl (%sfp), so we don't
-	     match above.  That's ok, the pseudo must have referenced
-	     the entire parameter, so just reset OFFSET.  */
-	  gcc_assert (decl == get_spill_slot_decl (false));
-	  offset = 0;
+	  if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
+	    return;
+	  offset += byte_lowpart_offset (GET_MODE (incoming),
+					 GET_MODE (decl_rtl));
 	}
+    }
 
-      if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
-	continue;
+  if (!decl)
+    return;
 
-      out = &VTI (ENTRY_BLOCK_PTR)->out;
+  if (parm != decl)
+    {
+      /* Assume that DECL_RTL was a pseudo that got spilled to
+	 memory.  The spill slot sharing code will force the
+	 memory to reference spill_slot_decl (%sfp), so we don't
+	 match above.  That's ok, the pseudo must have referenced
+	 the entire parameter, so just reset OFFSET.  */
+      gcc_assert (decl == get_spill_slot_decl (false));
+      offset = 0;
+    }
 
-      dv = dv_from_decl (parm);
+  if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
+    return;
 
-      if (target_for_debug_bind (parm)
-	  /* We can't deal with these right now, because this kind of
-	     variable is single-part.  ??? We could handle parallels
-	     that describe multiple locations for the same single
-	     value, but ATM we don't.  */
-	  && GET_CODE (incoming) != PARALLEL)
-	{
-	  cselib_val *val;
+  out = &VTI (ENTRY_BLOCK_PTR)->out;
 
-	  /* ??? We shouldn't ever hit this, but it may happen because
-	     arguments passed by invisible reference aren't dealt with
-	     above: incoming-rtl will have Pmode rather than the
-	     expected mode for the type.  */
-	  if (offset)
-	    continue;
-
-	  val = cselib_lookup (var_lowpart (mode, incoming), mode, true);
-
-	  /* ??? Float-typed values in memory are not handled by
-	     cselib.  */
-	  if (val)
-	    {
-	      preserve_value (val);
-	      set_variable_part (out, val->val_rtx, dv, offset,
-				 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
-	      dv = dv_from_value (val->val_rtx);
-	    }
-	}
+  dv = dv_from_decl (parm);
 
-      if (REG_P (incoming))
+  if (target_for_debug_bind (parm)
+      /* We can't deal with these right now, because this kind of
+	 variable is single-part.  ??? We could handle parallels
+	 that describe multiple locations for the same single
+	 value, but ATM we don't.  */
+      && GET_CODE (incoming) != PARALLEL)
+    {
+      cselib_val *val;
+
+      /* ??? We shouldn't ever hit this, but it may happen because
+	 arguments passed by invisible reference aren't dealt with
+	 above: incoming-rtl will have Pmode rather than the
+	 expected mode for the type.  */
+      if (offset)
+	return;
+
+      val = cselib_lookup (var_lowpart (mode, incoming), mode, true);
+
+      /* ??? Float-typed values in memory are not handled by
+	 cselib.  */
+      if (val)
 	{
-	  incoming = var_lowpart (mode, incoming);
-	  gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
-	  attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
-			     incoming);
-	  set_variable_part (out, incoming, dv, offset,
-			     VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
-	}
-      else if (MEM_P (incoming))
-	{
-	  incoming = var_lowpart (mode, incoming);
-	  set_variable_part (out, incoming, dv, offset,
+	  preserve_value (val);
+	  set_variable_part (out, val->val_rtx, dv, offset,
 			     VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
+	  dv = dv_from_value (val->val_rtx);
 	}
     }
 
+  if (REG_P (incoming))
+    {
+      incoming = var_lowpart (mode, incoming);
+      gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
+      attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
+			 incoming);
+      set_variable_part (out, incoming, dv, offset,
+			 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
+    }
+  else if (MEM_P (incoming))
+    {
+      incoming = var_lowpart (mode, incoming);
+      set_variable_part (out, incoming, dv, offset,
+			 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
+    }
+}
+
+/* Insert function parameters to IN and OUT sets of ENTRY_BLOCK.  */
+
+static void
+vt_add_function_parameters (void)
+{
+  tree parm;
+
+  for (parm = DECL_ARGUMENTS (current_function_decl);
+       parm; parm = DECL_CHAIN (parm))
+    vt_add_function_parameter (parm);
+
+  if (DECL_HAS_VALUE_EXPR_P (DECL_RESULT (current_function_decl)))
+    {
+      tree vexpr = DECL_VALUE_EXPR (DECL_RESULT (current_function_decl));
+
+      if (TREE_CODE (vexpr) == INDIRECT_REF)
+	vexpr = TREE_OPERAND (vexpr, 0);
+
+      if (TREE_CODE (vexpr) == PARM_DECL
+	  && DECL_ARTIFICIAL (vexpr)
+	  && !DECL_IGNORED_P (vexpr)
+	  && DECL_NAMELESS (vexpr))
+	vt_add_function_parameter (vexpr);
+    }
+
   if (MAY_HAVE_DEBUG_INSNS)
     {
       cselib_preserve_only_values ();

[-- Attachment #3: Type: text/plain, Size: 257 bytes --]


-- 
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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PR debug/46724] var-track address of RESULT_DECL
  2010-12-22  6:37   ` Alexandre Oliva
@ 2010-12-28 20:26     ` H.J. Lu
  2010-12-29  9:17       ` Alexandre Oliva
  0 siblings, 1 reply; 5+ messages in thread
From: H.J. Lu @ 2010-12-28 20:26 UTC (permalink / raw)
  To: Alexandre Oliva; +Cc: Richard Henderson, gcc-patches

On Tue, Dec 21, 2010 at 7:49 PM, Alexandre Oliva <aoliva@redhat.com> wrote:
> On Dec 21, 2010, Richard Henderson <rth@redhat.com> wrote:
>
>> Ok, with a function comment for vt_add_function_parameter.
>
> Thanks, here's what I installed.
>

This caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47079

-- 
H.J.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PR debug/46724] var-track address of RESULT_DECL
  2010-12-28 20:26     ` H.J. Lu
@ 2010-12-29  9:17       ` Alexandre Oliva
  0 siblings, 0 replies; 5+ messages in thread
From: Alexandre Oliva @ 2010-12-29  9:17 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Richard Henderson, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 918 bytes --]

On Dec 28, 2010, "H.J. Lu" <hjl.tools@gmail.com> wrote:

> On Tue, Dec 21, 2010 at 7:49 PM, Alexandre Oliva <aoliva@redhat.com> wrote:
>> On Dec 21, 2010, Richard Henderson <rth@redhat.com> wrote:

>>> Ok, with a function comment for vt_add_function_parameter.

>> Thanks, here's what I installed.

> This caused:

> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47079

Thanks.  Of course, this *had* to happen while my fast build machine was
on repairs, and I ended up cutting down testing to x86_64 only on my
older and slower build box :-(

On x86, .result_ptr was a MEM rather than a REG, and because result_ptr
wasn't a local VAR_DECL, its RTL wasn't properly devirtualized, and
dwarf2out didn't quite know what to do with virtual-incoming-args.

Fixed with the following patch (slightly different from the patch
uploaded to bugzilla, to fix a cut&pasto).  Regstrapped on x86_64 and
x86-linux-gnu.  Ok to install?


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: result-decl-value-more-pr47079.patch --]
[-- Type: text/x-diff, Size: 2272 bytes --]

for  gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/47079
	PR debug/46724
	* function.c (instantiate_expr): Instantiate incoming rtl of
	implicit arguments, and recurse on VALUE_EXPRs.
	(instantiate_decls): Instantiate rtl and VALUE_EXPR of result.
	* var-tracking.c (adjust_mems): Reject virtual_incoming_args_rtx.

Index: gcc/function.c
===================================================================
--- gcc/function.c.orig	2010-12-28 20:24:03.881770200 -0200
+++ gcc/function.c	2010-12-28 21:37:47.492920482 -0200
@@ -1784,8 +1784,21 @@ instantiate_expr (tree *tp, int *walk_su
   if (! EXPR_P (t))
     {
       *walk_subtrees = 0;
-      if (DECL_P (t) && DECL_RTL_SET_P (t))
-	instantiate_decl_rtl (DECL_RTL (t));
+      if (DECL_P (t))
+	{
+	  if (DECL_RTL_SET_P (t))
+	    instantiate_decl_rtl (DECL_RTL (t));
+	  if (TREE_CODE (t) == PARM_DECL && DECL_NAMELESS (t)
+	      && DECL_INCOMING_RTL (t))
+	    instantiate_decl_rtl (DECL_INCOMING_RTL (t));
+	  if ((TREE_CODE (t) == VAR_DECL
+	       || TREE_CODE (t) == RESULT_DECL)
+	      && DECL_HAS_VALUE_EXPR_P (t))
+	    {
+	      tree v = DECL_VALUE_EXPR (t);
+	      walk_tree (&v, instantiate_expr, NULL, NULL);
+	    }
+	}
     }
   return NULL;
 }
@@ -1835,6 +1848,18 @@ instantiate_decls (tree fndecl)
 	}
     }
 
+  if ((decl = DECL_RESULT (fndecl))
+      && TREE_CODE (decl) == RESULT_DECL)
+    {
+      if (DECL_RTL_SET_P (decl))
+	instantiate_decl_rtl (DECL_RTL (decl));
+      if (DECL_HAS_VALUE_EXPR_P (decl))
+	{
+	  tree v = DECL_VALUE_EXPR (decl);
+	  walk_tree (&v, instantiate_expr, NULL, NULL);
+	}
+    }
+
   /* Now process all variables defined in the function or its subblocks.  */
   instantiate_decls_1 (DECL_INITIAL (fndecl));
 
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c.orig	2010-12-28 19:14:24.501730254 -0200
+++ gcc/var-tracking.c	2010-12-28 20:43:03.825871640 -0200
@@ -805,6 +805,7 @@ adjust_mems (rtx loc, const_rtx old_rtx,
 	       && hard_frame_pointer_adjustment != -1
 	       && cfa_base_rtx)
 	return compute_cfa_pointer (hard_frame_pointer_adjustment);
+      gcc_checking_assert (loc != virtual_incoming_args_rtx);
       return loc;
     case MEM:
       mem = loc;

[-- Attachment #3: Type: text/plain, Size: 257 bytes --]


-- 
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

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-12-29  5:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-21 10:32 [PR debug/46724] var-track address of RESULT_DECL Alexandre Oliva
2010-12-21 18:32 ` Richard Henderson
2010-12-22  6:37   ` Alexandre Oliva
2010-12-28 20:26     ` H.J. Lu
2010-12-29  9:17       ` Alexandre Oliva

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).