mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-03 14:18:47 +00:00
Mock out #no_capture for future use
This commit is contained in:
+6
-7
@@ -6034,19 +6034,18 @@ gb_internal CallArgumentError check_call_arguments_internal(CheckerContext *c, A
|
|||||||
Entity *vt = pt->params->Tuple.variables[pt->variadic_index];
|
Entity *vt = pt->params->Tuple.variables[pt->variadic_index];
|
||||||
o.type = vt->type;
|
o.type = vt->type;
|
||||||
|
|
||||||
// NOTE(bill, 2024-07-14): minimize the stack usage for variadic parameter that use `#no_capture`
|
// NOTE(bill, 2024-07-14): minimize the stack usage for variadic parameters with the backing array
|
||||||
// on the variadic parameter
|
if (c->decl) {
|
||||||
if (c->decl && (vt->flags & EntityFlag_NoCapture)) {
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (NoCaptureData &nc : c->decl->no_captures) {
|
for (auto &vr : c->decl->variadic_reuses) {
|
||||||
if (are_types_identical(vt->type, nc.slice_type)) {
|
if (are_types_identical(vt->type, vr.slice_type)) {
|
||||||
nc.max_count = gb_max(nc.max_count, variadic_operands.count);
|
vr.max_count = gb_max(vr.max_count, variadic_operands.count);
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
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});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+24
-8
@@ -1954,7 +1954,7 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para
|
|||||||
p->flags &= ~FieldFlag_by_ptr;
|
p->flags &= ~FieldFlag_by_ptr;
|
||||||
}
|
}
|
||||||
if (p->flags&FieldFlag_no_capture) {
|
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;
|
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 (p->flags&FieldFlag_no_capture) {
|
||||||
if (!(is_variadic && variadic_index == variables.count)) {
|
if (is_variadic && variadic_index == variables.count) {
|
||||||
error(name, "'#no_capture' can only be applied to a variadic parameter");
|
if (p->flags & FieldFlag_c_vararg) {
|
||||||
p->flags &= ~FieldFlag_no_capture;
|
error(name, "'#no_capture' cannot be applied to a #c_vararg parameter");
|
||||||
} else if (p->flags & FieldFlag_c_vararg) {
|
p->flags &= ~FieldFlag_no_capture;
|
||||||
error(name, "'#no_capture' cannot be applied to a #c_vararg parameter");
|
} else {
|
||||||
p->flags &= ~FieldFlag_no_capture;
|
error(name, "'#no_capture' is already implied on all variadic parameter");
|
||||||
|
}
|
||||||
|
} else if (is_type_polymorphic(type)) {
|
||||||
|
// ignore
|
||||||
} else {
|
} 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 (is_poly_name) {
|
||||||
if (p->flags&FieldFlag_no_alias) {
|
if (p->flags&FieldFlag_no_alias) {
|
||||||
error(name, "'#no_alias' can only be applied to non constant values");
|
error(name, "'#no_alias' can only be applied to non constant values");
|
||||||
|
|||||||
+1
-1
@@ -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->deps, 0);
|
||||||
ptr_set_init(&d->type_info_deps, 0);
|
ptr_set_init(&d->type_info_deps, 0);
|
||||||
d->labels.allocator = heap_allocator();
|
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) {
|
gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) {
|
||||||
|
|||||||
+2
-2
@@ -181,7 +181,7 @@ char const *ProcCheckedState_strings[ProcCheckedState_COUNT] {
|
|||||||
"Checked",
|
"Checked",
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NoCaptureData {
|
struct VariadicReuseData {
|
||||||
Type *slice_type; // ..elem_type
|
Type *slice_type; // ..elem_type
|
||||||
isize max_count;
|
isize max_count;
|
||||||
};
|
};
|
||||||
@@ -224,7 +224,7 @@ struct DeclInfo {
|
|||||||
|
|
||||||
Array<BlockLabel> labels;
|
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
|
// 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;
|
struct lbModule *code_gen_module;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ struct lbArgType {
|
|||||||
LLVMAttributeRef align_attribute; // Optional
|
LLVMAttributeRef align_attribute; // Optional
|
||||||
i64 byval_alignment;
|
i64 byval_alignment;
|
||||||
bool is_byval;
|
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);
|
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->multiple_return_original_type) {
|
||||||
if (ft->original_arg_count <= i) {
|
if (ft->original_arg_count <= i) {
|
||||||
LLVMAddAttributeAtIndex(fn, arg_index+1, noalias_attr);
|
LLVMAddAttributeAtIndex(fn, arg_index+1, noalias_attr);
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ enum lbProcedureFlag : u32 {
|
|||||||
lbProcedureFlag_DebugAllocaCopy = 1<<1,
|
lbProcedureFlag_DebugAllocaCopy = 1<<1,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lbNoCaptureData {
|
struct lbVariadicReuseData {
|
||||||
Type *slice_type;
|
Type *slice_type;
|
||||||
lbAddr base_array;
|
lbAddr base_array;
|
||||||
};
|
};
|
||||||
@@ -341,7 +341,7 @@ struct lbProcedure {
|
|||||||
bool in_multi_assignment;
|
bool in_multi_assignment;
|
||||||
Array<LLVMValueRef> raw_input_parameters;
|
Array<LLVMValueRef> raw_input_parameters;
|
||||||
|
|
||||||
Array<lbNoCaptureData> no_captures;
|
Array<lbVariadicReuseData> variadic_reuses;
|
||||||
|
|
||||||
LLVMValueRef temp_callee_return_struct_memory;
|
LLVMValueRef temp_callee_return_struct_memory;
|
||||||
Ast *curr_stmt;
|
Ast *curr_stmt;
|
||||||
|
|||||||
+13
-19
@@ -517,7 +517,7 @@ gb_internal void lb_begin_procedure_body(lbProcedure *p) {
|
|||||||
lb_start_block(p, p->entry_block);
|
lb_start_block(p, p->entry_block);
|
||||||
|
|
||||||
map_init(&p->direct_parameters);
|
map_init(&p->direct_parameters);
|
||||||
p->no_captures.allocator = heap_allocator();
|
p->variadic_reuses.allocator = heap_allocator();
|
||||||
|
|
||||||
GB_ASSERT(p->type != nullptr);
|
GB_ASSERT(p->type != nullptr);
|
||||||
|
|
||||||
@@ -3452,27 +3452,21 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) {
|
|||||||
isize slice_len = var_args.count;
|
isize slice_len = var_args.count;
|
||||||
if (slice_len > 0) {
|
if (slice_len > 0) {
|
||||||
lbAddr base_array = {};
|
lbAddr base_array = {};
|
||||||
if (e->flags & EntityFlag_NoCapture) {
|
for (auto const &vr : p->variadic_reuses) {
|
||||||
for (lbNoCaptureData const &nc : p->no_captures) {
|
if (are_types_identical(vr.slice_type, slice_type)) {
|
||||||
if (are_types_identical(nc.slice_type, slice_type)) {
|
base_array = vr.base_array;
|
||||||
base_array = nc.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;
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
GB_ASSERT(base_array.addr.value != nullptr);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user