intrinsics.atomic_type_is_lock_free

This commit is contained in:
gingerBill
2022-04-02 14:38:42 +01:00
parent c3a292a8c7
commit a232c0888c
7 changed files with 50 additions and 5 deletions

View File

@@ -70,7 +70,7 @@ atomic_signal_fence :: #force_inline proc(order: memory_order) {
// 7.17.5 Lock-free property
atomic_is_lock_free :: #force_inline proc(obj: ^$T) -> bool {
return size_of(T) <= 8 && (intrinsics.type_is_integer(T) || intrinsics.type_is_pointer(T))
return intrinsics.atomic_type_is_lock_free(T)
}
// 7.17.6 Atomic integer types

View File

@@ -71,6 +71,8 @@ Atomic_Memory_Order :: enum {
Seq_Cst = 5,
}
atomic_type_is_lock_free :: proc($T: typeid) -> bool ---
atomic_thread_fence :: proc(order: Atomic_Memory_Order) ---
atomic_signal_fence :: proc(order: Atomic_Memory_Order) ---

View File

@@ -449,6 +449,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
case BuiltinProc_objc_find_class:
case BuiltinProc_objc_register_selector:
case BuiltinProc_objc_register_class:
case BuiltinProc_atomic_type_is_lock_free:
// NOTE(bill): The first arg may be a Type, this will be checked case by case
break;
@@ -3232,6 +3233,35 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
break;
case BuiltinProc_atomic_type_is_lock_free:
{
Ast *expr = ce->args[0];
Operand o = {};
check_expr_or_type(c, &o, expr);
if (o.mode == Addressing_Invalid || o.mode == Addressing_Builtin) {
return false;
}
if (o.type == nullptr || o.type == t_invalid || is_type_asm_proc(o.type)) {
error(o.expr, "Invalid argument to '%.*s'", LIT(builtin_name));
return false;
}
if (is_type_polymorphic(o.type)) {
error(o.expr, "'%.*s' of polymorphic type cannot be determined", LIT(builtin_name));
return false;
}
if (is_type_untyped(o.type)) {
error(o.expr, "'%.*s' of untyped type is not allowed", LIT(builtin_name));
return false;
}
Type *t = o.type;
bool is_lock_free = is_type_lock_free(t);
operand->mode = Addressing_Constant;
operand->type = t_untyped_bool;
operand->value = exact_value_bool(is_lock_free);
break;
}
case BuiltinProc_atomic_thread_fence:
case BuiltinProc_atomic_signal_fence:

View File

@@ -86,6 +86,7 @@ enum BuiltinProcId {
BuiltinProc_prefetch_write_instruction,
BuiltinProc_prefetch_write_data,
BuiltinProc_atomic_type_is_lock_free,
BuiltinProc_atomic_thread_fence,
BuiltinProc_atomic_signal_fence,
BuiltinProc_atomic_store,
@@ -305,6 +306,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
{STR_LIT("prefetch_write_instruction"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("prefetch_write_data"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_type_is_lock_free"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_thread_fence"), 1, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_signal_fence"), 1, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("atomic_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},

View File

@@ -45,9 +45,9 @@ enum EntityFlag : u64 {
EntityFlag_NoAlias = 1ull<<9,
EntityFlag_TypeField = 1ull<<10,
EntityFlag_Value = 1ull<<11,
EntityFlag_Sret = 1ull<<12,
EntityFlag_ByVal = 1ull<<13,
EntityFlag_BitFieldValue = 1ull<<14,
EntityFlag_PolyConst = 1ull<<15,
EntityFlag_NotExported = 1ull<<16,
EntityFlag_ConstInput = 1ull<<17,

View File

@@ -447,7 +447,7 @@ void lb_begin_procedure_body(lbProcedure *p) {
Type *ptr_type = alloc_type_pointer(reduce_tuple_to_single_type(p->type->Proc.results));
Entity *e = alloc_entity_param(nullptr, make_token_ident(name), ptr_type, false, false);
e->flags |= EntityFlag_Sret | EntityFlag_NoAlias;
e->flags |= EntityFlag_NoAlias;
return_ptr_value.value = LLVMGetParam(p->value, 0);
LLVMSetValueName2(return_ptr_value.value, cast(char const *)name.text, name.len);

View File

@@ -2218,6 +2218,17 @@ bool elem_type_can_be_constant(Type *t) {
return true;
}
bool is_type_lock_free(Type *t) {
t = core_type(t);
if (t == t_invalid) {
return false;
}
i64 sz = type_size_of(t);
// TODO(bill): Figure this out correctly
return sz <= build_context.max_align;
}
bool is_type_comparable(Type *t) {
t = base_type(t);