aaron.ballman added a comment. In D91979#2444327 <https://reviews.llvm.org/D91979#2444327>, @jdoerfert wrote:
> In D91979#2440554 <https://reviews.llvm.org/D91979#2440554>, @aaron.ballman > wrote: > >> Thank you for your patience with the delays getting to your review! Along >> with the documentation question, one line of thinking I'm also not clear on >> is whether this should be a type-based attribute rather than a >> declaration-based attribute. For instance, if you want to write an >> assumption about the parameters to a function, those are not in scope for a >> declaration attribute but are for a type attribute. > > I would like to see that, in our last proposal of something similar we > suggested to add something like `__attribute__((arg_attr(3, "nofree")))` > which would translate to the `nofree` IR attribute for argument 3. I can also > envision a type based assumption attribute but I feel a declaration one will > be needed nevertheless. We'll also add expression assumptions as they are > required by OpenMP and generally useful. The "payload" of the assume > attribute will then be a union, similar to the `AlignedAttribute`. I want to make sure we're on the same page with this. If the assumption is a unit of information that applies to a single parameter, then the attribute should be written on the parameter itself rather than using positional information. e.g., `void func(int i [[clang::whatever]]);` is preferable to `void func(int i) [[clang::whatever(1)]];` By writing the attribute directly on the parameter, we remove confusion over things like "are parameter indexes one-based or zero-based?" and "does the implicit 'this' parameter count?". If the assumption is unit of information that applies to the function but involves one or more parameters, then writing the attribute *might* makes sense as a type attribute. e.g., `void func(int i, int j) [[clang::whatever(i < j)]];` It sounds to me like we may wind up with both kinds of situations, which is fine. >> But also, it seems like this assumption information is something that would >> be useful to carry around as part of the function's identity. For instance, >> would users want to be able to make a call through a function pointer and >> have the same set of assumptions conveyed to the backend? > > Like other IR attributes, if you can go from the function pointer to a (set > of) declaration(s) you can use the attributes from that declaration. I don't > think this is any different than other function attributes, e.g., `readnone` > in this aspect. But what about the behavior the user sees? e.g., should the user be alerted to this being a potentially bad thing? void func(int *ip) [[clang::assume(ip != 0)]]; void other_func(int *ip); // No assumptions about ip int *get_ip(); // May return null ... void (*fp)(int *); if (rand() % 10 == 0) fp = other_func; else fp = func; // Should we warn about this? fp(get_ip()); // This could do bad things if fp == func because get_ip() may return null ================ Comment at: clang/include/clang/Basic/Attr.td:3482 + let Spellings = [Clang<"assume">]; + let Subjects = SubjectList<[Function]>; + let InheritEvenIfAlreadyPresent = 1; ---------------- Should this be supported on ObjCMethod declarations as well? ================ Comment at: clang/include/clang/Basic/AttrDocs.td:3930 +analysis and optimization passes can assume the "assumption" to hold. +This is similar to :ref:`__builtin_assume <langext-__builtin_assume>` but instead of an +expression that can be assumed to be non-zero, the assumption is expressed as ---------------- wrap to 80-col ================ Comment at: clang/include/clang/Basic/AttrDocs.td:3940 + +While LLVM plugins might utilize more assumption strings, the default LLVM +optimization passes are aware of the following assumptions: ---------------- ================ Comment at: clang/include/clang/Basic/AttrDocs.td:3950 +The OpenMP standard defines the meaning of OpenMP assumptions ("omp_XYZ" is +spelled "XYZ" in the OpenMP standard). + ---------------- Can you link to that standard here so users don't have to hunt for it? ================ Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:742 "the argument to %0 has side effects that will be discarded">, - InGroup<DiagGroup<"assume">>; + InGroup<Assumption>; +def warn_assume_attribute_string_unknown : Warning< ---------------- This changes behavior for users because `-Wno-assume` now needs to be spelled `-Wno-assumption` -- I think we may want to keep the diagnostics for the assumption attribute separate from the diagnostics for builtin assume. For instance, I think the assumption attribute warnings will all wind up leading to an ignored attribute, so perhaps the new grouping should be under the existing ignored attributes group. ================ Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:744 +def warn_assume_attribute_string_unknown : Warning< + "the assumption string '%0' is not known and might be misspelled">, + InGroup<Assumption>; ---------------- I'd say that this case should probably be worded `unknown assumption string '%0'; attribute ignored` ================ Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:747 +def warn_assume_attribute_string_unknown_suggested : Warning< + "the assumption string '%0' is not known and might be misspelled; " + "did you mean '%1'?">, ---------------- Similarly: `unknown assumption string '%0' may be misspelled; attribute ignored, did you mean '%1'?` ================ Comment at: clang/include/clang/Sema/Sema.h:10007 + /// Check if \p AssumptionStr is a known assumption and warn if not. + void CheckAssumptionAttr(SourceLocation Loc, StringRef AssumptionStr); + ---------------- I think this should probably return something so that the caller knows whether to drop the attribute or not? ================ Comment at: clang/lib/Sema/SemaDeclAttr.cpp:1681 + StringRef Str; + if (AL.getNumArgs() == 1 && !S.checkStringLiteralArgumentAttr(AL, 0, Str)) + return; ---------------- No need to check the count manually, the common attribute handler should do that for you already. ================ Comment at: clang/lib/Sema/SemaDeclAttr.cpp:1684 + + S.CheckAssumptionAttr(AL.getLoc(), Str); + ---------------- Does it make sense to warn about an unknown assumption string but then keep the attribute anyway? This seems like a situation where I'd expect the attribute to be dropped as it appears to be meaningless. Also, I think this should pass in the source location to the argument, not the attribute itself. You can get this information out of the call to `checkStringLiteralArgumentAttr()` (it's an optional parameter). ================ Comment at: clang/lib/Sema/SemaDeclAttr.cpp:1689 + +llvm::StringSet<> Sema::KnownAssumptionStrings({ + "omp_no_openmp", // OpenMP 5.1 ---------------- The current approach is reasonable, but I wonder if there's a way we can force this list to be filled out by the backend pass authors such that the frontend can query the backend for the supported list? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D91979/new/ https://reviews.llvm.org/D91979 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits