On Fri, Mar 28, 2014 at 01:15:39PM +0000, Andrew Haley wrote:
> On 03/28/2014 10:46 AM, Hannes Frederic Sowa wrote:
> > On Fri, Mar 28, 2014 at 09:41:41AM +0000, Andrew Haley wrote:
> >> On 03/28/2014 09:30 AM, Hannes Frederic Sowa wrote:
> >>> On Fri, Mar 28, 2014 at 09:10:11AM +0000, Andrew Haley wrote:
> >>>> On 03/28/2014 06:20 AM, dw wrote:
> >>>>> Using this clobber causes the compiler to flush all (modified)
> >>>>> registers
> >>>>> being used to store memory-based values to memory before executing the
> >>>>> @code{asm} statement.
> >>>>
> >>>> I don't know what a "memory-based" value is. This phrase doesn't help
> >>>> at all. In addition, it isn't true. Modified registers are not
> >>>> flushed to memory unless they are clobbered or their address is taken.
> >>>> This sentence should be deleted.
> >>>
> >>> i and sum form your example are not allocated in memory. If you make
> >>> one of them static you should be able to see the effect.
> >>
> >> I know. That's not the point. "memory-based" is not a well-defined
> >> term. In order to write clear documentation it is necessary either to
> >> define terms or to use terms that are already well-defined.
> >
> > Ok, I see the problem. Maybe something like this by avoiding the term?
> >
> > Using this clobber causes the compiler to flush all (modified) registers
> > being used to store values which gcc decided to originally allocate in
> > memory before executing the @code{asm} statement.
>
> Not really, no: that's not true.
Hmm, ok?
> >> What is true here is that all registers used to cache variables that
> >> are reachable from pointers in the program are flushed. Anything that
> >> is statically allocated is reachable, as is anything dynamically
> >> allocated by malloc; auto variables are not reachable unless their
> >> address is taken.
> >
> > One would have to go into detail of various optimizations which could
> > remove the address taking
>
> One would not: any such optimization would be incorrect. Any memory
> reachable from an inline asm statement with a memory clobber must
> be flushed to memory.
If I extend your example with an additional pointer and take the address of s
it still doesn't allocate s in memory and as such cannot flush out the
register content, which is perfectly legal. The pointer is completley
eliminated (this is an extreme example).
int sum(int a[], int l) {
int i;
int s = 0;
int *sp = &s;
for (i = 0; i < l; i++) {
asm volatile("nop # Nothing at all":::"memory");
*sp += a[i];
}
return s;
}
> > e.g. IMHO the last sentence of the paragraph already
> > deals with this.
>
> Which last sentence of what paragraph?
This one:
| For performance reasons, some variables only exist in registers and never
| get written to memory. The "memory" clobber does not force these values
| to get written to memory.
Btw. very nice work!
Thanks,
Hannes