mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-19 21:10:30 +00:00
Add intrinsics.likely and intrinsics.unlikely
This commit is contained in:
@@ -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 ---
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user