This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: assign_parm_setup_block handling of parallels
- From: Aldy Hernandez <aldyh at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>, gcc at gcc dot gnu dot org, ebotcazou at libertysurf dot fr, dje at watson dot ibm dot com
- Date: Wed, 12 Jan 2005 12:55:17 -0400
- Subject: Re: assign_parm_setup_block handling of parallels
- References: <20041223202824.GA8247@redhat.com> <20041223210400.GH19547@redhat.com> <20041223214543.GA16125@redhat.com> <20041223223759.GA19928@redhat.com>
On Thu, Dec 23, 2004 at 02:37:59PM -0800, Richard Henderson wrote:
> On Thu, Dec 23, 2004 at 05:45:43PM -0400, Aldy Hernandez wrote:
> > In my limited understanding of the problem I think we can allow the
> > optimization for one-member parallels iff the hard register will span
> > more than one register. I think this will satisfy both PPC64 and
> > Sparc64.
>
> I can't decide whether the better check is
>
> nelts > 0
> || hard_regno_nregs[REGNO (elt0)][GET_MODE (elt0)] > 1
As dicussed, you prefer this option.
I have tested the following patch on ppc-linux and ppc-eabispe. I know
you said it was OK, but could you eye it over since I had to split up
the condition?
Thanks.
* function.c (assign_parm_setup_block): Relax condition on
multi-register optimization.
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.600
diff -c -p -r1.600 function.c
*** function.c 11 Jan 2005 09:51:17 -0000 1.600
--- function.c 12 Jan 2005 00:27:51 -0000
*************** assign_parm_setup_block (struct assign_p
*** 2560,2601 ****
/* If we've a non-block object that's nevertheless passed in parts,
reconstitute it in register operations rather than on the stack. */
if (GET_CODE (entry_parm) == PARALLEL
! && data->nominal_mode != BLKmode
! && XVECLEN (entry_parm, 0) > 1
! && use_register_for_decl (parm))
{
! rtx parmreg = gen_reg_rtx (data->nominal_mode);
! push_to_sequence (all->conversion_insns);
! /* For values returned in multiple registers, handle possible
! incompatible calls to emit_group_store.
! For example, the following would be invalid, and would have to
! be fixed by the conditional below:
! emit_group_store ((reg:SF), (parallel:DF))
! emit_group_store ((reg:SI), (parallel:DI))
! An example of this are doubles in e500 v2:
! (parallel:DF (expr_list (reg:SI) (const_int 0))
! (expr_list (reg:SI) (const_int 4))). */
! if (data->nominal_mode != data->passed_mode)
! {
! rtx t = gen_reg_rtx (GET_MODE (entry_parm));
! emit_group_store (t, entry_parm, NULL_TREE,
! GET_MODE_SIZE (GET_MODE (entry_parm)));
! convert_move (parmreg, t, 0);
! }
! else
! emit_group_store (parmreg, entry_parm, data->nominal_type,
! int_size_in_bytes (data->nominal_type));
! all->conversion_insns = get_insns ();
! end_sequence ();
! SET_DECL_RTL (parm, parmreg);
! return;
}
size = int_size_in_bytes (data->passed_type);
--- 2560,2606 ----
/* If we've a non-block object that's nevertheless passed in parts,
reconstitute it in register operations rather than on the stack. */
if (GET_CODE (entry_parm) == PARALLEL
! && data->nominal_mode != BLKmode)
{
! rtx elt0 = XEXP (XVECEXP (entry_parm, 0, 0), 0);
! if ((XVECLEN (entry_parm, 0) > 1
! || hard_regno_nregs[REGNO (elt0)][GET_MODE (elt0)])
! && use_register_for_decl (parm))
! {
! rtx parmreg = gen_reg_rtx (data->nominal_mode);
! push_to_sequence (all->conversion_insns);
! /* For values returned in multiple registers, handle possible
! incompatible calls to emit_group_store.
! For example, the following would be invalid, and would have to
! be fixed by the conditional below:
! emit_group_store ((reg:SF), (parallel:DF))
! emit_group_store ((reg:SI), (parallel:DI))
! An example of this are doubles in e500 v2:
! (parallel:DF (expr_list (reg:SI) (const_int 0))
! (expr_list (reg:SI) (const_int 4))). */
! if (data->nominal_mode != data->passed_mode)
! {
! rtx t = gen_reg_rtx (GET_MODE (entry_parm));
! emit_group_store (t, entry_parm, NULL_TREE,
! GET_MODE_SIZE (GET_MODE (entry_parm)));
! convert_move (parmreg, t, 0);
! }
! else
! emit_group_store (parmreg, entry_parm, data->nominal_type,
! int_size_in_bytes (data->nominal_type));
! all->conversion_insns = get_insns ();
! end_sequence ();
!
! SET_DECL_RTL (parm, parmreg);
! return;
! }
}
size = int_size_in_bytes (data->passed_type);