aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2024-07-14 12:39:30 +0100
committergingerBill <bill@gingerbill.org>2024-07-14 12:39:30 +0100
commit3dff83f3dc2914cdfb9a8f19cf990682cda41b03 (patch)
tree216cbef3e900ba3d4291d7a49c03e61cf9b748ac /src
parent8642d719f0ece3625d535d47b41ff4d35072f47f (diff)
Mock out `#no_capture` for future use
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.cpp13
-rw-r--r--src/check_type.cpp32
-rw-r--r--src/checker.cpp2
-rw-r--r--src/checker.hpp4
-rw-r--r--src/llvm_abi.cpp6
-rw-r--r--src/llvm_backend.hpp4
-rw-r--r--src/llvm_backend_proc.cpp32
7 files changed, 54 insertions, 39 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 645d8ac5a..4edd34990 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -6034,19 +6034,18 @@ gb_internal CallArgumentError check_call_arguments_internal(CheckerContext *c, A
Entity *vt = pt->params->Tuple.variables[pt->variadic_index];
o.type = vt->type;
- // NOTE(bill, 2024-07-14): minimize the stack usage for variadic parameter that use `#no_capture`
- // on the variadic parameter
- if (c->decl && (vt->flags & EntityFlag_NoCapture)) {
+ // NOTE(bill, 2024-07-14): minimize the stack usage for variadic parameters with the backing array
+ if (c->decl) {
bool found = false;
- for (NoCaptureData &nc : c->decl->no_captures) {
- if (are_types_identical(vt->type, nc.slice_type)) {
- nc.max_count = gb_max(nc.max_count, variadic_operands.count);
+ for (auto &vr : c->decl->variadic_reuses) {
+ if (are_types_identical(vt->type, vr.slice_type)) {
+ vr.max_count = gb_max(vr.max_count, variadic_operands.count);
found = true;
break;
}
}
if (!found) {
- array_add(&c->decl->no_captures, NoCaptureData{vt->type, variadic_operands.count});
+ array_add(&c->decl->variadic_reuses, VariadicReuseData{vt->type, variadic_operands.count});
}
}
diff --git a/src/check_type.cpp b/src/check_type.cpp
index 466b9b3cd..7b75bf503 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -1954,7 +1954,7 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para
p->flags &= ~FieldFlag_by_ptr;
}
if (p->flags&FieldFlag_no_capture) {
- error(name, "'#no_capture' can only be applied to variable variadic fields");
+ error(name, "'#no_capture' can only be applied to variable fields");
p->flags &= ~FieldFlag_no_capture;
}
@@ -2059,16 +2059,32 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para
}
}
if (p->flags&FieldFlag_no_capture) {
- if (!(is_variadic && variadic_index == variables.count)) {
- error(name, "'#no_capture' can only be applied to a variadic parameter");
- p->flags &= ~FieldFlag_no_capture;
- } else if (p->flags & FieldFlag_c_vararg) {
- error(name, "'#no_capture' cannot be applied to a #c_vararg parameter");
- p->flags &= ~FieldFlag_no_capture;
+ if (is_variadic && variadic_index == variables.count) {
+ if (p->flags & FieldFlag_c_vararg) {
+ error(name, "'#no_capture' cannot be applied to a #c_vararg parameter");
+ p->flags &= ~FieldFlag_no_capture;
+ } else {
+ error(name, "'#no_capture' is already implied on all variadic parameter");
+ }
+ } else if (is_type_polymorphic(type)) {
+ // ignore
} else {
- error(name, "'#no_capture' is already implied on all variadic parameter");
+ if (is_type_internally_pointer_like(type)) {
+ // okay
+ } else if (is_type_slice(type) || is_type_string(type)) {
+ // okay
+ } else if (is_type_dynamic_array(type)) {
+ // okay
+ } else {
+ ERROR_BLOCK();
+ error(name, "'#no_capture' can only be applied to pointer-like types, slices, strings, and dynamic arrays");
+ error_line("\t'#no_capture' does not currently do anything useful\n");
+ p->flags &= ~FieldFlag_no_capture;
+ }
}
}
+
+
if (is_poly_name) {
if (p->flags&FieldFlag_no_alias) {
error(name, "'#no_alias' can only be applied to non constant values");
diff --git a/src/checker.cpp b/src/checker.cpp
index abacc13cb..9adf4ef3c 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -184,7 +184,7 @@ gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) {
ptr_set_init(&d->deps, 0);
ptr_set_init(&d->type_info_deps, 0);
d->labels.allocator = heap_allocator();
- d->no_captures.allocator = heap_allocator();
+ d->variadic_reuses.allocator = heap_allocator();
}
gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) {
diff --git a/src/checker.hpp b/src/checker.hpp
index 17722f6b6..2fadbe56a 100644
--- a/src/checker.hpp
+++ b/src/checker.hpp
@@ -181,7 +181,7 @@ char const *ProcCheckedState_strings[ProcCheckedState_COUNT] {
"Checked",
};
-struct NoCaptureData {
+struct VariadicReuseData {
Type *slice_type; // ..elem_type
isize max_count;
};
@@ -224,7 +224,7 @@ struct DeclInfo {
Array<BlockLabel> labels;
- Array<NoCaptureData> no_captures;
+ Array<VariadicReuseData> variadic_reuses;
// NOTE(bill): this is to prevent a race condition since these procedure literals can be created anywhere at any time
struct lbModule *code_gen_module;
diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp
index b2e485d01..9a3479b34 100644
--- a/src/llvm_abi.cpp
+++ b/src/llvm_abi.cpp
@@ -15,6 +15,7 @@ struct lbArgType {
LLVMAttributeRef align_attribute; // Optional
i64 byval_alignment;
bool is_byval;
+ bool no_capture;
};
@@ -159,6 +160,11 @@ gb_internal void lb_add_function_type_attributes(LLVMValueRef fn, lbFunctionType
LLVMAddAttributeAtIndex(fn, arg_index+1, arg->align_attribute);
}
+ if (arg->no_capture) {
+ LLVMAddAttributeAtIndex(fn, arg_index+1, nocapture_attr);
+ }
+
+
if (ft->multiple_return_original_type) {
if (ft->original_arg_count <= i) {
LLVMAddAttributeAtIndex(fn, arg_index+1, noalias_attr);
diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp
index 71fa1dbd0..24494e2af 100644
--- a/src/llvm_backend.hpp
+++ b/src/llvm_backend.hpp
@@ -296,7 +296,7 @@ enum lbProcedureFlag : u32 {
lbProcedureFlag_DebugAllocaCopy = 1<<1,
};
-struct lbNoCaptureData {
+struct lbVariadicReuseData {
Type *slice_type;
lbAddr base_array;
};
@@ -341,7 +341,7 @@ struct lbProcedure {
bool in_multi_assignment;
Array<LLVMValueRef> raw_input_parameters;
- Array<lbNoCaptureData> no_captures;
+ Array<lbVariadicReuseData> variadic_reuses;
LLVMValueRef temp_callee_return_struct_memory;
Ast *curr_stmt;
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index ec244e185..1585df865 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -517,7 +517,7 @@ gb_internal void lb_begin_procedure_body(lbProcedure *p) {
lb_start_block(p, p->entry_block);
map_init(&p->direct_parameters);
- p->no_captures.allocator = heap_allocator();
+ p->variadic_reuses.allocator = heap_allocator();
GB_ASSERT(p->type != nullptr);
@@ -3452,28 +3452,22 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) {
isize slice_len = var_args.count;
if (slice_len > 0) {
lbAddr base_array = {};
- if (e->flags & EntityFlag_NoCapture) {
- for (lbNoCaptureData const &nc : p->no_captures) {
- if (are_types_identical(nc.slice_type, slice_type)) {
- base_array = nc.base_array;
- break;
- }
+ for (auto const &vr : p->variadic_reuses) {
+ if (are_types_identical(vr.slice_type, slice_type)) {
+ base_array = vr.base_array;
+ break;
}
- DeclInfo *d = decl_info_of_entity(p->entity);
- if (d != nullptr && base_array.addr.value == nullptr) {
- for (NoCaptureData const &nc : d->no_captures) {
- if (are_types_identical(nc.slice_type, slice_type)) {
- base_array = lb_add_local_generated(p, alloc_type_array(elem_type, nc.max_count), true);
- array_add(&p->no_captures, lbNoCaptureData{slice_type, base_array});
- break;
- }
+ }
+ DeclInfo *d = decl_info_of_entity(p->entity);
+ if (d != nullptr && base_array.addr.value == nullptr) {
+ for (auto const &vr : d->variadic_reuses) {
+ if (are_types_identical(vr.slice_type, slice_type)) {
+ base_array = lb_add_local_generated(p, alloc_type_array(elem_type, vr.max_count), true);
+ array_add(&p->variadic_reuses, lbVariadicReuseData{slice_type, base_array});
+ break;
}
}
}
-
- if (base_array.addr.value == nullptr) {
- base_array = lb_add_local_generated(p, alloc_type_array(elem_type, slice_len), true);
- }
GB_ASSERT(base_array.addr.value != nullptr);
lbAddr slice = lb_add_local_generated(p, slice_type, true);