RFA: Do not convert a pass-by-reference parameter into pass-by-value when its address is taken

Nick Clifton nickc@redhat.com
Thu Jul 26 09:24:00 GMT 2007


Hi Guys,

  I would like permission to apply the following patch, although I
  have no easy way to demonstrate its correctness.  It fixes a
  problem encountered with an as yet un-contributed port whose ABI
  insists that longs and doubles be passed by reference rather than by
  value.  The problem is that these parameters would fit into
  registers if they were allowed to be placed there and the code in
  assign_parm_setup_reg() will move them into registers (during the
  function's prologue) whenever it can do so.  This works, except for
  the case where the address of the parameter is taken inside the body
  of the function.  Since the parameter is being passed by reference
  gcc does not generate any code to push the parameter onto the stack
  and so give it a memory address, but the code in
  assign_parm_setup_reg still moves the value of the parameter out of
  the memory location and into a register.

  This problem can be demonstrated by testcases like
  gcc.c-torture/compile/930217-1.c, but only when you have an ABI
  which forces simple types to be passed by reference.  The solution
  is quite straightforward - just do not load a passed by reference
  parameter into a register when its address is going to be taken.
  The attached patch does this and does not cause any regressions for
  an x86 toolchain with the gcc or g++ testsuites.

  So, please may I apply this patch ?

Cheers
  Nick

gcc/ChangeLog
2007-07-26  Nick Clifton  <nickc@redhat.com>

	* function.c (assign_parm_setup_reg): Do not move a passed by
	reference parameter into a register when its address is being
	taken.

Index: gcc/function.c
===================================================================
--- gcc/function.c	(revision 126948)
+++ gcc/function.c	(working copy)
@@ -2739,6 +2739,9 @@ assign_parm_setup_reg (struct assign_par
      in a register, put it in one.  */
   if (data->passed_pointer
       && TYPE_MODE (TREE_TYPE (parm)) != BLKmode
+      /* If we are taking the address of the value,
+	 then leave the pointer in the register.  */
+      && ! TREE_ADDRESSABLE (parm)
       /* If by-reference argument was promoted, demote it.  */
       && (TYPE_MODE (TREE_TYPE (parm)) != GET_MODE (DECL_RTL (parm))
 	  || use_register_for_decl (parm)))



More information about the Gcc-patches mailing list