Re: [PATCH] Add atomic type qualifier

2013-08-01 Thread Andrew MacLeod

On 07/26/2013 07:21 PM, Joseph S. Myers wrote:

On Fri, 26 Jul 2013, Andrew MacLeod wrote:


This patch adds an atomic type qualifier to GCC.   It can be accessed via
__attribute__((atomic)) or in C11 mode via the _Atomic keyword.

Why the attribute - why not just the keyword?


* When C11 refers to qualified types, by default it does not include
atomic types (6.2.5#27).  What's your rationale for including atomic in
TYPE_QUALS rather than making it separate?  With either approach, a review
of every reference to qualifiers in the front end is needed to determine
what's correct for atomic; did you find that including atomic in
qualifiers in the implementation made for fewer changes?

Ive gotten the expressions mostly working  (= and op= work great), but 
am having some issues with plain loads and identifying the correct time 
to emit the load...   I've also hacked up a rough approximation of what 
stdatomic.h would need.


I also think I'll revisit how atomic values are marked in the front 
end... now that Im doing  all the real work in the front end, I don't 
think I want that attribute all over the place like I did before. I 
may well decide to remove it from the qualifiers and make it a separate 
type now...   So don't worry about reviewing those files...


I likely wont get to this until I get back from vacation in a couple of 
weeks however.  I will post the state of things before I go, both for my 
own recollection when I return, and in case anyone just happens to feel 
really interested and wants to have a look at some of  the remaining 
required changes.  ha. I wish.Its starting to get close tho.


Andrew


Re: [PATCH] Add atomic type qualifier

2013-07-31 Thread Andrew MacLeod

On 07/30/2013 09:44 AM, Andrew MacLeod wrote:

On 07/30/2013 09:16 AM, Joseph S. Myers wrot


THis also means that for the 3 floating point operations all we need 
are RTL
insn patterns, no buitin.  And as with the other atomics, if the 
pattern
I think something will also be needed to specify allocation of the 
fenv_t

temporary (whether in memory or registers).

doesnt exist, we just wont emit it.  we could add a warning easily 
enough in

this case.
Note there's a difference between no need to emit it, no warning 
should be

given (soft float) and need to emit it but patterns not yet written so
warning should be given (hard float but patterns not yet implemented for
the architecture).


In fact, the flag could be the presence of the fenv_t variable.. Null 
for that variable field in the builtin indicate you don't need the 
patterns emitted.


I';ll get back to you in a bit with the actual built-in's format once 
I poke around the existing one and see how I can leverage it. I 
rewrote all that code last year and it ought to be pretty simple to 
add new operand support.  It better be anyway :-)




I worked out the built-ins and what they need to do... and you know 
what?  I'm not sure I see the point any more.


I am going to give a shot at simply expanding this code right in the 
front end.   For the floating and complex types I'll create temps and 
pass them to the generic atomic routines for load and 
compare_exchange... I should be able to directly call the same routines 
that sort out what can be mapped to lock free and what can't.  And in 
the end, the optimizers can sort out how to make things better. that way 
we dont need any support anywhere else. (well, we may need 3 builtins 
for the floating point stuff.. I don't know..  I'll worry about that later.)


On a side note,  after Friday, I'm off for 2 weeks, so I'll be pretty 
quiet until  the 19th or 20th.


Btw, if anyone wants to take a stab at a stdatomic.h file, that would be 
OK with me :-)


Andrew






Re: [PATCH] Add atomic type qualifier

2013-07-30 Thread Joseph S. Myers
On Mon, 29 Jul 2013, Andrew MacLeod wrote:

 Ive been poking at this today, and Im wondering what you think of the idea of
 adding a flag to MODIFY_EXPR,
 #define MODIFY_EXPR_IS_COMPOUND(NODE)
 MODIFY_EXPR_CHECK(NODE)-base.asm_written_flag
 
 and set that in the MODIFY_EXPR node when we create it from the x op= y form
 in the front end.   That flag seems to be free for expressions.

