From b36a81ef535b55afa3630eda6ff0b94f77f6c11e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 5 Dec 2024 10:44:53 +0000 Subject: [PATCH] ABI change: for indirect parameters size_of <= 16, do callee stack copy --- src/build_settings.cpp | 1 + src/llvm_backend_proc.cpp | 19 +++++++++++++++++++ src/main.cpp | 5 +++++ 3 files changed, 25 insertions(+) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 50fae93b8..15cc4f71d 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -467,6 +467,7 @@ struct BuildContext { BuildCacheData build_cache_data; bool internal_no_inline; + bool internal_by_value; bool no_threaded_checker; diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 5aee5b639..fee825a2f 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -579,6 +579,8 @@ gb_internal void lb_begin_procedure_body(lbProcedure *p) { p->raw_input_parameters = array_make(permanent_allocator(), raw_input_parameters_count); LLVMGetParams(p->value, p->raw_input_parameters.data); + bool is_odin_cc = is_calling_convention_odin(ft->calling_convention); + unsigned param_index = 0; for_array(i, params->variables) { Entity *e = params->variables[i]; @@ -613,9 +615,26 @@ gb_internal void lb_begin_procedure_body(lbProcedure *p) { } } else if (arg_type->kind == lbArg_Indirect) { if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) { + i64 sz = type_size_of(e->type); + bool do_callee_copy = false; + + if (is_odin_cc) { + do_callee_copy = sz <= 16; + if (build_context.internal_by_value) { + do_callee_copy = true; + } + } + lbValue ptr = {}; ptr.value = LLVMGetParam(p->value, param_offset+param_index); ptr.type = alloc_type_pointer(e->type); + + if (do_callee_copy) { + lbValue new_ptr = lb_add_local_generated(p, e->type, false).addr; + lb_mem_copy_non_overlapping(p, new_ptr, ptr, lb_const_int(p->module, t_uint, sz)); + ptr = new_ptr; + } + lb_add_entity(p->module, e, ptr); lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1, p->decl_block); } diff --git a/src/main.cpp b/src/main.cpp index 015269438..4d85a9e72 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -401,6 +401,7 @@ enum BuildFlagKind { BuildFlag_InternalModulePerFile, BuildFlag_InternalCached, BuildFlag_InternalNoInline, + BuildFlag_InternalByValue, BuildFlag_Tilde, @@ -612,6 +613,7 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_InternalModulePerFile, str_lit("internal-module-per-file"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_InternalCached, str_lit("internal-cached"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_InternalNoInline, str_lit("internal-no-inline"), BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_InternalByValue, str_lit("internal-by-value"), BuildFlagParam_None, Command_all); #if ALLOW_TILDE add_flag(&build_flags, BuildFlag_Tilde, str_lit("tilde"), BuildFlagParam_None, Command__does_build); @@ -1508,6 +1510,9 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_InternalNoInline: build_context.internal_no_inline = true; break; + case BuildFlag_InternalByValue: + build_context.internal_by_value = true; + break; case BuildFlag_Tilde: build_context.tilde_backend = true;