diff options
| author | gingerBill <ginger.bill.22@gmail.com> | 2016-08-19 23:35:09 +0100 |
|---|---|---|
| committer | gingerBill <ginger.bill.22@gmail.com> | 2016-08-19 23:35:09 +0100 |
| commit | 680274b6f1f1e36e27c94b4e60895338d413c84a (patch) | |
| tree | 1d68b9062ab743950878b41fe2cb6f2e81157462 /src/codegen | |
| parent | 745237459abb3fa91405fdba3895bd9f810bc9d2 (diff) | |
Implicit Context and #thread_local
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/codegen.cpp | 8 | ||||
| -rw-r--r-- | src/codegen/print_llvm.cpp | 140 | ||||
| -rw-r--r-- | src/codegen/ssa.cpp | 712 |
3 files changed, 411 insertions, 449 deletions
diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp index 34933b2a9..795d43a07 100644 --- a/src/codegen/codegen.cpp +++ b/src/codegen/codegen.cpp @@ -77,8 +77,10 @@ void ssa_gen_code(ssaGen *s) { } break; case Entity_Variable: { - // TODO(bill): global runtime initialization ssaValue *g = ssa_make_value_global(a, e, NULL); + if (decl->var_decl_tags & VarDeclTag_thread_local) { + g->Global.is_thread_local = true; + } ssaGlobalVariable var = {}; var.var = g; var.decl = decl; @@ -95,7 +97,7 @@ void ssa_gen_code(ssaGen *s) { name = pd->foreign_name; } ssaValue *p = ssa_make_value_procedure(a, m, e->type, decl->type_expr, body, name); - p->proc.tags = pd->tags; + p->Proc.tags = pd->tags; map_set(&m->values, hash_pointer(e), p); map_set(&m->members, hash_string(name), p); @@ -127,7 +129,7 @@ void ssa_gen_code(ssaGen *s) { map_set(&m->values, hash_pointer(e), p); map_set(&m->members, hash_string(name), p); - ssaProcedure *proc = &p->proc; + ssaProcedure *proc = &p->Proc; proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea? ssa_begin_procedure_body(proc); diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index 0790aa7d8..d3974d17c 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -230,10 +230,10 @@ void ssa_print_exact_value(gbFile *f, ssaModule *m, ExactValue value, Type *type if (is_type_float(type) && type->basic.kind == Basic_f32) { // IMPORTANT NOTE(bill): LLVM requires all floating point constants to be // a 64 bit number if bits_of(float type) <= 64. - // For some bizarre reason, you need to clear the bottom 28 bits + // For some bizarre reason, you need to clear the bottom 29 bits // https://groups.google.com/forum/#!topic/llvm-dev/IlqV3TbSk6M - u >>= 28; - u <<= 28; + u >>= 29; + u <<= 29; } ssa_fprintf(f, "0x%016llx", u); } break; @@ -262,19 +262,19 @@ void ssa_print_value(gbFile *f, ssaModule *m, ssaValue *value, Type *type_hint) } switch (value->kind) { case ssaValue_Constant: - ssa_print_exact_value(f, m, value->constant.value, type_hint); + ssa_print_exact_value(f, m, value->Constant.value, type_hint); break; case ssaValue_TypeName: - ssa_print_encoded_local(f, value->type_name.name); + ssa_print_encoded_local(f, value->TypeName.name); break; case ssaValue_Global: - ssa_print_encoded_global(f, value->global.entity->token.string); + ssa_print_encoded_global(f, value->Global.entity->token.string); break; case ssaValue_Param: - ssa_print_encoded_local(f, value->param.entity->token.string); + ssa_print_encoded_local(f, value->Param.entity->token.string); break; case ssaValue_Proc: - ssa_print_encoded_global(f, value->proc.name); + ssa_print_encoded_global(f, value->Proc.name); break; case ssaValue_Instr: ssa_fprintf(f, "%%%d", value->id); @@ -284,7 +284,7 @@ void ssa_print_value(gbFile *f, ssaModule *m, ssaValue *value, Type *type_hint) void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { GB_ASSERT(value->kind == ssaValue_Instr); - ssaInstr *instr = &value->instr; + ssaInstr *instr = &value->Instr; ssa_fprintf(f, "\t"); @@ -294,14 +294,14 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { } break; case ssaInstr_Local: { - Type *type = instr->local.entity->type; + Type *type = instr->Local.entity->type; ssa_fprintf(f, "%%%d = alloca ", value->id); ssa_print_type(f, m->sizes, type); ssa_fprintf(f, ", align %lld ", type_align_of(m->sizes, m->allocator, type)); { - String str = instr->local.entity->token.string; + String str = instr->Local.entity->token.string; if (str.len > 0) - ssa_fprintf(f, "; %.*s", LIT(instr->local.entity->token.string)); + ssa_fprintf(f, "; %.*s", LIT(instr->Local.entity->token.string)); } ssa_fprintf(f, "\n"); ssa_fprintf(f, "\tstore "); @@ -312,33 +312,33 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { } break; case ssaInstr_Store: { - Type *type = ssa_value_type(instr->store.address); + Type *type = ssa_type(instr->Store.address); ssa_fprintf(f, "store "); ssa_print_type(f, m->sizes, type); ssa_fprintf(f, " "); - ssa_print_value(f, m, instr->store.value, type); + ssa_print_value(f, m, instr->Store.value, type); ssa_fprintf(f, ", "); ssa_print_type(f, m->sizes, type); ssa_fprintf(f, "* "); - ssa_print_value(f, m, instr->store.address, type); + ssa_print_value(f, m, instr->Store.address, type); ssa_fprintf(f, "\n"); } break; case ssaInstr_Load: { - Type *type = instr->load.type; + Type *type = instr->Load.type; ssa_fprintf(f, "%%%d = load ", value->id); ssa_print_type(f, m->sizes, type); ssa_fprintf(f, ", "); ssa_print_type(f, m->sizes, type); ssa_fprintf(f, "* "); - ssa_print_value(f, m, instr->load.address, type); + ssa_print_value(f, m, instr->Load.address, type); ssa_fprintf(f, ", align %lld\n", type_align_of(m->sizes, m->allocator, type)); } break; case ssaInstr_GetElementPtr: { - Type *et = instr->get_element_ptr.elem_type; + Type *et = instr->GetElementPtr.elem_type; ssa_fprintf(f, "%%%d = getelementptr ", value->id); - if (instr->get_element_ptr.inbounds) { + if (instr->GetElementPtr.inbounds) { ssa_fprintf(f, "inbounds "); } @@ -346,10 +346,10 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { ssa_fprintf(f, ", "); ssa_print_type(f, m->sizes, et); ssa_fprintf(f, "* "); - ssa_print_value(f, m, instr->get_element_ptr.address, et); - for (isize i = 0; i < instr->get_element_ptr.index_count; i++) { - ssaValue *index = instr->get_element_ptr.indices[i]; - Type *t = ssa_value_type(index); + ssa_print_value(f, m, instr->GetElementPtr.address, et); + for (isize i = 0; i < instr->GetElementPtr.index_count; i++) { + ssaValue *index = instr->GetElementPtr.indices[i]; + Type *t = ssa_type(index); ssa_fprintf(f, ", "); ssa_print_type(f, m->sizes, t); ssa_fprintf(f, " "); @@ -359,13 +359,13 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { } break; case ssaInstr_ExtractValue: { - Type *et = instr->extract_value.elem_type; + Type *et = instr->ExtractValue.elem_type; ssa_fprintf(f, "%%%d = extractvalue ", value->id); ssa_print_type(f, m->sizes, et); ssa_fprintf(f, " "); - ssa_print_value(f, m, instr->extract_value.address, et); - ssa_fprintf(f, ", %d\n", instr->extract_value.index); + ssa_print_value(f, m, instr->ExtractValue.address, et); + ssa_fprintf(f, ", %d\n", instr->ExtractValue.index); } break; case ssaInstr_NoOp: {; @@ -374,28 +374,28 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { case ssaInstr_Br: {; ssa_fprintf(f, "br "); - if (instr->br.cond != NULL) { + if (instr->Br.cond != NULL) { ssa_print_type(f, m->sizes, t_bool); ssa_fprintf(f, " "); - ssa_print_value(f, m, instr->br.cond, t_bool); - ssa_fprintf(f, ", ", instr->br.cond->id); + ssa_print_value(f, m, instr->Br.cond, t_bool); + ssa_fprintf(f, ", ", instr->Br.cond->id); } ssa_fprintf(f, "label "); - ssa_fprintf(f, "%%"); ssa_print_block_name(f, instr->br.true_block); - if (instr->br.false_block != NULL) { + ssa_fprintf(f, "%%"); ssa_print_block_name(f, instr->Br.true_block); + if (instr->Br.false_block != NULL) { ssa_fprintf(f, ", label "); - ssa_fprintf(f, "%%"); ssa_print_block_name(f, instr->br.false_block); + ssa_fprintf(f, "%%"); ssa_print_block_name(f, instr->Br.false_block); } ssa_fprintf(f, "\n"); } break; case ssaInstr_Ret: { - auto *ret = &instr->ret; + auto *ret = &instr->Ret; ssa_fprintf(f, "ret "); if (ret->value == NULL) { ssa_fprintf(f, "void"); } else { - Type *t = ssa_value_type(ret->value); + Type *t = ssa_type(ret->value); ssa_print_type(f, m->sizes, t); ssa_fprintf(f, " "); ssa_print_value(f, m, ret->value, t); @@ -406,7 +406,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { } break; case ssaInstr_Conv: { - auto *c = &instr->conv; + auto *c = &instr->Conv; ssa_fprintf(f, "%%%d = %.*s ", value->id, LIT(ssa_conv_strings[c->kind])); ssa_print_type(f, m->sizes, c->from); ssa_fprintf(f, " "); @@ -422,8 +422,8 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { } break; case ssaInstr_BinaryOp: { - auto *bo = &value->instr.binary_op; - Type *type = get_base_type(ssa_value_type(bo->left)); + auto *bo = &value->Instr.BinaryOp; + Type *type = get_base_type(ssa_type(bo->left)); Type *elem_type = type; while (elem_type->kind == Type_Vector) { elem_type = get_base_type(elem_type->vector.elem); @@ -528,7 +528,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { } break; case ssaInstr_Call: { - auto *call = &instr->call; + auto *call = &instr->Call; Type *result_type = call->type; if (result_type) { ssa_fprintf(f, "%%%d = ", value->id); @@ -545,7 +545,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { ssa_fprintf(f, "("); if (call->arg_count > 0) { - Type *proc_type = get_base_type(ssa_value_type(call->value)); + Type *proc_type = get_base_type(ssa_type(call->value)); GB_ASSERT(proc_type->kind == Type_Proc); auto *params = &proc_type->proc.params->tuple; for (isize i = 0; i < call->arg_count; i++) { @@ -567,15 +567,15 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { case ssaInstr_Select: { ssa_fprintf(f, "%%%d = select i1 ", value->id); - ssa_print_value(f, m, instr->select.cond, t_bool); + ssa_print_value(f, m, instr->Select.cond, t_bool); ssa_fprintf(f, ", "); - ssa_print_type(f, m->sizes, ssa_value_type(instr->select.true_value)); + ssa_print_type(f, m->sizes, ssa_type(instr->Select.true_value)); ssa_fprintf(f, " "); - ssa_print_value(f, m, instr->select.true_value, ssa_value_type(instr->select.true_value)); + ssa_print_value(f, m, instr->Select.true_value, ssa_type(instr->Select.true_value)); ssa_fprintf(f, ", "); - ssa_print_type(f, m->sizes, ssa_value_type(instr->select.false_value)); + ssa_print_type(f, m->sizes, ssa_type(instr->Select.false_value)); ssa_fprintf(f, " "); - ssa_print_value(f, m, instr->select.false_value, ssa_value_type(instr->select.false_value)); + ssa_print_value(f, m, instr->Select.false_value, ssa_type(instr->Select.false_value)); ssa_fprintf(f, "\n"); } break; @@ -583,39 +583,39 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { ssa_fprintf(f, "call void @llvm.memmove.p0i8.p0i8."); ssa_print_type(f, m->sizes, t_int); ssa_fprintf(f, "(i8* "); - ssa_print_value(f, m, instr->copy_memory.dst, t_rawptr); + ssa_print_value(f, m, instr->CopyMemory.dst, t_rawptr); ssa_fprintf(f, ", i8* "); - ssa_print_value(f, m, instr->copy_memory.src, t_rawptr); + ssa_print_value(f, m, instr->CopyMemory.src, t_rawptr); ssa_fprintf(f, ", "); ssa_print_type(f, m->sizes, t_int); ssa_fprintf(f, " "); - ssa_print_value(f, m, instr->copy_memory.len, t_int); + ssa_print_value(f, m, instr->CopyMemory.len, t_int); char *vol_str = "false"; - if (instr->copy_memory.is_volatile) { + if (instr->CopyMemory.is_volatile) { vol_str = "true"; } - ssa_fprintf(f, ", i32 %d, i1 %s)\n", instr->copy_memory.align, vol_str); + ssa_fprintf(f, ", i32 %d, i1 %s)\n", instr->CopyMemory.align, vol_str); } break; case ssaInstr_ExtractElement: { - Type *vt = ssa_value_type(instr->extract_element.vector); + Type *vt = ssa_type(instr->ExtractElement.vector); ssa_fprintf(f, "%%%d = extractelement ", value->id); ssa_print_type(f, m->sizes, vt); ssa_fprintf(f, " "); - ssa_print_value(f, m, instr->extract_element.vector, vt); + ssa_print_value(f, m, instr->ExtractElement.vector, vt); ssa_fprintf(f, ", "); - Type *it = ssa_value_type(instr->extract_element.index); + Type *it = ssa_type(instr->ExtractElement.index); ssa_print_type(f, m->sizes, it); ssa_fprintf(f, " "); - ssa_print_value(f, m, instr->extract_element.index, it); + ssa_print_value(f, m, instr->ExtractElement.index, it); ssa_fprintf(f, "\n"); } break; case ssaInstr_InsertElement: { - auto *ie = &instr->insert_element; - Type *vt = ssa_value_type(ie->vector); + auto *ie = &instr->InsertElement; + Type *vt = ssa_type(ie->vector); ssa_fprintf(f, "%%%d = insertelement ", value->id); ssa_print_type(f, m->sizes, vt); @@ -623,21 +623,21 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { ssa_print_value(f, m, ie->vector, vt); ssa_fprintf(f, ", "); - ssa_print_type(f, m->sizes, ssa_value_type(ie->elem)); + ssa_print_type(f, m->sizes, ssa_type(ie->elem)); ssa_fprintf(f, " "); - ssa_print_value(f, m, ie->elem, ssa_value_type(ie->elem)); + ssa_print_value(f, m, ie->elem, ssa_type(ie->elem)); ssa_fprintf(f, ", "); - ssa_print_type(f, m->sizes, ssa_value_type(ie->index)); + ssa_print_type(f, m->sizes, ssa_type(ie->index)); ssa_fprintf(f, " "); - ssa_print_value(f, m, ie->index, ssa_value_type(ie->index)); + ssa_print_value(f, m, ie->index, ssa_type(ie->index)); ssa_fprintf(f, "\n"); } break; case ssaInstr_ShuffleVector: { - auto *sv = &instr->shuffle_vector; - Type *vt = ssa_value_type(sv->vector); + auto *sv = &instr->ShuffleVector; + Type *vt = ssa_type(sv->vector); ssa_fprintf(f, "%%%d = shufflevector ", value->id); ssa_print_type(f, m->sizes, vt); @@ -738,9 +738,9 @@ void ssa_print_proc(gbFile *f, ssaModule *m, ssaProcedure *proc) { void ssa_print_type_name(gbFile *f, ssaModule *m, ssaValue *v) { GB_ASSERT(v->kind == ssaValue_TypeName); - ssa_print_encoded_local(f, v->type_name.name); + ssa_print_encoded_local(f, v->TypeName.name); ssa_fprintf(f, " = type "); - ssa_print_type(f, m->sizes, get_base_type(v->type_name.type)); + ssa_print_type(f, m->sizes, get_base_type(v->TypeName.type)); ssa_fprintf(f, "\n"); } @@ -763,9 +763,9 @@ void ssa_print_llvm_ir(gbFile *f, ssaModule *m) { ssaValue *v = entry->value; switch (v->kind) { case ssaValue_TypeName: { - ssa_print_encoded_local(f, v->type_name.name); + ssa_print_encoded_local(f, v->TypeName.name); ssa_fprintf(f, " = type "); - ssa_print_type(f, m->sizes, get_base_type(v->type_name.type)); + ssa_print_type(f, m->sizes, get_base_type(v->TypeName.type)); ssa_fprintf(f, "\n"); } break; } @@ -790,16 +790,20 @@ void ssa_print_llvm_ir(gbFile *f, ssaModule *m) { ssaValue *v = entry->value; switch (v->kind) { case ssaValue_Global: { - auto *g = &v->global; + auto *g = &v->Global; ssa_print_encoded_global(f, g->entity->token.string); ssa_fprintf(f, " = "); + if (g->is_thread_local) { + ssa_fprintf(f, "thread_local "); + } if (g->is_constant) { ssa_fprintf(f, "private constant "); } else { ssa_fprintf(f, "global "); } - ssa_print_type(f, m->sizes, get_base_type(g->entity->type)); + + ssa_print_type(f, m->sizes, g->entity->type); ssa_fprintf(f, " "); if (g->value != NULL) { ssa_print_value(f, m, g->value, g->entity->type); @@ -810,7 +814,7 @@ void ssa_print_llvm_ir(gbFile *f, ssaModule *m) { } break; case ssaValue_Proc: { - ssa_print_proc(f, m, &v->proc); + ssa_print_proc(f, m, &v->Proc); } break; } } diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index 271ce3cfb..7760b725e 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -141,15 +141,15 @@ struct ssaInstr { struct { Entity *entity; Type *type; - } local; + } Local; struct { ssaValue *address; ssaValue *value; - } store; + } Store; struct { Type *type; ssaValue *address; - } load; + } Load; struct { ssaValue *address; Type * result_type; @@ -157,65 +157,65 @@ struct ssaInstr { ssaValue *indices[2]; isize index_count; b32 inbounds; - } get_element_ptr; + } GetElementPtr; struct { ssaValue *address; Type * result_type; Type * elem_type; i32 index; - } extract_value; + } ExtractValue; struct { ssaConvKind kind; ssaValue *value; Type *from, *to; - } conv; + } Conv; struct { ssaValue *cond; ssaBlock *true_block; ssaBlock *false_block; - } br; - struct { ssaValue *value; } ret; - struct {} unreachable; + } Br; + struct { ssaValue *value; } Ret; + struct {} Unreachable; struct { ssaValue *cond; ssaValue *true_value; ssaValue *false_value; - } select; + } Select; struct { Type *type; Token op; ssaValue *left, *right; - } binary_op; + } BinaryOp; struct { Type *type; // return type ssaValue *value; ssaValue **args; isize arg_count; - } call; + } Call; struct { ssaValue *dst, *src; ssaValue *len; i32 align; b32 is_volatile; - } copy_memory; + } CopyMemory; struct { ssaValue *vector; ssaValue *index; - } extract_element; + } ExtractElement; struct { ssaValue *vector; ssaValue *elem; ssaValue *index; - } insert_element; + } InsertElement; struct { ssaValue *vector; i32 *indices; isize index_count; Type *type; - } shuffle_vector; + } ShuffleVector; - struct {} startup_runtime; + struct {} StartupRuntime; }; }; @@ -244,25 +244,26 @@ struct ssaValue { struct { Type * type; ExactValue value; - } constant; + } Constant; struct { String name; Type * type; - } type_name; + } TypeName; struct { b32 is_constant; + b32 is_thread_local; Entity * entity; Type * type; ssaValue *value; - } global; + } Global; struct { ssaProcedure *parent; Entity *entity; Type * type; - } param; - ssaProcedure proc; - ssaBlock block; - ssaInstr instr; + } Param; + ssaProcedure Proc; + ssaBlock Block; + ssaInstr Instr; }; }; @@ -274,8 +275,8 @@ gb_global ssaValue *v_two32 = NULL; gb_global ssaValue *v_false = NULL; gb_global ssaValue *v_true = NULL; -struct ssaLvalue { - ssaValue *address; +struct ssaAddr { + ssaValue *addr; AstNode *expr; // NOTE(bill): Just for testing - probably remove later // HACK(bill): Fix how lvalues for vectors work @@ -283,13 +284,13 @@ struct ssaLvalue { ssaValue *index; }; -ssaLvalue ssa_make_lvalue(ssaValue *address, AstNode *expr) { - ssaLvalue v = {address, expr, false, NULL}; +ssaAddr ssa_make_addr(ssaValue *addr, AstNode *expr) { + ssaAddr v = {addr, expr, false, NULL}; return v; } -ssaLvalue ssa_make_lvalue_vector(ssaValue *address, ssaValue *index, AstNode *expr) { - ssaLvalue v = {address, expr, true, index}; +ssaAddr ssa_make_addr_vector(ssaValue *addr, ssaValue *index, AstNode *expr) { + ssaAddr v = {addr, expr, true, index}; return v; } @@ -322,29 +323,29 @@ void ssa_module_add_value(ssaModule *m, Entity *e, ssaValue *v) { } -Type *ssa_value_type(ssaValue *value); -void ssa_value_set_type(ssaValue *value, Type *type); +Type *ssa_type(ssaValue *value); +void ssa_set_type(ssaValue *value, Type *type); -Type *ssa_instr_type(ssaInstr *instr) { +Type *ssa_type(ssaInstr *instr) { switch (instr->kind) { case ssaInstr_Local: - return instr->local.type; + return instr->Local.type; case ssaInstr_Store: - return ssa_value_type(instr->store.address); + return ssa_type(instr->Store.address); case ssaInstr_Load: - return instr->load.type; + return instr->Load.type; case ssaInstr_GetElementPtr: - return instr->get_element_ptr.result_type; + return instr->GetElementPtr.result_type; case ssaInstr_ExtractValue: - return instr->extract_value.result_type; + return instr->ExtractValue.result_type; case ssaInstr_BinaryOp: - return instr->binary_op.type; + return instr->BinaryOp.type; case ssaInstr_Conv: - return instr->conv.to; + return instr->Conv.to; case ssaInstr_Select: - return ssa_value_type(instr->select.true_value); + return ssa_type(instr->Select.true_value); case ssaInstr_Call: { - Type *pt = get_base_type(instr->call.type); + Type *pt = get_base_type(instr->Call.type); if (pt != NULL) { if (pt->kind == Type_Tuple && pt->tuple.variable_count == 1) return pt->tuple.variables[0]->type; @@ -356,81 +357,83 @@ Type *ssa_instr_type(ssaInstr *instr) { return t_int; case ssaInstr_ExtractElement: { - Type *vt = ssa_value_type(instr->extract_element.vector); - return base_vector_type(get_base_type(vt)); + Type *vt = ssa_type(instr->ExtractElement.vector); + Type *bt = base_vector_type(get_base_type(vt)); + GB_ASSERT(!is_type_vector(bt)); + return bt; } break; case ssaInstr_InsertElement: - return ssa_value_type(instr->insert_element.vector); + return ssa_type(instr->InsertElement.vector); case ssaInstr_ShuffleVector: - return instr->shuffle_vector.type; + return instr->ShuffleVector.type; } return NULL; } -void ssa_instr_set_type(ssaInstr *instr, Type *type) { +void ssa_set_type(ssaInstr *instr, Type *type) { switch (instr->kind) { case ssaInstr_Local: - instr->local.type = type; + instr->Local.type = type; break; case ssaInstr_Store: - ssa_value_set_type(instr->store.value, type); + ssa_set_type(instr->Store.value, type); break; case ssaInstr_Load: - instr->load.type = type; + instr->Load.type = type; break; case ssaInstr_GetElementPtr: - instr->get_element_ptr.result_type = type; + instr->GetElementPtr.result_type = type; break; case ssaInstr_ExtractValue: - instr->extract_value.result_type = type; + instr->ExtractValue.result_type = type; break; case ssaInstr_BinaryOp: - instr->binary_op.type = type; + instr->BinaryOp.type = type; break; case ssaInstr_Conv: - instr->conv.to = type; + instr->Conv.to = type; break; case ssaInstr_Call: - instr->call.type = type; + instr->Call.type = type; break; } } -Type *ssa_value_type(ssaValue *value) { +Type *ssa_type(ssaValue *value) { switch (value->kind) { case ssaValue_Constant: - return value->constant.type; + return value->Constant.type; case ssaValue_TypeName: - return value->type_name.type; + return value->TypeName.type; case ssaValue_Global: - return value->global.type; + return value->Global.type; case ssaValue_Param: - return value->param.type; + return value->Param.type; case ssaValue_Proc: - return value->proc.type; + return value->Proc.type; case ssaValue_Instr: - return ssa_instr_type(&value->instr); + return ssa_type(&value->Instr); } return NULL; } -void ssa_value_set_type(ssaValue *value, Type *type) { +void ssa_set_type(ssaValue *value, Type *type) { switch (value->kind) { case ssaValue_TypeName: - value->type_name.type = type; + value->TypeName.type = type; break; case ssaValue_Global: - value->global.type = type; + value->Global.type = type; break; case ssaValue_Proc: - value->proc.type = type; + value->Proc.type = type; break; case ssaValue_Constant: - value->constant.type = type; + value->Constant.type = type; break; case ssaValue_Instr: - ssa_instr_set_type(&value->instr, type); + ssa_set_type(&value->Instr, type); break; } } @@ -439,7 +442,7 @@ void ssa_value_set_type(ssaValue *value, Type *type) { ssaValue *ssa_build_expr(ssaProcedure *proc, AstNode *expr); ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue *tv); -ssaLvalue ssa_build_addr(ssaProcedure *proc, AstNode *expr); +ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr); ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *a_type); ssaValue *ssa_emit_transmute(ssaProcedure *proc, ssaValue *value, Type *a_type); void ssa_build_proc(ssaValue *value, ssaProcedure *parent); @@ -453,233 +456,185 @@ ssaValue *ssa_alloc_value(gbAllocator a, ssaValueKind kind) { return v; } -ssaValue *ssa_alloc_instr(gbAllocator a, ssaInstrKind kind) { - ssaValue *v = ssa_alloc_value(a, ssaValue_Instr); - v->instr.kind = kind; +ssaValue *ssa_alloc_instr(ssaProcedure *proc, ssaInstrKind kind) { + ssaValue *v = ssa_alloc_value(proc->module->allocator, ssaValue_Instr); + v->Instr.kind = kind; + if (proc->curr_block) { + gb_array_append(proc->curr_block->values, v); + } return v; } ssaValue *ssa_make_value_type_name(gbAllocator a, String name, Type *type) { ssaValue *v = ssa_alloc_value(a, ssaValue_TypeName); - v->type_name.name = name; - v->type_name.type = type; + v->TypeName.name = name; + v->TypeName.type = type; return v; } ssaValue *ssa_make_value_global(gbAllocator a, Entity *e, ssaValue *value) { ssaValue *v = ssa_alloc_value(a, ssaValue_Global); - v->global.entity = e; - v->global.type = e->type; - v->global.value = value; + v->Global.entity = e; + v->Global.type = e->type; + v->Global.value = value; return v; } ssaValue *ssa_make_value_param(gbAllocator a, ssaProcedure *parent, Entity *e) { ssaValue *v = ssa_alloc_value(a, ssaValue_Param); - v->param.parent = parent; - v->param.entity = e; - v->param.type = e->type; + v->Param.parent = parent; + v->Param.entity = e; + v->Param.type = e->type; return v; } ssaValue *ssa_make_instr_local(ssaProcedure *p, Entity *e) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_Local); - ssaInstr *i = &v->instr; - i->local.entity = e; - i->local.type = e->type; - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } + ssaValue *v = ssa_alloc_instr(p, ssaInstr_Local); + ssaInstr *i = &v->Instr; + i->Local.entity = e; + i->Local.type = e->type; ssa_module_add_value(p->module, e, v); return v; } ssaValue *ssa_make_instr_store(ssaProcedure *p, ssaValue *address, ssaValue *value) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_Store); - ssaInstr *i = &v->instr; - i->store.address = address; - i->store.value = value; - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } + ssaValue *v = ssa_alloc_instr(p, ssaInstr_Store); + ssaInstr *i = &v->Instr; + i->Store.address = address; + i->Store.value = value; return v; } ssaValue *ssa_make_instr_load(ssaProcedure *p, ssaValue *address) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_Load); - ssaInstr *i = &v->instr; - i->load.address = address; - i->load.type = ssa_value_type(address); - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } + ssaValue *v = ssa_alloc_instr(p, ssaInstr_Load); + ssaInstr *i = &v->Instr; + i->Load.address = address; + i->Load.type = ssa_type(address); return v; } ssaValue *ssa_make_instr_get_element_ptr(ssaProcedure *p, ssaValue *address, ssaValue *index0, ssaValue *index1, isize index_count, b32 inbounds) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_GetElementPtr); - ssaInstr *i = &v->instr; - i->get_element_ptr.address = address; - i->get_element_ptr.indices[0] = index0; - i->get_element_ptr.indices[1] = index1; - i->get_element_ptr.index_count = index_count; - i->get_element_ptr.elem_type = ssa_value_type(address); - i->get_element_ptr.inbounds = inbounds; - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } + ssaValue *v = ssa_alloc_instr(p, ssaInstr_GetElementPtr); + ssaInstr *i = &v->Instr; + i->GetElementPtr.address = address; + i->GetElementPtr.indices[0] = index0; + i->GetElementPtr.indices[1] = index1; + i->GetElementPtr.index_count = index_count; + i->GetElementPtr.elem_type = ssa_type(address); + i->GetElementPtr.inbounds = inbounds; return v; } ssaValue *ssa_make_instr_extract_value(ssaProcedure *p, ssaValue *address, i32 index, Type *result_type) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_ExtractValue); - ssaInstr *i = &v->instr; - i->extract_value.address = address; - i->extract_value.index = index; - i->extract_value.result_type = result_type; - Type *et = ssa_value_type(address); - i->extract_value.elem_type = et; + ssaValue *v = ssa_alloc_instr(p, ssaInstr_ExtractValue); + ssaInstr *i = &v->Instr; + i->ExtractValue.address = address; + i->ExtractValue.index = index; + i->ExtractValue.result_type = result_type; + Type *et = ssa_type(address); + i->ExtractValue.elem_type = et; GB_ASSERT(et->kind == Type_Structure || et->kind == Type_Array || et->kind == Type_Tuple); - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } return v; } ssaValue *ssa_make_instr_binary_op(ssaProcedure *p, Token op, ssaValue *left, ssaValue *right) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_BinaryOp); - ssaInstr *i = &v->instr; - i->binary_op.op = op; - i->binary_op.left = left; - i->binary_op.right = right; - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } + ssaValue *v = ssa_alloc_instr(p, ssaInstr_BinaryOp); + ssaInstr *i = &v->Instr; + i->BinaryOp.op = op; + i->BinaryOp.left = left; + i->BinaryOp.right = right; return v; } ssaValue *ssa_make_instr_br(ssaProcedure *p, ssaValue *cond, ssaBlock *true_block, ssaBlock *false_block) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_Br); - ssaInstr *i = &v->instr; - i->br.cond = cond; - i->br.true_block = true_block; - i->br.false_block = false_block; - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } + ssaValue *v = ssa_alloc_instr(p, ssaInstr_Br); + ssaInstr *i = &v->Instr; + i->Br.cond = cond; + i->Br.true_block = true_block; + i->Br.false_block = false_block; return v; } ssaValue *ssa_make_instr_unreachable(ssaProcedure *p) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_Unreachable); - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } + ssaValue *v = ssa_alloc_instr(p, ssaInstr_Unreachable); return v; } ssaValue *ssa_make_instr_ret(ssaProcedure *p, ssaValue *value) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_Ret); - v->instr.ret.value = value; - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } + ssaValue *v = ssa_alloc_instr(p, ssaInstr_Ret); + v->Instr.Ret.value = value; return v; } ssaValue *ssa_make_instr_select(ssaProcedure *p, ssaValue *cond, ssaValue *t, ssaValue *f) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_Select); - v->instr.select.cond = cond; - v->instr.select.true_value = t; - v->instr.select.false_value = f; - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } + ssaValue *v = ssa_alloc_instr(p, ssaInstr_Select); + v->Instr.Select.cond = cond; + v->Instr.Select.true_value = t; + v->Instr.Select.false_value = f; return v; } ssaValue *ssa_make_instr_call(ssaProcedure *p, ssaValue *value, ssaValue **args, isize arg_count, Type *result_type) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_Call); - v->instr.call.value = value; - v->instr.call.args = args; - v->instr.call.arg_count = arg_count; - v->instr.call.type = result_type; - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } + ssaValue *v = ssa_alloc_instr(p, ssaInstr_Call); + v->Instr.Call.value = value; + v->Instr.Call.args = args; + v->Instr.Call.arg_count = arg_count; + v->Instr.Call.type = result_type; return v; } ssaValue *ssa_make_instr_copy_memory(ssaProcedure *p, ssaValue *dst, ssaValue *src, ssaValue *len, i32 align, b32 is_volatile) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_MemCopy); - v->instr.copy_memory.dst = dst; - v->instr.copy_memory.src = src; - v->instr.copy_memory.len = len; - v->instr.copy_memory.align = align; - v->instr.copy_memory.is_volatile = is_volatile; - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } + ssaValue *v = ssa_alloc_instr(p, ssaInstr_MemCopy); + v->Instr.CopyMemory.dst = dst; + v->Instr.CopyMemory.src = src; + v->Instr.CopyMemory.len = len; + v->Instr.CopyMemory.align = align; + v->Instr.CopyMemory.is_volatile = is_volatile; return v; } ssaValue *ssa_make_instr_conv(ssaProcedure *p, ssaConvKind kind, ssaValue *value, Type *from, Type *to) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_Conv); - v->instr.conv.kind = kind; - v->instr.conv.value = value; - v->instr.conv.from = from; - v->instr.conv.to = to; - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } + ssaValue *v = ssa_alloc_instr(p, ssaInstr_Conv); + v->Instr.Conv.kind = kind; + v->Instr.Conv.value = value; + v->Instr.Conv.from = from; + v->Instr.Conv.to = to; return v; } ssaValue *ssa_make_instr_extract_element(ssaProcedure *p, ssaValue *vector, ssaValue *index) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_ExtractElement); - v->instr.extract_element.vector = vector; - v->instr.extract_element.index = index; - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } + ssaValue *v = ssa_alloc_instr(p, ssaInstr_ExtractElement); + v->Instr.ExtractElement.vector = vector; + v->Instr.ExtractElement.index = index; return v; } ssaValue *ssa_make_instr_insert_element(ssaProcedure *p, ssaValue *vector, ssaValue *elem, ssaValue *index) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_InsertElement); - v->instr.insert_element.vector = vector; - v->instr.insert_element.elem = elem; - v->instr.insert_element.index = index; - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } + ssaValue *v = ssa_alloc_instr(p, ssaInstr_InsertElement); + v->Instr.InsertElement.vector = vector; + v->Instr.InsertElement.elem = elem; + v->Instr.InsertElement.index = index; return v; } ssaValue *ssa_make_instr_shuffle_vector(ssaProcedure *p, ssaValue *vector, i32 *indices, isize index_count) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_ShuffleVector); - v->instr.shuffle_vector.vector = vector; - v->instr.shuffle_vector.indices = indices; - v->instr.shuffle_vector.index_count = index_count; + ssaValue *v = ssa_alloc_instr(p, ssaInstr_ShuffleVector); + v->Instr.ShuffleVector.vector = vector; + v->Instr.ShuffleVector.indices = indices; + v->Instr.ShuffleVector.index_count = index_count; - Type *vt = get_base_type(ssa_value_type(vector)); - v->instr.shuffle_vector.type = make_type_vector(p->module->allocator, vt->vector.elem, index_count); + Type *vt = get_base_type(ssa_type(vector)); + v->Instr.ShuffleVector.type = make_type_vector(p->module->allocator, vt->vector.elem, index_count); - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } return v; } ssaValue *ssa_make_instr_no_op(ssaProcedure *p) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_NoOp); - if (p->curr_block) { - gb_array_append(p->curr_block->values, v); - } + ssaValue *v = ssa_alloc_instr(p, ssaInstr_NoOp); return v; } @@ -689,30 +644,30 @@ ssaValue *ssa_make_instr_no_op(ssaProcedure *p) { ssaValue *ssa_make_value_constant(gbAllocator a, Type *type, ExactValue value) { ssaValue *v = ssa_alloc_value(a, ssaValue_Constant); - v->constant.type = type; - v->constant.value = value; + v->Constant.type = type; + v->Constant.value = value; return v; } ssaValue *ssa_make_value_procedure(gbAllocator a, ssaModule *m, Type *type, AstNode *type_expr, AstNode *body, String name) { ssaValue *v = ssa_alloc_value(a, ssaValue_Proc); - v->proc.module = m; - v->proc.type = type; - v->proc.type_expr = type_expr; - v->proc.body = body; - v->proc.name = name; + v->Proc.module = m; + v->Proc.type = type; + v->Proc.type_expr = type_expr; + v->Proc.body = body; + v->Proc.name = name; return v; } ssaValue *ssa_make_value_block(ssaProcedure *proc, AstNode *node, Scope *scope, String label) { ssaValue *v = ssa_alloc_value(proc->module->allocator, ssaValue_Block); - v->block.label = label; - v->block.node = node; - v->block.scope = scope; - v->block.parent = proc; + v->Block.label = label; + v->Block.node = node; + v->Block.scope = scope; + v->Block.parent = proc; - gb_array_init(v->block.instrs, gb_heap_allocator()); - gb_array_init(v->block.values, gb_heap_allocator()); + gb_array_init(v->Block.instrs, gb_heap_allocator()); + gb_array_init(v->Block.values, gb_heap_allocator()); return v; } @@ -735,7 +690,7 @@ ssaInstr *ssa_get_last_instr(ssaBlock *block) { if (len > 0) { ssaValue *v = block->instrs[len-1]; GB_ASSERT(v->kind == ssaValue_Instr); - return &v->instr; + return &v->Instr; } } return NULL; @@ -755,8 +710,9 @@ b32 ssa_is_instr_terminating(ssaInstr *i) { } ssaValue *ssa_emit(ssaProcedure *proc, ssaValue *instr) { + GB_ASSERT(instr->kind == ssaValue_Instr); ssaBlock *b = proc->curr_block; - instr->instr.parent = b; + instr->Instr.parent = b; if (b) { ssaInstr *i = ssa_get_last_instr(b); if (!ssa_is_instr_terminating(i)) { @@ -805,9 +761,9 @@ ssaValue *ssa_add_param(ssaProcedure *proc, Entity *e) { -Type *ssa_lvalue_type(ssaLvalue lval) { - if (lval.address != NULL) { - return type_deref(ssa_value_type(lval.address)); +Type *ssa_type(ssaAddr lval) { + if (lval.addr != NULL) { + return ssa_type(lval.addr); } return NULL; } @@ -824,7 +780,7 @@ ssaBlock *ssa__make_block(ssaProcedure *proc, AstNode *node, String label) { } ssaValue *block = ssa_make_value_block(proc, node, scope, label); - return &block->block; + return &block->Block; } ssaBlock *ssa_add_block(ssaProcedure *proc, AstNode *node, String label) { @@ -903,28 +859,30 @@ void ssa_emit_no_op(ssaProcedure *proc) { -ssaValue *ssa_lvalue_store(ssaProcedure *proc, ssaLvalue lval, ssaValue *value) { - if (lval.address != NULL) { +ssaValue *ssa_lvalue_store(ssaProcedure *proc, ssaAddr lval, ssaValue *value) { + if (lval.addr != NULL) { if (lval.is_vector) { // HACK(bill): Fix how lvalues for vectors work - ssaValue *v = ssa_emit_load(proc, lval.address); - Type *elem_type = get_base_type(ssa_value_type(v))->vector.elem; + ssaValue *v = ssa_emit_load(proc, lval.addr); + Type *elem_type = get_base_type(ssa_type(v))->vector.elem; ssaValue *elem = ssa_emit_conv(proc, value, elem_type); ssaValue *out = ssa_emit(proc, ssa_make_instr_insert_element(proc, v, elem, lval.index)); - return ssa_emit_store(proc, lval.address, out); + return ssa_emit_store(proc, lval.addr, out); + } else { + value = ssa_emit_conv(proc, value, ssa_type(lval)); + return ssa_emit_store(proc, lval.addr, value); } - return ssa_emit_store(proc, lval.address, value); } return NULL; } -ssaValue *ssa_lvalue_load(ssaProcedure *proc, ssaLvalue lval) { - if (lval.address != NULL) { +ssaValue *ssa_lvalue_load(ssaProcedure *proc, ssaAddr lval) { + if (lval.addr != NULL) { if (lval.is_vector) { // HACK(bill): Fix how lvalues for vectors work - ssaValue *v = ssa_emit_load(proc, lval.address); + ssaValue *v = ssa_emit_load(proc, lval.addr); return ssa_emit(proc, ssa_make_instr_extract_element(proc, v, lval.index)); } - return ssa_emit_load(proc, lval.address); + return ssa_emit_load(proc, lval.addr); } GB_PANIC("Illegal lvalue load"); return NULL; @@ -957,12 +915,6 @@ void ssa_end_procedure_body(ssaProcedure *proc) { } -#if 0 - gb_for_array(i, proc->defer_stmts) { - gb_printf("defer %td - %p\n", proc->defer_stmts[i].scope_index, proc->defer_stmts[i].stmt); - } -#endif - // Number blocks and registers i32 reg_id = 0; gb_for_array(i, proc->blocks) { @@ -971,7 +923,7 @@ void ssa_end_procedure_body(ssaProcedure *proc) { gb_for_array(j, b->instrs) { ssaValue *value = b->instrs[j]; GB_ASSERT(value->kind == ssaValue_Instr); - ssaInstr *instr = &value->instr; + ssaInstr *instr = &value->Instr; // NOTE(bill): Ignore non-returning instructions switch (instr->kind) { case ssaInstr_Store: @@ -982,7 +934,7 @@ void ssa_end_procedure_body(ssaProcedure *proc) { case ssaInstr_StartupRuntime: continue; case ssaInstr_Call: - if (instr->call.type == NULL) { + if (instr->Call.type == NULL) { continue; } break; @@ -1016,7 +968,7 @@ ssaValue *ssa_emit_arith(ssaProcedure *proc, Token op, ssaValue *left, ssaValue ssaValue *neg = ssa_make_value_constant(proc->module->allocator, type, make_exact_value_integer(-1)); op.kind = Token_Xor; right = ssa_emit_arith(proc, op, right, neg, type); - ssa_value_set_type(right, type); + ssa_set_type(right, type); op.kind = Token_And; } /* fallthrough */ case Token_Add: @@ -1033,20 +985,20 @@ ssaValue *ssa_emit_arith(ssaProcedure *proc, Token op, ssaValue *left, ssaValue } ssaValue *v = ssa_make_instr_binary_op(proc, op, left, right); - ssa_value_set_type(v, type); + ssa_set_type(v, type); return ssa_emit(proc, v); } ssaValue *ssa_emit_comp(ssaProcedure *proc, Token op, ssaValue *left, ssaValue *right) { - Type *a = get_base_type(ssa_value_type(left)); - Type *b = get_base_type(ssa_value_type(right)); + Type *a = get_base_type(ssa_type(left)); + Type *b = get_base_type(ssa_type(right)); if (are_types_identical(a, b)) { // NOTE(bill): No need for a conversion } else if (left->kind == ssaValue_Constant) { - left = ssa_emit_conv(proc, left, ssa_value_type(right)); + left = ssa_emit_conv(proc, left, ssa_type(right)); } else if (right->kind == ssaValue_Constant) { - right = ssa_emit_conv(proc, right, ssa_value_type(left)); + right = ssa_emit_conv(proc, right, ssa_type(left)); } ssaValue *v = ssa_make_instr_binary_op(proc, op, left, right); @@ -1054,17 +1006,17 @@ ssaValue *ssa_emit_comp(ssaProcedure *proc, Token op, ssaValue *left, ssaValue * if (is_type_vector(a)) { result = make_type_vector(proc->module->allocator, t_bool, a->vector.count); } - ssa_value_set_type(v, result); + ssa_set_type(v, result); return ssa_emit(proc, v); } ssaValue *ssa_emit_ptr_offset(ssaProcedure *proc, ssaValue *ptr, ssaValue *offset) { - Type *type = ssa_value_type(ptr); + Type *type = ssa_type(ptr); ssaValue *gep = NULL; offset = ssa_emit_conv(proc, offset, t_int); gep = ssa_make_instr_get_element_ptr(proc, ptr, offset, NULL, 1, false); - gep->instr.get_element_ptr.elem_type = type_deref(type); - gep->instr.get_element_ptr.result_type = type; + gep->Instr.GetElementPtr.elem_type = type_deref(type); + gep->Instr.GetElementPtr.result_type = type; return ssa_emit(proc, gep); } @@ -1072,8 +1024,8 @@ ssaValue *ssa_emit_zero_gep(ssaProcedure *proc, ssaValue *s) { ssaValue *gep = NULL; // NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32 gep = ssa_make_instr_get_element_ptr(proc, s, NULL, NULL, 0, true); - gep->instr.get_element_ptr.elem_type = ssa_value_type(s); - gep->instr.get_element_ptr.result_type = ssa_value_type(s); + gep->Instr.GetElementPtr.elem_type = ssa_type(s); + gep->Instr.GetElementPtr.result_type = ssa_type(s); return ssa_emit(proc, gep); } @@ -1082,8 +1034,8 @@ ssaValue *ssa_emit_struct_gep(ssaProcedure *proc, ssaValue *s, ssaValue *index, // NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32 index = ssa_emit_conv(proc, index, t_i32); gep = ssa_make_instr_get_element_ptr(proc, s, v_zero, index, 2, true); - gep->instr.get_element_ptr.elem_type = ssa_value_type(s); - gep->instr.get_element_ptr.result_type = result_type; + gep->Instr.GetElementPtr.elem_type = ssa_type(s); + gep->Instr.GetElementPtr.result_type = result_type; return ssa_emit(proc, gep); } @@ -1102,17 +1054,17 @@ ssaValue *ssa_emit_struct_ev(ssaProcedure *proc, ssaValue *s, i32 index, Type *r ssaValue *ssa_array_elem(ssaProcedure *proc, ssaValue *array) { - Type *t = ssa_value_type(array); + Type *t = ssa_type(array); GB_ASSERT(t->kind == Type_Array); Type *base_type = t->array.elem; ssaValue *elem = ssa_make_instr_get_element_ptr(proc, array, v_zero, v_zero, 2, true); Type *result_type = make_type_pointer(proc->module->allocator, base_type); - elem->instr.get_element_ptr.elem_type = t; - elem->instr.get_element_ptr.result_type = result_type; + elem->Instr.GetElementPtr.elem_type = t; + elem->Instr.GetElementPtr.result_type = result_type; return ssa_emit(proc, elem); } ssaValue *ssa_array_len(ssaProcedure *proc, ssaValue *array) { - Type *t = ssa_value_type(array); + Type *t = ssa_type(array); GB_ASSERT(t->kind == Type_Array); return ssa_make_value_constant(proc->module->allocator, t_int, make_exact_value_integer(t->array.count)); } @@ -1121,35 +1073,35 @@ ssaValue *ssa_array_cap(ssaProcedure *proc, ssaValue *array) { } ssaValue *ssa_slice_elem(ssaProcedure *proc, ssaValue *slice) { - Type *t = ssa_value_type(slice); + Type *t = ssa_type(slice); GB_ASSERT(t->kind == Type_Slice); Type *result_type = make_type_pointer(proc->module->allocator, t->slice.elem); return ssa_emit_load(proc, ssa_emit_struct_gep(proc, slice, v_zero32, result_type)); } ssaValue *ssa_slice_len(ssaProcedure *proc, ssaValue *slice) { - Type *t = ssa_value_type(slice); + Type *t = ssa_type(slice); GB_ASSERT(t->kind == Type_Slice); return ssa_emit_load(proc, ssa_emit_struct_gep(proc, slice, v_one32, t_int)); } ssaValue *ssa_slice_cap(ssaProcedure *proc, ssaValue *slice) { - Type *t = ssa_value_type(slice); + Type *t = ssa_type(slice); GB_ASSERT(t->kind == Type_Slice); return ssa_emit_load(proc, ssa_emit_struct_gep(proc, slice, v_two32, t_int)); } ssaValue *ssa_string_elem(ssaProcedure *proc, ssaValue *string) { - Type *t = ssa_value_type(string); + Type *t = ssa_type(string); GB_ASSERT(t->kind == Type_Basic && t->basic.kind == Basic_string); Type *base_type = t_u8; ssaValue *elem = ssa_make_instr_get_element_ptr(proc, string, v_zero, v_zero32, 2, true); Type *result_type = make_type_pointer(proc->module->allocator, base_type); - elem->instr.get_element_ptr.elem_type = t; - elem->instr.get_element_ptr.result_type = result_type; + elem->Instr.GetElementPtr.elem_type = t; + elem->Instr.GetElementPtr.result_type = result_type; return ssa_emit_load(proc, ssa_emit(proc, elem)); } ssaValue *ssa_string_len(ssaProcedure *proc, ssaValue *string) { - Type *t = ssa_value_type(string); + Type *t = ssa_type(string); GB_ASSERT(t->kind == Type_Basic && t->basic.kind == Basic_string); return ssa_emit_load(proc, ssa_emit_struct_gep(proc, string, v_one32, t_int)); } @@ -1160,7 +1112,7 @@ ssaValue *ssa_emit_slice(ssaProcedure *proc, Type *slice_type, ssaValue *base, s // TODO(bill): array bounds checking for slice creation // TODO(bill): check that low < high <= max gbAllocator a = proc->module->allocator; - Type *base_type = get_base_type(ssa_value_type(base)); + Type *base_type = get_base_type(ssa_type(base)); if (low == NULL) { low = v_zero; @@ -1197,7 +1149,7 @@ ssaValue *ssa_emit_slice(ssaProcedure *proc, Type *slice_type, ssaValue *base, s ssaValue *slice = ssa_add_local_generated(proc, slice_type); ssaValue *gep = NULL; - gep = ssa_emit_struct_gep(proc, slice, v_zero32, ssa_value_type(elem)); + gep = ssa_emit_struct_gep(proc, slice, v_zero32, ssa_type(elem)); ssa_emit_store(proc, gep, elem); gep = ssa_emit_struct_gep(proc, slice, v_one32, t_int); @@ -1210,7 +1162,7 @@ ssaValue *ssa_emit_slice(ssaProcedure *proc, Type *slice_type, ssaValue *base, s } ssaValue *ssa_emit_substring(ssaProcedure *proc, ssaValue *base, ssaValue *low, ssaValue *high) { - Type *bt = get_base_type(ssa_value_type(base)); + Type *bt = get_base_type(ssa_type(base)); GB_ASSERT(bt == t_string); if (low == NULL) { low = v_zero; @@ -1228,7 +1180,7 @@ ssaValue *ssa_emit_substring(ssaProcedure *proc, ssaValue *base, ssaValue *low, ssaValue *str, *gep; str = ssa_add_local_generated(proc, t_string); - gep = ssa_emit_struct_gep(proc, str, v_zero32, ssa_value_type(elem)); + gep = ssa_emit_struct_gep(proc, str, v_zero32, ssa_type(elem)); ssa_emit_store(proc, gep, elem); gep = ssa_emit_struct_gep(proc, str, v_one32, t_int); @@ -1261,7 +1213,7 @@ ssaValue *ssa_add_global_string_array(ssaProcedure *proc, ExactValue value) { } ssaValue *ssa_emit_string(ssaProcedure *proc, ssaValue *elem, ssaValue *len) { - Type *t_u8_ptr = ssa_value_type(elem); + Type *t_u8_ptr = ssa_type(elem); GB_ASSERT(t_u8_ptr->kind == Type_Pointer); GB_ASSERT(is_type_u8(t_u8_ptr->pointer.elem)); @@ -1278,7 +1230,7 @@ ssaValue *ssa_emit_string(ssaProcedure *proc, ssaValue *elem, ssaValue *len) { ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) { - Type *src_type = ssa_value_type(value); + Type *src_type = ssa_type(value); if (are_types_identical(t, src_type)) { return value; } @@ -1291,7 +1243,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) { if (value->kind == ssaValue_Constant) { if (dst->kind == Type_Basic) { - ExactValue ev = value->constant.value; + ExactValue ev = value->Constant.value; if (is_type_float(dst)) { ev = exact_value_to_float(ev); } else if (is_type_string(dst)) { @@ -1382,6 +1334,16 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) { return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_bitcast, value, src, dst)); } + // pointer -> proc + if (is_type_pointer(src) && is_type_proc(dst)) { + return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_bitcast, value, src, dst)); + } + // proc -> pointer + if (is_type_proc(src) && is_type_pointer(dst)) { + return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_bitcast, value, src, dst)); + } + + // []byte/[]u8 <-> string if (is_type_u8_slice(src) && is_type_string(dst)) { @@ -1395,7 +1357,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) { ssaValue *str = ssa_add_local_generated(proc, src); ssa_emit_store(proc, str, value); ssaValue *elem = ssa_string_elem(proc, str); - ssaValue *elem_ptr = ssa_add_local_generated(proc, ssa_value_type(elem)); + ssaValue *elem_ptr = ssa_add_local_generated(proc, ssa_type(elem)); ssa_emit_store(proc, elem_ptr, elem); ssaValue *len = ssa_string_len(proc, str); @@ -1403,22 +1365,22 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) { return ssa_emit_load(proc, slice); } - // if (is_type_vector(dst)) { - // Type *dst_elem = dst->vector.elem; - // value = ssa_emit_conv(proc, value, dst_elem); - // ssaValue *v = ssa_add_local_generated(proc, t); - // v = ssa_emit_load(proc, v); - // v = ssa_emit(proc, ssa_make_instr_insert_element(proc, v, value, v_zero32)); - // // NOTE(bill): Broadcast lowest value to all values - // isize index_count = dst->vector.count; - // i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count); - // for (isize i = 0; i < index_count; i++) { - // indices[i] = 0; - // } + if (is_type_vector(dst)) { + Type *dst_elem = dst->vector.elem; + value = ssa_emit_conv(proc, value, dst_elem); + ssaValue *v = ssa_add_local_generated(proc, t); + v = ssa_emit_load(proc, v); + v = ssa_emit(proc, ssa_make_instr_insert_element(proc, v, value, v_zero32)); + // NOTE(bill): Broadcast lowest value to all values + isize index_count = dst->vector.count; + i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count); + for (isize i = 0; i < index_count; i++) { + indices[i] = 0; + } - // v = ssa_emit(proc, ssa_make_instr_shuffle_vector(proc, v, indices, index_count)); - // return v; - // } + v = ssa_emit(proc, ssa_make_instr_shuffle_vector(proc, v, indices, index_count)); + return v; + } gb_printf_err("Not Identical %s != %s\n", type_to_string(src_type), type_to_string(t)); @@ -1432,7 +1394,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) { ssaValue *ssa_emit_transmute(ssaProcedure *proc, ssaValue *value, Type *t) { - Type *src_type = ssa_value_type(value); + Type *src_type = ssa_type(value); if (are_types_identical(t, src_type)) { return value; } @@ -1497,8 +1459,8 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case_ast_node(ue, UnaryExpr, expr); switch (ue->op.kind) { case Token_Pointer: { - ssaValue *v = ssa_emit_zero_gep(proc, ssa_build_addr(proc, ue->expr).address); - ssa_value_set_type(v, type_of_expr(proc->module->info, expr)); + ssaValue *v = ssa_emit_zero_gep(proc, ssa_build_addr(proc, ue->expr).addr); + ssa_set_type(v, type_of_expr(proc->module->info, expr)); return v; } case Token_Add: @@ -1578,9 +1540,9 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue ssaValue *value = ssa_make_value_procedure(proc->module->allocator, proc->module, type, pl->type, pl->body, name); - value->proc.tags = pl->tags; + value->Proc.tags = pl->tags; - gb_array_append(proc->children, &value->proc); + gb_array_append(proc->children, &value->Proc); ssa_build_proc(value, proc); return value; @@ -1609,7 +1571,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue elem != NULL; elem = elem->next, index++) { ssaValue *field_elem = ssa_build_expr(proc, elem); - Type *t = ssa_value_type(field_elem); + Type *t = ssa_type(field_elem); GB_ASSERT(t->kind != Type_Tuple); ssaValue *ev = ssa_emit_conv(proc, field_elem, et); ssaValue *i = ssa_make_value_constant(proc->module->allocator, t_int, make_exact_value_integer(index)); @@ -1649,7 +1611,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue field_expr = ssa_build_expr(proc, elem); } - GB_ASSERT(ssa_value_type(field_expr)->kind != Type_Tuple); + GB_ASSERT(ssa_type(field_expr)->kind != Type_Tuple); field = st->fields[field_index]; @@ -1666,7 +1628,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue elem != NULL; elem = elem->next, index++) { ssaValue *field_expr = ssa_build_expr(proc, elem); - Type *t = ssa_value_type(field_expr); + Type *t = ssa_type(field_expr); GB_ASSERT(t->kind != Type_Tuple); ssaValue *ev = ssa_emit_conv(proc, field_expr, et); ssaValue *gep = ssa_emit_struct_gep(proc, v, index, et); @@ -1681,7 +1643,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue elem != NULL; elem = elem->next, index++) { ssaValue *field_expr = ssa_build_expr(proc, elem); - Type *t = ssa_value_type(field_expr); + Type *t = ssa_type(field_expr); GB_ASSERT(t->kind != Type_Tuple); ssaValue *ev = ssa_emit_conv(proc, field_expr, et); ssaValue *gep = ssa_emit_struct_gep(proc, array, index, et); @@ -1692,7 +1654,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue make_type_pointer(proc->module->allocator, et)); ssaValue *len = ssa_array_len(proc, array); ssaValue *gep = NULL; - gep = ssa_emit_struct_gep(proc, v, v_zero32, ssa_value_type(elem)); + gep = ssa_emit_struct_gep(proc, v, v_zero32, ssa_type(elem)); ssa_emit_store(proc, gep, elem); gep = ssa_emit_struct_gep(proc, v, v_one32, t_int); ssa_emit_store(proc, gep, len); @@ -1714,8 +1676,8 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case BuiltinProc_len: { // len :: proc(Type) -> int // NOTE(bill): len of an array is a constant expression - ssaValue *v = ssa_build_addr(proc, ce->arg_list).address; - Type *t = get_base_type(ssa_value_type(v)); + ssaValue *v = ssa_build_addr(proc, ce->arg_list).addr; + Type *t = get_base_type(ssa_type(v)); if (t == t_string) return ssa_string_len(proc, v); else if (t->kind == Type_Slice) @@ -1724,17 +1686,17 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case BuiltinProc_cap: { // cap :: proc(Type) -> int // NOTE(bill): cap of an array is a constant expression - ssaValue *v = ssa_build_addr(proc, ce->arg_list).address; - Type *t = get_base_type(ssa_value_type(v)); + ssaValue *v = ssa_build_addr(proc, ce->arg_list).addr; + Type *t = get_base_type(ssa_type(v)); return ssa_slice_cap(proc, v); } break; case BuiltinProc_copy: { // copy :: proc(dst, src: []Type) -> int AstNode *dst_node = ce->arg_list; AstNode *src_node = ce->arg_list->next; - ssaValue *dst_slice = ssa_build_addr(proc, dst_node).address; - ssaValue *src_slice = ssa_build_addr(proc, src_node).address; - Type *slice_type = get_base_type(ssa_value_type(dst_slice)); + ssaValue *dst_slice = ssa_build_addr(proc, dst_node).addr; + ssaValue *src_slice = ssa_build_addr(proc, src_node).addr; + Type *slice_type = get_base_type(ssa_type(dst_slice)); GB_ASSERT(slice_type->kind == Type_Slice); Type *elem_type = slice_type->slice.elem; i64 size_of_elem = type_size_of(proc->module->sizes, proc->module->allocator, elem_type); @@ -1764,13 +1726,13 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue // append :: proc(s: ^[]Type, item: Type) -> bool AstNode *sptr_node = ce->arg_list; AstNode *item_node = ce->arg_list->next; - ssaValue *slice = ssa_build_addr(proc, sptr_node).address; + ssaValue *slice = ssa_build_addr(proc, sptr_node).addr; ssaValue *elem = ssa_slice_elem(proc, slice); ssaValue *len = ssa_slice_len(proc, slice); ssaValue *cap = ssa_slice_cap(proc, slice); - Type *elem_type = type_deref(get_base_type(ssa_value_type(elem))); + Type *elem_type = type_deref(ssa_type(elem)); ssaValue *item_value = ssa_build_expr(proc, item_node); item_value = ssa_emit_conv(proc, item_value, elem_type); @@ -1795,7 +1757,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue make_exact_value_integer(item_size)); offset = ssa_emit_conv(proc, offset, t_rawptr); item = ssa_emit_ptr_offset(proc, item, v_zero); - ssa_value_set_type(item, make_type_pointer(proc->module->allocator, ssa_value_type(item))); + ssa_set_type(item, make_type_pointer(proc->module->allocator, ssa_type(item))); item = ssa_emit_conv(proc, item, t_rawptr); ssa_emit(proc, ssa_make_instr_copy_memory(proc, offset, item, byte_count, 1, false)); @@ -1838,7 +1800,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue // NOTE(bill): Regular call ssaValue *value = ssa_build_expr(proc, ce->proc); - Type *proc_type_ = get_base_type(ssa_value_type(value)); + Type *proc_type_ = get_base_type(ssa_type(value)); GB_ASSERT(proc_type_->kind == Type_Proc); auto *type = &proc_type_->proc; @@ -1848,7 +1810,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue for (AstNode *arg = ce->arg_list; arg != NULL; arg = arg->next) { ssaValue *a = ssa_build_expr(proc, arg); - Type *at = ssa_value_type(a); + Type *at = ssa_type(a); if (at->kind == Type_Tuple) { for (isize i = 0; i < at->tuple.variable_count; i++) { Entity *e = at->tuple.variables[i]; @@ -1870,11 +1832,11 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case_end; case_ast_node(se, SliceExpr, expr); - return ssa_emit_load(proc, ssa_build_addr(proc, expr).address); + return ssa_emit_load(proc, ssa_build_addr(proc, expr).addr); case_end; case_ast_node(ie, IndexExpr, expr); - return ssa_emit_load(proc, ssa_build_addr(proc, expr).address); + return ssa_emit_load(proc, ssa_build_addr(proc, expr).addr); case_end; } @@ -1902,7 +1864,7 @@ ssaValue *ssa_build_expr(ssaProcedure *proc, AstNode *expr) { ssaValue *value = NULL; if (tv->mode == Addressing_Variable) { - ssaLvalue addr = ssa_build_addr(proc, expr); + ssaAddr addr = ssa_build_addr(proc, expr); value = ssa_lvalue_load(proc, addr); } else { value = ssa_build_single_expr(proc, expr, tv); @@ -1912,11 +1874,11 @@ ssaValue *ssa_build_expr(ssaProcedure *proc, AstNode *expr) { } -ssaLvalue ssa_build_addr(ssaProcedure *proc, AstNode *expr) { +ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) { switch (expr->kind) { case_ast_node(i, Ident, expr); if (ssa_is_blank_ident(expr)) { - ssaLvalue val = {}; + ssaAddr val = {}; return val; } @@ -1928,7 +1890,7 @@ ssaLvalue ssa_build_addr(ssaProcedure *proc, AstNode *expr) { } else { GB_PANIC("Unknown value: %s, entity: %p\n", expr_to_string(expr), e); } - return ssa_make_lvalue(v, expr); + return ssa_make_addr(v, expr); case_end; case_ast_node(pe, ParenExpr, expr); @@ -1942,27 +1904,27 @@ ssaLvalue ssa_build_addr(ssaProcedure *proc, AstNode *expr) { Entity *entity = lookup_field(type, unparen_expr(se->selector), &field_index); GB_ASSERT(entity != NULL); - ssaValue *e = ssa_build_addr(proc, se->expr).address; + ssaValue *e = ssa_build_addr(proc, se->expr).addr; if (is_type_pointer(type)) { // NOTE(bill): Allow x^.y and x.y to be the same e = ssa_emit_load(proc, e); e = ssa_emit_ptr_offset(proc, e, v_zero); - ssa_value_set_type(e, type_deref(type)); + ssa_set_type(e, type_deref(type)); } ssaValue *v = ssa_emit_struct_gep(proc, e, field_index, entity->type); - return ssa_make_lvalue(v, expr); + return ssa_make_addr(v, expr); case_end; case_ast_node(ue, UnaryExpr, expr); switch (ue->op.kind) { case Token_Pointer: { - ssaLvalue lval = ssa_build_addr(proc, ue->expr); - // ssaValue *v = ssa_emit_zero_gep(proc, lval.address); - // Type *t = ssa_value_type(lval.address); - // ssa_value_set_type(lval.address, make_type_pointer(proc->module->allocator, t)); - // return ssa_make_lvalue(v, expr); + ssaAddr lval = ssa_build_addr(proc, ue->expr); + // ssaValue *v = ssa_emit_zero_gep(proc, lval.addr); + // Type *t = ssa_type(lval.addr); + // ssa_set_type(lval.addr, make_type_pointer(proc->module->allocator, t)); + // return ssa_make_addr(v, expr); return lval; } default: @@ -1978,7 +1940,7 @@ ssaLvalue ssa_build_addr(ssaProcedure *proc, AstNode *expr) { Type *type = type_of_expr(proc->module->info, expr); ssaValue *v = ssa_add_local_generated(proc, type); ssa_emit_store(proc, v, ssa_emit_conv(proc, ssa_build_expr(proc, be->left), type)); - return ssa_make_lvalue(v, expr); + return ssa_make_addr(v, expr); } case Token_transmute: { // HACK(bill): Do have to make new variable to do this? @@ -1986,7 +1948,7 @@ ssaLvalue ssa_build_addr(ssaProcedure *proc, AstNode *expr) { Type *type = type_of_expr(proc->module->info, expr); ssaValue *v = ssa_add_local_generated(proc, type); ssa_emit_store(proc, v, ssa_emit_transmute(proc, ssa_build_expr(proc, be->left), type)); - return ssa_make_lvalue(v, expr); + return ssa_make_addr(v, expr); } default: GB_PANIC("Invalid binary expression for ssa_build_addr: %.*s\n", LIT(be->op.string)); @@ -2001,18 +1963,18 @@ ssaLvalue ssa_build_addr(ssaProcedure *proc, AstNode *expr) { switch (t->kind) { case Type_Vector: { // HACK(bill): Fix how lvalues for vectors work - ssaValue *vector = ssa_build_addr(proc, ie->expr).address; + ssaValue *vector = ssa_build_addr(proc, ie->expr).addr; ssaValue *index = ssa_emit_conv(proc, ssa_build_expr(proc, ie->index), t_int); - return ssa_make_lvalue_vector(vector, index, expr); + return ssa_make_addr_vector(vector, index, expr); } break; case Type_Array: { - ssaValue *array = ssa_build_addr(proc, ie->expr).address; + ssaValue *array = ssa_build_addr(proc, ie->expr).addr; elem = ssa_array_elem(proc, array); } break; case Type_Slice: { - ssaValue *slice = ssa_build_addr(proc, ie->expr).address; + ssaValue *slice = ssa_build_addr(proc, ie->expr).addr; elem = ssa_slice_elem(proc, slice); } break; case Type_Basic: { // Basic_string @@ -2021,21 +1983,21 @@ ssaLvalue ssa_build_addr(ssaProcedure *proc, AstNode *expr) { ssaValue *array = ssa_add_global_string_array(proc, tv->value); elem = ssa_array_elem(proc, array); } else { - elem = ssa_string_elem(proc, ssa_build_addr(proc, ie->expr).address); + elem = ssa_string_elem(proc, ssa_build_addr(proc, ie->expr).addr); } } break; case Type_Pointer: { - elem = ssa_emit_load(proc, ssa_build_addr(proc, ie->expr).address); + elem = ssa_emit_load(proc, ssa_build_addr(proc, ie->expr).addr); } break; } ssaValue *index = ssa_emit_conv(proc, ssa_build_expr(proc, ie->index), t_int); v = ssa_emit_ptr_offset(proc, elem, index); - Type *lval_type = type_deref(ssa_value_type(v)); + Type *lval_type = type_deref(ssa_type(v)); // gb_printf("%s\n", type_to_string(lval_type)); - ssa_value_set_type(v, lval_type); - return ssa_make_lvalue(v, expr); + ssa_set_type(v, lval_type); + return ssa_make_addr(v, expr); case_end; case_ast_node(se, SliceExpr, expr); @@ -2051,13 +2013,13 @@ ssaLvalue ssa_build_addr(ssaProcedure *proc, AstNode *expr) { switch (type->kind) { case Type_Slice: case Type_Array: { - ssaValue *base = ssa_build_addr(proc, se->expr).address; - return ssa_make_lvalue(ssa_emit_slice(proc, type, base, low, high, max), expr); + ssaValue *base = ssa_build_addr(proc, se->expr).addr; + return ssa_make_addr(ssa_emit_slice(proc, type, base, low, high, max), expr); } break; case Type_Basic: { // NOTE(bill): max is not needed - ssaValue *base = ssa_build_addr(proc, se->expr).address; - return ssa_make_lvalue(ssa_emit_substring(proc, base, low, high), expr); + ssaValue *base = ssa_build_addr(proc, se->expr).addr; + return ssa_make_addr(ssa_emit_substring(proc, base, low, high), expr); } break; } @@ -2065,13 +2027,13 @@ ssaLvalue ssa_build_addr(ssaProcedure *proc, AstNode *expr) { case_end; case_ast_node(de, DerefExpr, expr); - ssaValue *e = ssa_emit_load(proc, ssa_build_addr(proc, de->expr).address); + ssaValue *e = ssa_emit_load(proc, ssa_build_addr(proc, de->expr).addr); ssaValue *gep = ssa_make_instr_get_element_ptr(proc, e, NULL, NULL, 0, false); - Type *t = type_deref(get_base_type(ssa_value_type(e))); - gep->instr.get_element_ptr.result_type = t; - gep->instr.get_element_ptr.elem_type = t; + Type *t = type_deref(ssa_type(e)); + gep->Instr.GetElementPtr.result_type = t; + gep->Instr.GetElementPtr.elem_type = t; ssaValue *v = ssa_emit(proc, gep); - return ssa_make_lvalue(v, expr); + return ssa_make_addr(v, expr); case_end; } @@ -2079,13 +2041,13 @@ ssaLvalue ssa_build_addr(ssaProcedure *proc, AstNode *expr) { "\tAstNode: %.*s\n", LIT(ast_node_strings[expr->kind])); - return ssa_make_lvalue(NULL, NULL); + return ssa_make_addr(NULL, NULL); } -void ssa_build_assign_op(ssaProcedure *proc, ssaLvalue lhs, ssaValue *value, Token op) { +void ssa_build_assign_op(ssaProcedure *proc, ssaAddr lhs, ssaValue *value, Token op) { ssaValue *old_value = ssa_lvalue_load(proc, lhs); - ssaValue *change = ssa_emit_conv(proc, value, ssa_value_type(old_value)); - ssaValue *new_value = ssa_emit_arith(proc, op, old_value, change, ssa_lvalue_type(lhs)); + ssaValue *change = ssa_emit_conv(proc, value, ssa_type(old_value)); + ssaValue *new_value = ssa_emit_arith(proc, op, old_value, change, ssa_type(old_value)); ssa_lvalue_store(proc, lhs, new_value); } @@ -2139,7 +2101,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { case_ast_node(vd, VarDecl, node); if (vd->kind == Declaration_Mutable) { if (vd->name_count == vd->value_count) { // 1:1 assigment - gbArray(ssaLvalue) lvals; + gbArray(ssaAddr) lvals; gbArray(ssaValue *) inits; gb_array_init_reserve(lvals, gb_heap_allocator(), vd->name_count); gb_array_init_reserve(inits, gb_heap_allocator(), vd->name_count); @@ -2147,11 +2109,11 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { defer (gb_array_free(inits)); for (AstNode *name = vd->name_list; name != NULL; name = name->next) { - ssaLvalue lval = ssa_make_lvalue(NULL, NULL); + ssaAddr lval = ssa_make_addr(NULL, NULL); if (!ssa_is_blank_ident(name)) { ssa_add_local_for_identifier(proc, name); lval = ssa_build_addr(proc, name); - GB_ASSERT(lval.address != NULL); + GB_ASSERT(lval.addr != NULL); } gb_array_append(lvals, lval); @@ -2164,10 +2126,8 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { gb_for_array(i, inits) { - if (lvals[i].address != NULL) { - ssaValue *v = ssa_emit_conv(proc, inits[i], ssa_value_type(lvals[i].address)); - ssa_lvalue_store(proc, lvals[i], v); - } + ssaValue *v = ssa_emit_conv(proc, inits[i], ssa_type(lvals[i])); + ssa_lvalue_store(proc, lvals[i], v); } } else if (vd->value_count == 0) { // declared and zero-initialized @@ -2177,7 +2137,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { } } } else { // Tuple(s) - gbArray(ssaLvalue) lvals; + gbArray(ssaAddr) lvals; gbArray(ssaValue *) inits; gb_array_init_reserve(lvals, gb_heap_allocator(), vd->name_count); gb_array_init_reserve(inits, gb_heap_allocator(), vd->name_count); @@ -2185,7 +2145,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { defer (gb_array_free(inits)); for (AstNode *name = vd->name_list; name != NULL; name = name->next) { - ssaLvalue lval = ssa_make_lvalue(NULL, NULL); + ssaAddr lval = ssa_make_addr(NULL, NULL); if (!ssa_is_blank_ident(name)) { ssa_add_local_for_identifier(proc, name); lval = ssa_build_addr(proc, name); @@ -2196,7 +2156,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { for (AstNode *value = vd->value_list; value != NULL; value = value->next) { ssaValue *init = ssa_build_expr(proc, value); - Type *t = ssa_value_type(init); + Type *t = ssa_type(init); if (t->kind == Type_Tuple) { for (isize i = 0; i < t->tuple.variable_count; i++) { Entity *e = t->tuple.variables[i]; @@ -2210,7 +2170,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { gb_for_array(i, inits) { - ssaValue *v = ssa_emit_conv(proc, inits[i], ssa_value_type(lvals[i].address)); + ssaValue *v = ssa_emit_conv(proc, inits[i], ssa_type(lvals[i])); ssa_lvalue_store(proc, lvals[i], v); } } @@ -2239,10 +2199,10 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { ssaValue *value = ssa_make_value_procedure(proc->module->allocator, proc->module, e->type, pd->type, pd->body, name); - value->proc.tags = pd->tags; + value->Proc.tags = pd->tags; ssa_module_add_value(proc->module, e, value); - gb_array_append(proc->children, &value->proc); + gb_array_append(proc->children, &value->Proc); ssa_build_proc(value, proc); } else { String name = pd->name->Ident.token.string; @@ -2256,7 +2216,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { ssaValue *value = ssa_make_value_procedure(proc->module->allocator, proc->module, e->type, pd->type, pd->body, name); ssa_module_add_value(proc->module, e, value); - gb_array_append(proc->children, &value->proc); + gb_array_append(proc->children, &value->Proc); ssa_build_proc(value, proc); } case_end; @@ -2290,8 +2250,8 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { } else if (op.kind == Token_Decrement) { op.kind = Token_Sub; } - ssaLvalue lval = ssa_build_addr(proc, ids->expr); - ssaValue *one = ssa_emit_conv(proc, v_one, ssa_lvalue_type(lval)); + ssaAddr lval = ssa_build_addr(proc, ids->expr); + ssaValue *one = ssa_emit_conv(proc, v_one, ssa_type(lval)); ssa_build_assign_op(proc, lval, one, op); case_end; @@ -2299,14 +2259,14 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { case_ast_node(as, AssignStmt, node); switch (as->op.kind) { case Token_Eq: { - gbArray(ssaLvalue) lvals; + gbArray(ssaAddr) lvals; gb_array_init(lvals, gb_heap_allocator()); defer (gb_array_free(lvals)); for (AstNode *lhs = as->lhs_list; lhs != NULL; lhs = lhs->next) { - ssaLvalue lval = {}; + ssaAddr lval = {}; if (!ssa_is_blank_ident(lhs)) { lval = ssa_build_addr(proc, lhs); } @@ -2339,7 +2299,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { for (AstNode *rhs = as->rhs_list; rhs != NULL; rhs = rhs->next) { ssaValue *init = ssa_build_expr(proc, rhs); - Type *t = ssa_value_type(init); + Type *t = ssa_type(init); // TODO(bill): refactor for code reuse as this is repeated a bit if (t->kind == Type_Tuple) { for (isize i = 0; i < t->tuple.variable_count; i++) { @@ -2366,7 +2326,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { i32 kind = op.kind; kind += Token_Add - Token_AddEq; // Convert += to + op.kind = cast(TokenKind)kind; - ssaLvalue lhs = ssa_build_addr(proc, as->lhs_list); + ssaAddr lhs = ssa_build_addr(proc, as->lhs_list); ssaValue *value = ssa_build_expr(proc, as->rhs_list); ssa_build_assign_op(proc, lhs, value, op); } break; @@ -2402,7 +2362,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { } else if (return_count == 1) { Entity *e = return_type_tuple->variables[0]; v = ssa_build_expr(proc, rs->result_list); - ssa_value_set_type(v, e->type); + ssa_set_type(v, e->type); } else if (return_count == 0) { // No return values } else { @@ -2416,7 +2376,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { i++, r = r->next) { Entity *e = return_type_tuple->variables[i]; ssaValue *res = ssa_build_expr(proc, r); - ssa_value_set_type(res, e->type); + ssa_set_type(res, e->type); ssaValue *field = ssa_emit_struct_gep(proc, v, i, e->type); ssa_emit_store(proc, field, res); } @@ -2547,11 +2507,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { void ssa_emit_startup_runtime(ssaProcedure *proc) { GB_ASSERT(proc->parent == NULL && are_strings_equal(proc->name, make_string("main"))); - ssaValue *v = ssa_alloc_instr(proc->module->allocator, ssaInstr_StartupRuntime); - if (proc->curr_block) { - gb_array_append(proc->curr_block->values, v); - } - ssa_emit(proc, v); + ssa_emit(proc, ssa_alloc_instr(proc, ssaInstr_StartupRuntime)); } void ssa_insert_code_before_proc(ssaProcedure* proc, ssaProcedure *parent) { @@ -2564,7 +2520,7 @@ void ssa_insert_code_before_proc(ssaProcedure* proc, ssaProcedure *parent) { void ssa_build_proc(ssaValue *value, ssaProcedure *parent) { - ssaProcedure *proc = &value->proc; + ssaProcedure *proc = &value->Proc; proc->parent = parent; |