On Fri, Aug 21, 2015 at 10:35 AM, Michael Zolotukhin via cfe-commits < cfe-commits@lists.llvm.org> wrote:
> Yes, I've considered a builitin as an alternative. In fact, I started with > it as it was easier to implement, but then decided to switch to type > attribute due to the following reasons: > > 1. ARM ACLE 2.0 mentions attribute. Though it's not a final version of the > document, AFAIU, I still preferred to use it as an argument for > type-attribute. > I don't think this argument carries much weight by itself: I would imagine that the reason this was listed as a possible future direction was to solicit feedback from implementers and users; I think it's entirely appropriate for our feedback to be "this is the wrong approach". Another objection I have to the ACLE proposal is that it puts the attribute on a pointer type but applies it to the pointee. This seems to make various reasonable use cases awkward to support. For instance, suppose I want to have a global variable to which I perform nontemporal loads and stores: I would need to take the address of that global, cast it to a nontemporal pointer, and dereference that in order to get a nontemporal operation. It would seem more natural to have the attribute apply to any type, and to apply to loads and stores of that type. So: int __attribute__((nontemporal)) *p; // a pointer to a nontemporal int int * __attribute__((nontemporal)) q; // a pointer (within nontemporal storage) to an int int x = *p; // normal load of p, nontemporal load of *p int y = *q; // nontemporal load of q, normal load of *q 2. Once we introduce a builtin, we'll have to support it forever (otherwise > we could break someone's code). With the attribute the burden is much > smaller, as we can just start ignoring it at any point if we need to - all > the code will remain correct and compilable. > Whatever we do here, we will in practice support it forever. We already have target-specific versions of these nontemporal operations that we intend to support forever. The support cost of the builtins is lower than that of a type attribute. 3. We'll need to have an intrinsic for every type + separate intrinsics for > loads and stores. If we use the type attribute, one fits all. > Builtins can have custom type checking, and if they do they can effectively be overloaded for any type. (See the atomic builtins for an example.) > 4. While it's true, that this is more type of operation, than a type, I > think in real use-cases a user would rarely need to use it on a single > operation. I.e. nontemporal operations are usually used for processing bulk > volumes of data, and probably this data is almost always is processed as a > whole. That's why I think it's fine to mark the entire 'data' as > nontemporal. And, if a user then wants to work with a small subset of it, > she can use a usual (not nontemporal) pointer to it. > OK, so you'd require a cast to/from a nontemporal type at the entry/exit of such code? That's probably reasonable, but like Aaron, I'm not really sure what usage patterns will appear in the wild here. 5. Personally, I find the code using attributes more elegant than using > builtins. Compare: > > void foo(float *__attribute__((nontemporal)) dst, > float *__attribute__((nontemporal)) src1, > float *__attribute__((nontemporal)) src2) { > *dst = *src1 + *src2; > } > > and > > void foo(float *dst, float *src1, float *src2) { > float s1 = __builtin_nontemporal_load(src1); > float s2 = __builtin_nontemporal_load(src2); > __builtin_nontemporal_store(s1 + s2, dst); > } > > But that said, in the end I'm open to other alternatives (including > builtins), and this thread is just an attempt to find the best option. I think my personal preference here would depend on how important it is that these operations are nontemporal -- the latter formulation makes this a lot more obvious (the reader really can't miss that fact).
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits