[llvm-branch-commits] [llvm] [IR] Introduce `llvm.experimental.hot()` (PR #84850)

Vitaly Buka via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Mar 12 13:31:19 PDT 2024


================
@@ -1722,6 +1722,11 @@ def int_debugtrap : Intrinsic<[]>,
 def int_ubsantrap : Intrinsic<[], [llvm_i8_ty],
                               [IntrNoReturn, IntrCold, ImmArg<ArgIndex<0>>]>;
 
+// Return true if profile counter for containing block is hot.
+def int_experimental_hot : Intrinsic<[llvm_i1_ty], [],
+                                      [IntrInaccessibleMemOnly, IntrWriteMem,
----------------
vitalybuka wrote:

No, we have no more precise attribute. E.g. int_sideeffect is declared this way as well.
There are a few comments for similar cases around, I'll add one here to.
We need to lock intrinsic in place, without it, it will be moved to the entry block and value shared between users. So it will work as function level, vs block level.

With ThinLTO it should not be a problem, in postlink we rerun simplification and optimization with intrinsic lowered to  true or false. I tried to remove this attribute and make it function level, but can't measure perf difference.

Alternative is to have intrinsic without sideeffects but with dependency like this:
```
%condition = call i1 @llvm.experimenta.hot(i1 %ubsan_condition)
```
This way we can lock it in place. But this will not help us with assert() with sideeffects as we discussed before.

So I tried both with UBSAN, ThinLTO and plain, and 

```
call i1 @llvm.experimenta.hot()
```

is consistently, but close to noise, faster then:

```
call i1 @llvm.experimenta.hot(i1 %ubsan_condition)
```

I believe because  `or i1 %ubsan, @llvm.experimenta.hot()`  is more predictable for early transformation passes than `@llvm.experimenta.hot(i1 %ubsan_condition)`.

Both intrinsic approaches faster then removing traps.

https://github.com/llvm/llvm-project/pull/84850


More information about the llvm-branch-commits mailing list