On 13/06/15 18:49, Sebastian wrote: > On Fri, 12 Jun 2015 19:53:03 +0100 > Andrew Haley <aph@xxxxxxxxxx> 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.