Make USE_NEW_LLVM_ABI_SYSTEM the actual behaviour and remove the previous approach

This commit is contained in:
gingerBill
2021-02-25 13:17:00 +00:00
parent 84deee75cc
commit 3eae69effc
2 changed files with 110 additions and 405 deletions

View File

@@ -1,12 +1,6 @@
#include "llvm_backend.hpp"
#include "llvm_abi.cpp"
#ifdef USE_NEW_LLVM_ABI_SYSTEM
#define USE_LLVM_ABI 1
#else
#define USE_LLVM_ABI 0
#endif
gb_global lbAddr lb_global_type_info_data = {};
gb_global lbAddr lb_global_type_info_member_types = {};
gb_global lbAddr lb_global_type_info_member_names = {};
@@ -434,11 +428,7 @@ void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
GB_ASSERT(value.value != nullptr);
value = lb_emit_conv(p, value, lb_addr_type(addr));
if (USE_LLVM_ABI) {
lb_emit_store(p, addr.addr, value);
} else {
LLVMBuildStore(p->builder, value.value, addr.addr.value);
}
lb_emit_store(p, addr.addr, value);
}
void lb_const_store(lbValue ptr, lbValue value) {
@@ -1280,146 +1270,85 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
}
case Type_Proc:
{
if (USE_LLVM_ABI) {
if (m->internal_type_level > 256) { // 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 (m->internal_type_level > 256) { // 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 (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;
}
param_count += 1;
}
}
m->internal_type_level += 1;
defer (m->internal_type_level -= 1);
LLVMTypeRef ret = nullptr;
LLVMTypeRef *params = gb_alloc_array(heap_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);
}
}
}
isize 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;
}
Type *e_type = reduce_tuple_to_single_type(e->type);
LLVMTypeRef param_type = nullptr;
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);
// params[param_index++] = lb_type(m, t_context_ptr);
}
GB_ASSERT(param_index == param_count);
lbFunctionType *ft = lb_get_abi_info(m->ctx, params, param_count, ret, ret != nullptr, type->Proc.calling_convention);
map_set(&m->function_type_map, hash_type(type), ft);
LLVMTypeRef new_abi_fn_ptr_type = lb_function_type_to_llvm_ptr(ft, type->Proc.c_vararg);
LLVMTypeRef new_abi_fn_type = LLVMGetElementType(new_abi_fn_ptr_type);
// LLVMTypeRef new_ret = LLVMGetReturnType(new_abi_fn_type);
// LLVMTypeRef old_ret = LLVMGetReturnType(old_abi_fn_type);
// unsigned new_count = LLVMCountParamTypes(new_abi_fn_type);
// unsigned old_count = LLVMCountParamTypes(old_abi_fn_type);
// GB_ASSERT_MSG(new_count == old_count, "%u %u, %s %s", new_count, old_count, LLVMPrintTypeToString(new_abi_fn_type), LLVMPrintTypeToString(old_abi_fn_type));
return new_abi_fn_ptr_type;
param_count += 1;
}
} else {
LLVMTypeRef old_abi_fn_type = nullptr;
}
m->internal_type_level += 1;
defer (m->internal_type_level -= 1);
set_procedure_abi_types(type);
LLVMTypeRef return_type = LLVMVoidTypeInContext(ctx);
if (type->Proc.return_by_pointer) {
// Void
} else if (type->Proc.abi_compat_result_type != nullptr) {
return_type = lb_type(m, type->Proc.abi_compat_result_type);
LLVMTypeRef ret = nullptr;
LLVMTypeRef *params = gb_alloc_array(heap_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);
}
}
}
isize 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;
}
isize extra_param_count = 0;
if (type->Proc.return_by_pointer) {
extra_param_count += 1;
}
if (type->Proc.calling_convention == ProcCC_Odin) {
extra_param_count += 1;
}
Type *e_type = reduce_tuple_to_single_type(e->type);
isize param_count = type->Proc.abi_compat_params.count + extra_param_count;
auto param_types = array_make<LLVMTypeRef>(temporary_allocator(), 0, param_count);
if (type->Proc.return_by_pointer) {
array_add(&param_types, LLVMPointerType(lb_type(m, type->Proc.abi_compat_result_type), 0));
}
for_array(i, type->Proc.abi_compat_params) {
Type *param = type->Proc.abi_compat_params[i];
if (param == nullptr) {
continue;
}
if (type->Proc.params->Tuple.variables[i]->flags & EntityFlag_CVarArg) {
GB_ASSERT(i+1 == type->Proc.abi_compat_params.count);
break;
}
if (is_type_tuple(param)) {
param = base_type(param);
for_array(j, param->Tuple.variables) {
Entity *v = param->Tuple.variables[j];
if (v->kind != Entity_Variable) {
// Sanity check
continue;
}
LLVMTypeRef t = lb_type(m, v->type);
array_add(&param_types, t);
}
LLVMTypeRef param_type = nullptr;
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 {
array_add(&param_types, lb_type(m, param));
param_type = lb_type(m, e_type);
}
}
if (type->Proc.calling_convention == ProcCC_Odin) {
array_add(&param_types, lb_type(m, t_rawptr));
// array_add(&param_types, lb_type(m, t_context_ptr));
}
old_abi_fn_type = LLVMFunctionType(return_type, param_types.data, cast(unsigned)param_types.count, type->Proc.c_vararg);
return LLVMPointerType(old_abi_fn_type, 0);
params[param_index++] = param_type;
}
}
if (param_index < param_count) {
params[param_index++] = lb_type(m, t_rawptr);
// params[param_index++] = lb_type(m, t_context_ptr);
}
GB_ASSERT(param_index == param_count);
lbFunctionType *ft = lb_get_abi_info(m->ctx, params, param_count, ret, ret != nullptr, type->Proc.calling_convention);
map_set(&m->function_type_map, hash_type(type), ft);
LLVMTypeRef new_abi_fn_ptr_type = lb_function_type_to_llvm_ptr(ft, type->Proc.c_vararg);
LLVMTypeRef new_abi_fn_type = LLVMGetElementType(new_abi_fn_ptr_type);
// LLVMTypeRef new_ret = LLVMGetReturnType(new_abi_fn_type);
// LLVMTypeRef old_ret = LLVMGetReturnType(old_abi_fn_type);
// unsigned new_count = LLVMCountParamTypes(new_abi_fn_type);
// unsigned old_count = LLVMCountParamTypes(old_abi_fn_type);
// GB_ASSERT_MSG(new_count == old_count, "%u %u, %s %s", new_count, old_count, LLVMPrintTypeToString(new_abi_fn_type), LLVMPrintTypeToString(old_abi_fn_type));
return new_abi_fn_ptr_type;
}
break;
@@ -1467,7 +1396,7 @@ LLVMTypeRef lb_type(lbModule *m, Type *type) {
m->internal_type_level += 1;
llvm_type = lb_type_internal(m, type);
m->internal_type_level -= 1;
if (USE_LLVM_ABI && m->internal_type_level == 0) {
if (m->internal_type_level == 0) {
map_set(&m->types, hash_type(type), llvm_type);
if (is_type_named(type)) {
map_set(&m->llvm_types, hash_pointer(llvm_type), type);
@@ -2009,6 +1938,20 @@ void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *nam
void lb_ensure_abi_function_type(lbModule *m, lbProcedure *p) {
if (p->abi_function_type != nullptr) {
return;
}
auto hash = hash_type(p->type);
lbFunctionType **ft_found = map_get(&m->function_type_map, hash);
if (ft_found == nullptr) {
LLVMTypeRef llvm_proc_type = lb_type(p->module, p->type);
ft_found = map_get(&m->function_type_map, hash);
}
GB_ASSERT(ft_found != nullptr);
p->abi_function_type = *ft_found;
GB_ASSERT(p->abi_function_type != nullptr);
}
lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) {
GB_ASSERT(entity != nullptr);
@@ -2070,12 +2013,9 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) {
p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
lbFunctionType **ft_found = map_get(&m->function_type_map, hash_type(p->type));
if (USE_LLVM_ABI && ft_found) {
lbFunctionType *abi_ft = *ft_found;
p->abi_function_type = abi_ft;
lb_add_function_type_attributes(p->value, abi_ft, abi_ft->calling_convention);
} else {
lb_ensure_abi_function_type(m, p);
lb_add_function_type_attributes(p->value, p->abi_function_type, p->abi_function_type->calling_convention);
if (false) {
lbCallingConventionKind cc_kind = lbCallingConvention_C;
// TODO(bill): Clean up this logic
if (build_context.metrics.os != TargetOs_js) {
@@ -2124,10 +2064,6 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) {
// NOTE(bill): offset==0 is the return value
isize offset = 1;
if (pt->Proc.return_by_pointer) {
if (!USE_LLVM_ABI) {
lb_add_proc_attribute_at_index(p, 1, "sret");
lb_add_proc_attribute_at_index(p, 1, "noalias");
}
offset = 2;
}
@@ -2160,14 +2096,6 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) {
}
}
if (!USE_LLVM_ABI && pt->Proc.calling_convention == ProcCC_Odin) {
lb_add_proc_attribute_at_index(p, offset+parameter_index, "noalias");
lb_add_proc_attribute_at_index(p, offset+parameter_index, "nonnull");
lb_add_proc_attribute_at_index(p, offset+parameter_index, "nocapture");
}
{ // Debug Information
unsigned line = cast(unsigned)entity->token.pos.line;
@@ -2252,34 +2180,6 @@ lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type
}
isize parameter_index = 0;
if (!USE_LLVM_ABI && pt->Proc.param_count) {
TypeTuple *params = &pt->Proc.params->Tuple;
for (isize i = 0; i < pt->Proc.param_count; i++) {
Entity *e = params->variables[i];
Type *original_type = e->type;
Type *abi_type = pt->Proc.abi_compat_params[i];
if (e->kind != Entity_Variable) continue;
if (i+1 == params->variables.count && pt->Proc.c_vararg) {
continue;
}
if (is_type_tuple(abi_type)) {
for_array(j, abi_type->Tuple.variables) {
Type *tft = abi_type->Tuple.variables[j]->type;
if (e->flags&EntityFlag_NoAlias) {
lb_add_proc_attribute_at_index(p, offset+parameter_index+j, "noalias");
}
}
parameter_index += abi_type->Tuple.variables.count;
} else {
if (e->flags&EntityFlag_NoAlias) {
lb_add_proc_attribute_at_index(p, offset+parameter_index, "noalias");
}
parameter_index += 1;
}
}
}
if (pt->Proc.calling_convention == ProcCC_Odin) {
lb_add_proc_attribute_at_index(p, offset+parameter_index, "noalias");
lb_add_proc_attribute_at_index(p, offset+parameter_index, "nonnull");
@@ -2504,7 +2404,8 @@ void lb_begin_procedure_body(lbProcedure *p) {
GB_ASSERT(p->type != nullptr);
if (p->abi_function_type) {
lb_ensure_abi_function_type(p->module, p);
{
lbFunctionType *ft = p->abi_function_type;
unsigned param_offset = 0;
@@ -2602,80 +2503,6 @@ void lb_begin_procedure_body(lbProcedure *p) {
res = lb_add_local(p, e->type, e);
}
if (e->Variable.param_value.kind != ParameterValue_Invalid) {
lbValue c = lb_handle_param_value(p, e->type, e->Variable.param_value, e->token.pos);
lb_addr_store(p, res, c);
}
}
}
}
} else {
i32 parameter_index = 0;
lbValue return_ptr_value = {};
if (p->type->Proc.return_by_pointer) {
// NOTE(bill): this must be parameter 0
Type *ptr_type = alloc_type_pointer(reduce_tuple_to_single_type(p->type->Proc.results));
Entity *e = alloc_entity_param(nullptr, make_token_ident(str_lit("agg.result")), ptr_type, false, false);
e->flags |= EntityFlag_Sret | EntityFlag_NoAlias;
return_ptr_value.value = LLVMGetParam(p->value, 0);
return_ptr_value.type = ptr_type;
p->return_ptr = lb_addr(return_ptr_value);
lb_add_entity(p->module, e, return_ptr_value);
parameter_index += 1;
}
if (p->type->Proc.params != nullptr) {
TypeTuple *params = &p->type->Proc.params->Tuple;
auto abi_types = p->type->Proc.abi_compat_params;
for_array(i, params->variables) {
Entity *e = params->variables[i];
if (e->kind != Entity_Variable) {
continue;
}
Type *abi_type = e->type;
if (abi_types.count > 0) {
abi_type = abi_types[i];
}
if (e->token.string != "") {
lb_add_param(p, e, nullptr, abi_type, parameter_index);
}
if (is_type_tuple(abi_type)) {
parameter_index += cast(i32)abi_type->Tuple.variables.count;
} else {
parameter_index += 1;
}
}
}
if (p->type->Proc.has_named_results) {
GB_ASSERT(p->type->Proc.result_count > 0);
TypeTuple *results = &p->type->Proc.results->Tuple;
for_array(i, results->variables) {
Entity *e = results->variables[i];
GB_ASSERT(e->kind == Entity_Variable);
if (e->token.string != "") {
GB_ASSERT(!is_blank_ident(e->token));
lbAddr res = {};
if (p->type->Proc.return_by_pointer) {
lbValue ptr = return_ptr_value;
if (results->variables.count != 1) {
ptr = lb_emit_struct_ep(p, ptr, cast(i32)i);
}
res = lb_addr(ptr);
lb_add_entity(p->module, e, ptr);
} else {
res = lb_add_local(p, e->type, e);
}
if (e->Variable.param_value.kind != ParameterValue_Invalid) {
lbValue c = lb_handle_param_value(p, e->type, e->Variable.param_value, e->token.pos);
lb_addr_store(p, res, c);
@@ -4469,53 +4296,30 @@ void lb_build_stmt(lbProcedure *p, Ast *node) {
}
if (p->abi_function_type) {
if (p->abi_function_type->ret.kind == lbArg_Indirect) {
if (res.value != nullptr) {
LLVMBuildStore(p->builder, res.value, p->return_ptr.addr.value);
} else {
LLVMBuildStore(p->builder, LLVMConstNull(p->abi_function_type->ret.type), p->return_ptr.addr.value);
}
lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
LLVMBuildRetVoid(p->builder);
lb_ensure_abi_function_type(p->module, p);
if (p->abi_function_type->ret.kind == lbArg_Indirect) {
if (res.value != nullptr) {
LLVMBuildStore(p->builder, res.value, p->return_ptr.addr.value);
} else {
LLVMValueRef ret_val = res.value;
ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.type);
if (p->abi_function_type->ret.cast_type != nullptr) {
ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.cast_type);
}
lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
LLVMBuildRet(p->builder, ret_val);
LLVMBuildStore(p->builder, LLVMConstNull(p->abi_function_type->ret.type), p->return_ptr.addr.value);
}
lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
LLVMBuildRetVoid(p->builder);
} else {
GB_ASSERT(!USE_LLVM_ABI);
if (p->type->Proc.return_by_pointer) {
if (res.value != nullptr) {
lb_addr_store(p, p->return_ptr, res);
} else {
lb_addr_store(p, p->return_ptr, lb_const_nil(p->module, p->type->Proc.abi_compat_result_type));
}
lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
LLVMBuildRetVoid(p->builder);
} else {
GB_ASSERT_MSG(res.value != nullptr, "%.*s", LIT(p->name));
Type *abi_rt = p->type->Proc.abi_compat_result_type;
if (!are_types_identical(res.type, abi_rt)) {
res = lb_emit_transmute(p, res, abi_rt);
}
lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
LLVMBuildRet(p->builder, res.value);
LLVMValueRef ret_val = res.value;
ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.type);
if (p->abi_function_type->ret.cast_type != nullptr) {
ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.cast_type);
}
lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
LLVMBuildRet(p->builder, ret_val);
}
case_end;
case_ast_node(is, IfStmt, node);
@@ -7279,8 +7083,7 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr,
LLVMBasicBlockRef curr_block = LLVMGetInsertBlock(p->builder);
GB_ASSERT(curr_block != p->decl_block->block);
if (USE_LLVM_ABI) {
{
LLVMTypeRef ftp = lb_type(p->module, value.type);
LLVMTypeRef ft = LLVMGetElementType(ftp);
LLVMValueRef fn = value.value;
@@ -7295,13 +7098,6 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr,
res.value = ret;
res.type = abi_rt;
return res;
} else {
LLVMValueRef ret = LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(p->module, value.type)), value.value, args, arg_count, "");;
lbValue res = {};
res.value = ret;
res.type = abi_rt;
return res;
}
}
@@ -7362,7 +7158,7 @@ lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args,
auto processed_args = array_make<lbValue>(permanent_allocator(), 0, args.count);
if (USE_LLVM_ABI) {
{
lbFunctionType **ft_found = nullptr;
ft_found = map_get(&m->function_type_map, hash_type(pt));
if (!ft_found) {
@@ -7455,95 +7251,6 @@ lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args,
lb_emit_call_internal(p, value, {}, processed_args, nullptr, context_ptr, inlining);
}
} else {
for (isize i = 0; i < param_count; i++) {
Entity *e = pt->Proc.params->Tuple.variables[i];
if (e->kind != Entity_Variable) {
// array_add(&processed_args, args[i]);
continue;
}
GB_ASSERT(e->flags & EntityFlag_Param);
Type *original_type = e->type;
Type *new_type = pt->Proc.abi_compat_params[i];
Type *arg_type = args[i].type;
if (are_types_identical(arg_type, new_type)) {
// NOTE(bill): Done
array_add(&processed_args, args[i]);
} else if (!are_types_identical(original_type, new_type)) {
if (is_type_pointer(new_type) && !is_type_pointer(original_type)) {
Type *av = core_type(type_deref(new_type));
if (are_types_identical(av, core_type(original_type))) {
if (e->flags&EntityFlag_ImplicitReference) {
array_add(&processed_args, lb_address_from_load_or_generate_local(p, args[i]));
} else if (!is_type_pointer(arg_type)) {
array_add(&processed_args, lb_copy_value_to_ptr(p, args[i], original_type, 16));
}
} else {
array_add(&processed_args, lb_emit_transmute(p, args[i], new_type));
}
} else if (new_type == t_llvm_bool) {
array_add(&processed_args, lb_emit_conv(p, args[i], new_type));
} else if (is_type_integer(new_type) || is_type_float(new_type) || is_type_boolean(new_type)) {
array_add(&processed_args, lb_emit_transmute(p, args[i], new_type));
} else if (is_type_simd_vector(new_type)) {
array_add(&processed_args, lb_emit_transmute(p, args[i], new_type));
} else if (is_type_tuple(new_type)) {
Type *abi_type = pt->Proc.abi_compat_params[i];
Type *st = struct_type_from_systemv_distribute_struct_fields(abi_type);
lbValue x = {};
i64 st_sz = type_size_of(st);
i64 arg_sz = type_size_of(args[i].type);
if (st_sz == arg_sz) {
x = lb_emit_transmute(p, args[i], st);
} else {
// NOTE(bill): struct{f32, f32, f32} != struct{#simd[2]f32, f32}
GB_ASSERT(st_sz > arg_sz);
lbAddr xx = lb_add_local_generated(p, st, false);
lbValue pp = lb_emit_conv(p, xx.addr, alloc_type_pointer(args[i].type));
lb_emit_store(p, pp, args[i]);
x = lb_addr_load(p, xx);
}
for (isize j = 0; j < new_type->Tuple.variables.count; j++) {
lbValue xx = lb_emit_struct_ev(p, x, cast(i32)j);
array_add(&processed_args, xx);
}
}
} else {
lbValue x = lb_emit_conv(p, args[i], new_type);
array_add(&processed_args, x);
}
}
if (inlining == ProcInlining_none) {
inlining = p->inlining;
}
Type *abi_rt = reduce_tuple_to_single_type(pt->Proc.abi_compat_result_type);
Type *rt = reduce_tuple_to_single_type(results);
if (pt->Proc.return_by_pointer) {
lbValue return_ptr = {};
if (use_return_ptr_hint && p->return_ptr_hint_value.value != nullptr) {
if (are_types_identical(type_deref(p->return_ptr_hint_value.type), rt)) {
return_ptr = p->return_ptr_hint_value;
p->return_ptr_hint_used = true;
}
}
if (return_ptr.value == nullptr) {
lbAddr r = lb_add_local_generated(p, rt, true);
return_ptr = r.addr;
}
GB_ASSERT(is_type_pointer(return_ptr.type));
lb_emit_call_internal(p, value, return_ptr, processed_args, nullptr, context_ptr, inlining);
result = lb_emit_load(p, return_ptr);
} else {
result = lb_emit_call_internal(p, value, {}, processed_args, abi_rt, context_ptr, inlining);
if (abi_rt != rt) {
result = lb_emit_transmute(p, result, rt);
}
}
}
Entity **found = map_get(&p->module->procedure_values, hash_pointer(value.value));

View File

@@ -31,7 +31,7 @@ gb_global Timings global_timings = {0};
#if defined(GB_SYSTEM_OSX)
#include <llvm/Config/llvm-config.h>
#if LLVM_VERSION_MAJOR < 11
#if LLVM_VERSION_MAJOR < 11
#error LLVM Version 11+ is required => "brew install llvm@11"
#endif
#endif
@@ -1844,9 +1844,7 @@ void print_show_unused(Checker *c) {
void enforce_platform_settings(void) {
#if defined(GB_SYSTEM_OSX) && defined(GB_CPU_ARM)
#if defined(USE_NEW_LLVM_ABI_SYSTEM)
build_context.use_llvm_api = true;
#endif
build_context.use_llvm_api = true;
#endif
}