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.