On 04/27/2012 04:37 AM, Richard Guenther wrote:
Since integral atomics are always of an unsigned type ,  I could switch over
and use 'unsigned size' instead of 'tree fntype' for them (I will rename
it), but then things may  be more complicated when dealing with generic
atomics...  those can be structure or array types and I was planning to
allow leaving the type in case I discover something useful I can do with it.
  It may ultimately turn out that the real type isn't going to matter, in
which case I will remove it and replace it with an unsigned int for size.
So it eventually will support variable-size types?
we support arbitrary sized objects now for exchange, compare_exchange, load, and store. I just havent added the support to gimple_atomic yet. Thats next on my list.
And the reason memmodel is a tree is because, as ridiculous as it seems, it
can ultimately be a runtime value.    Even barring that, it shows up as a
variable after inlining before various propagation engines run, especially
in the  C++ templates.  So it must be a tree.
Ick.  That sounds gross.  So, if it ends up a variable at the time we generate
assembly we use a "conservative" constant value for it?
Indeed, ICK, and yes, I make it SEQ_CST at compile time if a variable value gets all the way through to codegen.
Hmm, ok. So you are changing GENERIC in fact. I suppose _Atomic is restricted to global variables. Can I attach _Atomic to allocated storage via pointer casts? Consider writing up semantics of _Atomic into generic.texi please.

Yes, I have a start on implementing _Atomic which adds the bit to the type. And no, it isn't restricted to globals... it just indicates said hunk of memory must be accessed in an atomic manner. You can use it on automatics if you want...

I believe _Atomic can also be used in casts as well. so an atomic call may have to be injected into a dereference expression as well to load or update memory.

I'll update .texi along with the patch when I get to it.



Well, they are calls with a very well-defined set of side-effects. Otherwise not representing them as calls would be a waste of time. Thus, no - they do not need to be considered "calls" everywhere (well, treating them the same as calls should be conservative) but treating them as "atomics" even if they were expanded as calls needs to be correct.

Yeah, I was starting with them as calls just to be conservative and get the same behaviour, then refine them by examining each GIMPLE_ATOMIC use in detail.
Looks like a hieararchy "no target or anything else" ->  "target" ->
"expr" ->  "memorder" would work, with only "lhs" being optional and
present everywhere.
Of course the hierarchy only makes sense for things that are not trees
(I was thinking of memorder originally - but that thought fell apart).
  So in the
end apart from abstracting a base for FENCE the flat hieararchy makes sense
(all but FENCE have a type / size).
Is it really worth it to have 2 different types of gimple_atomic nodes in order to avoid having an unused type field in atomic_fence? Atomic_fence has an order field, so it requires the use of op[0] in order for gimple_atomic_order() to work properly, we can't have all the other gimple nodes inherit from that, so we'd need a base which basically has just the KIND in it, and target/no-target nodes inherit from that. So we'd have:

                    /    gimple_atomic_fence
atomic_base
                    \   gimple_atomic_all_others

then all the checks for is_gimple_atomic() have to look for both gimple_atomic_all_others and gimple_atomic_fence.


Perhaps a better option is to shift all the operands by one since the type is a tree... ie, if there is a a target, there is also a type entry, so
op[0] remains ORDER,
op[1] is the newly inserted TYPE
op[2] then becomes the TARGET,
op[3...] ,when present, are all shifted over by one.

the type can be removed from the structure and now there would be no wastage. Is that reasonable?

Andrew

Reply via email to