This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]