Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Unsafe.Unlikely (Assume) draft implementation
Just a quick draft for dotnet/runtime#4966 for both RyuJIT CoreCLR and Mono-LLVM (maybe it will help to push it forward since it's 4 years old). It allows programmers to give hints to JIT about branches' probabilities, e.g. to avoid goto hacks [like this](https://github.com/dotnet/runtime/blob/469ece74b6e5b7e94991dde21b3c2409194ceab9/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs#L523) in perf critical code. #### Sample: ```csharp static int Foo(int a) { if (Unsafe.Unlikely(a <= 0)) // hint: `a` is unlikely to be <= 0 return a * a; return 0; } ``` #### Codegen without `Unlikely`: ```asm 85D2 test edx, edx 7F06 jg SHORT G_M36845_IG05 8BC2 mov eax, edx 0FAFC2 imul eax, edx C3 ret ;; return a * a G_M36845_IG05: 8BC2 mov eax, edx C3 ret ;; return 0 ``` #### Codgen with `Unlikely` (this is what this PR emits) ```asm 85D2 test edx, edx 7E03 jle SHORT G_M4270_IG05 8BC2 mov eax, edx C3 ret ;; return 0 G_M4270_IG05: 8BC2 mov eax, edx 0FAFC2 imul eax, edx C3 ret ;; return a * a ``` Also, I implemented it for Mono-LLVM (I use `@llvm.expect.i32` intrinsic, which is emitted when you use `__builtin_expect` in C/C++) #### Mono-LLVM without `Unlikely` ```asm mov ecx, edi imul ecx, ecx ;; Mono-LLVM emits branchless code for our sample xor eax, eax test edi, edi cmovle eax, ecx ret ``` #### Mono-LLVM with `Unlikely` ```asm xor eax, eax test edi, edi jle 1 <gram_Foo1__int_+0x7> ;; branch is better than cmove in this case ret ;; return 0 imul edi, edi mov eax, edi ret ;; return a * a ``` cc @jkotas
- Loading branch information