[PATCH] D79121: Add nomerge function attribute to clang
Reid Kleckner via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon May 4 14:32:49 PDT 2020
rnk added inline comments.
================
Comment at: clang/lib/CodeGen/CGStmt.cpp:611
void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) {
+ for (const auto *A: S.getAttrs())
+ if (A->getKind() == attr::NoMerge) {
----------------
Can we use S.hasAttr, or does that not exist for statements?
================
Comment at: clang/lib/CodeGen/CGStmt.cpp:615
+ break;
+ }
EmitStmt(S.getSubStmt(), S.getAttrs());
----------------
Please use SaveAndRestore, since this could be re-entrant. Consider cases like:
[[clang::nomerge]] foo(1, ({bar(); [[clang::nomerge]] baz(); 2}), qux());
The inner nomerge will "unset" the outer one too early.
This is similar to what will happen if we allow nomerge on compound statements as in:
[[clang::nomerge]] if (cond) {
foo();
[[clang::nomerge}] foo();
foo(); // will not carry nomerge unless we restore to old value
}
================
Comment at: clang/lib/CodeGen/CodeGenFunction.h:599
/// region.
bool IsInPreservedAIRegion = false;
----------------
I would put your field after this one, and name it more specific, something like `InNoMergeAttributedStmt`. This field tracks a similar concept of being within a region
================
Comment at: clang/test/CodeGen/attr-nomerge.cpp:6
+
+void foo(int i) {
+ [[clang::nomerge]] bar();
----------------
aaron.ballman wrote:
> I'd appreciate seeing some more complex tests showing the behavior of the attribute. As some examples:
> ```
> // Does this work on dynamically initialized global statics?
> [[clang::nomerge]] static int i = foo() + bar();
>
> void func() {
> // Is the lambda function call operator nomerge, the contained calls within the lambda, or none of the above?
> [[clang::nomerge]] [] { foo(); bar(); }();
>
> // Do we mark the implicit function calls to begin()/end() as nomerge?
> [[clang::nomerge]] for (auto foo : some_container) {}
>
> // Does it apply to builtins as well?
> [[clang::nomerge]] foo(__builtin_strlen("bar"), __builtin_strlen("bar"));
>
> // Does it apply to the substatement of a label?
> [[clang::nomerge]] how_about_this: f(bar(), bar());
>
> // Does it apply across the components of a for statement?
> for (foo(); bar(); baz()) {}
> }
> ```
I think the emergent behavior from the current implementation is reasonable. For lambdas, it applies to the outer call, not the inner lambda body.
I don't see any reason to make this work for global variables currently.
We could try to ban the application of this attribute to compound statements and statments containing them (`{}`, `if`, `for`), but that's a lot of effort. I could go either way.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D79121/new/
https://reviews.llvm.org/D79121
More information about the cfe-commits
mailing list