diff options
| author | gingerBill <gingerBill@users.noreply.github.com> | 2026-01-30 10:49:55 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-30 10:49:55 +0000 |
| commit | 19b545e7cb0b09a7c8b3424ca8276b9e37f8de80 (patch) | |
| tree | 974b844bf082c526f6a12396c4a80adfc73b9a60 /src/llvm_backend_proc.cpp | |
| parent | 8b745c3909a3482aebe27998d8b870286e448e35 (diff) | |
| parent | 5a21213fa5e2c74d5021adb2a87f0cc441a38eab (diff) | |
Merge branch 'master' into bill/feature-using-stmt
Diffstat (limited to 'src/llvm_backend_proc.cpp')
| -rw-r--r-- | src/llvm_backend_proc.cpp | 65 |
1 files changed, 45 insertions, 20 deletions
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 27167aefd..837d7ce48 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -12,9 +12,9 @@ gb_internal void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue sr len = lb_emit_conv(p, len, t_int); char const *name = "llvm.memmove"; - if (LLVMIsConstant(len.value)) { + if (!p->is_startup && LLVMIsConstant(len.value)) { i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value); - if (const_len <= 4*build_context.int_size) { + if (const_len <= lb_max_zero_init_size()) { name = "llvm.memmove.inline"; } } @@ -41,9 +41,9 @@ gb_internal void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValu len = lb_emit_conv(p, len, t_int); char const *name = "llvm.memcpy"; - if (LLVMIsConstant(len.value)) { + if (!p->is_startup && LLVMIsConstant(len.value)) { i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value); - if (const_len <= 4*build_context.int_size) { + if (const_len <= lb_max_zero_init_size()) { name = "llvm.memcpy.inline"; } } @@ -117,6 +117,7 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i p->type_expr = decl->type_expr; p->body = pl->body; p->inlining = pl->inlining; + p->tailing = pl->tailing; p->is_foreign = entity->Procedure.is_foreign; p->is_export = entity->Procedure.is_export; p->is_entry_point = false; @@ -152,6 +153,10 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i 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 (build_context.disable_unwind) { + lb_add_attribute_to_proc(m, p->value, "nounwind"); + } + if (pt->Proc.diverging) { lb_add_attribute_to_proc(m, p->value, "noreturn"); } @@ -346,7 +351,7 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i if (build_context.sanitizer_flags & SanitizerFlag_Memory && !entity->Procedure.no_sanitize_memory) { lb_add_attribute_to_proc(m, p->value, "sanitize_memory"); } - if (build_context.sanitizer_flags & SanitizerFlag_Thread) { + if (build_context.sanitizer_flags & SanitizerFlag_Thread && !entity->Procedure.no_sanitize_thread) { lb_add_attribute_to_proc(m, p->value, "sanitize_thread"); } } @@ -387,6 +392,7 @@ gb_internal lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name p->body = nullptr; p->tags = 0; p->inlining = ProcInlining_none; + p->tailing = ProcTailing_none; p->is_foreign = false; p->is_export = false; p->is_entry_point = false; @@ -855,7 +861,7 @@ gb_internal Array<lbValue> lb_value_to_array(lbProcedure *p, gbAllocator const & -gb_internal lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr, Array<lbValue> const &processed_args, Type *abi_rt, lbAddr context_ptr, ProcInlining inlining) { +gb_internal lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr, Array<lbValue> const &processed_args, Type *abi_rt, lbAddr context_ptr, ProcInlining inlining, ProcTailing tailing) { GB_ASSERT(p->module->ctx == LLVMGetTypeContext(LLVMTypeOf(value.value))); unsigned arg_count = cast(unsigned)processed_args.count; @@ -972,6 +978,15 @@ gb_internal lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue break; } + switch (tailing) { + case ProcTailing_none: + break; + case ProcTailing_must_tail: + LLVMSetTailCall(ret, true); + LLVMSetTailCallKind(ret, LLVMTailCallKindMustTail); + break; + } + lbValue res = {}; res.value = ret; res.type = abi_rt; @@ -1045,7 +1060,7 @@ gb_internal lbValue lb_emit_conjugate(lbProcedure *p, lbValue val, Type *type) { return lb_emit_load(p, res); } -gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining) { +gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining, ProcTailing tailing) { lbModule *m = p->module; Type *pt = base_type(value.type); @@ -1168,10 +1183,10 @@ gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> c if (return_by_pointer) { lbValue return_ptr = lb_add_local_generated(p, rt, true).addr; - lb_emit_call_internal(p, value, return_ptr, processed_args, nullptr, context_ptr, inlining); + lb_emit_call_internal(p, value, return_ptr, processed_args, nullptr, context_ptr, inlining, tailing); result = lb_emit_load(p, return_ptr); } else if (rt != nullptr) { - result = lb_emit_call_internal(p, value, {}, processed_args, rt, context_ptr, inlining); + result = lb_emit_call_internal(p, value, {}, processed_args, rt, context_ptr, inlining, tailing); if (ft->ret.cast_type) { result.value = OdinLLVMBuildTransmute(p, result.value, ft->ret.cast_type); } @@ -1184,7 +1199,7 @@ gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> c result = lb_emit_conv(p, result, rt); } } else { - lb_emit_call_internal(p, value, {}, processed_args, nullptr, context_ptr, inlining); + lb_emit_call_internal(p, value, {}, processed_args, nullptr, context_ptr, inlining, tailing); } if (original_rt != rt) { @@ -1212,15 +1227,6 @@ gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> c } tuple_fix_values[ret_count-1] = result; - #if 0 - for (isize j = 0; j < ret_count; j++) { - tuple_geps[j] = lb_emit_struct_ep(p, result_ptr, cast(i32)j); - } - for (isize j = 0; j < ret_count; j++) { - lb_emit_store(p, tuple_geps[j], tuple_fix_values[j]); - } - #endif - result = lb_emit_load(p, result_ptr); lbTupleFix tf = {tuple_fix_values}; @@ -4411,6 +4417,25 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { return lb_handle_objc_auto_send(p, expr, slice(call_args, 0, call_args.count)); } - return lb_emit_call(p, value, call_args, ce->inlining); + + ProcInlining inlining = ce->inlining; + ProcTailing tailing = ce->tailing; + + if (tailing == ProcTailing_none && + proc_entity && proc_entity->kind == Entity_Procedure && + proc_entity->decl_info && + proc_entity->decl_info->proc_lit) { + ast_node(pl, ProcLit, proc_entity->decl_info->proc_lit); + + if (pl->inlining != ProcInlining_none) { + inlining = pl->inlining; + } + + if (pl->tailing != ProcTailing_none) { + tailing = pl->tailing; + } + } + + return lb_emit_call(p, value, call_args, inlining, tailing); } |