Add intrinsics.likely and intrinsics.unlikely

This commit is contained in:
gingerBill
2026-03-15 15:39:52 +00:00
parent 7207b545e6
commit a0685f0511
4 changed files with 53 additions and 2 deletions

View File

@@ -77,7 +77,9 @@ prefetch_write_instruction :: proc(address: rawptr, #const locality: i32 /* 0..=
prefetch_write_data :: proc(address: rawptr, #const locality: i32 /* 0..=3 */) ---
// Compiler Hints
expect :: proc(val, expected_val: $T) -> T ---
expect :: proc(val, expected_val: $T) -> T ---
likely :: proc(val: $T) -> T where type_is_boolean(T) ---
unlikely :: proc(val: $T) -> T where type_is_boolean(T) ---
// Linux and Darwin Only
syscall :: proc(id: uintptr, args: ..uintptr) -> uintptr ---

View File

@@ -6257,6 +6257,33 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
operand->type = x.type;
}
break;
case BuiltinProc_likely:
case BuiltinProc_unlikely:
{
Operand x = {};
check_expr(c, &x, ce->args[0]);
if (x.mode == Addressing_Invalid) {
return false;
}
if (!is_type_boolean(x.type)) {
gbString xt = type_to_string(x.type);
error(x.expr, "Expected a boolean expression to '%.*s', got %s", LIT(builtin_name), xt);
gb_string_free(xt);
*operand = x; // minimize error propagation
return true;
}
if (x.mode == Addressing_Constant) {
// NOTE(bill): just completely ignore this intrinsic entirely
*operand = x;
return true;
}
operand->mode = Addressing_Value;
operand->type = x.type;
}
break;
case BuiltinProc_prefetch_read_instruction:
case BuiltinProc_prefetch_read_data:

View File

@@ -144,6 +144,8 @@ BuiltinProc__atomic_end,
BuiltinProc_fixed_point_div_sat,
BuiltinProc_expect,
BuiltinProc_likely,
BuiltinProc_unlikely,
BuiltinProc__simd_begin,
BuiltinProc_simd_add,
@@ -527,7 +529,9 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
{STR_LIT("fixed_point_mul_sat"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("fixed_point_div_sat"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("expect"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("expect"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("likely"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("unlikely"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("simd_add"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},

View File

@@ -3369,6 +3369,24 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
return lb_emit_conv(p, res, t);
}
case BuiltinProc_likely:
case BuiltinProc_unlikely:
{
Type *t = default_type(tv.type);
lbValue x = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t);
lbValue y = lb_const_bool(p->module, t, id == BuiltinProc_likely);
char const *name = "llvm.expect";
LLVMTypeRef types[1] = {lb_type(p->module, t)};
lbValue res = {};
LLVMValueRef args[2] = { x.value, y.value };
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
res.type = t;
return lb_emit_conv(p, res, t);
}
case BuiltinProc_prefetch_read_instruction:
case BuiltinProc_prefetch_read_data:
case BuiltinProc_prefetch_write_instruction: