Are arrays guaranteed to be affected by a "memory" clobber?
Andrew Haley
aph@redhat.com
Sat Jun 13 19:51:00 GMT 2015
On 13/06/15 18:49, Sebastian wrote:
> On Fri, 12 Jun 2015 19:53:03 +0100
> Andrew Haley <aph@redhat.com> wrote:
>
>>> That's the whole point about the example.
>>
>> No it's not. The only thing moved across the barrier is the
>> division. A memory op cannot be moved across a memory barrier.
> One memory barrier is at the cli(), as the article points out "where
> the potentially slow division is moved across cli(),". The
> assignment to val is moved, over that.
Ah, okay. I wasn't even thinking of that assignment as a memory
operation: see below.
> It was before cli() in the C
> source and it's after cli() after optimization. As your own comment
> shows.
>
>> Here's the code:
>>
>> 00000112 <test2>:
>> 112: bc 01 movw r22, r24
>> 114: f8 94 cli
> That's the cli().
>
>> 116: 8f ef ldi r24, 0xFF ; 255
>> 118: 9f ef ldi r25, 0xFF ; 255
>> 11a: 0e 94 96 00 call 0x12c ; 0x12c <__udivmodhi4>
>> 11e: 70 93 01 02 sts 0x0201, r23
>> 122: 60 93 00 02 sts 0x0200, r22
>>
>> The store to val is here ^
> Thanks. Didn't try to find that, just figured that it would be
> difficult to assign the result of the division before the division
> happened.
> So you just confirmed everything. This is after cli().
> Actually, I think you're wrong here - this is not the store to val
> (I guess you could r24 consider to be val, since that's it at the
> beginning of the function), it's the store to ivar.
Sorry, yes. I made a mistake. I meant the store to ivar.
> The store to val never happens, it is optimized away because val is
> not a volatile variable, it's just a temporary one which is never
> used afterwards.
Yes. val has been eliminated by the compiler.
> Which, still, is the point of the article: Because val is not
> declared volatile, it is not "memory", so assignments to it (and the
> division required to happen before the assignment) can be moved
> across the barrier.
The question of whether a local variable is considered by GCC to be
"in memory" depends on whether it has ever had its address taken.
So, if you say
int n;
int *p = &n;
then n is potentially a memory operand. (But be careful not to extend
this too far: if GCC knows that p is not used, it may be eliminated
and n is no longer potentially in memory.) If a variable is global it
is also a memory operand. But if a local variable never has its
address taken, no memory operation can access it (because there is no
way to know where it is.) Therefore it is not affected by a memory
clobber.
> So, again, why would it be ok to remove the volatile qualifier from
> my array elements? How else can I be sure a variable of mine is
> "memory"?
The only way to be really sure is to use volatile. But it depends
on exactly what you're trying to do: if you're more specific we can
provide better advice.
Andrew.
More information about the Gcc-help
mailing list