Re: [RFD] Using the 'memory constraint' trick to avoid memory clobber doesn't work

2014-11-13 Thread dw



I've forgot if someone mentioned whether we have a test-case in
our test-suite for this feature.


I'm looking thru gcc/testsuite/*.c to see if I can spot anything. It's 
not easy since there is a lot of asm and the people who write these 
are apparently allergic to using comments to describe what they are 
testing.


So, I found a few tests that were *using* this feature.  But they seem 
to be checking for an ICE or page fault, rather than checking to see if 
the generated code was avoiding the memory clobber.


dw


Re: Request for discussion: Rewrite of inline assembler docs

2014-04-01 Thread dw


On 3/31/2014 1:41 AM, Andrew Haley wrote:

On 03/31/2014 05:44 AM, dw wrote:

So, after looking over this discussion, I have updated the text. This
time no undefined terms, while still conveying all the points I had in mind:

The "memory" clobber tells the compiler that the assembly code performs
memory reads or writes to items other than those listed in the input and
output operands (for example accessing the memory pointed to by one of
the input parameters).  To ensure memory contains correct values, GCC
may need to flush specific register values to memory before executing
the asm. Further, the compiler will not assume that any values read from
memory before the @code{asm} will remain unchanged after the @code{asm};
it will reload them as needed.  This effectively forms a read/write
memory barrier for the compiler.

Note that this clobber does not prevent the @emph{processor} from doing
speculative reads past the @code{asm} statement. To stop that, you need
processor-specific fence instructions.

Objections?

No, none.  That's fine.


Done.

I believe all the proposed changes are now included.  The latest 
extend.texi and extend.texi.patch can be found in 
(http://www.LimeGreenSocks.com/gcc/extend05.zip) and the latest html 
pages are at 
(http://www.LimeGreenSocks.com/gcc/Using-Assembly-Language-with-C.html). 
If you were expecting a change and it isn't there, let me know.


Anyone else have something before I send this to gcc-patches? Going... 
going...





Re: Request for discussion: Rewrite of inline assembler docs

2014-03-30 Thread dw
So, after looking over this discussion, I have updated the text. This 
time no undefined terms, while still conveying all the points I had in mind:


The "memory" clobber tells the compiler that the assembly code performs 
memory reads or writes to items other than those listed in the input and 
output operands (for example accessing the memory pointed to by one of 
the input parameters).  To ensure memory contains correct values, GCC 
may need to flush specific register values to memory before executing 
the asm. Further, the compiler will not assume that any values read from 
memory before the @code{asm} will remain unchanged after the @code{asm}; 
it will reload them as needed.  This effectively forms a read/write 
memory barrier for the compiler.


Note that this clobber does not prevent the @emph{processor} from doing 
speculative reads past the @code{asm} statement. To stop that, you need 
processor-specific fence instructions.


Objections?

dw


Re: Request for discussion: Rewrite of inline assembler docs

2014-03-27 Thread dw



Looks great to me.  Just noticed one small nit: in the extended asm
section, "=irm" isn't valid, since you can't assign to an immediate.


Doh!  I probably copied this from the Input section.  Good catch.


Also, in the section about clobbers:

   It causes the compiler to flush all registers to memory before
   executing the asm statement.

At first I read this as meaning "all registers are saved somewhere in
memory before the asm".  Maybe something like "flush all pending stores"?
Not sure whether that's better or not though.


You are right, and this is an important point.  I have re-worked this 
whole paragraph.  Old:


It causes the compiler to flush all registers to memory before executing 
the |asm| statement. Further, the compiler will not assume that any 
values read before the |asm| will remain unchanged after the |asm|; it 
will reload them as needed. This effectively forms a read/write barrier 
for the compiler.


New:

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.  Further, the compiler will not assume that any 
memory-based values read before the @code{asm} will remain unchanged 
after the @code{asm}; it will reload them as needed.  This effectively 
forms a read/write memory barrier for the compiler.  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.



Thanks again for all the work on this.


Anything else?


Richard




Re: Request for discussion: Rewrite of inline assembler docs

2014-03-26 Thread dw



I think it really is general though. In:

The same problem can occur if one output parameter (@var{a}) allows a
register constraint, is updating the parameter value, and references an
address while another output parameter (@var{b}) allows a memory
constraint.


Yep, you're right.  I have trimmed this back to just:

The same problem can occur if one output parameter (@var{a}) allows a 
register constraint

and another output parameter (@var{b}) allows a memory constraint.

Seems like that's the last of it then.  I've updated the web pages 
(http://www.LimeGreenSocks.com/gcc/Using-Assembly-Language-with-C.html) 
if you want to look at how it turned out.


Unless you have something else, I'm going to start composing the email 
for gcc-patches.


Thanks for the help.

dw



Re: Request for discussion: Rewrite of inline assembler docs

2014-03-26 Thread dw


On 3/25/2014 4:20 AM, Richard Sandiford wrote:

dw  writes:

asm ("" : "=m" (*x), "=r" (y));

you have to assume that the address in %0 might use the same register as %1

Ok, now I'm getting there.  It helps that I've compiled some examples
and can see what is happening.  This one is subtle.  I'm going to have
to go back and review my code to see if I've ever done this.

So, the existing text (which only talks about overlaps with input
parameters) reads:

"Unless an output operand has the '&' constraint modifier (see
Modifiers), GCC may allocate it in the same register as an unrelated
input operand, on the assumption that the assembler code will consume
its inputs before producing outputs. This assumption may be false if the
assembler code actually consists of more than one instruction. In this
case, use '&' for each output operand that must not overlap an input."

I'm thinking about adding something like this after it:

"The same problem can occur if one of the output parameters allows a
register constraint and contains an address.  In this case, GCC may use

maybe "...and another output parameter contains..."?  Filtering that
through:


the same register for this parameter as it does for other output
parameters that allow a memory constraint.  This can produce
inconsistent results if the register address is updated before updating
the memory address.  Combining the '&' constraint with the register
constraint prevents this overlap and resolves the inconsistency."

That's as clear as I can come up with.  Better?

how about:

The same problem can occur if one output parameter @var{a} allows a register
constraint and another output parameter @var{b} allows a memory constraint.
The memory address in @var{b} may contain registers and GCC treats those
registers as inputs to the asm.  As above, GCC assumes that such input
registers are consumed before any outputs are written.  If in fact the
asm writes to @var{a} before @var{b}, it may inadvertently change the
address used for @var{b}.  Combining the '&' constraint with the register
constraint prevents this overlap and ensures that @var{a} and @var{b}
can be written in either order.

Not sure that's much good though, sorry.


That helps alot.  Of course I had to fiddle with it just a bit more...

While adding the '&' ensures that modifying @var{a} will not affect what 
address is referenced by @var{b}, I worry that someone might assume by 
implication that *omitting* it means that b will always follow a.  But I 
don't believe that's guaranteed.  It seems like it might, or it might 
not depending on the "whims" of the optimizer, with tiny changes in 
"unrelated" code swinging things back and forth.


Also, I believe the problem is slightly more limited than the language 
above (both yours and mine) implies.


These points plus some minor languages changes gives me:

The same problem can occur if one output parameter (@var{a}) allows a 
register constraint, is updating the parameter value, and references an 
address while another output parameter (@var{b}) allows a memory 
constraint. The code generated by GCC to access the memory address in 
@var{b} can contain registers which @emph{might} be shared by @var{a}, 
and GCC considers those registers to be inputs to the asm.  As above, 
GCC assumes that such input registers are consumed before any outputs 
are written.  This assumption may result in incorrect behavior if the 
asm writes to @var{a} before using @var{b}.  Combining the '@code{&}' 
constraint with the register constraint ensures that modifying @var{a} 
will not affect what address is referenced by @var{b}.  Omitting the 
'@code{&}' constraint means that the location of @var{b} will be 
undefined if @var{a} is modified before using @var{b}.


Done?


Thanks,
Richard




Re: Request for discussion: Rewrite of inline assembler docs

2014-03-24 Thread dw



Sorry for the slow response.


Thanks for getting back to me.  I was pretty sure I didn't have this all 
quite right yet.



   asm ("" : "=m" (*x), "=r" (y));

you have to assume that the address in %0 might use the same register as %1


Ok, now I'm getting there.  It helps that I've compiled some examples 
and can see what is happening.  This one is subtle.  I'm going to have 
to go back and review my code to see if I've ever done this.


So, the existing text (which only talks about overlaps with input 
parameters) reads:


"Unless an output operand has the '&' constraint modifier (see 
Modifiers), GCC may allocate it in the same register as an unrelated 
input operand, on the assumption that the assembler code will consume 
its inputs before producing outputs. This assumption may be false if the 
assembler code actually consists of more than one instruction. In this 
case, use '&' for each output operand that must not overlap an input."


I'm thinking about adding something like this after it:

"The same problem can occur if one of the output parameters allows a 
register constraint and contains an address.  In this case, GCC may use 
the same register for this parameter as it does for other output 
parameters that allow a memory constraint.  This can produce 
inconsistent results if the register address is updated before updating 
the memory address.  Combining the '&' constraint with the register 
constraint prevents this overlap and resolves the inconsistency."


That's as clear as I can come up with.  Better?

dw


Re: Request for discussion: Rewrite of inline assembler docs

2014-03-22 Thread dw


On 3/21/2014 2:57 AM, James Greenhalgh wrote:

On Thu, Feb 27, 2014 at 11:07:21AM +, Andrew Haley wrote:

Over the years there has been a great deal of traffic on these lists
caused by misunderstandings of GCC's inline assembler.  That's partly
because it's inherently tricky, but the existing documentation needs
to be improved.

dw  has done a fairly thorough reworking of
the documentation.  I've helped a bit.

Section 6.41 of the GCC manual has been rewritten.  It has become:

6.41 How to Use Inline Assembly Language in C Code
6.41.1 Basic Asm - Assembler Instructions with No Operands
6.41.2 Extended Asm - Assembler Instructions with C Expression Operands

We could simply post the patch to GCC-patches and have at it, but I
think it's better to discuss the document here first.  You can read it
at

This documentation looks like a huge improvement.


Thanks, I've worked hard to make it so.


As the discussion here seems to have stalled, perhaps it is time to propose
the patch to gcc-patches?


Sorry, I wanted to make sure the people who were discussing it had a 
chance to finish responding, then I got caught up in other projects.  
I'll try to roll the comments into the docs this weekend.



I'm certainly keen to see this make it to trunk, the increase in clarity
is substantial.


Exactly so.  Trying to figure this all out from the existing docs drove 
me crazy.  That's what motivated me to fix this.  My goal is to make it 
so the next guy who has to struggle with this has an easier time than I did.



Thanks,
James




Re: Request for discussion: Rewrite of inline assembler docs

2014-03-05 Thread dw


On 3/3/2014 3:36 AM, Richard Sandiford wrote:

dw  writes:

On 2/27/2014 11:32 PM, Richard Sandiford wrote:

dw  writes:

On 2/27/2014 4:11 AM, Richard Sandiford wrote:

Andrew Haley  writes:

Over the years there has been a great deal of traffic on these lists
caused by misunderstandings of GCC's inline assembler.  That's partly
because it's inherently tricky, but the existing documentation needs
to be improved.

dw  has done a fairly thorough reworking of
the documentation.  I've helped a bit.

Section 6.41 of the GCC manual has been rewritten.  It has become:

6.41 How to Use Inline Assembly Language in C Code
6.41.1 Basic Asm - Assembler Instructions with No Operands
6.41.2 Extended Asm - Assembler Instructions with C Expression Operands

We could simply post the patch to GCC-patches and have at it, but I
think it's better to discuss the document here first.  You can read it
at

http://www.LimeGreenSocks.com/gcc/Basic-Asm.html
http://www.LimeGreenSocks.com/gcc/Extended-Asm.html
http://www.LimeGreenSocks.com/gcc/extend04.zip (contains .texi, .patch,
and affected html pages)

All comments are very welcome.

Thanks for doing this, looks like a big improvement.

Thanks, I did my best.  I appreciate you taking the time to review them.


A couple of comments:

The section on basic asms says:

 Do not expect a sequence of asm statements to remain perfectly
 consecutive after compilation. To ensure that assembler instructions
 maintain their order, use a single asm statement containing multiple
 instructions. Note that GCC's optimizer can move asm statements
 relative to other code, including across jumps.

The "maintain their order" might be a bit misleading, since volatile asms
(including basic asms) must always be executed in the original order.
Maybe this was meaning placement/address order instead?

This statement is based on this text from the existing docs:

"Similarly, you can't expect a sequence of volatile |asm| instructions
to remain perfectly consecutive. If you want consecutive output, use a
single |asm|."

I do not dispute what you are saying.  I just want to confirm that the
existing docs are incorrect before making a change.  Also, see Andi's
response re -fno-toplevel-reorder.

It seems to me that recommending "single statement" is both the
clearest, and the safest approach here.  But I'm prepared to change my
mind if there is consensus I should.

Right.  I agree with that part.  I just thought that the "maintain their
order" could be misunderstood as meaning execution order, whereas I think
both sentences of the original docs were talking about being "perfectly
consecutive" (which to me means "there are no other instructions inbetween").

