aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_utility.cpp
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2022-11-17 15:29:28 +0000
committerGitHub <noreply@github.com>2022-11-17 15:29:28 +0000
commit15bbdb2030510b9d15918536c7da8af3a376c0be (patch)
tree60210e6a4ea6d6a34f286f1f4770e4f6fbd2737d /src/llvm_backend_utility.cpp
parent48c9c1682c347adb7e743a6a6f8c70f08420c197 (diff)
parent3949e2220feca6c718a27ecc0fd5cb1cde56f7b7 (diff)
Merge pull request #2181 from odin-lang/map-dev
New `map` internals
Diffstat (limited to 'src/llvm_backend_utility.cpp')
-rw-r--r--src/llvm_backend_utility.cpp93
1 files changed, 50 insertions, 43 deletions
diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp
index a54171b51..101b9dbfb 100644
--- a/src/llvm_backend_utility.cpp
+++ b/src/llvm_backend_utility.cpp
@@ -203,26 +203,19 @@ lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t) {
if (is_type_uintptr(src) && is_type_internally_pointer_like(dst)) {
res.value = LLVMBuildIntToPtr(p->builder, value.value, lb_type(m, t), "");
return res;
- }
- if (is_type_internally_pointer_like(src) && is_type_uintptr(dst)) {
+ } else if (is_type_internally_pointer_like(src) && is_type_uintptr(dst)) {
res.value = LLVMBuildPtrToInt(p->builder, value.value, lb_type(m, t), "");
return res;
- }
-
- if (is_type_integer(src) && is_type_internally_pointer_like(dst)) {
+ } else if (is_type_integer(src) && is_type_internally_pointer_like(dst)) {
res.value = LLVMBuildIntToPtr(p->builder, value.value, lb_type(m, t), "");
return res;
} else if (is_type_internally_pointer_like(src) && is_type_integer(dst)) {
res.value = LLVMBuildPtrToInt(p->builder, value.value, lb_type(m, t), "");
return res;
- }
-
- if (is_type_internally_pointer_like(src) && is_type_internally_pointer_like(dst)) {
+ } else if (is_type_internally_pointer_like(src) && is_type_internally_pointer_like(dst)) {
res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(p->module, t), "");
return res;
- }
-
- if (is_type_simd_vector(src) && is_type_simd_vector(dst)) {
+ } else if (is_type_simd_vector(src) && is_type_simd_vector(dst)) {
res.value = LLVMBuildBitCast(p->builder, value.value, lb_type(p->module, t), "");
return res;
} else if (is_type_array_like(src) && is_type_simd_vector(dst)) {
@@ -239,9 +232,11 @@ lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t) {
ap = lb_emit_conv(p, ap, alloc_type_pointer(value.type));
lb_emit_store(p, ap, value);
return lb_addr_load(p, addr);
- }
-
- if (lb_is_type_aggregate(src) || lb_is_type_aggregate(dst)) {
+ } else if (is_type_map(src) && are_types_identical(t_raw_map, t)) {
+ res.value = value.value;
+ res.type = t;
+ return res;
+ } else if (lb_is_type_aggregate(src) || lb_is_type_aggregate(dst)) {
lbValue s = lb_address_from_load_or_generate_local(p, value);
lbValue d = lb_emit_transmute(p, s, alloc_type_pointer(t));
return lb_emit_load(p, d);
@@ -990,14 +985,13 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
}
} else if (is_type_map(t)) {
init_map_internal_types(t);
- Type *itp = alloc_type_pointer(t->Map.internal_type);
+ Type *itp = alloc_type_pointer(t_raw_map);
s = lb_emit_transmute(p, s, itp);
- Type *gst = t->Map.internal_type;
- GB_ASSERT(gst->kind == Type_Struct);
switch (index) {
- case 0: result_type = get_struct_field_type(gst, 0); break;
- case 1: result_type = get_struct_field_type(gst, 1); break;
+ case 0: result_type = get_struct_field_type(t_raw_map, 0); break;
+ case 1: result_type = get_struct_field_type(t_raw_map, 1); break;
+ case 2: result_type = get_struct_field_type(t_raw_map, 2); break;
}
} else if (is_type_array(t)) {
return lb_emit_array_epi(p, s, index);
@@ -1130,10 +1124,10 @@ lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index) {
case Type_Map:
{
init_map_internal_types(t);
- Type *gst = t->Map.internal_type;
switch (index) {
- case 0: result_type = get_struct_field_type(gst, 0); break;
- case 1: result_type = get_struct_field_type(gst, 1); break;
+ case 0: result_type = get_struct_field_type(t_raw_map, 0); break;
+ case 1: result_type = get_struct_field_type(t_raw_map, 1); break;
+ case 2: result_type = get_struct_field_type(t_raw_map, 2); break;
}
}
break;
@@ -1439,34 +1433,47 @@ lbValue lb_dynamic_array_allocator(lbProcedure *p, lbValue da) {
return lb_emit_struct_ev(p, da, 3);
}
-lbValue lb_map_entries(lbProcedure *p, lbValue value) {
- Type *t = base_type(value.type);
- GB_ASSERT_MSG(t->kind == Type_Map, "%s", type_to_string(t));
- init_map_internal_types(t);
- i32 index = 1;
- lbValue entries = lb_emit_struct_ev(p, value, index);
- return entries;
+lbValue lb_map_len(lbProcedure *p, lbValue value) {
+ GB_ASSERT_MSG(is_type_map(value.type) || are_types_identical(value.type, t_raw_map), "%s", type_to_string(value.type));
+ lbValue len = lb_emit_struct_ev(p, value, 1);
+ return lb_emit_conv(p, len, t_int);
}
-
-lbValue lb_map_entries_ptr(lbProcedure *p, lbValue value) {
- Type *t = base_type(type_deref(value.type));
- GB_ASSERT_MSG(t->kind == Type_Map, "%s", type_to_string(t));
- init_map_internal_types(t);
- i32 index = 1;
- lbValue entries = lb_emit_struct_ep(p, value, index);
- return entries;
+lbValue lb_map_len_ptr(lbProcedure *p, lbValue map_ptr) {
+ Type *type = map_ptr.type;
+ GB_ASSERT(is_type_pointer(type));
+ type = type_deref(type);
+ GB_ASSERT_MSG(is_type_map(type) || are_types_identical(type, t_raw_map), "%s", type_to_string(type));
+ return lb_emit_struct_ep(p, map_ptr, 1);
}
-lbValue lb_map_len(lbProcedure *p, lbValue value) {
- lbValue entries = lb_map_entries(p, value);
- return lb_dynamic_array_len(p, entries);
+lbValue lb_map_cap(lbProcedure *p, lbValue value) {
+ GB_ASSERT_MSG(is_type_map(value.type) || are_types_identical(value.type, t_raw_map), "%s", type_to_string(value.type));
+ lbValue zero = lb_const_int(p->module, t_uintptr, 0);
+ lbValue one = lb_const_int(p->module, t_uintptr, 1);
+
+ lbValue mask = lb_const_int(p->module, t_uintptr, MAP_CACHE_LINE_SIZE-1);
+
+ lbValue data = lb_emit_struct_ev(p, value, 0);
+ lbValue log2_cap = lb_emit_arith(p, Token_And, data, mask, t_uintptr);
+ lbValue cap = lb_emit_arith(p, Token_Shl, one, log2_cap, t_uintptr);
+ lbValue cmp = lb_emit_comp(p, Token_CmpEq, data, zero);
+ return lb_emit_conv(p, lb_emit_select(p, cmp, zero, cap), t_int);
}
-lbValue lb_map_cap(lbProcedure *p, lbValue value) {
- lbValue entries = lb_map_entries(p, value);
- return lb_dynamic_array_cap(p, entries);
+lbValue lb_map_data_uintptr(lbProcedure *p, lbValue value) {
+ GB_ASSERT(is_type_map(value.type) || are_types_identical(value.type, t_raw_map));
+ lbValue data = lb_emit_struct_ev(p, value, 0);
+ u64 mask_value = 0;
+ if (build_context.word_size == 4) {
+ mask_value = 0xfffffffful & ~(MAP_CACHE_LINE_SIZE-1);
+ } else {
+ mask_value = 0xffffffffffffffffull & ~(MAP_CACHE_LINE_SIZE-1);
+ }
+ lbValue mask = lb_const_int(p->module, t_uintptr, mask_value);
+ return lb_emit_arith(p, Token_And, data, mask, t_uintptr);
}
+
lbValue lb_soa_struct_len(lbProcedure *p, lbValue value) {
Type *t = base_type(value.type);
bool is_ptr = false;