[MPlayer-dev-eng] Improved remove-logo filter

Trent Piepho xyzzy at speakeasy.org
Mon Nov 6 12:20:03 CET 2006


On Mon, 6 Nov 2006, Uoti Urpala wrote:
> On Sun, 2006-11-05 at 13:37 -0800, Trent Piepho wrote:
> > On Sun, 5 Nov 2006, Michael Niedermayer wrote:
> > > and copying variables onto the stack can improve speed alot, gcc svn does
> > > this according to uoti, maybe violating your dont copy constraint?
> >
> > It sounded to me like what Uoti found was an asm construct that modified a
> > variable through a pointer with out telling gcc about it.  Something like:
> >
> > int x, *p = x;
> > asm("movl $0, (%0)" : : "r"(p));
> >
> > Of course something like that will not work, because gcc doesn't know the
> > value of x has changed.
>
> The construct was similar to that, but there were no free registers in
> which gcc could keep anything extra during the asm, and there was no
> optimization gcc could do based on just "it must be the same as last
> time". It failed because gcc made a copy of the variable *on the stack*.
> For an example where this obviously makes sense consider a chain of
> pointers like a->b->c->d->e->f used in several places in the code. The
> final value of f is a common subexpression; even if it cannot fit in a
> register it makes a lot more sense to make a copy of it on the stack
> than to go through the whole chain every time the value is accessed.
>
> >   It needs "memory" on the clobber list, or better
> > yet, "=m"(x) as an output.
>
> ... except that if "=m" cannot point to an alias of the variable, your
> "better" alternative is a bad idea since it requires allocating a
> register to hold &x unless x is a stack variable or similar that can be
> accessed without needing an explicit pointer.

You're wrong about that.  Try it.

int x;
void foo(void) { asm("# %0 %1" : "=m"(x) : "r"(&x)); }

gcc -fPIC -O2 -S test.c  # PIC so &x isn't a constant

#APP
        # (%eax) %eax
#NO_APP

Or with a pointer as the source:

int *p;
void foo(void) { asm("# %0 %1" : "=m"(*p) : "r"(p)); }
        movl    p, %eax
#APP
        # (%eax) %eax
#NO_APP

If you ask for the address of x in a register, then it doesn't take another
register to provide a memory reference to x.  Provided that gcc can figure
the two are the same.  One will just be %reg and the other (%reg).

> >   And ask the gcc devs WTF one is supposed to do to write
> > a spin-lock.
>
> I've already explained this exact thing TWICE. Are you retarted or what?
> If you need side effects which don't directly affect the current thread
> to happen then you must specify "volatile". This is true even for plain
> C, without any asm whatsoever.

And I already explained to you that you are wrong about what volatile
means.  It just means that all the loads and stores implied by the code
must exist.  If you write this:

volatile int x;
x <<= 1;

gcc is free to generate code that does this:

tmp = x;
tmp <<= 1;
x = tmp;

The x<<=1 expression only implies that there will be a load of x before the
shift and a store afterward.  gcc is free to make a copy of x into a
register or the stack between the load and store.

It is the same with asm constructs.  If you write this:

volatile int x;
x = 1;
asm(" " : : "r"(x));

gcc will give you a _copy_ of x in a register.  It will store 1 into x's
memory location (implied by the assignment operator), then it will load x's
memory into a register (the load implied by the asm input), and the asm
will have a _copy_ of x.

You may wish that the way gcc worked is that if an asm has a volatile
operand, then a memory reference (but not a register) must not be a copy.
But that is not how it works.



More information about the MPlayer-dev-eng mailing list