aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-08-09 15:36:18 +0100
committergingerBill <bill@gingerbill.org>2022-08-09 15:36:18 +0100
commitcb0a59bb2cfdeb971e88f329f07783ba1f93a5c9 (patch)
tree1996d06dc99ef64112515cb4bd3e0a3853850f9f
parent076700bd226aa620e8f6c45e6d9ad5a660299144 (diff)
Eliminate use of LLVMGetElementType for pointers
-rw-r--r--core/log/log_allocator.odin31
-rw-r--r--src/llvm_abi.cpp10
-rw-r--r--src/llvm_backend.cpp4
-rw-r--r--src/llvm_backend.hpp5
-rw-r--r--src/llvm_backend_expr.cpp2
-rw-r--r--src/llvm_backend_general.cpp210
-rw-r--r--src/llvm_backend_proc.cpp14
-rw-r--r--src/llvm_backend_type.cpp10
-rw-r--r--src/llvm_backend_utility.cpp4
9 files changed, 164 insertions, 126 deletions
diff --git a/core/log/log_allocator.odin b/core/log/log_allocator.odin
index eb7a6b377..997bd1a68 100644
--- a/core/log/log_allocator.odin
+++ b/core/log/log_allocator.odin
@@ -29,6 +29,8 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
old_memory: rawptr, old_size: int, location := #caller_location) -> ([]byte, runtime.Allocator_Error) {
la := (^Log_Allocator)(allocator_data)
+ padding := " " if la.prefix != "" else ""
+
if !la.locked {
la.locked = true
defer la.locked = false
@@ -38,7 +40,7 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
logf(
level=la.level,
fmt_str = "%s%s>>> ALLOCATOR(mode=.Alloc, size=%d, alignment=%d)",
- args = {la.prefix, " " if la.prefix != "" else "", size, alignment},
+ args = {la.prefix, padding, size, alignment},
location = location,
)
case .Free:
@@ -46,14 +48,14 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
logf(
level=la.level,
fmt_str = "%s%s<<< ALLOCATOR(mode=.Free, ptr=%p, size=%d)",
- args = {la.prefix, " " if la.prefix != "" else "", old_memory, old_size},
+ args = {la.prefix, padding, old_memory, old_size},
location = location,
)
} else {
logf(
level=la.level,
fmt_str = "%s%s<<< ALLOCATOR(mode=.Free, ptr=%p)",
- args = {la.prefix, " " if la.prefix != "" else "", old_memory},
+ args = {la.prefix, padding, old_memory},
location = location,
)
}
@@ -61,32 +63,45 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
logf(
level=la.level,
fmt_str = "%s%s<<< ALLOCATOR(mode=.Free_All)",
- args = {la.prefix, " " if la.prefix != "" else ""},
+ args = {la.prefix, padding},
location = location,
)
case .Resize:
logf(
level=la.level,
fmt_str = "%s%s>>> ALLOCATOR(mode=.Resize, ptr=%p, old_size=%d, size=%d, alignment=%d)",
- args = {la.prefix, " " if la.prefix != "" else "", old_memory, old_size, size, alignment},
+ args = {la.prefix, padding, old_memory, old_size, size, alignment},
location = location,
)
case .Query_Features:
logf(
level=la.level,
fmt_str = "%s%ALLOCATOR(mode=.Query_Features)",
- args = {la.prefix, " " if la.prefix != "" else ""},
+ args = {la.prefix, padding},
location = location,
)
case .Query_Info:
logf(
level=la.level,
fmt_str = "%s%ALLOCATOR(mode=.Query_Info)",
- args = {la.prefix, " " if la.prefix != "" else ""},
+ args = {la.prefix, padding},
location = location,
)
}
}
- return la.allocator.procedure(la.allocator.data, mode, size, alignment, old_memory, old_size, location)
+ data, err := la.allocator.procedure(la.allocator.data, mode, size, alignment, old_memory, old_size, location)
+ if !la.locked {
+ la.locked = true
+ defer la.locked = false
+ if err != nil {
+ logf(
+ level=la.level,
+ fmt_str = "%s%ALLOCATOR ERROR=%v",
+ args = {la.prefix, padding, error},
+ location = location,
+ )
+ }
+ }
+ return data, err
} \ No newline at end of file
diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp
index b22a839b3..2ff55c79b 100644
--- a/src/llvm_abi.cpp
+++ b/src/llvm_abi.cpp
@@ -62,7 +62,7 @@ bool lb_is_type_kind(LLVMTypeRef type, LLVMTypeKind kind) {
return LLVMGetTypeKind(type) == kind;
}
-LLVMTypeRef lb_function_type_to_llvm_ptr(lbFunctionType *ft, bool is_var_arg) {
+LLVMTypeRef lb_function_type_to_llvm_raw(lbFunctionType *ft, bool is_var_arg) {
unsigned arg_count = cast(unsigned)ft->args.count;
unsigned offset = 0;
@@ -108,10 +108,16 @@ LLVMTypeRef lb_function_type_to_llvm_ptr(lbFunctionType *ft, bool is_var_arg) {
}
unsigned total_arg_count = arg_index;
LLVMTypeRef func_type = LLVMFunctionType(ret, args, total_arg_count, is_var_arg);
- return LLVMPointerType(func_type, 0);
+ return func_type;
}
+// LLVMTypeRef lb_function_type_to_llvm_ptr(lbFunctionType *ft, bool is_var_arg) {
+// LLVMTypeRef func_type = lb_function_type_to_llvm_raw(ft, is_var_arg);
+// return LLVMPointerType(func_type, 0);
+// }
+
+
void lb_add_function_type_attributes(LLVMValueRef fn, lbFunctionType *ft, ProcCallingConvention calling_convention) {
if (ft == nullptr) {
return;
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index bcd11c8ea..6ee1541d6 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -739,11 +739,11 @@ lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *start
lb_begin_procedure_body(p);
if (startup_type_info) {
- LLVMBuildCall2(p->builder, lb_llvm_get_pointer_type(lb_type(main_module, startup_type_info->type)), startup_type_info->value, nullptr, 0, "");
+ LLVMBuildCall2(p->builder, lb_type_internal_for_procedures_raw(main_module, startup_type_info->type), startup_type_info->value, nullptr, 0, "");
}
if (objc_names) {
- LLVMBuildCall2(p->builder, lb_llvm_get_pointer_type(lb_type(main_module, objc_names->type)), objc_names->value, nullptr, 0, "");
+ LLVMBuildCall2(p->builder, lb_type_internal_for_procedures_raw(main_module, objc_names->type), objc_names->value, nullptr, 0, "");
}
for_array(i, global_variables) {
diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp
index 05dfb3734..149f1e711 100644
--- a/src/llvm_backend.hpp
+++ b/src/llvm_backend.hpp
@@ -127,6 +127,7 @@ struct lbModule {
AstPackage *pkg; // associated
PtrMap<Type *, LLVMTypeRef> types;
+ PtrMap<Type *, LLVMTypeRef> func_raw_types;
PtrMap<void *, lbStructFieldRemapping> struct_field_remapping; // Key: LLVMTypeRef or Type *
i32 internal_type_level;
@@ -330,7 +331,8 @@ lbProcedure *lb_create_procedure(lbModule *module, Entity *entity, bool ignore_b
void lb_end_procedure(lbProcedure *p);
-LLVMTypeRef lb_type(lbModule *m, Type *type);
+LLVMTypeRef lb_type(lbModule *m, Type *type);
+LLVMTypeRef llvm_get_element_type(LLVMTypeRef type);
lbBlock *lb_create_block(lbProcedure *p, char const *name, bool append=false);
@@ -343,7 +345,6 @@ lbValue lb_const_int(lbModule *m, Type *type, u64 value);
lbAddr lb_addr(lbValue addr);
Type *lb_addr_type(lbAddr const &addr);
-LLVMTypeRef lb_llvm_get_pointer_type(LLVMTypeRef type);
LLVMTypeRef llvm_addr_type(lbModule *module, lbValue addr_val);
void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value);
lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr);
diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp
index 4ae46aeb8..7568f975e 100644
--- a/src/llvm_backend_expr.cpp
+++ b/src/llvm_backend_expr.cpp
@@ -3345,7 +3345,7 @@ lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) {
default: GB_PANIC("Unhandled inline asm dialect"); break;
}
- LLVMTypeRef func_type = lb_llvm_get_pointer_type(lb_type(p->module, t));
+ LLVMTypeRef func_type = lb_type_internal_for_procedures_raw(p->module, t);
LLVMValueRef the_asm = llvm_get_inline_asm(func_type, asm_string, constraints_string, ia->has_side_effects, ia->has_side_effects, dialect);
GB_ASSERT(the_asm != nullptr);
return {the_asm, t};
diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp
index b212ee8b8..eb5cf371c 100644
--- a/src/llvm_backend_general.cpp
+++ b/src/llvm_backend_general.cpp
@@ -56,6 +56,7 @@ void lb_init_module(lbModule *m, Checker *c) {
gbAllocator a = heap_allocator();
map_init(&m->types, a);
+ map_init(&m->func_raw_types, a);
map_init(&m->struct_field_remapping, a);
map_init(&m->values, a);
map_init(&m->soa_values, a);
@@ -1416,6 +1417,116 @@ String lb_get_entity_name(lbModule *m, Entity *e, String default_name) {
}
+LLVMTypeRef lb_type_internal_for_procedures_raw(lbModule *m, Type *type) {
+ Type *original_type = type;
+ type = base_type(original_type);
+ GB_ASSERT(type->kind == Type_Proc);
+
+ LLVMTypeRef *found = map_get(&m->func_raw_types, type);
+ if (found) {
+ return *found;
+ }
+
+ unsigned param_count = 0;
+ if (type->Proc.calling_convention == ProcCC_Odin) {
+ param_count += 1;
+ }
+
+ if (type->Proc.param_count != 0) {
+ GB_ASSERT(type->Proc.params->kind == Type_Tuple);
+ for_array(i, type->Proc.params->Tuple.variables) {
+ Entity *e = type->Proc.params->Tuple.variables[i];
+ if (e->kind != Entity_Variable) {
+ continue;
+ }
+ if (e->flags & EntityFlag_CVarArg) {
+ continue;
+ }
+ param_count += 1;
+ }
+ }
+ m->internal_type_level += 1;
+ defer (m->internal_type_level -= 1);
+
+ LLVMTypeRef ret = nullptr;
+ LLVMTypeRef *params = gb_alloc_array(permanent_allocator(), LLVMTypeRef, param_count);
+ if (type->Proc.result_count != 0) {
+ Type *single_ret = reduce_tuple_to_single_type(type->Proc.results);
+ ret = lb_type(m, single_ret);
+ if (ret != nullptr) {
+ if (is_type_boolean(single_ret) &&
+ is_calling_convention_none(type->Proc.calling_convention) &&
+ type_size_of(single_ret) <= 1) {
+ ret = LLVMInt1TypeInContext(m->ctx);
+ }
+ }
+ }
+
+ unsigned param_index = 0;
+ if (type->Proc.param_count != 0) {
+ GB_ASSERT(type->Proc.params->kind == Type_Tuple);
+ for_array(i, type->Proc.params->Tuple.variables) {
+ Entity *e = type->Proc.params->Tuple.variables[i];
+ if (e->kind != Entity_Variable) {
+ continue;
+ }
+ if (e->flags & EntityFlag_CVarArg) {
+ continue;
+ }
+ Type *e_type = reduce_tuple_to_single_type(e->type);
+
+ LLVMTypeRef param_type = nullptr;
+ if (e->flags & EntityFlag_ByPtr) {
+ param_type = lb_type(m, alloc_type_pointer(e_type));
+ } else if (is_type_boolean(e_type) &&
+ type_size_of(e_type) <= 1) {
+ param_type = LLVMInt1TypeInContext(m->ctx);
+ } else {
+ if (is_type_proc(e_type)) {
+ param_type = lb_type(m, t_rawptr);
+ } else {
+ param_type = lb_type(m, e_type);
+ }
+ }
+
+ params[param_index++] = param_type;
+ }
+ }
+ if (param_index < param_count) {
+ params[param_index++] = lb_type(m, t_rawptr);
+ }
+ GB_ASSERT(param_index == param_count);
+
+ lbFunctionType *ft = lb_get_abi_info(m->ctx, params, param_count, ret, ret != nullptr, type->Proc.calling_convention);
+ {
+ for_array(j, ft->args) {
+ auto arg = ft->args[j];
+ GB_ASSERT_MSG(LLVMGetTypeContext(arg.type) == ft->ctx,
+ "\n\t%s %td/%td"
+ "\n\tArgTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
+ LLVMPrintTypeToString(arg.type),
+ j, ft->args.count,
+ LLVMGetTypeContext(arg.type), ft->ctx, LLVMGetGlobalContext());
+ }
+ GB_ASSERT_MSG(LLVMGetTypeContext(ft->ret.type) == ft->ctx,
+ "\n\t%s"
+ "\n\tRetTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
+ LLVMPrintTypeToString(ft->ret.type),
+ LLVMGetTypeContext(ft->ret.type), ft->ctx, LLVMGetGlobalContext());
+ }
+
+ map_set(&m->function_type_map, type, ft);
+ LLVMTypeRef new_abi_fn_type = lb_function_type_to_llvm_raw(ft, type->Proc.c_vararg);
+
+ GB_ASSERT_MSG(LLVMGetTypeContext(new_abi_fn_type) == m->ctx,
+ "\n\tFuncTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
+ LLVMGetTypeContext(new_abi_fn_type), m->ctx, LLVMGetGlobalContext());
+
+ map_set(&m->func_raw_types, type, new_abi_fn_type);
+
+ return new_abi_fn_type;
+
+}
LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
LLVMContextRef ctx = m->ctx;
i64 size = type_size_of(type); // Check size
@@ -1919,103 +2030,8 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
if (m->internal_type_level > 1) { // TODO HACK(bill): is this really enough?
return LLVMPointerType(LLVMIntTypeInContext(m->ctx, 8), 0);
} else {
- unsigned param_count = 0;
- if (type->Proc.calling_convention == ProcCC_Odin) {
- param_count += 1;
- }
-
- if (type->Proc.param_count != 0) {
- GB_ASSERT(type->Proc.params->kind == Type_Tuple);
- for_array(i, type->Proc.params->Tuple.variables) {
- Entity *e = type->Proc.params->Tuple.variables[i];
- if (e->kind != Entity_Variable) {
- continue;
- }
- if (e->flags & EntityFlag_CVarArg) {
- continue;
- }
- param_count += 1;
- }
- }
- m->internal_type_level += 1;
- defer (m->internal_type_level -= 1);
-
- LLVMTypeRef ret = nullptr;
- LLVMTypeRef *params = gb_alloc_array(permanent_allocator(), LLVMTypeRef, param_count);
- if (type->Proc.result_count != 0) {
- Type *single_ret = reduce_tuple_to_single_type(type->Proc.results);
- ret = lb_type(m, single_ret);
- if (ret != nullptr) {
- if (is_type_boolean(single_ret) &&
- is_calling_convention_none(type->Proc.calling_convention) &&
- type_size_of(single_ret) <= 1) {
- ret = LLVMInt1TypeInContext(m->ctx);
- }
- }
- }
-
- unsigned param_index = 0;
- if (type->Proc.param_count != 0) {
- GB_ASSERT(type->Proc.params->kind == Type_Tuple);
- for_array(i, type->Proc.params->Tuple.variables) {
- Entity *e = type->Proc.params->Tuple.variables[i];
- if (e->kind != Entity_Variable) {
- continue;
- }
- if (e->flags & EntityFlag_CVarArg) {
- continue;
- }
- Type *e_type = reduce_tuple_to_single_type(e->type);
-
- LLVMTypeRef param_type = nullptr;
- if (e->flags & EntityFlag_ByPtr) {
- param_type = lb_type(m, alloc_type_pointer(e_type));
- } else if (is_type_boolean(e_type) &&
- type_size_of(e_type) <= 1) {
- param_type = LLVMInt1TypeInContext(m->ctx);
- } else {
- if (is_type_proc(e_type)) {
- param_type = lb_type(m, t_rawptr);
- } else {
- param_type = lb_type(m, e_type);
- }
- }
-
- params[param_index++] = param_type;
- }
- }
- if (param_index < param_count) {
- params[param_index++] = lb_type(m, t_rawptr);
- }
- GB_ASSERT(param_index == param_count);
-
- lbFunctionType *ft = lb_get_abi_info(m->ctx, params, param_count, ret, ret != nullptr, type->Proc.calling_convention);
- {
- for_array(j, ft->args) {
- auto arg = ft->args[j];
- GB_ASSERT_MSG(LLVMGetTypeContext(arg.type) == ft->ctx,
- "\n\t%s %td/%td"
- "\n\tArgTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
- LLVMPrintTypeToString(arg.type),
- j, ft->args.count,
- LLVMGetTypeContext(arg.type), ft->ctx, LLVMGetGlobalContext());
- }
- GB_ASSERT_MSG(LLVMGetTypeContext(ft->ret.type) == ft->ctx,
- "\n\t%s"
- "\n\tRetTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
- LLVMPrintTypeToString(ft->ret.type),
- LLVMGetTypeContext(ft->ret.type), ft->ctx, LLVMGetGlobalContext());
- }
-
- map_set(&m->function_type_map, type, ft);
- LLVMTypeRef new_abi_fn_ptr_type = lb_function_type_to_llvm_ptr(ft, type->Proc.c_vararg);
- LLVMTypeRef new_abi_fn_type = lb_llvm_get_pointer_type(new_abi_fn_ptr_type);
-
- GB_ASSERT_MSG(LLVMGetTypeContext(new_abi_fn_type) == m->ctx,
- "\n\tFuncTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
- LLVMGetTypeContext(new_abi_fn_type), m->ctx, LLVMGetGlobalContext());
-
- return new_abi_fn_ptr_type;
+ LLVMTypeRef proc_raw_type = lb_type_internal_for_procedures_raw(m, type);
+ return LLVMPointerType(proc_raw_type, 0);
}
break;
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index 756a93db7..392ff14c2 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -129,8 +129,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body)
}
char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
- LLVMTypeRef func_ptr_type = lb_type(m, p->type);
- LLVMTypeRef func_type = lb_llvm_get_pointer_type(func_ptr_type);
+ LLVMTypeRef func_type = lb_get_procedure_raw_type(m, p->type);
p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
@@ -354,8 +353,7 @@ lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type
char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
- LLVMTypeRef func_ptr_type = lb_type(m, p->type);
- LLVMTypeRef func_type = lb_llvm_get_pointer_type(func_ptr_type);
+ LLVMTypeRef func_type = lb_get_procedure_raw_type(m, p->type);
p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
@@ -753,12 +751,12 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr,
GB_ASSERT(curr_block != p->decl_block->block);
{
- LLVMTypeRef ftp = lb_type(p->module, value.type);
+ LLVMTypeRef fnp = lb_type_internal_for_procedures_raw(p->module, value.type);
+ LLVMTypeRef ftp = LLVMPointerType(fnp, 0);
LLVMValueRef fn = value.value;
if (!lb_is_type_kind(LLVMTypeOf(value.value), LLVMFunctionTypeKind)) {
fn = LLVMBuildPointerCast(p->builder, fn, ftp, "");
}
- LLVMTypeRef fnp = lb_llvm_get_pointer_type(LLVMTypeOf(fn));
GB_ASSERT_MSG(lb_is_type_kind(fnp, LLVMFunctionTypeKind), "%s", LLVMPrintTypeToString(fnp));
{
@@ -2723,7 +2721,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
{
Type *param_types[2] = {t_u32, t_u32};
Type *type = alloc_type_proc_from_types(param_types, gb_count_of(param_types), tv.type, false, ProcCC_None);
- LLVMTypeRef func_type = lb_llvm_get_pointer_type(lb_type(p->module, type));
+ LLVMTypeRef func_type = lb_get_procedure_raw_type(p->module, type);
LLVMValueRef the_asm = llvm_get_inline_asm(
func_type,
str_lit("cpuid"),
@@ -2743,7 +2741,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
case BuiltinProc_x86_xgetbv:
{
Type *type = alloc_type_proc_from_types(&t_u32, 1, tv.type, false, ProcCC_None);
- LLVMTypeRef func_type = lb_llvm_get_pointer_type(lb_type(p->module, type));
+ LLVMTypeRef func_type = lb_get_procedure_raw_type(p->module, type);
LLVMValueRef the_asm = llvm_get_inline_asm(
func_type,
str_lit("xgetbv"),
diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp
index 10cae9e6c..ba4135901 100644
--- a/src/llvm_backend_type.cpp
+++ b/src/llvm_backend_type.cpp
@@ -130,12 +130,16 @@ lbValue lb_get_type_info_ptr(lbModule *m, Type *type) {
return res;
}
-// The use of this method needs to be eliminated.
-LLVMTypeRef lb_llvm_get_pointer_type(LLVMTypeRef type)
-{
+// NOTE: The use of this method needs to be eliminated for pointers.
+LLVMTypeRef llvm_get_element_type(LLVMTypeRef type) {
return LLVMGetElementType(type);
}
+LLVMTypeRef lb_get_procedure_raw_type(lbModule *m, Type *type) {
+ return lb_type_internal_for_procedures_raw(m, type);
+}
+
+
lbValue lb_type_info_member_types_offset(lbProcedure *p, isize count) {
GB_ASSERT(p->module == &p->module->gen->default_module);
lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_types.addr, lb_global_type_info_member_types_index);
diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp
index b6589a080..665ba1553 100644
--- a/src/llvm_backend_utility.cpp
+++ b/src/llvm_backend_utility.cpp
@@ -96,9 +96,7 @@ LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValu
args[2] = LLVMBuildIntCast2(p->builder, len, types[1], /*signed*/false, "");
// We always get the function pointer type rather than the function and there is apparently no way around that?
- LLVMTypeRef type = lb_type(p->module, pr.type);
-
- type = lb_llvm_get_pointer_type(type);
+ LLVMTypeRef type = lb_type_internal_for_procedures_raw(p->module, pr.type);
return LLVMBuildCall2(p->builder, type, pr.value, args, gb_count_of(args), "");
}