From fb8fa5217d4a5081dacc0a74a786cd2efc964fdb Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 13 Sep 2021 00:58:39 +0100 Subject: [PATCH] Begin minimize `Type` size by replacing `Array` with `Slice` etc --- src/array.cpp | 13 +++++++++ src/check_builtin.cpp | 32 ++++++++++----------- src/check_expr.cpp | 36 +++++++++++++++-------- src/check_type.cpp | 55 +++++++++++++++++++----------------- src/checker.cpp | 39 ++++++++++++++----------- src/llvm_backend.cpp | 6 ++-- src/llvm_backend_const.cpp | 4 +-- src/llvm_backend_expr.cpp | 8 +++--- src/llvm_backend_general.cpp | 2 +- src/llvm_backend_proc.cpp | 4 +-- src/llvm_backend_stmt.cpp | 6 ++-- src/llvm_backend_type.cpp | 4 +-- src/types.cpp | 48 ++++++++++++++++--------------- 13 files changed, 147 insertions(+), 110 deletions(-) diff --git a/src/array.cpp b/src/array.cpp index 90d85563c..521fa91e2 100644 --- a/src/array.cpp +++ b/src/array.cpp @@ -150,6 +150,19 @@ void slice_copy(Slice *slice, Slice const &data, isize offset, isize count +template +gb_inline Slice slice(Slice const &array, isize lo, isize hi) { + GB_ASSERT(0 <= lo && lo <= hi && hi <= array.count); + Slice out = {}; + isize len = hi-lo; + if (len > 0) { + out.data = array.data+lo; + out.count = len; + } + return out; +} + + template void slice_ordered_remove(Slice *array, isize index) { GB_ASSERT(0 <= index && index < array->count); diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 1f3928bd8..1f9eea45d 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -64,13 +64,13 @@ void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name Type *right_type = nullptr; if (x->type->kind == Type_Tuple) { auto const &vars = x->type->Tuple.variables; - auto lhs = array_slice(vars, 0, vars.count-1); + auto lhs = slice(vars, 0, vars.count-1); auto rhs = vars[vars.count-1]; if (lhs.count == 1) { left_type = lhs[0]->type; } else if (lhs.count != 0) { left_type = alloc_type_tuple(); - left_type->Tuple.variables = array_make_from_ptr(lhs.data, lhs.count, lhs.count); + left_type->Tuple.variables = lhs; } right_type = rhs->type; @@ -120,13 +120,13 @@ void check_or_return_split_types(CheckerContext *c, Operand *x, String const &na Type *right_type = nullptr; if (x->type->kind == Type_Tuple) { auto const &vars = x->type->Tuple.variables; - auto lhs = array_slice(vars, 0, vars.count-1); + auto lhs = slice(vars, 0, vars.count-1); auto rhs = vars[vars.count-1]; if (lhs.count == 1) { left_type = lhs[0]->type; } else if (lhs.count != 0) { left_type = alloc_type_tuple(); - left_type->Tuple.variables = array_make_from_ptr(lhs.data, lhs.count, lhs.count); + left_type->Tuple.variables = lhs; } right_type = rhs->type; @@ -1156,12 +1156,12 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 if (is_type_struct(type)) { isize variable_count = type->Struct.fields.count; - array_init(&tuple->Tuple.variables, a, variable_count); + slice_init(&tuple->Tuple.variables, a, variable_count); // TODO(bill): Should I copy each of the entities or is this good enough? gb_memmove_array(tuple->Tuple.variables.data, type->Struct.fields.data, variable_count); } else if (is_type_array(type)) { isize variable_count = cast(isize)type->Array.count; - array_init(&tuple->Tuple.variables, a, variable_count); + slice_init(&tuple->Tuple.variables, a, variable_count); for (isize i = 0; i < variable_count; i++) { tuple->Tuple.variables[i] = alloc_entity_array_elem(nullptr, blank_token, type->Array.elem, cast(i32)i); } @@ -1240,14 +1240,14 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 } else if (is_type_enum(type)) { operand->mode = Addressing_Constant; operand->type = original_type; - operand->value = type->Enum.min_value; + operand->value = *type->Enum.min_value; return true; } else if (is_type_enumerated_array(type)) { Type *bt = base_type(type); GB_ASSERT(bt->kind == Type_EnumeratedArray); operand->mode = Addressing_Constant; operand->type = bt->EnumeratedArray.index; - operand->value = bt->EnumeratedArray.min_value; + operand->value = *bt->EnumeratedArray.min_value; return true; } gbString type_str = type_to_string(original_type); @@ -1414,14 +1414,14 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 } else if (is_type_enum(type)) { operand->mode = Addressing_Constant; operand->type = original_type; - operand->value = type->Enum.max_value; + operand->value = *type->Enum.max_value; return true; } else if (is_type_enumerated_array(type)) { Type *bt = base_type(type); GB_ASSERT(bt->kind == Type_EnumeratedArray); operand->mode = Addressing_Constant; operand->type = bt->EnumeratedArray.index; - operand->value = bt->EnumeratedArray.max_value; + operand->value = *bt->EnumeratedArray.max_value; return true; } gbString type_str = type_to_string(original_type); @@ -1788,8 +1788,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 if (elem == nullptr) { elem = alloc_type_struct(); elem->Struct.scope = s; - elem->Struct.fields = fields; - elem->Struct.tags = array_make(permanent_allocator(), fields.count); + elem->Struct.fields = slice_from_array(fields); + elem->Struct.tags = slice_make(permanent_allocator(), fields.count); elem->Struct.node = dummy_node_struct; type_set_offsets(elem); } @@ -1938,8 +1938,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 if (is_type_array(elem)) { Type *old_array = base_type(elem); soa_struct = alloc_type_struct(); - soa_struct->Struct.fields = array_make(heap_allocator(), cast(isize)old_array->Array.count); - soa_struct->Struct.tags = array_make(heap_allocator(), cast(isize)old_array->Array.count); + soa_struct->Struct.fields = slice_make(heap_allocator(), cast(isize)old_array->Array.count); + soa_struct->Struct.tags = slice_make(heap_allocator(), cast(isize)old_array->Array.count); soa_struct->Struct.node = operand->expr; soa_struct->Struct.soa_kind = StructSoa_Fixed; soa_struct->Struct.soa_elem = elem; @@ -1971,8 +1971,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 Type *old_struct = base_type(elem); soa_struct = alloc_type_struct(); - soa_struct->Struct.fields = array_make(heap_allocator(), old_struct->Struct.fields.count); - soa_struct->Struct.tags = array_make(heap_allocator(), old_struct->Struct.tags.count); + soa_struct->Struct.fields = slice_make(heap_allocator(), old_struct->Struct.fields.count); + soa_struct->Struct.tags = slice_make(heap_allocator(), old_struct->Struct.tags.count); soa_struct->Struct.node = operand->expr; soa_struct->Struct.soa_kind = StructSoa_Fixed; soa_struct->Struct.soa_elem = elem; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 8607ee3cb..69d60d651 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1023,10 +1023,10 @@ bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source, if (poly->EnumeratedArray.count != source->EnumeratedArray.count) { return false; } - if (compare_exact_values(Token_NotEq, poly->EnumeratedArray.min_value, source->EnumeratedArray.min_value)) { + if (compare_exact_values(Token_NotEq, *poly->EnumeratedArray.min_value, *source->EnumeratedArray.min_value)) { return false; } - if (compare_exact_values(Token_NotEq, poly->EnumeratedArray.max_value, source->EnumeratedArray.max_value)) { + if (compare_exact_values(Token_NotEq, *poly->EnumeratedArray.max_value, *source->EnumeratedArray.max_value)) { return false; } return is_polymorphic_type_assignable(c, poly->EnumeratedArray.index, source->EnumeratedArray.index, true, modify_type); @@ -3425,8 +3425,8 @@ bool check_index_value(CheckerContext *c, Type *main_type, bool open_range, Ast if (is_type_enum(index_type)) { Type *bt = base_type(index_type); GB_ASSERT(bt->kind == Type_Enum); - ExactValue lo = bt->Enum.min_value; - ExactValue hi = bt->Enum.max_value; + ExactValue const &lo = *bt->Enum.min_value; + ExactValue const &hi = *bt->Enum.max_value; String lo_str = {}; String hi_str = {}; if (bt->Enum.fields.count > 0) { @@ -3556,7 +3556,7 @@ ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 in if (is_type_enumerated_array(node->tav.type)) { Type *bt = base_type(node->tav.type); GB_ASSERT(bt->kind == Type_EnumeratedArray); - corrected_index = index + exact_value_to_i64(bt->EnumeratedArray.min_value); + corrected_index = index + exact_value_to_i64(*bt->EnumeratedArray.min_value); } if (op != Token_RangeHalf) { if (lo <= corrected_index && corrected_index <= hi) { @@ -3580,7 +3580,7 @@ ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 in if (is_type_enumerated_array(node->tav.type)) { Type *bt = base_type(node->tav.type); GB_ASSERT(bt->kind == Type_EnumeratedArray); - index_value = exact_value_sub(index_value, bt->EnumeratedArray.min_value); + index_value = exact_value_sub(index_value, *bt->EnumeratedArray.min_value); } i64 field_index = exact_value_to_i64(index_value); @@ -3738,6 +3738,18 @@ void check_did_you_mean_type(String const &name, Array const &fields) check_did_you_mean_print(&d); } +void check_did_you_mean_type(String const &name, Slice const &fields) { + ERROR_BLOCK(); + + DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); + defer (did_you_mean_destroy(&d)); + + for_array(i, fields) { + did_you_mean_append(&d, fields[i]->token.string); + } + check_did_you_mean_print(&d); +} + void check_did_you_mean_scope(String const &name, Scope *scope) { ERROR_BLOCK(); @@ -7305,8 +7317,8 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type gbString index_type_str = type_to_string(index_type); defer (gb_string_free(index_type_str)); - i64 total_lo = exact_value_to_i64(t->EnumeratedArray.min_value); - i64 total_hi = exact_value_to_i64(t->EnumeratedArray.max_value); + i64 total_lo = exact_value_to_i64(*t->EnumeratedArray.min_value); + i64 total_hi = exact_value_to_i64(*t->EnumeratedArray.max_value); String total_lo_string = {}; String total_hi_string = {}; @@ -7319,10 +7331,10 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type if (f->kind != Entity_Constant) { continue; } - if (total_lo_string.len == 0 && compare_exact_values(Token_CmpEq, f->Constant.value, t->EnumeratedArray.min_value)) { + if (total_lo_string.len == 0 && compare_exact_values(Token_CmpEq, f->Constant.value, *t->EnumeratedArray.min_value)) { total_lo_string = f->token.string; } - if (total_hi_string.len == 0 && compare_exact_values(Token_CmpEq, f->Constant.value, t->EnumeratedArray.max_value)) { + if (total_hi_string.len == 0 && compare_exact_values(Token_CmpEq, f->Constant.value, *t->EnumeratedArray.max_value)) { total_hi_string = f->token.string; } if (total_lo_string.len != 0 && total_hi_string.len != 0) { @@ -8472,13 +8484,13 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type Type *params = alloc_type_tuple(); Type *results = alloc_type_tuple(); if (param_types.count != 0) { - array_init(¶ms->Tuple.variables, heap_allocator(), param_types.count); + slice_init(¶ms->Tuple.variables, heap_allocator(), param_types.count); for_array(i, param_types) { params->Tuple.variables[i] = alloc_entity_param(scope, blank_token, param_types[i], false, true); } } if (return_type != nullptr) { - array_init(&results->Tuple.variables, heap_allocator(), 1); + slice_init(&results->Tuple.variables, heap_allocator(), 1); results->Tuple.variables[0] = alloc_entity_param(scope, blank_token, return_type, false, true); } diff --git a/src/check_type.cpp b/src/check_type.cpp index 3541eef61..2c9f589c7 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -92,10 +92,10 @@ bool does_field_type_allow_using(Type *t) { return false; } -void check_struct_fields(CheckerContext *ctx, Ast *node, Array *fields, Array *tags, Slice const ¶ms, +void check_struct_fields(CheckerContext *ctx, Ast *node, Slice *fields, Slice *tags, Slice const ¶ms, isize init_field_capacity, Type *struct_type, String context) { - *fields = array_make(heap_allocator(), 0, init_field_capacity); - *tags = array_make(heap_allocator(), 0, init_field_capacity); + auto fields_array = array_make(heap_allocator(), 0, init_field_capacity); + auto tags_array = array_make(heap_allocator(), 0, init_field_capacity); GB_ASSERT(node->kind == Ast_StructType); GB_ASSERT(struct_type->kind == Type_Struct); @@ -153,20 +153,20 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Array *fields Entity *field = alloc_entity_field(ctx->scope, name_token, type, is_using, field_src_index); add_entity(ctx, ctx->scope, name, field); - array_add(fields, field); + array_add(&fields_array, field); String tag = p->tag.string; if (tag.len != 0 && !unquote_string(permanent_allocator(), &tag, 0, tag.text[0] == '`')) { error(p->tag, "Invalid string literal"); tag = {}; } - array_add(tags, tag); + array_add(&tags_array, tag); field_src_index += 1; } if (is_using && p->names.count > 0) { - Type *first_type = (*fields)[fields->count-1]->type; + Type *first_type = fields_array[fields_array.count-1]->type; Type *t = base_type(type_deref(first_type)); if (!does_field_type_allow_using(t) && @@ -182,6 +182,9 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Array *fields populate_using_entity_scope(ctx, node, p, type); } } + + *fields = slice_from_array(fields_array); + *tags = slice_from_array(tags_array); } @@ -498,7 +501,7 @@ Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_para if (entities.count > 0) { Type *tuple = alloc_type_tuple(); - tuple->Tuple.variables = entities; + tuple->Tuple.variables = slice_from_array(entities); polymorphic_params_type = tuple; } } @@ -816,8 +819,8 @@ void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast enum_type->Enum.fields = fields; enum_type->Enum.names = make_names_field_for_struct(ctx, ctx->scope); - enum_type->Enum.min_value = min_value; - enum_type->Enum.max_value = max_value; + *enum_type->Enum.min_value = min_value; + *enum_type->Enum.max_value = max_value; enum_type->Enum.min_value_index = min_value_index; enum_type->Enum.max_value_index = max_value_index; @@ -1705,7 +1708,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is } Type *tuple = alloc_type_tuple(); - tuple->Tuple.variables = variables; + tuple->Tuple.variables = slice_from_array(variables); if (success_) *success_ = success; if (specialization_count_) *specialization_count_ = specialization_count; @@ -1815,7 +1818,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { } } - tuple->Tuple.variables = variables; + tuple->Tuple.variables = slice_from_array(variables); return tuple; } @@ -2059,7 +2062,7 @@ i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) { Type *make_optional_ok_type(Type *value, bool typed) { gbAllocator a = permanent_allocator(); Type *t = alloc_type_tuple(); - array_init(&t->Tuple.variables, a, 2); + slice_init(&t->Tuple.variables, a, 2); t->Tuple.variables[0] = alloc_entity_field(nullptr, blank_token, value, false, 0); t->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, typed ? t_bool : t_untyped_bool, false, 1); return t; @@ -2083,11 +2086,11 @@ void init_map_entry_type(Type *type) { */ Scope *s = create_scope(nullptr, builtin_pkg->scope); - auto fields = array_make(permanent_allocator(), 0, 4); - array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("hash")), t_uintptr, false, cast(i32)fields.count, EntityState_Resolved)); - array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("next")), t_int, false, cast(i32)fields.count, EntityState_Resolved)); - array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("key")), type->Map.key, false, cast(i32)fields.count, EntityState_Resolved)); - array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("value")), type->Map.value, false, cast(i32)fields.count, EntityState_Resolved)); + auto fields = slice_make(permanent_allocator(), 4); + fields[0] = alloc_entity_field(s, make_token_ident(str_lit("hash")), t_uintptr, false, cast(i32)fields.count, EntityState_Resolved); + fields[1] = alloc_entity_field(s, make_token_ident(str_lit("next")), t_int, false, cast(i32)fields.count, EntityState_Resolved); + fields[2] = alloc_entity_field(s, make_token_ident(str_lit("key")), type->Map.key, false, cast(i32)fields.count, EntityState_Resolved); + fields[3] = alloc_entity_field(s, make_token_ident(str_lit("value")), type->Map.value, false, cast(i32)fields.count, EntityState_Resolved); entry_type->Struct.fields = fields; @@ -2120,9 +2123,9 @@ void init_map_internal_types(Type *type) { Type *entries_type = alloc_type_dynamic_array(type->Map.entry_type); - auto fields = array_make(permanent_allocator(), 0, 2); - array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("hashes")), hashes_type, false, 0, EntityState_Resolved)); - array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("entries")), entries_type, false, 1, EntityState_Resolved)); + auto fields = slice_make(permanent_allocator(), 2); + fields[0] = alloc_entity_field(s, make_token_ident(str_lit("hashes")), hashes_type, false, 0, EntityState_Resolved); + fields[1] = alloc_entity_field(s, make_token_ident(str_lit("entries")), entries_type, false, 1, EntityState_Resolved); generated_struct_type->Struct.fields = fields; @@ -2239,8 +2242,8 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el field_count = 0; soa_struct = alloc_type_struct(); - soa_struct->Struct.fields = array_make(heap_allocator(), field_count+extra_field_count); - soa_struct->Struct.tags = array_make(heap_allocator(), field_count+extra_field_count); + soa_struct->Struct.fields = slice_make(heap_allocator(), field_count+extra_field_count); + soa_struct->Struct.tags = slice_make(heap_allocator(), field_count+extra_field_count); soa_struct->Struct.node = array_typ_expr; soa_struct->Struct.soa_kind = soa_kind; soa_struct->Struct.soa_elem = elem; @@ -2254,8 +2257,8 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el field_count = cast(isize)old_array->Array.count; soa_struct = alloc_type_struct(); - soa_struct->Struct.fields = array_make(heap_allocator(), field_count+extra_field_count); - soa_struct->Struct.tags = array_make(heap_allocator(), field_count+extra_field_count); + soa_struct->Struct.fields = slice_make(heap_allocator(), field_count+extra_field_count); + soa_struct->Struct.tags = slice_make(heap_allocator(), field_count+extra_field_count); soa_struct->Struct.node = array_typ_expr; soa_struct->Struct.soa_kind = soa_kind; soa_struct->Struct.soa_elem = elem; @@ -2296,8 +2299,8 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el GB_ASSERT(old_struct->Struct.tags.count == field_count); soa_struct = alloc_type_struct(); - soa_struct->Struct.fields = array_make(heap_allocator(), field_count+extra_field_count); - soa_struct->Struct.tags = array_make(heap_allocator(), field_count+extra_field_count); + soa_struct->Struct.fields = slice_make(heap_allocator(), field_count+extra_field_count); + soa_struct->Struct.tags = slice_make(heap_allocator(), field_count+extra_field_count); soa_struct->Struct.node = array_typ_expr; soa_struct->Struct.soa_kind = soa_kind; soa_struct->Struct.soa_elem = elem; diff --git a/src/checker.cpp b/src/checker.cpp index 5544ef58e..8d85784fa 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4865,22 +4865,25 @@ void check_deferred_procedures(Checker *c) { Entity *dst = src->Procedure.deferred_procedure.entity; GB_ASSERT(dst != nullptr); GB_ASSERT(dst->kind == Entity_Procedure); + + char const *attribute = "deferred_none"; + switch (dst_kind) { + case DeferredProcedure_none: + attribute = "deferred_none"; + break; + case DeferredProcedure_in: + attribute = "deferred_in"; + break; + case DeferredProcedure_out: + attribute = "deferred_out"; + break; + case DeferredProcedure_in_out: + attribute = "deferred_in_out"; + break; + } if (is_type_polymorphic(src->type) || is_type_polymorphic(dst->type)) { - switch (dst_kind) { - case DeferredProcedure_none: - error(src->token, "'deferred_none' cannot be used with a polymorphic procedure"); - break; - case DeferredProcedure_in: - error(src->token, "'deferred_in' cannot be used with a polymorphic procedure"); - break; - case DeferredProcedure_out: - error(src->token, "'deferred_out' cannot be used with a polymorphic procedure"); - break; - case DeferredProcedure_in_out: - error(src->token, "'deferred_in_out' cannot be used with a polymorphic procedure"); - break; - } + error(src->token, "'%s' cannot be used with a polymorphic procedure", attribute); continue; } @@ -4974,17 +4977,19 @@ void check_deferred_procedures(Checker *c) { GB_ASSERT(src_results->kind == Type_Tuple); len += src_results->Tuple.variables.count; } - array_init(&sv, heap_allocator(), 0, len); + slice_init(&sv, heap_allocator(), len); + isize offset = 0; if (src_params != nullptr) { for_array(i, src_params->Tuple.variables) { - array_add(&sv, src_params->Tuple.variables[i]); + sv[offset++] = src_params->Tuple.variables[i]; } } if (src_results != nullptr) { for_array(i, src_results->Tuple.variables) { - array_add(&sv, src_results->Tuple.variables[i]); + sv[offset++] = src_results->Tuple.variables[i]; } } + GB_ASSERT(offset == len); if (are_types_identical(tsrc, dst_params)) { diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 5fff3c486..3e8498776 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -761,7 +761,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime) if (build_context.metrics.os == TargetOs_windows && build_context.build_mode == BuildMode_DynamicLibrary) { is_dll_main = true; name = str_lit("DllMain"); - array_init(¶ms->Tuple.variables, permanent_allocator(), 3); + slice_init(¶ms->Tuple.variables, permanent_allocator(), 3); params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("hinstDLL"), t_rawptr, false, true); params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("fdwReason"), t_u32, false, true); params->Tuple.variables[2] = alloc_entity_param(nullptr, make_token_ident("lpReserved"), t_rawptr, false, true); @@ -769,12 +769,12 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime) name = str_lit("mainCRTStartup"); } else { has_args = true; - array_init(¶ms->Tuple.variables, permanent_allocator(), 2); + slice_init(¶ms->Tuple.variables, permanent_allocator(), 2); params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("argc"), t_i32, false, true); params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("argv"), t_ptr_cstring, false, true); } - array_init(&results->Tuple.variables, permanent_allocator(), 1); + slice_init(&results->Tuple.variables, permanent_allocator(), 1); results->Tuple.variables[0] = alloc_entity_param(nullptr, blank_token, t_i32, false, true); Type *proc_type = alloc_type_proc(nullptr, diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 5ad2b09b6..d46992976 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -690,8 +690,8 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc isize value_index = 0; - i64 total_lo = exact_value_to_i64(type->EnumeratedArray.min_value); - i64 total_hi = exact_value_to_i64(type->EnumeratedArray.max_value); + i64 total_lo = exact_value_to_i64(*type->EnumeratedArray.min_value); + i64 total_hi = exact_value_to_i64(*type->EnumeratedArray.max_value); for (i64 i = total_lo; i <= total_hi; i++) { bool found = false; diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index a4b4564c0..efd0eaf40 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -2872,13 +2872,13 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { auto index_tv = type_and_value_of_expr(ie->index); lbValue index = {}; - if (compare_exact_values(Token_NotEq, t->EnumeratedArray.min_value, exact_value_i64(0))) { + if (compare_exact_values(Token_NotEq, *t->EnumeratedArray.min_value, exact_value_i64(0))) { if (index_tv.mode == Addressing_Constant) { - ExactValue idx = exact_value_sub(index_tv.value, t->EnumeratedArray.min_value); + ExactValue idx = exact_value_sub(index_tv.value, *t->EnumeratedArray.min_value); index = lb_const_value(p->module, index_type, idx); } else { index = lb_emit_conv(p, lb_build_expr(p, ie->index), t_int); - index = lb_emit_arith(p, Token_Sub, index, lb_const_value(p->module, index_type, t->EnumeratedArray.min_value), index_type); + index = lb_emit_arith(p, Token_Sub, index, lb_const_value(p->module, index_type, *t->EnumeratedArray.min_value), index_type); } } else { index = lb_emit_conv(p, lb_build_expr(p, ie->index), t_int); @@ -3472,7 +3472,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { } - i32 index_offset = cast(i32)exact_value_to_i64(bt->EnumeratedArray.min_value); + i32 index_offset = cast(i32)exact_value_to_i64(*bt->EnumeratedArray.min_value); for_array(i, temp_data) { i32 index = temp_data[i].elem_index - index_offset; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 113c9ba62..f481c122e 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -1670,7 +1670,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { LLVMTypeRef *fields = gb_alloc_array(permanent_allocator(), LLVMTypeRef, field_count); i64 alignment = type_align_of(type); unsigned size_of_union = cast(unsigned)type_size_of(type); - fields[0] = lb_alignment_prefix_type_hack(m, alignment); + fields[0] = lb_alignment_prefix_type_hack(m, gb_min(alignment, 16)); fields[1] = LLVMArrayType(lb_type(m, t_u8), size_of_union); return LLVMStructTypeInContext(ctx, fields, field_count, false); } diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index ffbb532f0..ce6807571 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1393,7 +1393,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, Type *res_type = nullptr; gbAllocator a = permanent_allocator(); res_type = alloc_type_tuple(); - array_init(&res_type->Tuple.variables, a, 2); + slice_init(&res_type->Tuple.variables, a, 2); res_type->Tuple.variables[0] = alloc_entity_field(nullptr, blank_token, type, false, 0); res_type->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1); @@ -1738,7 +1738,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, if (tv.type->kind == Type_Tuple) { Type *fix_typed = alloc_type_tuple(); - array_init(&fix_typed->Tuple.variables, permanent_allocator(), 2); + slice_init(&fix_typed->Tuple.variables, permanent_allocator(), 2); fix_typed->Tuple.variables[0] = tv.type->Tuple.variables[0]; fix_typed->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1); diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 148790ac6..ac922b642 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -332,8 +332,8 @@ void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValu val = lb_emit_load(p, lb_emit_array_ep(p, expr, idx)); // NOTE(bill): Override the idx value for the enumeration Type *index_type = expr_type->EnumeratedArray.index; - if (compare_exact_values(Token_NotEq, expr_type->EnumeratedArray.min_value, exact_value_u64(0))) { - idx = lb_emit_arith(p, Token_Add, idx, lb_const_value(m, index_type, expr_type->EnumeratedArray.min_value), index_type); + if (compare_exact_values(Token_NotEq, *expr_type->EnumeratedArray.min_value, exact_value_u64(0))) { + idx = lb_emit_arith(p, Token_Add, idx, lb_const_value(m, index_type, *expr_type->EnumeratedArray.min_value), index_type); } } break; @@ -984,7 +984,7 @@ void lb_build_unroll_range_stmt(lbProcedure *p, AstUnrollRangeStmt *rs, Scope *s lb_addr_store(p, val0_addr, lb_emit_load(p, elem)); } if (val1_type) { - ExactValue idx = exact_value_add(exact_value_i64(i), t->EnumeratedArray.min_value); + ExactValue idx = exact_value_add(exact_value_i64(i), *t->EnumeratedArray.min_value); lb_addr_store(p, val1_addr, lb_const_value(m, val1_type, idx)); } diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index af3fadc3c..f5665c718 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -450,8 +450,8 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da lbValue min_value = lb_emit_struct_ep(p, tag, 4); lbValue max_value = lb_emit_struct_ep(p, tag, 5); - lbValue min_v = lb_const_value(m, t_i64, t->EnumeratedArray.min_value); - lbValue max_v = lb_const_value(m, t_i64, t->EnumeratedArray.max_value); + lbValue min_v = lb_const_value(m, t_i64, *t->EnumeratedArray.min_value); + lbValue max_v = lb_const_value(m, t_i64, *t->EnumeratedArray.max_value); lb_emit_store(p, min_value, min_v); lb_emit_store(p, max_value, max_v); diff --git a/src/types.cpp b/src/types.cpp index 37a05d5a6..4362ae45b 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -129,9 +129,9 @@ enum StructSoaKind { }; struct TypeStruct { - Array fields; - Array tags; - Array offsets; + Slice fields; + Slice tags; + Slice offsets; Ast * node; Scope * scope; @@ -145,12 +145,12 @@ struct TypeStruct { i64 soa_count; StructSoaKind soa_kind; - bool are_offsets_set; - bool are_offsets_being_processed; - bool is_packed; - bool is_raw_union; bool is_polymorphic; - bool is_poly_specialized; + bool are_offsets_set : 1; + bool are_offsets_being_processed : 1; + bool is_packed : 1; + bool is_raw_union : 1; + bool is_poly_specialized : 1; }; struct TypeUnion { @@ -216,8 +216,8 @@ struct TypeProc { TYPE_KIND(EnumeratedArray, struct { \ Type *elem; \ Type *index; \ - ExactValue min_value; \ - ExactValue max_value; \ + ExactValue *min_value; \ + ExactValue *max_value; \ i64 count; \ TokenKind op; \ }) \ @@ -239,14 +239,14 @@ struct TypeProc { Scope * scope; \ Entity * names; \ Type * base_type; \ - ExactValue min_value; \ - ExactValue max_value; \ + ExactValue *min_value; \ + ExactValue *max_value; \ isize min_value_index; \ isize max_value_index; \ }) \ TYPE_KIND(Tuple, struct { \ - Array variables; /* Entity_Variable */ \ - Array offsets; \ + Slice variables; /* Entity_Variable */ \ + Slice offsets; \ bool are_offsets_being_processed; \ bool are_offsets_set; \ bool is_packed; \ @@ -803,15 +803,17 @@ Type *alloc_type_array(Type *elem, i64 count, Type *generic_count = nullptr) { return t; } -Type *alloc_type_enumerated_array(Type *elem, Type *index, ExactValue min_value, ExactValue max_value, TokenKind op) { +Type *alloc_type_enumerated_array(Type *elem, Type *index, ExactValue const *min_value, ExactValue const *max_value, TokenKind op) { Type *t = alloc_type(Type_EnumeratedArray); t->EnumeratedArray.elem = elem; t->EnumeratedArray.index = index; - t->EnumeratedArray.min_value = min_value; - t->EnumeratedArray.max_value = max_value; + t->EnumeratedArray.min_value = gb_alloc_item(permanent_allocator(), ExactValue); + t->EnumeratedArray.max_value = gb_alloc_item(permanent_allocator(), ExactValue); + gb_memmove(t->EnumeratedArray.min_value, min_value, gb_size_of(ExactValue)); + gb_memmove(t->EnumeratedArray.max_value, max_value, gb_size_of(ExactValue)); t->EnumeratedArray.op = op; - t->EnumeratedArray.count = 1 + exact_value_to_i64(exact_value_sub(max_value, min_value)); + t->EnumeratedArray.count = 1 + exact_value_to_i64(exact_value_sub(*max_value, *min_value)); return t; } @@ -841,6 +843,8 @@ Type *alloc_type_union() { Type *alloc_type_enum() { Type *t = alloc_type(Type_Enum); + t->Enum.min_value = gb_alloc_item(permanent_allocator(), ExactValue); + t->Enum.max_value = gb_alloc_item(permanent_allocator(), ExactValue); return t; } @@ -3080,9 +3084,9 @@ i64 type_align_of_internal(Type *t, TypePath *path) { return gb_clamp(next_pow2(type_size_of_internal(t, path)), 1, build_context.word_size); } -Array type_set_offsets_of(Array const &fields, bool is_packed, bool is_raw_union) { +Slice type_set_offsets_of(Slice const &fields, bool is_packed, bool is_raw_union) { gbAllocator a = permanent_allocator(); - auto offsets = array_make(a, fields.count); + auto offsets = slice_make(a, fields.count); i64 curr_offset = 0; if (is_raw_union) { for_array(i, fields) { @@ -3463,7 +3467,7 @@ Type *reduce_tuple_to_single_type(Type *original_type) { Type *alloc_type_struct_from_field_types(Type **field_types, isize field_count, bool is_packed) { Type *t = alloc_type_struct(); - t->Struct.fields = array_make(heap_allocator(), field_count); + t->Struct.fields = slice_make(heap_allocator(), field_count); Scope *scope = nullptr; for_array(i, t->Struct.fields) { @@ -3483,7 +3487,7 @@ Type *alloc_type_tuple_from_field_types(Type **field_types, isize field_count, b } Type *t = alloc_type_tuple(); - t->Tuple.variables = array_make(heap_allocator(), field_count); + t->Tuple.variables = slice_make(heap_allocator(), field_count); Scope *scope = nullptr; for_array(i, t->Tuple.variables) {