> On Sun, 10 May 2015, Jan Hubicka wrote:
>
> > > On i386, peepholes that transform memory load and register-indirect jump
> > > into
> > > memory-indirect jump are overly restrictive in that they don't allow
> > > combining
> > > when the jump target is loaded into %eax, and the called function returns
> > > a
> > > value (also in %eax, so it's not dead after the call). Fix this by
> > > checking
> > > for same source and output register operands separately.
> > >
> > > OK?
> > > * config/i386/i386.md (sibcall_value_memory): Extend peepholes to
> > > allow memory address in %eax.
> > > (sibcall_value_pop_memory): Likewise.
> >
> > Why do we need the check for liveness after all? There is SIBLING_CALL_P
> > (peep2_next_insn (1)) so we know that the function terminates by the call
> > and there are no other uses of the value.
>
> Indeed. Uros, the peep2_reg_dead_p check was added by your patch as svn
> revision 211776, git commit e51f8b8fed. Would you agree that the check is not
> necessary for sibcalls as Honza explains? Would you approve a patch that
> removes it in the sibcall peepholes I modify in the patch under discussion?
>
> > Don't we however need to check that operands[0] is not used by the
> > call_insn as
> > parameter of the call? I.e. something like
> >
> > void
> > test(void (*callback ()))
> > {
> > callback(callback);
> > }
>
> You need a pointer-to-pointer-to-function to trigger the peephole. Something
> like this:
>
> void foo()
> {
> void (**bar)(void*);
> asm("":"=r"(bar));
> (*bar)(*bar);
> }
>
> > I think instead of peep2_reg_dead_p we want to check that the parameter is
> > not in
> > CALL_INSN_FUNCTION_USAGE of the sibcall..
>
> Playing with the above testcase I can't induce failure. It seems today GCC
> won't allocate the same register as callee address and one of the arguments.
> Do you want me to implement such a check anyway?
Hmm, only way I can trigger same register is:
void foo()
{
void (**bar)(void*);
asm("":"=r"(bar));
register void (*var)(void *) asm("%eax");
var=*bar;
asm("":"+r"(var));
var(var);
}
removing the second asm makes CSE to forward propagae the memory operand
to call that makes the call different from the register variable.
Still I would check for that, but this is more Uros' area.
Honza