This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RFA: Do not convert a pass-by-reference parameter into pass-by-value when its address is taken
- From: Nick Clifton <nickc at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 26 Jul 2007 10:07:21 +0100
- Subject: RFA: Do not convert a pass-by-reference parameter into pass-by-value when its address is taken
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)))