My suggestion is that the IR generated by the front end should make it 
completely explicit what may need retrying with a compare-and-exchange, 
rather than relying on non-obvious details to reconstruct the semantics 
required at gimplification time - there are too many transformations 
(folding etc.) that may happen on existing trees and no clear way to be 
confident that you can still identify all the operands accurately after 
such transformations.  That is, an ATOMIC_COMPOUND_MODIFY_EXPR or similar, 
whose operands are: the LHS of the assignment; a temporary variable, old 
in C11 footnote 113; the RHS; and the old op val expression complete 
with the conversion to the type of the LHS.  Gimplification would then 
(carry out the effects of stabilize_reference on the LHS and save_expr on 
the RHS and) do old = LHS; followed by the do-while compare-exchange 
loop.

A flag on the expression could indicate that the floating-point semantics 
are required.  I'd guess back ends would need to provide three insn 
patterns, corresponding to feholdexcept, feclearexcept and feupdateenv, 
that there'd be corresponding built-in functions for these used at 
gimplification time, and that a target hook would give the type used for 
fenv_t by these built-in functions (*not* necessarily the same as the 
fenv_t used by any implementation of the functions in libm).  The target 
should also be able to declare that there's no support for floating-point 
exceptions (e.g. for soft-float) and so floating-point cases don't need 
any special handling.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH] Add atomic type qualifier

2013-07-30 Thread Andrew MacLeod

On 07/30/2013 07:41 AM, Joseph S. Myers wrote:

On Mon, 29 Jul 2013, Andrew MacLeod wrote:


Ive been poking at this today, and Im wondering what you think of the idea of
adding a flag to MODIFY_EXPR,
#define MODIFY_EXPR_IS_COMPOUND(NODE)
MODIFY_EXPR_CHECK(NODE)-base.asm_written_flag

and set that in the MODIFY_EXPR node when we create it from the x op= y form
in the front end.   That flag seems to be free for expressions.

My suggestion is that the IR generated by the front end should make it
completely explicit what may need retrying with a compare-and-exchange,
rather than relying on non-obvious details to reconstruct the semantics
required at gimplification time - there are too many transformations
(folding etc.) that may happen on existing trees and no clear way to be
confident that you can still identify all the operands accurately after
such transformations.  That is, an ATOMIC_COMPOUND_MODIFY_EXPR or similar,
whose operands are: the LHS of the assignment; a temporary variable, old
in C11 footnote 113; the RHS; and the old op val expression complete
with the conversion to the type of the LHS.  Gimplification would then
(carry out the effects of stabilize_reference on the LHS and save_expr on
the RHS and) do old = LHS; followed by the do-while compare-exchange
loop.
In fact, after thinking about it overnight, I came to similar 
conclusions...  I believe it requires new builtin(s) for these 
operations.   Something like


   __atomic_compound_assign (atomic_expr, enum atomic_operation_type, 
blah, blah,...)


A call to this builtin would be generated right from the parser when it 
sees the op= expression, and the built-in can then travel throughout 
gimple as a normal atomic built-in operation like the rest.  During 
expansion to RTL it can be turned into whatever sequence we happen to 
need.   This is what happens currently with the various 
__atomic_fetch_op and __atomic_op_fetch.  In fact, they are a subset of 
required operations, so I should be able to combine the implementation 
of those with this new one.


 Is C++ planning to match  these behaviours in the atomic library? It 
would need to access this builtin as well so that the C++ template code 
can invoke it.




A flag on the expression could indicate that the floating-point semantics
are required.  I'd guess back ends would need to provide three insn
patterns, corresponding to feholdexcept, feclearexcept and feupdateenv,
that there'd be corresponding built-in functions for these used at
gimplification time, and that a target hook would give the type used for
fenv_t by these built-in functions (*not* necessarily the same as the
fenv_t used by any implementation of the functions in libm).  The target
should also be able to declare that there's no support for floating-point
exceptions (e.g. for soft-float) and so floating-point cases don't need
any special handling.

I think the fact that it requires floating point sematics should be 
determinable from the types of the expressions involved.  If there is a 
floating point somewhere, then we'll need to utilize the patterns.  
we'll still have the types, although it would certainly be easy enough 
to add a flag to the builtin... and maybe thats the way to go after all.


THis also means that for the 3 floating point operations all we need are 
RTL insn patterns, no buitin.  And as with the other atomics, if the 
pattern doesnt exist, we just wont emit it.  we could add a warning 
easily enough in this case.


I think we're somewhere good now :-)

I guess I'll do the same thing for normal references to an atomic 
variable... issue the atomic load or atomic store directly from the 
parser...


Andrew


Re: [PATCH] Add atomic type qualifier