Hmm.  I'm not seeing the differences here that you do.

Well, like you say, things can be moved across branches.  So, although
this is a very artificial example:

  asm ("x");
  asm ("y");

could become:

  goto bar;

foo:
  asm ("y");
  ...

bar:
  asm ("x");
  goto foo;

This has reordered the instructions in the sense that they have a
different order in memory.  But they are still _executed_ in the same
order.  Actually reordering the execution would be a serious bug.

So I just want to avoid anything that gives the impression that "y" can
be executed before "x" in this example.  I still think:


Since the existing docs say "GCC's optimizer can move asm statements
relative to other code", how would you feel about:

"Do not expect a sequence of |asm| statements to remain perfectly
consecutive after compilation. If you want to stop the compiler from
reordering or inserting anything into a sequence of assembler
instructions, use a single |asm| statement containing multiple
instructions. Note that GCC's optimizer can move |asm| statements
relative to other code, including across jumps."

...this gives the impression that we might try to execute volatiles
in a different order.


Ahh!  Ok, I see what you mean.  Hmm.  Based on the description of 
"no-toplevel-reorder", I assumed that it actually *might* re-order them.


So, more like:

"GCC's optimizer can move asm statements relative to other
code, including across jumps.  This has implications for code
that contains a sequence of asm statements.  While the execution
order of asm statements will be preserved, do not expect the sequence of asm
statements to remain perfectly consecutive in the compiler's output.
To ensure that assembler instructions maintain their order, use a
single asm statement containing multiple instructions."



