aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-04-02 14:38:42 +0100
committergingerBill <bill@gingerbill.org>2022-04-02 14:38:42 +0100
commita232c0888c4b711ceb94563defdeef514eafb28a (patch)
treefab13fa9ecf83f5744c0bc6d71dd53f65782758f /src
parentc3a292a8c7baeef53436ce5cd15c2e18e6c52943 (diff)
`intrinsics.atomic_type_is_lock_free`
Diffstat (limited to 'src')
-rw-r--r--src/check_builtin.cpp30
-rw-r--r--src/checker_builtin_procs.hpp2
-rw-r--r--src/entity.cpp6
-rw-r--r--src/llvm_backend_proc.cpp2
-rw-r--r--src/types.cpp11
5 files changed, 47 insertions, 4 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp
index 8b8814176..abe58855b 100644
--- a/src/check_builtin.cpp
+++ b/src/check_builtin.cpp
@@ -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:
diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp
index c6b0afee0..fe14ae372 100644
--- a/src/checker_builtin_procs.hpp
+++ b/src/checker_builtin_procs.hpp
@@ -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},
diff --git a/src/entity.cpp b/src/entity.cpp
index 17fa884e1..1f87f7af6 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -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,
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index 4de2af9d8..96ff19d10 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -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);
diff --git a/src/types.cpp b/src/types.cpp
index e10dae1ed..b4dc17256 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -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);