2013-07-30 Thread Joseph S. Myers
On Tue, 30 Jul 2013, Andrew MacLeod wrote:

  A flag on the expression could indicate that the floating-point semantics
  are required.  I'd guess back ends would need to provide three insn
  patterns, corresponding to feholdexcept, feclearexcept and feupdateenv,
  that there'd be corresponding built-in functions for these used at
  gimplification time, and that a target hook would give the type used for
  fenv_t by these built-in functions (*not* necessarily the same as the
  fenv_t used by any implementation of the functions in libm).  The target
  should also be able to declare that there's no support for floating-point
  exceptions (e.g. for soft-float) and so floating-point cases don't need
  any special handling.
  
 I think the fact that it requires floating point sematics should be
 determinable from the types of the expressions involved.  If there is a

My reasoning for such a flag is:

The gimplifier shouldn't need to know the details of the semantics for 
operand promotions, how various arithmetic on complex numbers is carried 
out, and how a result is converted back to the destination type for the 
store.  Even if it's the language-specific gimplification code rather than 
the language-independent gimplifier, we still want those details to be in 
one place (currently build_binary_op for the binary operation semantics), 
shared by atomic and non-atomic operations.

Hence my suggestion that the operands to the new built-in function / 
operation do not include the unmodified RHS, and do not directly specify 
the operation in question.  Instead, one operand is an expression of the 
form

  (convert-to-LHS-type) (old op val)

where old and val are the temporary variables given in C11 footnote 
113 and probably allocated by the front end (val initialized once, old 
initialized once but then potentially changing each time through the 
loop).  The trees for that expression would be generated by 
build_binary_op and contain everything required for the semantics of e.g. 
complex arithmetic.

It's true that in the case where floating-point issues arise, 
floating-point types will be involved somewhere in this expression (and 
otherwise, they will not be - though the initializer for val might 
itself have involved floating-point arithmetic), but you'd need to search 
recursively for them; having a flag seems simpler.

 THis also means that for the 3 floating point operations all we need are RTL
 insn patterns, no buitin.  And as with the other atomics, if the pattern

I think something will also be needed to specify allocation of the fenv_t 
temporary (whether in memory or registers).

 doesnt exist, we just wont emit it.  we could add a warning easily enough in
 this case.

Note there's a difference between no need to emit it, no warning should be 
given (soft float) and need to emit it but patterns not yet written so 
warning should be given (hard float but patterns not yet implemented for 
the architecture).

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH] Add atomic type qualifier

2013-07-30 Thread Andrew MacLeod

On 07/30/2013 09:16 AM, Joseph S. Myers wrot

My reasoning for such a flag is:



Hence my suggestion that the operands to the new built-in function /
operation do not include the unmodified RHS, and do not directly specify
the operation in question.  Instead, one operand is an expression of the
form

   (convert-to-LHS-type) (old op val)

where old and val are the temporary variables given in C11 footnote
113 and probably allocated by the front end (val initialized once, old
initialized once but then potentially changing each time through the
loop).  The trees for that expression would be generated by
build_binary_op and contain everything required for the semantics of e.g.
complex arithmetic.

It's true that in the case where floating-point issues arise,
floating-point types will be involved somewhere in this expression (and
otherwise, they will not be - though the initializer for val might
itself have involved floating-point arithmetic), but you'd need to search
recursively for them; having a flag seems simpler.


I agree.


THis also means that for the 3 floating point operations all we need are RTL
insn patterns, no buitin.  And as with the other atomics, if the pattern

I think something will also be needed to specify allocation of the fenv_t
temporary (whether in memory or registers).


doesnt exist, we just wont emit it.  we could add a warning easily enough in
this case.

Note there's a difference between no need to emit it, no warning should be
given (soft float) and need to emit it but patterns not yet written so
warning should be given (hard float but patterns not yet implemented for
the architecture).


In fact, the flag could be the presence of the fenv_t variable.. Null 
for that variable field in the builtin indicate you don't need the 
patterns emitted.


I';ll get back to you in a bit with the actual built-in's format once I 
poke around the existing one and see how I can leverage it. I rewrote 
all that code last year and it ought to be pretty simple to add new 
operand support.  It better be anyway :-)


Amndrew





Re: [PATCH] Add atomic type qualifier

2013-07-29 Thread Andrew MacLeod

On 07/28/2013 03:34 PM, Joseph S. Myers wrote:

