eddyz87 added a comment.

In D152986#4425736 <https://reviews.llvm.org/D152986#4425736>, @rnk wrote:

> 

Thank you for the review!

> The purpose of the attribute is really limited to preserving source location 
> information on instructions, and this isn't really a supported usage.

But it would prevent merging, right? I understand that using this attribute 
might block some legitimate optimizations.
Or do you mean that it is a "best effort" thing and not all transformations 
might honor it?

> The BPF backend and verifier needs to learn to tolerate valid LLVM transforms 
> if it wants to be a real LLVM backend. Of course, you can do what you like.

Well, I agree with that. The issue here is with the map API design: it is 
polymorphic, but it is expected that at load time verifier can replace all 
polymorphic calls with static calls.
People know it and write code in a way that allows verifier to infer which 
static functions to call. So I have limited options here:

- either adjust IR at early stages of pipeline so that specific calls are not 
altered;
- or do nothing and recommend users to use `[[clang::nomerge]]` on statement 
level or insert something like `asm volatile ("" :::"memory")` here and there.

But, yeah, I understand that is is not a C language semantics and headache is 
mine.

> Considered in the context of the original use case, I think it's reasonable 
> to allow the attribute on function pointers for the same reasons we allow it 
> on function declarations. It makes it easy to work the attribute onto the 
> direct call sites of the function without modifying tons of source code. 
> However, I'd like to see clearer documentation on the limitations.

Please see my "inline" response.



================
Comment at: clang/include/clang/Basic/AttrDocs.td:551-555
 calls to the specified function from merging. It has no effect on indirect 
 calls.
+
+``nomerge`` attribute can be specified for pointers to functions, all
+calls done through such pointer would be protected from merging.
----------------
rnk wrote:
> This statement of the attribute having "no effect on indirect calls" is 
> slightly confusing now that we talk about function pointers immediately 
> afterward. Can you please rework this a bit, and clarify that when applied to 
> function pointers, the attribute only takes effect when the call target is 
> directly the variable which carries the attribute? For example, this has no 
> effect:
> ```
> void (*fp)() __attribute__((nomerge));
> void callit() {
>   auto tmp = fp;
>   tmp();
>   (*fp)(); // I think TargetDecl will be null in the code, tell me if I'm 
> wrong
> }
> ```
I can make it more elaborate, would the text as below be fine?
Regarding TargetDecl value it is not null both times:
- `(VarDecl 'tmp' (ImplicitCastExpr (DeclRefExpr (Var fp))))`
- `(VarDecl 'fp')`

---

``nomerge`` attribute can also be used as function attribute to prevent all 
calls to the specified function from merging. It has no effect on indirect 
calls to such functions. For example:

.. code-block:: c++

  [[clang::nomerge]] void foo(int) {}
  
  void bar(int x) {
    auto *ptr = foo;
    if (x) foo(1); else foo(2); // will not be merged
    if (x) ptr(1); else ptr(2); // indirect call, can be merged
  }

``nomerge`` attribute can also be used for pointers to functions to
prevent calls through such pointer from merging. In such case the
effect applies only to a specific function pointer. For example:

.. code-block:: c++

  [[clang::nomerge]] void (*foo)(int);
  
  void bar(int x) {
    auto *ptr = foo;
    if (x) foo(1); else foo(2); // will not be merged
    if (x) ptr(1); else ptr(2); // 'ptr' has no 'nomerge' attribute,
                                // can be merged
  }



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152986/new/

https://reviews.llvm.org/D152986

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to