aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-11-08 12:18:36 +0000
committergingerBill <bill@gingerbill.org>2022-11-08 12:18:36 +0000
commited58374964889db91b38fe95db409111819790ca (patch)
tree6607cf40b0685fd9c71c0871c04f01cbbd3f42fb /src
parent6dd4d1a9244cb7ba1c819e457d7aef493d5eb482 (diff)
Make `Map_Info` store pointers to cell info rather than inline
Diffstat (limited to 'src')
-rw-r--r--src/check_builtin.cpp23
-rw-r--r--src/checker.cpp3
-rw-r--r--src/checker_builtin_procs.hpp2
-rw-r--r--src/llvm_backend.cpp14
-rw-r--r--src/llvm_backend.hpp3
-rw-r--r--src/llvm_backend_general.cpp1
-rw-r--r--src/llvm_backend_proc.cpp3
-rw-r--r--src/types.cpp2
8 files changed, 49 insertions, 2 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp
index b8bf1bcc7..457100d6e 100644
--- a/src/check_builtin.cpp
+++ b/src/check_builtin.cpp
@@ -5363,6 +5363,29 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
break;
}
+ case BuiltinProc_type_map_info:
+ {
+ Operand op = {};
+ Type *bt = check_type(c, ce->args[0]);
+ Type *type = base_type(bt);
+ if (type == nullptr || type == t_invalid) {
+ error(ce->args[0], "Expected a type for '%.*s'", LIT(builtin_name));
+ return false;
+ }
+ if (!is_type_map(type)) {
+ gbString t = type_to_string(type);
+ error(ce->args[0], "Expected a map type for '%.*s', got %s", LIT(builtin_name), t);
+ gb_string_free(t);
+ return false;
+ }
+
+ add_map_key_type_dependencies(c, type);
+
+ operand->mode = Addressing_Value;
+ operand->type = t_map_info_ptr;
+ break;
+ }
+
case BuiltinProc_constant_utf16_cstring:
{
String value = {};
diff --git a/src/checker.cpp b/src/checker.cpp
index fa3ef245b..5b9e83bda 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -2851,6 +2851,9 @@ void init_core_map_type(Checker *c) {
t_map_info = find_core_type(c, str_lit("Map_Info"));
t_map_cell_info = find_core_type(c, str_lit("Map_Cell_Info"));
t_raw_map = find_core_type(c, str_lit("Raw_Map"));
+
+ t_map_info_ptr = alloc_type_pointer(t_map_info);
+ t_map_cell_info_ptr = alloc_type_pointer(t_map_cell_info);
}
void init_preload(Checker *c) {
diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp
index c59ae7867..72639e071 100644
--- a/src/checker_builtin_procs.hpp
+++ b/src/checker_builtin_procs.hpp
@@ -277,6 +277,7 @@ BuiltinProc__type_simple_boolean_end,
BuiltinProc_type_equal_proc,
BuiltinProc_type_hasher_proc,
+ BuiltinProc_type_map_info,
BuiltinProc__type_end,
@@ -572,6 +573,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
{STR_LIT("type_equal_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_hasher_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
+ {STR_LIT("type_map_info"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index fa9727106..960ef84f6 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -502,6 +502,11 @@ lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, A
LLVMValueRef lb_gen_map_cell_info(lbModule *m, Type *type) {
+ lbAddr *found = map_get(&m->map_cell_info_map, type);
+ if (found) {
+ return found->addr.value;
+ }
+
i64 size = 0, len = 0;
map_cell_size_and_len(type, &size, &len);
@@ -510,8 +515,15 @@ LLVMValueRef lb_gen_map_cell_info(lbModule *m, Type *type) {
const_values[1] = lb_const_int(m, t_uintptr, type_align_of(type)).value;
const_values[2] = lb_const_int(m, t_uintptr, size).value;
const_values[3] = lb_const_int(m, t_uintptr, len).value;
- return llvm_const_named_struct(m, t_map_cell_info, const_values, gb_count_of(const_values));
+ LLVMValueRef llvm_res = llvm_const_named_struct(m, t_map_cell_info, const_values, gb_count_of(const_values));
+ lbValue res = {llvm_res, t_map_cell_info};
+
+ lbAddr addr = lb_add_global_generated(m, t_map_cell_info, res, nullptr);
+ lb_make_global_private_const(addr);
+
+ map_set(&m->map_cell_info_map, type, addr);
+ return addr.addr.value;
}
lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type) {
map_type = base_type(map_type);
diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp
index 2b9014d94..065bf4943 100644
--- a/src/llvm_backend.hpp
+++ b/src/llvm_backend.hpp
@@ -160,7 +160,8 @@ struct lbModule {
StringMap<lbAddr> objc_classes;
StringMap<lbAddr> objc_selectors;
- PtrMap<Type *, lbAddr> map_info_map;
+ PtrMap<Type *, lbAddr> map_cell_info_map; // address of runtime.Map_Info
+ PtrMap<Type *, lbAddr> map_info_map; // address of runtime.Map_Cell_Info
};
struct lbGenerator {
diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp
index ffc7a1496..b7654614e 100644
--- a/src/llvm_backend_general.cpp
+++ b/src/llvm_backend_general.cpp
@@ -76,6 +76,7 @@ void lb_init_module(lbModule *m, Checker *c) {
string_map_init(&m->objc_selectors, a);
map_init(&m->map_info_map, a, 0);
+ map_init(&m->map_cell_info_map, a, 0);
}
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index a9de7b231..3881790e0 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -2324,6 +2324,9 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
case BuiltinProc_type_hasher_proc:
return lb_get_hasher_proc_for_type(p->module, ce->args[0]->tav.type);
+ case BuiltinProc_type_map_info:
+ return lb_gen_map_info_ptr(p->module, ce->args[0]->tav.type);
+
case BuiltinProc_fixed_point_mul:
case BuiltinProc_fixed_point_div:
case BuiltinProc_fixed_point_mul_sat:
diff --git a/src/types.cpp b/src/types.cpp
index c92d8a78f..ca15531dd 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -685,6 +685,8 @@ gb_global Type *t_source_code_location_ptr = nullptr;
gb_global Type *t_map_info = nullptr;
gb_global Type *t_map_cell_info = nullptr;
+gb_global Type *t_map_info_ptr = nullptr;
+gb_global Type *t_map_cell_info_ptr = nullptr;
gb_global Type *t_raw_map = nullptr;