On Fri, 26 Jul 2013, Andrew MacLeod wrote:


What it doesn't do:

* It doesn't implement the stdatomic.h header - do you intend that to be
provided by GCC or glibc?

(Substantive review of the full patch still to come.)


I figured gcc would provide it...   but I hadn't given it a ton of 
thought on whether that was good or bad.  again, that sort of thing 
isn't really my strong suit :-)



   * It doesn't implement the C11 expression expansion into atomic built-ins.
ie, you can't write:
_Atomic int x;
  x = 0;
   and have the result be an atomic operation calling __atomic_store (x,
0).   That will be in a  follow on patch. So none of the expression expansion
from C11 is included yet. This just enables that.

The hardest part will probably be compound assignment to an atomic object
where either operand of the assignment has floating-point type - see C11
footnote 113, but you can't actually use feholdexcept or feclearexcept or
feupdateenv here because that would introduce libm dependencies, so back
ends will need to provide appropriate insn patterns to do those operations
inline.
  
Blick. What were they smoking the night before... I guess we'll probably 
need to enhance the current atomic patterns in RTL...We should be 
able to figure out that its floating point and invoke the appropriate 
RTL pattern during expansion rather than an existing one.OR just 
frigging call libatomic and let it deal with it. :-)  I guess there 
wouldnt be any other fallback available. Actually, thats a mess... no 
way for the librtary to know its floating point unless you tell it 
somehow with new entry points or somesuch..  very lame.


I planned to do the work in gimplification... let the atomic decls 
through, and during gimplification, loads or stores of an atomic decl 
would be converted to the appropriate load or store builtin, and at the 
same time recognize the  'decl = decl op value' expression and replace 
those as appropriate with atomic_op_fetch operations.   I had discussed 
this at some length with Lawrence crowl and Jeffrey Yasskin some time 
ago..   At gimplification time we no longer know whether the original 
form was
decl op= val  or decl = decl op val;, but the decision was that it is ok 
to recognize decl = decl op val and make that atomic.. it would still 
satisfy the language requirements..


Andrew



Re: [PATCH] Add atomic type qualifier

2013-07-29 Thread Joseph S. Myers
On Mon, 29 Jul 2013, Andrew MacLeod wrote:

 Blick. What were they smoking the night before... I guess we'll probably need
 to enhance the current atomic patterns in RTL...We should be able to
 figure out that its floating point and invoke the appropriate RTL pattern
 during expansion rather than an existing one.OR just frigging call
 libatomic and let it deal with it. :-)  I guess there wouldnt be any other
 fallback available. Actually, thats a mess... no way for the librtary to know
 its floating point unless you tell it somehow with new entry points or
 somesuch..  very lame.

Note that you only need *one* of the types to be floating-point for this 
issue to apply.  If you have

_Atomic char c;
float f;

c /= f;

then all the same requirements apply; there may be exceptions to discard 
not just from the division, but from the conversion of a float division 
result to char.

 I planned to do the work in gimplification... let the atomic decls through,
 and during gimplification, loads or stores of an atomic decl would be
 converted to the appropriate load or store builtin, and at the same time
 recognize the  'decl = decl op value' expression and replace those as
 appropriate with atomic_op_fetch operations.   I had discussed this at some
 length with Lawrence crowl and Jeffrey Yasskin some time ago..   At
 gimplification time we no longer know whether the original form was
 decl op= val  or decl = decl op val;, but the decision was that it is ok to
 recognize decl = decl op val and make that atomic.. it would still satisfy the
 language requirements..

I think that's probably OK (though, is this a theorem of the formal 
modelling work that has been done on the memory model?), but note it's not 
just a decl but an arbitrary pointer dereference (the address of the 
lvalue is only evaluated once, no matter how many compare-and-exchange 
operations are needed), and the operation may end up looking like

*ptr = (convert to type of *ptr) ((promote) *ptr op (promote) val)

rather than a simple decl = decl op val.  Or something more complicated if 
the operation involves complex numbers - look at what gets for mixed real 
/ complex arithmetic, for example.  Given

_Atomic _Complex float f;
double d;

f += d;

the atomicity is for the whole complex number (and so the 
compare-and-exchange needs to work on the whole number) although only the 
real part is modified by the addition.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH] Add atomic type qualifier

2013-07-29 Thread Andrew MacLeod

