This is the mail archive of the gcc-help@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: why the barrier() can not take effect?


I have modified the code as follows:

#include <stdio.h>

#define barrier() __asm__ __volatile__("": : :"memory")

int main()
{
     int i, n;
     int s = 0;
     int *p;

     scanf("%d", &n);
     for (i = 0; i < n; i++)
          s += i;
     barrier();
     p = &s;  <--- for s, the & operator is used
     printf("%d %d %d\n", i, n, *p);  <--- the s is referenced through a pointer

     return 0;
}

and the corresponding asm code is as follows:

        leal    -8(%ebp), %eax
        pushl   %eax
        pushl   $.LC0
        call    scanf
        movl    -8(%ebp), %edx
        addl    $16, %esp
        testl   %edx, %edx
        jg      .L2
        movl    $0, %eax
        movl    $0, %ecx
        jmp     .L4
.L2:
        movl    $0, %eax
        movl    $0, %ecx
.L5:
        addl    %eax, %ecx
        incl    %eax
        cmpl    %edx, %eax
        jne     .L5
.L4:
       <---  after the barrier(()
        pushl   %ecx  <---  In spite of using the '&' operator, the
value of s is still gotten from the register rather than the
corresponding memory location.
        pushl   -8(%ebp)  <--- the value of n is gotten from its
memory location indeed
        pushl   %eax
        pushl   $.LC1
        call    printf

Alough the '&' operator is used for both 's' and 'n', gcc deals with
them differently. The former's value is in a register, while the
latter's value is retrieved from the corresponding memory location. I
wonder the difference.

2010/12/22 Andrew Haley <aph@redhat.com>:
> On 12/22/2010 03:16 PM, Parmenides wrote:
>>
>> Hi,
>>
>> ? ? According to the gcc's manual, in an extended assembly statement,
>> if the string "memory" is added to the list of of clobbered registers,
>> it will cause "gcc to not keep memory values cached in registers
>> across the assembler instrution and not optimize stores or loads to
>> that memory". To this end, IMO, after this kind of statement all
>> values cached in registers should be write into the corresponding
>> memory locations. But, the following example illustrates some
>> different thing.
>>
>> #define barrier() __asm__ __volatile__("": : :"memory")
>>
>> int main()
>> {
>> ? ? int i, n;
>> ? ? int s = 0;
>>
>> ? ? scanf("%d",&n);
>> ? ? for (i = 0; i< ?n; i++)
>> ? ? ? ? ?s += i;
>> ? ? barrier();
>> ? ? printf("%d\n", s);
>>
>> ? ? return 0;
>> }
>>
>> # gcc -S -O tst.c
>>
>> We get the assembly code like this:
>>
>> ? ? ? ?leal ? ?-8(%ebp), %eax
>> ? ? ? ?pushl ? %eax
>> ? ? ? ?pushl ? $.LC0
>> ? ? ? ?call ? ?scanf
>> ? ? ? ?movl ? ?-8(%ebp), %edx<--- cache n into edx
>> ? ? addl ? ?$16, %esp
>> ? ? ? ?testl ? %edx, %edx
>> ? ? ? ?jg ? ? ?.L2
>> ? ? ? ?movl ? ?$0, %ecx
>> ? ? ? ?jmp ? ? .L4
>> .L2:
>> ? ? ? ?movl ? ?$0, %eax<--- cache i into eax
>> ? ? movl ? ?$0, %ecx<--- ?cache s into ecx
>> .L5:
>> ? ? ? ?addl ? ?%eax, %ecx
>> ? ? ? ?incl ? ?%eax
>> ? ? cmpl ? ?%eax, %edx
>> ? ? ? ?jne ? ? .L5
>> .L4:
>> <--- at this point, I think the barrier() will cause the values cached
>> in edx, eax and ecx will be write back to n, i, and s, respectively.
>> But, this is not really the case.
>>
>> ? ? ? ?subl ? ?$8, %esp
>> ? ? ? ?pushl ? %ecx
>> ? ? pushl ? $.LC1
>> ? ? ? ?call ? ?printf
>
> Well, i and s never have their address taken, so they are not forced
> into memory, and the memory clobber can't affect them.
>
> Andrew.
>


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