This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [comitted]: Revert 80387 register argument passing patch
Jan Hubicka wrote:
The unfortunate conclusion of all this mess is, that variables simply
can't be passed in stack, although reg-stack.c in some way advertises
this funcitonality (look for the comment in subst_stack_regs()).
Hi,
it seems to me that all you were missing is to properly update stack_in
datastructure to mention the arguments that are supposedly already being
on the stack. See /* Put the incoming arguments to the stack. */
in my variant of your patch
http://gcc.gnu.org/ml/gcc-patches/2000-07/msg00150.html
and some compensating code in next hunk.
Actually you need to set up out_stack of entry block and compensate all
edges between entry block and its successors _after_ registers in
successor blocks were converted. This is due to:
/* Avoid emitting the swap if this is the first register stack insn
of the current_block. Instead update the current_block's stack_in
and let compensate edges take care of this for us. */
Your patch would create invalid passing for the cases, such as (suppose
a, b, and c were passed in registers):
double foo (double a, double b, double c, double d)
{
return c * d + a;
}
Your patch would pop b, but woudn't swap c and a around (due to above
comment). These problems can be solved (by the call to compensate_edge
()), but the real problem is with uninitialized variables, exposed in
gcc.c-torture/compile/20040908-1.c:
double foo()
{
int i;
double d;
if (i)
bar();
else
if (d) return 0;
}
gcc -O2:
foo:
flds .LC1 <<< here!
subl $12, %esp
testl %eax, %eax
jne .L11
There is no way to separate "live" uninitialized slots and register
passing slots. I tried to clear a register in stack_in structure of the
successor block, but some other (invalid as above) testcases broke due
to wrong starting stack, calculated from stack_in (it should be noted,
that when no uninitialized variables were present, huge source files
were compiled correctly). Also considering the fact, that you can't load
an arbitrary uninitialized slot (as you can pop with fstp), so QNaNs
will _always_ be positioned at the top of the stack, no matter which
slot is uninitialized, I pull out of this mess.
Since we can use insn with memory operand, and memory stores before the
call are somehow masked by the latency of call insn, I think that
register passing for stack architectures is pretty much DOA. Also, there
is a big chance of fxch insn sequences to get stack into the right order
before call and at procedure entry point and one or two possible fstps
that remove excess arguments from the stack at procedure entry. I think
that all this arguments are more than enough to revert register passing
patch.
And finally, there was no measurable gain in povray ;)
But given that I would rather see x87 away, I quite agree with you that
this is not the most important feature around.
Indeed. It looks that very last performance points have already been
squeezed out of x87.
Uros.