diff options
| author | gingerBill <bill@gingerbill.org> | 2023-02-03 15:07:44 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2023-02-03 15:07:44 +0000 |
| commit | de0a3e0ab986f6ea9c73315a8405103a4e147bb8 (patch) | |
| tree | 888bd539c7954c4972b3ff25c803d98765ef5b03 /src | |
| parent | d26110da7f0757dc4d6cc4e2da6bb3d95d97e96b (diff) | |
Minor change to `byval` for readonly parameters
Diffstat (limited to 'src')
| -rw-r--r-- | src/llvm_backend.cpp | 6 | ||||
| -rw-r--r-- | src/llvm_backend.hpp | 1 | ||||
| -rw-r--r-- | src/llvm_backend_proc.cpp | 15 | ||||
| -rw-r--r-- | src/llvm_backend_utility.cpp | 39 |
4 files changed, 56 insertions, 5 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index b22d7c9a2..34c1ec9b4 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -495,11 +495,11 @@ gb_internal lbValue lb_map_get_proc_for_type(lbModule *m, Type *type) { lb_add_proc_attribute_at_index(p, 1+0, "nonnull"); lb_add_proc_attribute_at_index(p, 1+0, "noalias"); - // lb_add_proc_attribute_at_index(p, 1+0, "readonly"); + lb_add_proc_attribute_at_index(p, 1+0, "readonly"); lb_add_proc_attribute_at_index(p, 1+2, "nonnull"); lb_add_proc_attribute_at_index(p, 1+2, "noalias"); - // lb_add_proc_attribute_at_index(p, 1+2, "readonly"); + lb_add_proc_attribute_at_index(p, 1+2, "readonly"); lbBlock *loop_block = lb_create_block(p, "loop"); lbBlock *hash_block = lb_create_block(p, "hash"); @@ -599,6 +599,8 @@ gb_internal lbValue lb_map_get_proc_for_type(lbModule *m, Type *type) { LLVMBuildRet(p->builder, res.value); } + gb_printf_err("%s\n", LLVMPrintValueToString(p->value)); + return {p->value, p->type}; } diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index e151d2be1..7bf287b49 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -325,6 +325,7 @@ struct lbProcedure { lbTargetList * target_list; PtrMap<Entity *, lbValue> direct_parameters; bool in_multi_assignment; + Array<LLVMValueRef> raw_input_parameters; Ast *curr_stmt; diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 89a59de62..c1cbff048 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -538,6 +538,10 @@ gb_internal void lb_begin_procedure_body(lbProcedure *p) { if (p->type->Proc.params != nullptr) { TypeTuple *params = &p->type->Proc.params->Tuple; + unsigned raw_input_parameters_count = LLVMCountParams(p->value); + p->raw_input_parameters = array_make<LLVMValueRef>(permanent_allocator(), raw_input_parameters_count); + LLVMGetParams(p->value, p->raw_input_parameters.data); + unsigned param_index = 0; for_array(i, params->variables) { Entity *e = params->variables[i]; @@ -1028,9 +1032,14 @@ gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> c } else if (arg->kind == lbArg_Indirect) { lbValue ptr = {}; if (arg->is_byval) { - if (is_odin_cc && are_types_identical(original_type, t_source_code_location)) { - ptr = lb_address_from_load_or_generate_local(p, x); - } else { + if (is_odin_cc) { + if (are_types_identical(original_type, t_source_code_location)) { + ptr = lb_address_from_load_or_generate_local(p, x); + } else { + ptr = lb_address_from_load_if_readonly_parameter(p, x); + } + } + if (ptr.value == nullptr) { ptr = lb_copy_value_to_ptr(p, x, original_type, arg->byval_alignment); } } else if (is_odin_cc) { diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index dbed32b82..a4ef61531 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -868,6 +868,45 @@ gb_internal lbValue lb_address_from_load(lbProcedure *p, lbValue value) { return {}; } +gb_internal lbValue lb_address_from_load_if_readonly_parameter(lbProcedure *p, lbValue x) { + if (!LLVMIsALoadInst(x.value)) { + return {}; + } + + LLVMValueRef optr = LLVMGetOperand(x.value, 0); + while (optr && LLVMIsABitCastInst(optr)) { + optr = LLVMGetOperand(optr, 0); + } + LLVMAttributeIndex param_index = 1; + if (p->return_ptr.addr.value) { + param_index++; + } + + bool is_parameter = false; + for (LLVMValueRef param : p->raw_input_parameters) { + if (param == optr) { + is_parameter = true; + break; + } + param_index++; + } + if (is_parameter) { + unsigned readonly_attr_kind = LLVMGetEnumAttributeKindForName("readonly", 8); + unsigned n = LLVMGetAttributeCountAtIndex(p->value, param_index); + if (n) { + TEMPORARY_ALLOCATOR_GUARD(); + LLVMAttributeRef *attrs = gb_alloc_array(temporary_allocator(), LLVMAttributeRef, n); + LLVMGetAttributesAtIndex(p->value, param_index, attrs); + for (unsigned i = 0; i < n; i++) { + if (LLVMGetEnumAttributeKind(attrs[i]) == readonly_attr_kind) { + return lb_address_from_load_or_generate_local(p, x); + } + } + } + } + return {}; +} + gb_internal lbStructFieldRemapping lb_get_struct_remapping(lbModule *m, Type *t) { t = base_type(t); |