This is the mail archive of the gcc-bugs@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]

Re: Bug in haifa scheduler ?


Am Sun, 28 Jun 1998 schrieb Richard Henderson:
>In article <Pine.HPP.3.96.980627022254.29572D-100000.cygnus.egcs.bugs@gra-ux1.iram.es>,
>Gabriel Paubert <paubert@iram.es> wrote:
>>> But without the "memory" in the asm the compiler doesn't know that the
>>> changes memory and thus the compiler decides it is safe (for example)
>>> to hold a value that was loaded from memory in a register across the
>>> asm statement.
>>
>>That's exactly what I want (unless there is a misunderstanding somewhere). 
>>Most I/O instructions do not have side effect on variables (local and
>>global) kept in registers, they simply should be treated as an access to
>>volatile memory.
>
>Not good enough.  The thing is, marking an asm as clobbering memory
>also acts as a kind of synchronization point, forcing gcc to drop
>pending writes to memory.
>
>Why, you ask, isn't a volatile memory reference good enough?  Because
>a volatile memory reference does _not_ mean that the write will be
>done immediately.  Rather it means that it will not be elided nor
>reordered with respect to other memory references.
>
>So by eliding the memory clobber, you are telling gcc that memory
>references may be moved across this asm with impunity.

Aah!, this clarifies things even more for me. Thinking about it I came up with
the following possible solution:

extern inline void eieio(void)
{
    __asm__ __volatile__ ("eieio" : : : "memory" );
}

#define EIEIO_IN(port,data) \
        __asm__ __volatile__ ("eieio" : "=r" (data)  : "0" (data), "r" (port), "m" (*port) );

#define EIEIO_OUT(port,data) \
        __asm__ __volatile__ ("eieio" : "=m" (*port) : "r" (data), "r" (port) );

extern inline int in_8(volatile unsigned char *addr)
{
        int ret;

        ret = *addr;
        EIEIO_IN(addr, ret);
        return ret;
}

extern inline void out_8(volatile unsigned char *addr, int val)
{
        *addr = val;
        EIEIO_OUT(addr, val);
}

I think this should give gcc maximum possible freedom to optimize and thus
performance (which is the main concern of Gabriel) should be "optimal", but
still the purpose of asm("eieio") is retained in all situations.

What do you think?

Franz.


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