[PATCH] Adjust DECL_INCOMING_RTL for pass_by_reference parameters (PR debug/48163)

Jakub Jelinek jakub@redhat.com
Thu Mar 17 18:37:00 GMT 2011


Hi!

If a PARM_DECL is not passed by reference because the FE decides so
(then the PARM_DECL is DECL_BY_REFERENCE and has pointer type), but
because pass_by_reference said so, then apparently DECL_INCOMING
is the Pmode pointer to the MEM instead of the actual incoming location
and the fact that expansion decided that isn't stored anywhere.
While we could in theory reconstruct that by doing all the
INIT_CUMULATIVE_ARGS/*function_arg{,_advance}/pass_by_reference etc.,
that is fairly costly to do and just guessing whether it is the case
isn't reliable.

One place where we want to know that is in expand_debug_expr since
my recent change to add ENTRY_VALUE if debug stmts reference a parameter
that isn't used in the function at all.  But the debug info emitters
want to know that too, and DECL_INCOMING_RTL seems to be there just
for them.

I was considering adding some DECL_INCOMING_BY_REFERENCE bit to PARM_DECL,
but I think it is actually better if DECL_INCOMING_RTL in that case is
just a MEM of the right mode with the register (or stack slot MEM) as
address.

This patch fixes both the problem of e.g. complex-1.c on cris-elf
where expand_debug_expr was upset that DECL_INCOMING_RTL was SImode,
but the argument was supposed to be DFmode, and also e.g. improves
debug info for -g -m32 -O+ on powerpc-linux:

struct S { char buf[16]; };

void foo (struct S a, int b, int c, int d, int e, int f, int g, int h, struct S i)
{
}

without the patch there is no location info for A and I parameters,
with this patch the location info is present and correct.

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

2011-03-17  Jakub Jelinek  <jakub@redhat.com>

	PR debug/48163
	* function.c (assign_parms): For data.passed_pointer parms
	use MEM of data.entry_parm instead of data.entry_parm itself
	as DECL_INCOMING_RTL.
	* dwarf2out.c (rtl_for_decl_location): Use DECL_INCOMING_RTL
	also when passed and declared mode is the same, DECL_RTL
	is a MEM with pseudo as address and DECL_INCOMING_RTL is
	a MEM too.

--- gcc/function.c.jj	2011-03-11 12:16:39.000000000 +0100
+++ gcc/function.c	2011-03-17 11:44:41.000000000 +0100
@@ -3403,7 +3403,15 @@ assign_parms (tree fndecl)
 	}
 
       /* Record permanently how this parm was passed.  */
-      set_decl_incoming_rtl (parm, data.entry_parm, data.passed_pointer);
+      if (data.passed_pointer)
+	{
+	  rtx incoming_rtl
+	    = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (data.passed_type)),
+			   data.entry_parm);
+	  set_decl_incoming_rtl (parm, incoming_rtl, true);
+	}
+      else
+	set_decl_incoming_rtl (parm, data.entry_parm, false);
 
       /* Update info on where next arg arrives in registers.  */
       targetm.calls.function_arg_advance (&all.args_so_far, data.promoted_mode,
--- gcc/dwarf2out.c.jj	2011-03-17 09:38:00.000000000 +0100
+++ gcc/dwarf2out.c	2011-03-17 12:07:01.000000000 +0100
@@ -16719,7 +16719,13 @@ rtl_for_decl_location (tree decl)
     }
   else if (TREE_CODE (decl) == PARM_DECL)
     {
-      if (rtl == NULL_RTX || is_pseudo_reg (rtl))
+      if (rtl == NULL_RTX
+	  || is_pseudo_reg (rtl)
+	  || (MEM_P (rtl)
+	      && is_pseudo_reg (XEXP (rtl, 0))
+	      && DECL_INCOMING_RTL (decl)
+	      && MEM_P (DECL_INCOMING_RTL (decl))
+	      && GET_MODE (rtl) == GET_MODE (DECL_INCOMING_RTL (decl))))
 	{
 	  tree declared_type = TREE_TYPE (decl);
 	  tree passed_type = DECL_ARG_TYPE (decl);
@@ -16731,7 +16737,8 @@ rtl_for_decl_location (tree decl)
 	     all cases where (rtl == NULL_RTX) just below.  */
 	  if (dmode == pmode)
 	    rtl = DECL_INCOMING_RTL (decl);
-	  else if (SCALAR_INT_MODE_P (dmode)
+	  else if ((rtl == NULL_RTX || is_pseudo_reg (rtl))
+		   && SCALAR_INT_MODE_P (dmode)
 		   && GET_MODE_SIZE (dmode) <= GET_MODE_SIZE (pmode)
 		   && DECL_INCOMING_RTL (decl))
 	    {

	Jakub



More information about the Gcc-patches mailing list