From 55733171c19aa53aebbe343d7541c3c5a1597c46 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 17 Jul 2023 23:16:50 +0100 Subject: [PATCH] Planning for multi-valued expressions in the tilde backend --- src/tilde_backend.cpp | 13 +++++++++++++ src/tilde_backend.hpp | 9 +++++++++ src/tilde_expr.cpp | 4 ++++ src/tilde_proc.cpp | 9 ++++----- src/tilde_stmt.cpp | 15 +++++++++++++++ 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/tilde_backend.cpp b/src/tilde_backend.cpp index 00e665b62..97f2dcccd 100644 --- a/src/tilde_backend.cpp +++ b/src/tilde_backend.cpp @@ -118,7 +118,20 @@ gb_internal cgValue cg_lvalue_addr(TB_Node *node, Type *type) { return v; } +gb_internal cgValue cg_value_multi(cgValueMultiNodes *multi_nodes, Type *type) { + GB_ASSERT(type->kind == Type_Tuple); + GB_ASSERT(multi_nodes != nullptr); + GB_ASSERT(type->Tuple.variables.count > 1); + GB_ASSERT(multi_nodes->nodes.count == type->Tuple.variables.count); + cgValue v = {}; + v.kind = cgValue_Multi; + v.type = type; + v.multi_nodes = multi_nodes; + return v; +} + gb_internal cgAddr cg_addr(cgValue const &value) { + GB_ASSERT(value.kind != cgValue_Multi); cgAddr addr = {}; addr.kind = cgAddr_Default; addr.addr = value; diff --git a/src/tilde_backend.hpp b/src/tilde_backend.hpp index 9e88cb4c7..54d84302d 100644 --- a/src/tilde_backend.hpp +++ b/src/tilde_backend.hpp @@ -34,6 +34,11 @@ enum cgValueKind : u32 { cgValue_Value, cgValue_Addr, cgValue_Symbol, + cgValue_Multi, +}; + +struct cgValueMultiNodes { + Slice nodes; }; struct cgValue { @@ -42,6 +47,7 @@ struct cgValue { union { TB_Symbol *symbol; TB_Node * node; + cgValueMultiNodes *multi_nodes; }; }; @@ -132,6 +138,9 @@ struct cgProcedure { TB_FunctionPrototype *proto; TB_Symbol *symbol; + // includes parameters, pointers to return values, and context ptr + Slice param_nodes; + Entity * entity; cgModule *module; String name; diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp index 4e43089b2..473baf763 100644 --- a/src/tilde_expr.cpp +++ b/src/tilde_expr.cpp @@ -1,4 +1,5 @@ gb_internal cgValue cg_flatten_value(cgProcedure *p, cgValue value) { + GB_ASSERT(value.kind != cgValue_Multi); if (value.kind == cgValue_Symbol) { GB_ASSERT(is_type_internally_pointer_like(value.type)); value = cg_value(tb_inst_get_symbol_address(p->func, value.symbol), value.type); @@ -152,6 +153,9 @@ gb_internal cgValue cg_emit_transmute(cgProcedure *p, cgValue value, Type *type) case cgValue_Symbol: GB_PANIC("should be handled above"); break; + case cgValue_Multi: + GB_PANIC("cannot transmute multiple values at once"); + break; } return value; diff --git a/src/tilde_proc.cpp b/src/tilde_proc.cpp index 078c2ef9c..d08f611fc 100644 --- a/src/tilde_proc.cpp +++ b/src/tilde_proc.cpp @@ -333,7 +333,7 @@ gb_internal cgProcedure *cg_procedure_create(cgModule *m, Entity *entity, bool i size_t out_param_count = 0; p->debug_type = cg_debug_type_for_proc(m, p->type); TB_Node **params = tb_function_set_prototype_from_dbg(p->func, p->debug_type, arena, &out_param_count); - gb_unused(params); + p->param_nodes = {params, cast(isize)out_param_count}; p->proto = tb_function_get_prototype(p->func); p->symbol = cast(TB_Symbol *)p->func; @@ -387,7 +387,7 @@ gb_internal cgProcedure *cg_procedure_create_dummy(cgModule *m, String const &li size_t out_param_count = 0; p->debug_type = cg_debug_type_for_proc(m, p->type); TB_Node **params = tb_function_set_prototype_from_dbg(p->func, p->debug_type, arena, &out_param_count); - gb_unused(params); + p->param_nodes = {params, cast(isize)out_param_count}; p->proto = tb_function_get_prototype(p->func); @@ -420,12 +420,11 @@ gb_internal void cg_procedure_begin(cgProcedure *p) { continue; } - if (param_index >= p->proto->param_count) { + if (param_index >= p->param_nodes.count) { break; } - // TB_Node *ptr = tb_inst_param_addr(p->func, param_index); - TB_Node *param = tb_inst_param(p->func, param_index++); + TB_Node *param = p->param_nodes[param_index++]; TB_Node *ptr = tb_inst_local(p->func, cast(TB_CharUnits)type_size_of(e->type), cast(TB_CharUnits)type_align_of(e->type)); TB_DataType dt = cg_data_type(e->type); tb_inst_store(p->func, dt, ptr, param, cast(TB_CharUnits)type_align_of(e->type), false); diff --git a/src/tilde_stmt.cpp b/src/tilde_stmt.cpp index afc915115..6680277ed 100644 --- a/src/tilde_stmt.cpp +++ b/src/tilde_stmt.cpp @@ -10,6 +10,9 @@ gb_internal cgValue cg_emit_load(cgProcedure *p, cgValue const &ptr, bool is_vol case cgValue_Addr: GB_PANIC("NOT POSSIBLE - Cannot load an lvalue to begin with"); break; + case cgValue_Multi: + GB_PANIC("NOT POSSIBLE - Cannot load multiple values at once"); + break; case cgValue_Symbol: return cg_lvalue_addr(tb_inst_get_symbol_address(p->func, ptr.symbol), type); } @@ -27,6 +30,9 @@ gb_internal cgValue cg_emit_load(cgProcedure *p, cgValue const &ptr, bool is_vol case cgValue_Addr: the_ptr = tb_inst_load(p->func, TB_TYPE_PTR, ptr.node, alignment, is_volatile); break; + case cgValue_Multi: + GB_PANIC("NOT POSSIBLE - Cannot load multiple values at once"); + break; case cgValue_Symbol: the_ptr = tb_inst_get_symbol_address(p->func, ptr.symbol); break; @@ -35,6 +41,8 @@ gb_internal cgValue cg_emit_load(cgProcedure *p, cgValue const &ptr, bool is_vol } gb_internal void cg_emit_store(cgProcedure *p, cgValue dst, cgValue const &src, bool is_volatile) { + GB_ASSERT_MSG(dst.kind != cgValue_Multi, "cannot store to multiple values at once"); + if (dst.kind == cgValue_Addr) { dst = cg_emit_load(p, dst, is_volatile); } else if (dst.kind == cgValue_Symbol) { @@ -130,6 +138,9 @@ gb_internal cgValue cg_address_from_load(cgProcedure *p, cgValue value) { case cgValue_Symbol: GB_PANIC("Symbol is an invalid use case for cg_address_from_load"); return {}; + case cgValue_Multi: + GB_PANIC("Multi is an invalid use case for cg_address_from_load"); + break; } GB_PANIC("Invalid cgValue for cg_address_from_load"); return {}; @@ -143,6 +154,8 @@ gb_internal bool cg_addr_is_empty(cgAddr const &addr) { return addr.addr.node == nullptr; case cgValue_Symbol: return addr.addr.symbol == nullptr; + case cgValue_Multi: + return addr.addr.multi_nodes == nullptr; } return true; } @@ -670,6 +683,8 @@ gb_internal cgValue cg_address_from_load_or_generate_local(cgProcedure *p, cgVal break; case cgValue_Addr: return cg_value(value.node, alloc_type_pointer(value.type)); + case cgValue_Multi: + GB_PANIC("cgValue_Multi not allowed"); } cgAddr res = cg_add_local(p, value.type, nullptr, false);