On 07/29/2013 10:59 AM, Andrew MacLeod wrote:
Blick. What were they smoking the night before... I guess we'll 
probably need to enhance the current atomic patterns in RTL...We 
should be able to figure out that its floating point and invoke the 
appropriate RTL pattern during expansion rather than an existing 
one.OR just frigging call libatomic and let it deal with it. :-)  
I guess there wouldnt be any other fallback available. Actually, thats 
a mess... no way for the librtary to know its floating point unless 
you tell it somehow with new entry points or somesuch..  very lame.


Actually, in hind sight, we will need new atomic builtins  It lists 
other operators we need to support that we currently do not: They list

*, / , % + -^ |
we currently  don't support *,/, modulus, right or left shift.

Maybe the simple thing is simply to emit the compare_exchange loop for 
all these, and not bother libatomic with them at all.We can 
eventually add rtl patterns for them if we want better performance for 
these new bits.


As for the floating point operations, emit the same loop, and if there 
is a target pattern emit it, otherwise issue a warning saying those 
footnote items are not properly protected or whatever.


Also, If I read this right, arithmetic type also includes complex type 
does it not?  which means we need to support this for complex as well...


Does C++14(or onward) intend to support these additions as well?

Andrew


Re: [PATCH] Add atomic type qualifier

2013-07-29 Thread Andrew MacLeod

On 07/29/2013 12:06 PM, Joseph S. Myers wrote:

On Mon, 29 Jul 2013, Andrew MacLeod wrote:


Blick. What were they smoking the night before... I guess we'll probably need
to enhance the current atomic patterns in RTL...We should be able to
figure out that its floating point and invoke the appropriate RTL pattern
during expansion rather than an existing one.OR just frigging call
libatomic and let it deal with it. :-)  I guess there wouldnt be any other
fallback available. Actually, thats a mess... no way for the librtary to know
its floating point unless you tell it somehow with new entry points or
somesuch..  very lame.

Note that you only need *one* of the types to be floating-point for this
issue to apply.  If you have

_Atomic char c;
float f;

c /= f;

then all the same requirements apply; there may be exceptions to discard
not just from the division, but from the conversion of a float division
result to char.

yes, unfortunately.   but  gimplification should turn this to:
t0 = c
t1 =(float) t0
t2 = t0 / f
t3 = (char) t2
c = t3

so we simply see a floating point division bracketted by load and store 
from a TYPE_ATOMIC expression. so we'd should be able to recognize the 
need for the floating point extra stuff based on the type of the 
operation .  and just wrap the whole blasted thing.


I must say, I'm not a fan :-)




I planned to do the work in gimplification... let the atomic decls through,
and during gimplification, loads or stores of an atomic decl would be
converted to the appropriate load or store builtin, and at the same time
recognize the  'decl = decl op value' expression and replace those as
appropriate with atomic_op_fetch operations.   I had discussed this at some
length with Lawrence crowl and Jeffrey Yasskin some time ago..   At
gimplification time we no longer know whether the original form was
decl op= val  or decl = decl op val;, but the decision was that it is ok to
recognize decl = decl op val and make that atomic.. it would still satisfy the
language requirements..

I think that's probably OK (though, is this a theorem of the formal
modelling work that has been done on the memory model?), but note it's not

I have no idea if its a theorem or not.

just a decl but an arbitrary pointer dereference (the address of the
lvalue is only evaluated once, no matter how many compare-and-exchange
operations are needed), and the operation may end up looking like

*ptr = (convert to type of *ptr) ((promote) *ptr op (promote) val)

rather than a simple decl = decl op val.  Or something more complicated if
I think gimplification takes care of that as well since all assignments 
have to be in the form   DECL = VALUE op VALUE.. it constructs the 
sequence so that something like

*op_expr += 1

is properly transformed to
t0 = op_expr
  t1 = *t0
t2 = t1 + 1
*t0 = t2

With the TYPE_ATOMIC attribute set and rippled through the op_expr 
expression, we know that
*t0 is atomic in nature, so t1 is an atomic load, *t0 is an atomic 
store, and looking back at t2 = t1 + 1 can see that this is an atomic += 1.


same thing with a normal load of an expression... the TYPE_ATOMIC gimple 
attribute *ought* to tell us everything we need.



the operation involves complex numbers - look at what gets for mixed real
/ complex arithmetic, for example.  Given