It might also be
worth mentioning that the number of instances of an asm in the output
may be different from the input.  (Can it increase as well as decrease?
I'm not sure off-hand, but probably y

Re: Request for discussion: Rewrite of inline assembler docs

2014-03-03 Thread dw


On 2/27/2014 8:12 PM, Andi Kleen wrote:

dw  writes:

What would you say to something like this:

"Since GCC does not parse the asm, it has no visibility of any static
variables or functions it references.  This may result in those
symbols getting discarded by GCC as unused.  To avoid this problem,
list the symbols as inputs or outputs."

output makes no sense I think, only input.


For static functions, yes.  However won't static data have the same 
problem?  And static data could be input or output.



You still need the part about the top-level asm, where input
doesn't work.


Accessing variables from Basic asm has more problems than this. If you 
are inside a function that accesses globals from both asm and C, the 
results will probably be a mess.  That's why the current docs for Basic 
asm say:


"Safely accessing C data and calling functions from Basic |asm| is more 
complex than it may appear. To access C data, it is better to use 
Extended |asm|. "


However, you are right, more is needed.  How about:

"For asm blocks outside of functions (which must be Basic asm), be aware 
that since GCC does not parse the asm, it has no visibility of any 
static variables or functions it references.  This may result in those 
symbols getting discarded by GCC as unused."



And another common problem:

For top level asm there is no guarantee the compiler outputs the
statements in order.

Well, basic asm (which is the only thing you can use at top level)
already says:

"Do not expect a sequence of |asm| statements to remain perfectly
consecutive after compilation. To ensure that assembler instructions
maintain their order, use a single |asm| statement containing multiple
instructions. Note that GCC's optimizer can move |asm| statements
relative to other code, including across jumps. "

Is something more needed?

Yes it should be made clear that this applies to top-level asm
too.


I believe what you call "top level" the docs call "Basic asm." This same 
statement is in both sections.



-Andi




Re: Request for discussion: Rewrite of inline assembler docs

2014-02-27 Thread dw


On 2/27/2014 9:35 AM, Andi Kleen wrote:

Andrew Haley  writes:


Over the years there has been a great deal of traffic on these lists
caused by misunderstandings of GCC's inline assembler.  That's partly
because it's inherently tricky, but the existing documentation needs
to be improved.

dw  has done a fairly thorough reworking of
the documentation.  I've helped a bit.


It would be nice if you could include some discussion of the LTO
reference problems.

Something like:

It is not legal to reference a static variable or function symbol from
the assembler code, as the compiler may optimize unused symbols
away. For inline asm in functions these should be referred as "m" input
arguments. For top level asm the referenced symbol should be made global
and marked with __attribute__((externally_visible)) .


What would you say to something like this:

"Since GCC does not parse the asm, it has no visibility of any static 
variables or functions it references.  This may result in those symbols 
getting discarded by GCC as unused.  To avoid this problem, list the 
symbols as inputs or outputs."



And another common problem:

For top level asm there is no guarantee the compiler outputs the
statements in order.


Well, basic asm (which is the only thing you can use at top level) 
already says:


"Do not expect a sequence of |asm| statements to remain perfectly 
consecutive after compilation. To ensure that assembler instructions 
maintain their order, use a single |asm| statement containing multiple 
instructions. Note that GCC's optimizer can move |asm| statements 
relative to other code, including across jumps. "


Is something more needed?


[unless -fno-toplevel-reorder is specified, but I'm not should mention that]

-Andi




Re: Request for discussion: Rewrite of inline assembler docs

2014-02-27 Thread dw


On 2/27/2014 4:22 AM, Kyrill Tkachov wrote:

On 27/02/14 11:07, Andrew Haley wrote:

Over the years there has been a great deal of traffic on these lists
caused by misunderstandings of GCC's inline assembler.  That's partly
because it's inherently tricky, but the existing documentation needs
to be improved.

dw  has done a fairly thorough reworking of
the documentation.  I've helped a bit.

Section 6.41 of the GCC manual has been rewritten.  It has become:

6.41 How to Use Inline Assembly Language in C Code
6.41.1 Basic Asm - Assembler Instructions with No Operands
6.41.2 Extended Asm - Assembler Instructions with C Expression Operands

We could simply post the patch to GCC-patches and have at it, but I
think it's better to discuss the document here first.  You can read it
at

http://www.LimeGreenSocks.com/gcc/Basic-Asm.html
http://www.LimeGreenSocks.com/gcc/Extended-Asm.html
http://www.LimeGreenSocks.com/gcc/extend04.zip (contains .texi, .patch,
and affected html pages)

All comments are very welcome.

Hi Andrew, dw,

Thanks for doing this!


Thanks for taking the time to review it.



In the Extended Asm documentation: Other format strings section:
"'%=' outputs a number that is unique to each instruction in the 
entire compilation."


I find the term 'instruction' to be confusing here. From what I 
understand the number is unique to each asm statement, which may 
contain multiple assembly instructions. IMHO it would be clearer to 
say "unique to each asm statement"


I'm not sure your text quite gets us there either.  If (as Richard 
suggests), the asm can get duplicated, I'd expect each to get a unique 
value for %=.  And I'd want to be clear about what happens if you do 
#define DO_SOMETHING asm("%=":).


How would you feel about:

"'%=' outputs a number that is unique to each instance of the asm 
statement in the entire compilation."




Kyrill




Andrew.









Re: Request for discussion: Rewrite of inline assembler docs

