aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-02-03 15:07:44 +0000
committergingerBill <bill@gingerbill.org>2023-02-03 15:07:44 +0000
commitde0a3e0ab986f6ea9c73315a8405103a4e147bb8 (patch)
tree888bd539c7954c4972b3ff25c803d98765ef5b03 /src
parentd26110da7f0757dc4d6cc4e2da6bb3d95d97e96b (diff)
Minor change to `byval` for readonly parameters
Diffstat (limited to 'src')
-rw-r--r--src/llvm_backend.cpp6
-rw-r--r--src/llvm_backend.hpp1
-rw-r--r--src/llvm_backend_proc.cpp15
-rw-r--r--src/llvm_backend_utility.cpp39
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);