On Fri, Aug 22, 2014 at 1:47 AM, Mike Stump <mikest...@comcast.net> wrote: > On Aug 21, 2014, at 4:22 AM, Richard Biener <richard.guent...@gmail.com> > wrote: >> I still say we need to solve the issue at language level - that is, >> try to figure out what the language standard says about >> >> volatile struct X x, y; > >> x = y; > > The definition of x = y doesn’t change wrt volatile above. See below for the > semantic of x = y; What this does is it makes the members of x and y > volatile: > > [#7] EXAMPLE 2 In: | > > struct s { int i; const int ci; }; > struct s s; > const struct s cs; > volatile struct s vs; > > the various members have the types: | > > s.i int > s.ci const int > cs.i const int > cs.ci const int > vs.i volatile int > vs.ci volatile const int > >> or about >> >> struct X { volatile int x; } x, y; >> >> x = y; > > So, what the C99 standard[1] says is that memcpy copies n characters from one > to the other, leaving unspecified the order of the copy. C++98 reuses by > reference those semantics. Of course, there are quite a few memcpy > implementations that don’t do that. > > For x = y, in C++98, it is defined like so: > > 8 The implicitly-defined copy constructor for class X performs a member- > wise copy of its subobjects. The order of copying is the same as the > order of initialization of bases and members in a user-defined con- > structor (see _class.base.init_). Each subobject is copied in the > manner appropriate to its type
Thats quite specific ;) > which means a volatile int member translates to volatile SI read/write as > appropriate, or put another way, one can’t use memcpy for it. Now, that > isn’t to say that we can’t change the language standard or improve it with > different semantics. > > For C99: > > [#2] In simple assignment (=), the value of the right > operand is converted to the type of the assignment > expression and replaces the value stored in the object > designated by the left operand. > > which I’d claim isn’t exactly clear and precise. Clearly what they were > thinking was: Indeed. > 36)Thus, for example, structure assignment may be > implemented element-at-a-time or via memcpy. > > left not exactly well defined is the case of volatile. Reasonable people > would say that volatile semantics are likely the same as C++98 (also, C++ was > mostly just noting what we thought the C standard said in the first place). > > I don’t keep up on DRs that might explicitly cover details, so I’d defer > those those if any. > >> I expect that most structs have volatile for a bogus reason >> anyway and we slow down and enlarge code for no good reason. > > Yes, I suspect if we put in code to handle volatile members better, that no > code will care. Why, cause no one has asked for those semantics, no code > depends upon those semantics. Though, in time, some code might care. > >> So - why bother fixing this? ISTR reading in the C standard >> that structure assignments are expected to compile to memcpy. > > Your ISTR is quoted for you above. That wording isn’t a prescription of > semantics. It is an observation that there are some situations where the > implementation may use memcpy. > > In C99, sig_atomic_t defines when something is lock free, leaving unspecific > what else may be. In later C++ standards (for example C++14), > [atomics.lockfree] defines additional types that are atomic. > > > 1 - I use n843 for C99, which is slightly different from the standard, but in > this case I suspect it is the same. So after reading the std quotations I still think that if we want to fix anything here then we want to fix it in the frontends (only the C++ FE knows init order in the details required - though I suppose the description was for non-POD types where the FE may already do this). _If_ we want to do this in the middle-end then I suggest to do the decomposition during gimplification as the rest of the middle-end doesn't treat the second example as a volatile aggregate copy at all. Fixing this with the proposed patch doesn't really fix it and it will perform the worst of all implementations (a byte-by-byte copy certainly will break that hardware access the patch was meant to fix, also thinking of a struct with volatile bitfields and -fstrict-volatile-bitfields). I'd still lean towards doing this in frontends (or c-family/ code). Richard.