On Mon, Feb 29, 2016 at 07:17:55PM +0100, Michael Matz wrote: > Hi, > > On Sat, 27 Feb 2016, Paul E. McKenney wrote: > > > But we do already have something very similar with signed integer > > overflow. If the compiler can see a way to generate faster code that > > does not handle the overflow case, then the semantics suddenly change > > from twos-complement arithmetic to something very strange. The standard > > does not specify all the ways that the implementation might deduce that > > faster code can be generated by ignoring the overflow case, it instead > > simply says that signed integer overflow invoked undefined behavior. > > > > And if that is a problem, you use unsigned integers instead of signed > > integers. > > > > So it seems that we should be able to do something very similar here. > > For this case the important pice of information to convey one or the other > meaning in source code is the _type_ of involved entities, not annotations > on the operations. signed type -> undefined overflow, unsigned type -> > modulo arithmetic; easy, and it nicely carries automatically through > operation chains (and pointers) without any annotations. > > I feel much of the complexity in the memory order specifications, also > with your recent (much better) wording to explain dependency chains, would > be much easier if the 'carries-dependency' would be encoded into the types > of operands. For purpose of example, let's call the marker "blaeh" (not > atomic to not confuse with existing use :) ): > > int foo; > blaeh int global; > int *somep; > blae int *blaehp; > f () { > blaehp = &foo; // might be okay, adds restrictions on accesses through > // blaehp, but not through 'foo' directly > blaehp = &global; > if (somep == blaehp) > { > /* Even though the value is equal ... */ > ... *blaehp ... /* ... a compiler can't rewrite this into *somep */ > } > } > > A "carries-dependency" on some operation (e.g. a call) would be added by > using a properly typed pointer at those arguments (or return type) where > it matters. You can't give a blaeh pointer to something only accepting > non-blaeh pointers (without cast). > > Pointer addition and similar transformations involving a blaeh pointer and > some integer would still give a blaeh pointer, and hence by default also > solve the problem of cancellations. > > Such marking via types would not solve all problems in an optimal way if > you had two overlapping but independend dependency chains (all of them > would collapse to one chain and hence made dependend, which still is > conservatively correct). > > OTOH introducing new type qualifiers is a much larger undertaking, so I > can understand one wants to avoid this. I think it'd ultimately be > clearer, though. As has been stated in this thread, we do need the unmarked variant. For the marked variant, there are quite a few possible solutions with varying advantages and disadvantages: o Attribute already exists, but is not carried by the type system. Could be enforced by external tools. o Storage class could be added with fewer effects on the type system, but the reaction to this suggestion in October was not all that positive. o Non-type keywords for objects has been suggested, might be worth revisiting. o Adding to the type system allows type enforcement on the one hand, but makes it harder to write code that can be used for both RCU-protected and not-RCU-protected data structures. (This sort of thing is not uncommon in the Linux kernel.) There are probably others, but those are the ones I recall at the moment. Thanx, Paul -- To unsubscribe from this list: send the line "unsubscribe linux-arch" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html