_Atomic _Complex float f;
double d;

f += d;

the atomicity is for the whole complex number (and so the
compare-and-exchange needs to work on the whole number) although only the
real part is modified by the addition.



complex I hadn't thought about until just now, I'll have to look.  I 
know we can deal with parts on complex sometimes.   Hopefully at 
gimplification time we still have the whole complex reference and if we 
just take care of that with the atomic builtins, we'll maintain the 
entire thing as we need.


Andrew









Re: [PATCH] Add atomic type qualifier

2013-07-29 Thread Joseph S. Myers
On Mon, 29 Jul 2013, Andrew MacLeod wrote:

 complex I hadn't thought about until just now, I'll have to look.  I know we
 can deal with parts on complex sometimes.   Hopefully at gimplification time
 we still have the whole complex reference and if we just take care of that
 with the atomic builtins, we'll maintain the entire thing as we need.

You have things in a fairly complicated form, building up COMPLEX_EXPRs 
out of operations on the individual parts of the complex operands.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH] Add atomic type qualifier

2013-07-29 Thread Andrew MacLeod

On 07/29/2013 12:42 PM, Joseph S. Myers wrote:

On Mon, 29 Jul 2013, Andrew MacLeod wrote:


complex I hadn't thought about until just now, I'll have to look.  I know we
can deal with parts on complex sometimes.   Hopefully at gimplification time
we still have the whole complex reference and if we just take care of that
with the atomic builtins, we'll maintain the entire thing as we need.

You have things in a fairly complicated form, building up COMPLEX_EXPRs
out of operations on the individual parts of the complex operands.


I tried:

  __complex__ double d;
int main (void)
{

  d = 0;
  d = d + 5;
}

and it seems to break it into:
d = __complex__ (0.0, 0.0);

and
d.1 = d;
  d.0 = d.1;
  D.1723 = REALPART_EXPR d.0;
  D.1724 = D.1723 + 5.0e+0;
  D.1725 = IMAGPART_EXPR d.0;
  d.2 = COMPLEX_EXPR D.1724, D.1725;
  d = d.2;

so again the loads and stores to (D) appear to be completely wrap the 
entire complex operation, so this should be handle-able the same way...


So you really should be able to key into the atomic load from D followed 
by the store to D and look at whats in between.


I thini is is straightforward in the gimplifier, we ought to have the d 
=d op V expression at some point and be able to detect that d is the 
same and atomic, and check op.   but if it turns out not to be, then I 
could simply turn those atomic loads and stores into atomic loads and 
stores  in the gimplifier and stop there., Then have a very early 
always-run SSA pass pattern match looking for atomic stores fed from 
atomic loads, and examine the operations in between, looking for 
patterns that match  d = d op v, and then turning the loads/store and 
intermediate bits into the specified compare_exchange loops...


I'll get to this shortly.

Andrew


Re: [PATCH] Add atomic type qualifier

2013-07-29 Thread Andrew MacLeod

On 07/29/2013 12:06 PM, Joseph S. Myers wrote:

On Mon, 29 Jul 2013, Andrew MacLeod wrote:


I planned to do the work in gimplification... let the atomic decls through,
and during gimplification, loads or stores of an atomic decl would be
converted to the appropriate load or store builtin, and at the same time
recognize the  'decl = decl op value' expression and replace those as
appropriate with atomic_op_fetch operations.   I had discussed this at some
length with Lawrence crowl and Jeffrey Yasskin some time ago..   At
gimplification time we no longer know whether the original form was
decl op= val  or decl = decl op val;, but the decision was that it is ok to
recognize decl = decl op val and make that atomic.. it would still satisfy the
language requirements..

I think that's probably OK (though, is this a theorem of the formal
modelling work that has been done on the memory model?), but note it's not
just a decl but an arbitrary pointer dereference (the address of the
lvalue is only evaluated once, no matter how many compare-and-exchange
operations are needed), and the operation may end up looking like

*ptr = (convert to type of *ptr) ((promote) *ptr op (promote) val)

rather than a simple decl = decl op val.  Or something more complicated if
the operation involves complex numbers - look at what gets for mixed real
/ complex arithmetic, for example.  Given

_Atomic _Complex float f;
double d;

f += d;

the atomicity is for the whole complex number (and so the
compare-and-exchange needs to work on the whole number) although only the
real part is modified by the addition.



