Add expect and trap to core.builtins

This exists mostly as a way to harmonise between the different spellings of the same concepts in LDC and GDC, rather than to provide a useful implementation from DMD.
This commit is contained in:
Nicholas Wilson 2024-08-24 08:08:01 +08:00 committed by Nicholas Wilson
parent eeeb43a60f
commit 3bcdd191d2
2 changed files with 50 additions and 0 deletions

View file

@ -0,0 +1,7 @@
Adds `expect`, `[un]likely`, `trap` to `core.builtins`
Adds the functions `expect` and `likely`/unlikely` for branch and value hints for the LDC/GDC compilers.
DMD ignores these hints.
Adds `trap` to lowered to the target dependent trap instruction.
If the target does not have a trap instruction, this intrinsic will be lowered to the call of the abort() function.

View file

@ -51,3 +51,46 @@ version (LDC)
/// Writes `s` to `stderr` during CTFE (does nothing at runtime).
void __ctfeWrite(scope const(char)[] s) @nogc @safe pure nothrow {}
version (GNU)
{
/// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fexpect
alias expect = __builtin_expect;
/// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005ftrap
alias trap = __builtin_trap;
}
else version (LDC)
{
/// https://llvm.org/docs/LangRef.html#llvm-expect-intrinsic
alias expect = llvm_expect;
debug
/// https://llvm.org/docs/LangRef.html#llvm-debugtrap-intrinsic
alias trap = llvm_debugtrap;
else
/// https://llvm.org/docs/LangRef.html#llvm-trap-intrinsic
alias trap = llvm_trap;
}
else version (DigitalMars)
{
pragma(inline, true)
T expect(T)(T val, T expected) if (__traits(isIntegral, T))
{
return val;
}
pragma(inline, true)
void trap()
{
debug
{
version(D_InlineAsm_X86)
asm nothrow @nogc pure @trusted { int 3; }
}
assert(0);
}
}
/// Provide static branch hints
pragma(inline, true) bool likely(bool b) { return expect(b, true); }
///
pragma(inline, true) bool unlikely(bool b) { return expect(b, false); }