From 737b8e42e4b2c5c0aa94da2aed37c9d9634ce866 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 20 Jul 2023 00:48:52 +0100 Subject: [PATCH] Global constants for arrays --- src/tilde_const.cpp | 103 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 93 insertions(+), 10 deletions(-) diff --git a/src/tilde_const.cpp b/src/tilde_const.cpp index d89e43c2f..dcacefdb0 100644 --- a/src/tilde_const.cpp +++ b/src/tilde_const.cpp @@ -253,10 +253,10 @@ gb_internal isize cg_global_const_calculate_region_count(ExactValue const &value case ExactValue_Compound: { ast_node(cl, CompoundLit, value.value_compound); Type *bt = base_type(type); - if (bt->kind == Type_Struct) { + switch (bt->kind) { + case Type_Struct: if (cl->elems[0]->kind == Ast_FieldValue) { - isize elem_count = cl->elems.count; - for (isize i = 0; i < elem_count; i++) { + for (isize i = 0; i < cl->elems.count; i++) { ast_node(fv, FieldValue, cl->elems[i]); String name = fv->field->Ident.token.string; @@ -314,8 +314,44 @@ gb_internal isize cg_global_const_calculate_region_count(ExactValue const &value count += cg_global_const_calculate_region_count(value, type); } } - } else { + break; + case Type_Array: + if (!cg_elem_type_can_be_constant(bt->Array.elem)) { + break; + } + for (Ast *elem : cl->elems) { + if (elem->kind == Ast_FieldValue) { + ast_node(fv, FieldValue, elem); + ExactValue const &value = elem->FieldValue.value->tav.value; + if (is_ast_range(fv->field)) { + ast_node(ie, BinaryExpr, fv->field); + TypeAndValue lo_tav = ie->left->tav; + TypeAndValue hi_tav = ie->right->tav; + GB_ASSERT(lo_tav.mode == Addressing_Constant); + GB_ASSERT(hi_tav.mode == Addressing_Constant); + + TokenKind op = ie->op.kind; + i64 lo = exact_value_to_i64(lo_tav.value); + i64 hi = exact_value_to_i64(hi_tav.value); + if (op != Token_RangeHalf) { + hi += 1; + } + + for (i64 i = lo; i < hi; i++) { + count += cg_global_const_calculate_region_count(value, bt->Array.elem); + } + } else { + count += cg_global_const_calculate_region_count(value, bt->Array.elem); + } + } else { + ExactValue const &value = elem->tav.value; + count += cg_global_const_calculate_region_count(value, bt->Array.elem); + } + } + break; + default: GB_PANIC("TODO(bill): %s", type_to_string(type)); + break; } }break; } @@ -479,9 +515,13 @@ gb_internal TB_Global *cg_global_const_comp_literal(cgModule *m, Type *original_ gb_printf_err("global_region_count %td\n", global_region_count); } + if (cl->elems.count == 0) { + return global; + } Type *bt = base_type(original_type); - if (bt->kind == Type_Struct) { + switch (bt->kind) { + case Type_Struct: if (cl->elems[0]->kind == Ast_FieldValue) { isize elem_count = cl->elems.count; for (isize i = 0; i < elem_count; i++) { @@ -500,9 +540,7 @@ gb_internal TB_Global *cg_global_const_comp_literal(cgModule *m, Type *original_ } i64 offset = type_offset_of_from_selection(bt, sel); - if (cg_global_const_add_region(m, global, value, sel.entity->type, base_offset+offset)) { - continue; - } + cg_global_const_add_region(m, global, value, sel.entity->type, base_offset+offset); } } else { for_array(i, cl->elems) { @@ -520,10 +558,55 @@ gb_internal TB_Global *cg_global_const_comp_literal(cgModule *m, Type *original_ if (tav.mode != Addressing_Invalid) { value = tav.value; } - if (cg_global_const_add_region(m, global, value, f->type, base_offset+offset)) { - continue; + cg_global_const_add_region(m, global, value, f->type, base_offset+offset); + } + } + return global; + + case Type_Array: + if (cl->elems[0]->kind == Ast_FieldValue) { + Type *et = bt->Array.elem; + i64 elem_size = type_size_of(et); + for (Ast *elem : cl->elems) { + ast_node(fv, FieldValue, elem); + + ExactValue const &value = fv->value->tav.value; + + if (is_ast_range(fv->field)) { + ast_node(ie, BinaryExpr, fv->field); + TypeAndValue lo_tav = ie->left->tav; + TypeAndValue hi_tav = ie->right->tav; + GB_ASSERT(lo_tav.mode == Addressing_Constant); + GB_ASSERT(hi_tav.mode == Addressing_Constant); + + TokenKind op = ie->op.kind; + i64 lo = exact_value_to_i64(lo_tav.value); + i64 hi = exact_value_to_i64(hi_tav.value); + if (op != Token_RangeHalf) { + hi += 1; + } + + for (i64 i = lo; i < hi; i++) { + i64 offset = i * elem_size; + cg_global_const_add_region(m, global, value, et, base_offset+offset); + } + } else { + TypeAndValue index_tav = fv->field->tav; + GB_ASSERT(index_tav.mode == Addressing_Constant); + i64 i = exact_value_to_i64(index_tav.value); + i64 offset = i * elem_size; + cg_global_const_add_region(m, global, value, et, base_offset+offset); } } + } else { + Type *et = bt->Array.elem; + i64 elem_size = type_size_of(et); + i64 offset = 0; + for (Ast *elem : cl->elems) { + ExactValue const &value = elem->tav.value; + cg_global_const_add_region(m, global, value, et, base_offset+offset); + offset += elem_size; + } } return global;