Ive been poking at this today, and Im wondering what you think of the 
idea of adding a flag to MODIFY_EXPR,
#define MODIFY_EXPR_IS_COMPOUND(NODE) 
MODIFY_EXPR_CHECK(NODE)-base.asm_written_flag


and set that in the MODIFY_EXPR node when we create it from the x op= 
y form in the front end.   That flag seems to be free for expressions.


 It will then be trivial to locate these expressions and issue a 
builtin or the wrapper compare_exchange code during gimplification. We 
just check if MODIFY_EXPR_IS_COMPOUND() is true and TYPE_ATOMIC() is set 
on the expression type.   (Ive already confirmed the atomic type is set 
as the attribute ripples up to the MODIFY_EXPR node's type.) then we 
know all the important bits from the MODIFY_EXPR to perform the operation.


Otherwise, it looks like it can get a bit hairy...

What do you think?  As a side effect, we also only get it for the actual 
statements we care about as well.


Andrew





Re: [PATCH] Add atomic type qualifier

2013-07-28 Thread Joseph S. Myers
On Fri, 26 Jul 2013, Andrew MacLeod wrote:

 What it doesn't do:

* It doesn't implement the stdatomic.h header - do you intend that to be 
provided by GCC or glibc?

(Substantive review of the full patch still to come.)

   * It doesn't implement the C11 expression expansion into atomic built-ins.
 ie, you can't write:
 _Atomic int x;
  x = 0;
   and have the result be an atomic operation calling __atomic_store (x,
 0).   That will be in a  follow on patch. So none of the expression expansion
 from C11 is included yet. This just enables that.

The hardest part will probably be compound assignment to an atomic object 
where either operand of the assignment has floating-point type - see C11 
footnote 113, but you can't actually use feholdexcept or feclearexcept or 
feupdateenv here because that would introduce libm dependencies, so back 
ends will need to provide appropriate insn patterns to do those operations 
inline.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH] Add atomic type qualifier

2013-07-26 Thread Andi Kleen
Andrew MacLeod amacl...@redhat.com writes:

 What it doesn't do:
   * It doesn't implement the C11 expression expansion into atomic
 built-ins.  ie, you can't write:
 _Atomic int x;
  x = 0;
   and have the result be an atomic operation calling
 __atomic_store (x, 0).   

How would this work if you want a different memory order?

-Andi

-- 
a...@linux.intel.com -- Speaking for myself only


Re: [PATCH] Add atomic type qualifier

2013-07-26 Thread Andrew MacLeod

On 07/26/2013 03:01 PM, Andi Kleen wrote:

Andrew MacLeod amacl...@redhat.com writes:

What it doesn't do:
   * It doesn't implement the C11 expression expansion into atomic
built-ins.  ie, you can't write:
_Atomic int x;
  x = 0;
   and have the result be an atomic operation calling
__atomic_store (x, 0).

How would this work if you want a different memory order?


The way the standard is defined, any implicit operation like that is 
seq_cst.  If you want something other than seq-cst, you have to 
explicitly call atomic_store (x, 0, model).


C11 also provides all those same atomic routines that c++11 provides for 
this reason.  They just decided to try to implement the c++ atomic 
templates in the language along the way :-P  so it feels very much like 
c++ atomics...


Andrew


Re: [PATCH] Add atomic type qualifier

2013-07-26 Thread Hans-Peter Nilsson
On Fri, 26 Jul 2013, Andrew MacLeod wrote:
 This patch adds an atomic type qualifier to GCC.   It can be accessed via
 __attribute__((atomic)) or in C11 mode via the _Atomic keyword.

 HP, you might want to give this a try and see if you can get the alignment
 correct for the cris port finally :-)

Looks like the means to that end are there now.  Thanks!
Though I won't be able to look into it for a while.
(Looking at two more weeks of vacation and likely a hectic
period after that.)

Note to self (mostly): also implement target-specific warning
when the layout of a composite type including an atomic
(naturally aligned) type would differ from normal (unaligned;
packed) layout.

brgds, H-P


Re: [PATCH] Add atomic type qualifier

2013-07-26 Thread Andi Kleen
Andrew MacLeod amacl...@redhat.com writes:

 The way the standard is defined, any implicit operation like that is
 seq_cst.  If you want something other than seq-cst, you have to
 explicitly call atomic_store (x, 0, model).

