aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/llvm_backend.cpp')
-rw-r--r--src/llvm_backend.cpp501
1 files changed, 104 insertions, 397 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index 41a56c312..59d5847dd 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -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;
- }
- 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);
- }
- }
+ 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);
- 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);
+ 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);
}
- 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;
}
- } else {
- LLVMTypeRef old_abi_fn_type = nullptr;
-
- 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);
- }
+ }
- 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;
+ 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 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));
- }
+ Type *e_type = reduce_tuple_to_single_type(e->type);
- 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;
@@ -2609,80 +2510,6 @@ void lb_begin_procedure_body(lbProcedure *p) {
}
}
}
- } 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);
- }
- }
- }
- }
}
if (p->type->Proc.calling_convention == ProcCC_Odin) {
Entity *e = alloc_entity_param(nullptr, make_token_ident(str_lit("__.context_ptr")), t_context_ptr, false, false);
@@ -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);
}
- } 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));
+ lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
- 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);
+ LLVMBuildRetVoid(p->builder);
+ } 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);
}
+
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));