From c4033c215e01343709a0d7928c277a6425f53524 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 25 Jul 2023 14:37:19 +0100 Subject: [PATCH] Support non-constant global slices --- src/tilde.cpp | 25 ++++++++++++--------- src/tilde.hpp | 3 +++ src/tilde_const.cpp | 8 ++++++- src/tilde_expr.cpp | 55 ++++++++++++++++++++++++++++++++++++++------- src/tilde_proc.cpp | 7 ++++-- 5 files changed, 77 insertions(+), 21 deletions(-) diff --git a/src/tilde.cpp b/src/tilde.cpp index 6cd8a42af..64fe70ec4 100644 --- a/src/tilde.cpp +++ b/src/tilde.cpp @@ -694,22 +694,14 @@ gb_internal bool cg_generate_code(Checker *c, LinkerData *linker_data) { Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_Odin); cgProcedure *p = cg_procedure_create_dummy(m, str_lit(CG_STARTUP_RUNTIME_PROC_NAME), proc_type); p->is_startup = true; - - cg_procedure_begin(p); - cg_global_variables_initialize(p, &global_variables); - - tb_inst_ret(p->func, 0, nullptr); - cg_procedure_end(p); + cg_startup_runtime_proc = p; } if (true) { Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_Odin); cgProcedure *p = cg_procedure_create_dummy(m, str_lit(CG_CLEANUP_RUNTIME_PROC_NAME), proc_type); p->is_startup = true; - - cg_procedure_begin(p); - tb_inst_ret(p->func, 0, nullptr); - cg_procedure_end(p); + cg_cleanup_runtime_proc = p; } auto *min_dep_set = &info->minimum_dependency_set; @@ -741,6 +733,19 @@ gb_internal bool cg_generate_code(Checker *c, LinkerData *linker_data) { array_add(&procedures_to_generate, p); } } + { + cgProcedure *p = cg_startup_runtime_proc; + cg_procedure_begin(p); + cg_global_variables_initialize(p, &global_variables); + tb_inst_ret(p->func, 0, nullptr); + cg_procedure_end(p); + } + { + cgProcedure *p = cg_cleanup_runtime_proc; + cg_procedure_begin(p); + tb_inst_ret(p->func, 0, nullptr); + cg_procedure_end(p); + } for (cgProcedure *p : procedures_to_generate) { cg_add_procedure_to_queue(p); diff --git a/src/tilde.hpp b/src/tilde.hpp index 087655d83..72d5048bb 100644 --- a/src/tilde.hpp +++ b/src/tilde.hpp @@ -257,6 +257,9 @@ gb_global GlobalTypeInfoData cg_global_type_info_member_usings = {}; gb_global GlobalTypeInfoData cg_global_type_info_member_tags = {}; gb_global GlobalTypeInfoData cg_global_type_info_member_enum_values = {}; +gb_global cgProcedure *cg_startup_runtime_proc = nullptr; +gb_global cgProcedure *cg_cleanup_runtime_proc = nullptr; + gb_internal TB_Arena *cg_arena(void); diff --git a/src/tilde_const.cpp b/src/tilde_const.cpp index d37edb89a..5b34480f4 100644 --- a/src/tilde_const.cpp +++ b/src/tilde_const.cpp @@ -555,11 +555,11 @@ gb_internal bool cg_global_const_add_region(cgModule *m, ExactValue const &value return true; } - GB_ASSERT(!is_type_array_like(bt)); switch (value.kind) { case ExactValue_Bool: { + GB_ASSERT_MSG(!is_type_array_like(bt), "%s", type_to_string(type)); bool *res = cast(bool *)tb_global_add_region(m->mod, global, offset, size); *res = !!value.value_bool; } @@ -567,6 +567,7 @@ gb_internal bool cg_global_const_add_region(cgModule *m, ExactValue const &value case ExactValue_Integer: { + GB_ASSERT_MSG(!is_type_array_like(bt), "%s", type_to_string(type)); void *res = tb_global_add_region(m->mod, global, offset, size); cg_write_big_int_at_ptr(res, &value.value_integer, type); } @@ -574,6 +575,7 @@ gb_internal bool cg_global_const_add_region(cgModule *m, ExactValue const &value case ExactValue_Float: { + GB_ASSERT_MSG(!is_type_array_like(bt), "%s", type_to_string(type)); f64 f = exact_value_to_f64(value); void *res = tb_global_add_region(m->mod, global, offset, size); switch (size) { @@ -586,6 +588,7 @@ gb_internal bool cg_global_const_add_region(cgModule *m, ExactValue const &value case ExactValue_Pointer: { + GB_ASSERT_MSG(!is_type_array_like(bt), "%s", type_to_string(type)); void *res = tb_global_add_region(m->mod, global, offset, size); *(u64 *)res = exact_value_to_u64(value); } @@ -603,6 +606,7 @@ gb_internal bool cg_global_const_add_region(cgModule *m, ExactValue const &value case ExactValue_Typeid: { + GB_ASSERT_MSG(!is_type_array_like(bt), "%s", type_to_string(type)); void *dst = tb_global_add_region(m->mod, global, offset, size); u64 id = cg_typeid_as_u64(m, value.value_typeid); cg_write_uint_at_ptr(dst, id, t_typeid); @@ -621,6 +625,7 @@ gb_internal bool cg_global_const_add_region(cgModule *m, ExactValue const &value break; case ExactValue_Complex: { + GB_ASSERT_MSG(!is_type_array_like(bt), "%s", type_to_string(type)); Complex128 c = {}; if (value.value_complex) { c = *value.value_complex; @@ -644,6 +649,7 @@ gb_internal bool cg_global_const_add_region(cgModule *m, ExactValue const &value break; case ExactValue_Quaternion: { + GB_ASSERT_MSG(!is_type_array_like(bt), "%s", type_to_string(type)); // @QuaternionLayout Quaternion256 q = {}; if (value.value_quaternion) { diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp index 4caf33ccf..96f17bfcf 100644 --- a/src/tilde_expr.cpp +++ b/src/tilde_expr.cpp @@ -86,6 +86,39 @@ gb_internal cgValue cg_find_value_from_entity(cgModule *m, Entity *e) { return {}; } +gb_internal cgValue cg_get_using_variable(cgProcedure *p, Entity *e) { + GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Using); + String name = e->token.string; + Entity *parent = e->using_parent; + Selection sel = lookup_field(parent->type, name, false); + GB_ASSERT(sel.entity != nullptr); + cgValue *pv = map_get(&p->module->values, parent); + + cgValue v = {}; + + if (pv == nullptr && parent->flags & EntityFlag_SoaPtrField) { + // NOTE(bill): using SOA value (probably from for-in statement) + GB_PANIC("TODO(bill): cg_get_soa_variable_addr"); + // cgAddr parent_addr = cg_get_soa_variable_addr(p, parent); + // v = cg_addr_get_ptr(p, parent_addr); + } else if (pv != nullptr) { + v = *pv; + } else { + GB_ASSERT_MSG(e->using_expr != nullptr, "%.*s %.*s", LIT(e->token.string), LIT(name)); + v = cg_build_addr_ptr(p, e->using_expr); + } + GB_ASSERT(v.node != nullptr); + GB_ASSERT_MSG(parent->type == type_deref(v.type), "%s %s", type_to_string(parent->type), type_to_string(v.type)); + cgValue ptr = cg_emit_deep_field_gep(p, v, sel); + // if (parent->scope) { + // if ((parent->scope->flags & (ScopeFlag_File|ScopeFlag_Pkg)) == 0) { + // cg_add_debug_local_variable(p, ptr.value, e->type, e->token); + // } + // } else { + // cg_add_debug_local_variable(p, ptr.value, e->type, e->token); + // } + return ptr; +} gb_internal cgAddr cg_build_addr_from_entity(cgProcedure *p, Entity *e, Ast *expr) { GB_ASSERT(e != nullptr); if (e->kind == Entity_Constant) { @@ -111,9 +144,8 @@ gb_internal cgAddr cg_build_addr_from_entity(cgProcedure *p, Entity *e, Ast *exp if (found) { v = *found; } else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) { - GB_PANIC("TODO(bill): cg_get_using_variable"); // NOTE(bill): Calculate the using variable every time - // v = cg_get_using_variable(p, e); + v = cg_get_using_variable(p, e); } else if (e->flags & EntityFlag_SoaPtrField) { GB_PANIC("TODO(bill): cg_get_soa_variable_addr"); // return cg_get_soa_variable_addr(p, e); @@ -434,11 +466,10 @@ gb_internal cgValue cg_emit_comp(cgProcedure *p, TokenKind op_kind, cgValue left } GB_ASSERT(runtime_procedure != nullptr); - GB_PANIC("TODO(bill): cg_emit_runtime_call"); - // auto args = array_make(permanent_allocator(), 2); - // args[0] = left; - // args[1] = right; - // return cg_emit_runtime_call(p, runtime_procedure, args); + auto args = slice_make(permanent_allocator(), 2); + args[0] = left; + args[1] = right; + return cg_emit_runtime_call(p, runtime_procedure, args); } if (is_type_complex(a)) { @@ -2514,7 +2545,15 @@ cgAddr cg_build_addr_compound_lit(cgProcedure *p, Ast *expr) { TB_CharUnits backing_size = cast(TB_CharUnits)(type_size_of(bt->Slice.elem) * count); TB_CharUnits align = cast(TB_CharUnits)type_align_of(bt->Slice.elem); - TB_Node *backing = tb_inst_local(p->func, backing_size, align); + + TB_Node *backing = nullptr; + if (p->is_startup) { + TB_Global *global = tb_global_create(p->module->mod, 0, "", nullptr, TB_LINKAGE_PRIVATE); + tb_global_set_storage(p->module->mod, tb_module_get_data(p->module->mod), global, backing_size, align, 0); + backing = tb_inst_get_symbol_address(p->func, cast(TB_Symbol *)global); + } else { + backing = tb_inst_local(p->func, backing_size, align); + } cgValue data = cg_value(backing, alloc_type_multi_pointer(bt->Slice.elem)); diff --git a/src/tilde_proc.cpp b/src/tilde_proc.cpp index 3a0624583..80948adea 100644 --- a/src/tilde_proc.cpp +++ b/src/tilde_proc.cpp @@ -408,8 +408,11 @@ gb_internal void cg_procedure_end(cgProcedure *p) { return; } if (tb_inst_get_control(p->func)) { - GB_ASSERT(p->type->Proc.result_count == 0); - tb_inst_ret(p->func, 0, nullptr); + if (p->type->Proc.result_count == 0) { + tb_inst_ret(p->func, 0, nullptr); + } else { + tb_inst_unreachable(p->func); + } } if (p->module->do_threading) {