Thanks.

This doesn't sound like a good default for x86. seq_cst requires 
somewhat expensive extra barriers that most people most likely don't
need.

-Andi

-- 
a...@linux.intel.com -- Speaking for myself only


Re: [PATCH] Add atomic type qualifier

2013-07-26 Thread Andrew MacLeod

On 07/26/2013 05:13 PM, Andi Kleen wrote:

Andrew MacLeod amacl...@redhat.com writes:

The way the standard is defined, any implicit operation like that is
seq_cst.  If you want something other than seq-cst, you have to
explicitly call atomic_store (x, 0, model).

Thanks.

This doesn't sound like a good default for x86. seq_cst requires
somewhat expensive extra barriers that most people most likely don't
need.


Its the only truly safe default for a multi-threaded environment.

These are the same defaults you get with C++11 as well if you don't 
explicitly use a memory model in your atomic operations:

ie
 __int_type  load(memory_order __m = memory_order_seq_cst) const noexcept

So if you don't want seq-cst, you need to specify exactly what you do want.


Andrew





Re: [PATCH] Add atomic type qualifier

2013-07-26 Thread Joseph S. Myers
On Fri, 26 Jul 2013, Andrew MacLeod wrote:

 This patch adds an atomic type qualifier to GCC.   It can be accessed via
 __attribute__((atomic)) or in C11 mode via the _Atomic keyword.

Why the attribute - why not just the keyword?

I'll review the patch in detail later (which will involve checking each 
reference to atomic or qualified in the language part of C11, checking 
for appropriate implementation and complaining if it appears to be 
missing, and checking for appropriate testcases and complaining if those 
appear to be missing).  But some comments now:

* pedwarns for using a C11 feature in previous standard modes should as 
per usual practice be pedwarns-if-pedantic.

* I don't see anything obvious in the parser changes to implement the 
_Atomic ( type-name ) version of the syntax for atomic types (6.7.2.4).

* When C11 refers to qualified types, by default it does not include 
atomic types (6.2.5#27).  What's your rationale for including atomic in 
TYPE_QUALS rather than making it separate?  With either approach, a review 
of every reference to qualifiers in the front end is needed to determine 
what's correct for atomic; did you find that including atomic in 
qualifiers in the implementation made for fewer changes?

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH] Add atomic type qualifier

2013-07-26 Thread Andrew MacLeod

On 07/26/2013 07:21 PM, Joseph S. Myers wrote:

On Fri, 26 Jul 2013, Andrew MacLeod wrote:


This patch adds an atomic type qualifier to GCC.   It can be accessed via
__attribute__((atomic)) or in C11 mode via the _Atomic keyword.

Why the attribute - why not just the keyword?

2 reasons:
  1 - we currently have at least one target who cannot express their 
alignment requirements for an atomic value (ie, a short with 4 byte 
alignment).  Use of__attribute((atomic)) will allow proper expression 
and usage within the atomic built-ins without using C11.
 2 - compatibility with C11 and C++11.  Ultimately, the atomic object 
can be upsized (ie,a  6 byte object sized up to be 8 bytes).   _Atomic 
would do that for C11, but we cant really use _Atomic within the c++11 
template files, so __attribute__((atomic)) seemed pretty natural.   As 
well, this will allow c++ atomic templates to work on aforementioned 
target(s).





I'll review the patch in detail later (which will involve checking each
reference to atomic or qualified in the language part of C11, checking
for appropriate implementation and complaining if it appears to be
missing, and checking for appropriate testcases and complaining if those
appear to be missing).  But some comments now:

* pedwarns for using a C11 feature in previous standard modes should as
per usual practice be pedwarns-if-pedantic.

* I don't see anything obvious in the parser changes to implement the
_Atomic ( type-name ) version of the syntax for atomic types (6.7.2.4).

* When C11 refers to qualified types, by default it does not include
atomic types (6.2.5#27).  What's your rationale for including atomic in
TYPE_QUALS rather than making it separate?  With either approach, a review
of every reference to qualifiers in the front end is needed to determine
what's correct for atomic; did you find that including atomic in
qualifiers in the implementation made for fewer changes?

I'm not good at front ends... don't really know them at all. Parsing and 
syntax and semantics scare me.   This was my initial attempt to enable 
_Atomic and hoped for help with the rest from those who do :-)  
observation and changes welcome.



Andrew