This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: (i386-linux x sh-elf) More weak stack addressing
- To: Toshiyasu Morita <tm at netcom dot com>
- Subject: Re: (i386-linux x sh-elf) More weak stack addressing
- From: Joern Rennecke <amylaar at pasanda dot cygnus dot co dot uk>
- Date: Wed, 19 Jul 2000 17:56:36 +0100 (BST)
- CC: Joern Rennecke <amylaar at pasanda dot cygnus dot co dot uk>, gcc-bugs at gcc dot gnu dot org dot gcc, gcc at gcc dot gnu dot org
> I suspect a more comprehensive solution is required.
>
> Even with this patch, I see the following generated elsewhere:
>
> 6237:vtkTriangleStrip.ii **** cell->DeepCopy(*this);
> 49924 0280 FC7F add #-4,r15
> 49925 0282 7CE7 mov #124,r7 <- here
> 49926 0284 6F93 mov.w .L103,r3
> 49927 0286 EC37 add r14,r7 <- here
> 49928 0288 7A52 mov.l @(40,r7),r2
> 49929 028a EC33 add r14,r3
> 49930 028c 7A57 mov.l @(40,r7),r7
> 49931 028e 2351 mov.l @(12,r2),r1
> 49932 0290 6077 add #96,r7
> 49933 0292 7713 mov.l r7,@(28,r3)
What else would you do, with only r3 and r7 available as reload registers?
sometimes there just aren't enough reload registers to go around.
I tried a more elaborate patch that peeks ahead what reloads are
actually useful for future inheritance, but it actually results in
one more assembler line for your testcase.
Well, unless you peek ahead beyond labels, then it saves 5 lines,
but such a strategy doesn't really make any sense.
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/reload1.c,v
retrieving revision 1.216
diff -p -r1.216 reload1.c
*** reload1.c 2000/06/06 02:40:14 1.216
--- reload1.c 2000/07/19 16:43:52
*************** allocate_reload_reg (chain, r, last_relo
*** 4953,4960 ****
int r;
int last_reload;
{
! int i, pass, count;
!
/* If we put this reload ahead, thinking it is a group,
then insist on finding a group. Otherwise we can grab a
reg that some other reload needs.
--- 4953,5001 ----
int r;
int last_reload;
{
! int i, pass, count, want_inherit, q, force_group;
! rtx in, last;
! struct insn_chain *next;
!
! /* Check if this reload's value is useful for future inheritance. */
! want_inherit = 0;
! in = rld[r].in_reg;
! if (in
! && ! rld[r].out
! && (CONSTANT_P (in)
! || GET_CODE (in) == REG
! || (GET_CODE (in) == PLUS
! && (XEXP (in, 0) == stack_pointer_rtx
! || XEXP (in, 0) == frame_pointer_rtx)
! && CONSTANT_P (XEXP (in, 1)))))
! {
! for (q = r + 1; q < chain->n_reloads; q++)
! if (rtx_equal_p (rld[r].in_reg, chain->rld[q].in_reg))
! want_inherit = 1;
! #if 0
! want_inherit = 1;
! #endif
! last = chain->insn;
! for (next = chain, count = n_spills * 3;
! (next = next->next_need_reload) && --count >= 0;)
! {
! #if 1
! if (! no_labels_between_p (last, next->insn))
! {
! count = -1;
! break;
! }
! #endif
! last = next->insn;
! for (q = next->n_reloads; --q >= 0;)
! if (rtx_equal_p (rld[r].in_reg, next->rld[q].in_reg))
! break;
! if (q >= 0)
! break;
! }
! if (count >= 0)
! want_inherit = 1;
! }
/* If we put this reload ahead, thinking it is a group,
then insist on finding a group. Otherwise we can grab a
reg that some other reload needs.
*************** allocate_reload_reg (chain, r, last_relo
*** 4968,4974 ****
Perhaps those classes should be avoided for reloading
by use of more alternatives. */
! int force_group = rld[r].nregs > 1 && ! last_reload;
/* If we want a single register and haven't yet found one,
take any reg in the right class and not in use.
--- 5009,5015 ----
Perhaps those classes should be avoided for reloading
by use of more alternatives. */
! force_group = rld[r].nregs > 1 && ! last_reload;
/* If we want a single register and haven't yet found one,
take any reg in the right class and not in use.
*************** allocate_reload_reg (chain, r, last_relo
*** 4982,4988 ****
reloads A and B can share regs. These need two regs.
Suppose A and B are given different regs.
That leaves none for C. */
! for (pass = 0; pass < 2; pass++)
{
/* I is the index in spill_regs.
We advance it round-robin between insns to use all spill regs
--- 5023,5029 ----
reloads A and B can share regs. These need two regs.
Suppose A and B are given different regs.
That leaves none for C. */
! for (pass = 0; pass < 2 + want_inherit; pass++)
{
/* I is the index in spill_regs.
We advance it round-robin between insns to use all spill regs
*************** allocate_reload_reg (chain, r, last_relo
*** 5017,5025 ****
/* Look first for regs to share, then for unshared. But
don't share regs used for inherited reloads; they are
the ones we want to preserve. */
! && (pass
! || (TEST_HARD_REG_BIT (reload_reg_used_at_all,
! regnum)
&& ! TEST_HARD_REG_BIT (reload_reg_used_for_inherit,
regnum))))
{
--- 5058,5066 ----
/* Look first for regs to share, then for unshared. But
don't share regs used for inherited reloads; they are
the ones we want to preserve. */
! && (pass > want_inherit
! || ((!! TEST_HARD_REG_BIT (reload_reg_used_at_all, regnum)
! ^ (want_inherit > pass))
&& ! TEST_HARD_REG_BIT (reload_reg_used_for_inherit,
regnum))))
{
*************** allocate_reload_reg (chain, r, last_relo
*** 5062,5067 ****
--- 5103,5118 ----
/* We should have found a spill register by now. */
if (count >= n_spills)
return 0;
+
+ if (TEST_HARD_REG_BIT (reload_reg_used_for_inherit, spill_regs[i]))
+ {
+ #if 1
+ want_inherit = 0;
+ CLEAR_HARD_REG_BIT (reload_reg_used_for_inherit, spill_regs[i]);
+ #endif
+ }
+ if (want_inherit)
+ SET_HARD_REG_BIT (reload_reg_used_for_inherit, spill_regs[i]);
/* I is the index in SPILL_REG_RTX of the reload register we are to
allocate. Get an rtx for it and find its register number. */