2014-02-27 Thread dw


On 2/27/2014 4:11 AM, Richard Sandiford wrote:

Andrew Haley  writes:

Over the years there has been a great deal of traffic on these lists
caused by misunderstandings of GCC's inline assembler.  That's partly
because it's inherently tricky, but the existing documentation needs
to be improved.

dw  has done a fairly thorough reworking of
the documentation.  I've helped a bit.

Section 6.41 of the GCC manual has been rewritten.  It has become:

6.41 How to Use Inline Assembly Language in C Code
6.41.1 Basic Asm - Assembler Instructions with No Operands
6.41.2 Extended Asm - Assembler Instructions with C Expression Operands

We could simply post the patch to GCC-patches and have at it, but I
think it's better to discuss the document here first.  You can read it
at

http://www.LimeGreenSocks.com/gcc/Basic-Asm.html
http://www.LimeGreenSocks.com/gcc/Extended-Asm.html
http://www.LimeGreenSocks.com/gcc/extend04.zip (contains .texi, .patch,
and affected html pages)

All comments are very welcome.

Thanks for doing this, looks like a big improvement.


Thanks, I did my best.  I appreciate you taking the time to review them.


A couple of comments:

The section on basic asms says:

   Do not expect a sequence of asm statements to remain perfectly
   consecutive after compilation. To ensure that assembler instructions
   maintain their order, use a single asm statement containing multiple
   instructions. Note that GCC's optimizer can move asm statements
   relative to other code, including across jumps.

The "maintain their order" might be a bit misleading, since volatile asms
(including basic asms) must always be executed in the original order.
Maybe this was meaning placement/address order instead?


This statement is based on this text from the existing docs:

"Similarly, you can't expect a sequence of volatile |asm| instructions 
to remain perfectly consecutive. If you want consecutive output, use a 
single |asm|."


I do not dispute what you are saying.  I just want to confirm that the 
existing docs are incorrect before making a change.  Also, see Andi's 
response re -fno-toplevel-reorder.


It seems to me that recommending "single statement" is both the 
clearest, and the safest approach here.  But I'm prepared to change my 
mind if there is consensus I should.



It might also be
worth mentioning that the number of instances of an asm in the output
may be different from the input.  (Can it increase as well as decrease?
I'm not sure off-hand, but probably yes.)


So, in the volatile section, how about something like this for decrease:

"GCC does not delete a volatile |asm| if it is reachable, but may delete 
it if it can prove that control flow never reaches the location of the 
instruction."


For increase (not quite sure where to put this yet):

"Under certain circumstances, GCC may duplicate your asm code as part of 
optimization.  This can lead to unexpected duplicate symbol errors 
during compilation if symbols or labels are being used. Using %=  (see 
Assembler Template) may help resolve this problem."



In the extended section:

   Unless an output operand has the '&' constraint modifier (see
   Modifiers), GCC may allocate it in the same register as an unrelated
   input operand, [...]

It could also use it for addresses in other (memory) outputs.


Ok.  But I'm not sure this really adds anything.  Having warned people 
that the register may be re-used unless '&' is used seems sufficient.



For:

   When using asmSymbolicNames for the output operands, you may use these
   names instead of digits.

it might be worth mentioning that you need the enclosing [...].


Done.



Thanks,
Richard






Re: [doc] Fixing reference inside Extended-Asm.html

2013-11-22 Thread dw



Is the version of texinfo buggy to generate online documentation?


Sorry for the delayed response.  I was hoping the gcc expert on docs 
would respond so I could see who that was.


I have been doing some work on Extended-Asm.html (see the work in 
progress at 
http://www.limegreensocks.com/gcc/Using-Assembly-Language-with-C.html) 
and I haven't had a problem generating output.


dw


Need a copyright assignment and a copyright disclaimer form

2013-04-24 Thread dw
I am attempting to submit a patch for the gcc documentation (see 
http://gcc.gnu.org/ml/gcc-help/2013-04/msg00193.html).  I am told that I 
need to submit one of these two forms.  Please send me copies so I can 
select one and submit it.


dw