diff options
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/codegen.cpp | 13 | ||||
| -rw-r--r-- | src/codegen/print_llvm.cpp | 28 | ||||
| -rw-r--r-- | src/codegen/ssa.cpp | 112 |
3 files changed, 88 insertions, 65 deletions
diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp index be2e598eb..a6d6b404c 100644 --- a/src/codegen/codegen.cpp +++ b/src/codegen/codegen.cpp @@ -296,19 +296,19 @@ void ssa_gen_tree(ssaGen *s) { Type *t_string_slice_ptr = make_type_pointer(a, make_type_slice(a, t_string)); auto get_type_info_ptr = [](ssaProcedure *proc, ssaValue *type_info_data, Type *type) -> ssaValue * { - return ssa_emit_array_gep(proc, type_info_data, - ssa_type_info_index(proc->module->info, type)); + return ssa_emit_array_ep(proc, type_info_data, cast(i32)ssa_type_info_index(proc->module->info, type)); }; - isize type_info_member_index = 0; + i32 type_info_member_index = 0; - auto type_info_member_offset = [](ssaProcedure *proc, ssaValue *data, isize count, isize *index) -> ssaValue * { - ssaValue *offset = ssa_emit_array_gep(proc, data, *index); + auto type_info_member_offset = [](ssaProcedure *proc, ssaValue *data, isize count, i32 *index) -> ssaValue * { + ssaValue *offset = ssa_emit_array_ep(proc, data, *index); *index += count; return offset; }; + for_array(type_info_map_index, info->type_info_map.entries) { auto *entry = &info->type_info_map.entries[type_info_map_index]; Type *t = cast(Type *)cast(uintptr)entry->key.key; @@ -659,7 +659,7 @@ void ssa_gen_tree(ssaGen *s) { } if (tag != NULL) { - ssaValue *gep = ssa_emit_array_gep(proc, type_info_data, entry_index); + ssaValue *gep = ssa_emit_array_ep(proc, type_info_data, entry_index); ssaValue *val = ssa_emit_conv(proc, ssa_emit_load(proc, tag), t_type_info); ssa_emit_store(proc, gep, val); } @@ -673,6 +673,7 @@ void ssa_gen_tree(ssaGen *s) { ssa_build_proc(m->procs[i], m->procs[i]->Proc.parent); } + // m->layout = make_string("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"); } diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index 6b420236b..a1495f302 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -715,14 +715,24 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) { ssa_fprintf(f, "\n"); } break; - case ssaInstr_ExtractValue: { - Type *et = instr->ExtractValue.elem_type; + case ssaInstr_ArrayExtractValue: { + Type *et = ssa_type(instr->ArrayExtractValue.address); ssa_fprintf(f, "%%%d = extractvalue ", value->index); ssa_print_type(f, m, et); ssa_fprintf(f, " "); - ssa_print_value(f, m, instr->ExtractValue.address, et); - ssa_fprintf(f, ", %d\n", instr->ExtractValue.index); + ssa_print_value(f, m, instr->ArrayExtractValue.address, et); + ssa_fprintf(f, ", %d\n", instr->ArrayExtractValue.index); + } break; + + case ssaInstr_StructExtractValue: { + Type *et = ssa_type(instr->StructExtractValue.address); + ssa_fprintf(f, "%%%d = extractvalue ", value->index); + + ssa_print_type(f, m, et); + ssa_fprintf(f, " "); + ssa_print_value(f, m, instr->StructExtractValue.address, et); + ssa_fprintf(f, ", %d\n", instr->StructExtractValue.index); } break; case ssaInstr_Jump: {; @@ -731,14 +741,14 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) { ssa_fprintf(f, "\n"); } break; - case ssaInstr_CondJump: {; + case ssaInstr_If: {; ssa_fprintf(f, "br "); ssa_print_type(f, m, t_bool); ssa_fprintf(f, " "); - ssa_print_value(f, m, instr->CondJump.cond, t_bool); - ssa_fprintf(f, ", ", instr->CondJump.cond->index); - ssa_fprintf(f, "label %%"); ssa_print_block_name(f, instr->CondJump.true_block); - ssa_fprintf(f, ", label %%"); ssa_print_block_name(f, instr->CondJump.false_block); + ssa_print_value(f, m, instr->If.cond, t_bool); + ssa_fprintf(f, ", ", instr->If.cond->index); + ssa_fprintf(f, "label %%"); ssa_print_block_name(f, instr->If.true_block); + ssa_fprintf(f, ", label %%"); ssa_print_block_name(f, instr->If.false_block); ssa_fprintf(f, "\n"); } break; diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index fe167398f..b18802ec7 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -154,14 +154,14 @@ struct ssaProcedure { SSA_INSTR_KIND(ZeroInit), \ SSA_INSTR_KIND(Store), \ SSA_INSTR_KIND(Load), \ + SSA_INSTR_KIND(PtrOffset), \ SSA_INSTR_KIND(ArrayElementPtr), \ SSA_INSTR_KIND(StructElementPtr), \ - SSA_INSTR_KIND(PtrOffset), \ - SSA_INSTR_KIND(ExtractValue), \ - SSA_INSTR_KIND(InsertValue), \ + SSA_INSTR_KIND(ArrayExtractValue), \ + SSA_INSTR_KIND(StructExtractValue), \ SSA_INSTR_KIND(Conv), \ SSA_INSTR_KIND(Jump), \ - SSA_INSTR_KIND(CondJump), \ + SSA_INSTR_KIND(If), \ SSA_INSTR_KIND(Return), \ SSA_INSTR_KIND(Select), \ SSA_INSTR_KIND(Phi), \ @@ -255,9 +255,13 @@ struct ssaInstr { struct { ssaValue *address; Type * result_type; - Type * elem_type; i32 index; - } ExtractValue; + } ArrayExtractValue; + struct { + ssaValue *address; + Type * result_type; + i32 index; + } StructExtractValue; struct { ssaValue *value; ssaValue *elem; @@ -275,7 +279,7 @@ struct ssaInstr { ssaValue *cond; ssaBlock *true_block; ssaBlock *false_block; - } CondJump; + } If; struct { ssaValue *value; } Return; @@ -547,10 +551,10 @@ Type *ssa_instr_type(ssaInstr *instr) { return ssa_type(instr->PtrOffset.address); case ssaInstr_Phi: return instr->Phi.type; - case ssaInstr_ExtractValue: - return instr->ExtractValue.result_type; - case ssaInstr_InsertValue: - return ssa_type(instr->InsertValue.value); + case ssaInstr_ArrayExtractValue: + return instr->ArrayExtractValue.result_type; + case ssaInstr_StructExtractValue: + return instr->StructExtractValue.result_type; case ssaInstr_BinaryOp: return instr->BinaryOp.type; case ssaInstr_Conv: @@ -661,19 +665,19 @@ void ssa_add_operands(Array<ssaValue *> *ops, ssaInstr *i) { array_add(ops, i->PtrOffset.address); array_add(ops, i->PtrOffset.offset); break; - case ssaInstr_ExtractValue: - array_add(ops, i->ExtractValue.address); + case ssaInstr_ArrayExtractValue: + array_add(ops, i->ArrayExtractValue.address); break; - case ssaInstr_InsertValue: - array_add(ops, i->InsertValue.value); + case ssaInstr_StructExtractValue: + array_add(ops, i->StructExtractValue.address); break; case ssaInstr_Conv: array_add(ops, i->Conv.value); break; case ssaInstr_Jump: break; - case ssaInstr_CondJump: - array_add(ops, i->CondJump.cond); + case ssaInstr_If: + array_add(ops, i->If.cond); break; case ssaInstr_Return: if (i->Return.value != NULL) { @@ -904,27 +908,26 @@ ssaValue *ssa_make_instr_ptr_offset(ssaProcedure *p, ssaValue *address, ssaValue -ssaValue *ssa_make_instr_extract_value(ssaProcedure *p, ssaValue *address, i32 index, Type *result_type) { - ssaValue *v = ssa_alloc_instr(p, ssaInstr_ExtractValue); +ssaValue *ssa_make_instr_array_extract_value(ssaProcedure *p, ssaValue *address, i32 index) { + ssaValue *v = ssa_alloc_instr(p, ssaInstr_ArrayExtractValue); 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; + i->ArrayExtractValue.address = address; + i->ArrayExtractValue.index = index; + Type *t = base_type(ssa_type(address)); + GB_ASSERT(is_type_array(t)); + i->ArrayExtractValue.result_type = t->Array.elem; return v; } -ssaValue *ssa_make_instr_insert_value(ssaProcedure *p, ssaValue *value, ssaValue *elem, i32 index) { - Type *t = ssa_type(value); - GB_ASSERT(is_type_array(t) || is_type_struct(t)); - ssaValue *v = ssa_alloc_instr(p, ssaInstr_InsertValue); - v->Instr.InsertValue.value = value; - v->Instr.InsertValue.elem = elem; - v->Instr.InsertValue.index = index; + +ssaValue *ssa_make_instr_struct_extract_value(ssaProcedure *p, ssaValue *address, i32 index, Type *result_type) { + ssaValue *v = ssa_alloc_instr(p, ssaInstr_StructExtractValue); + ssaInstr *i = &v->Instr; + i->StructExtractValue.address = address; + i->StructExtractValue.index = index; + i->StructExtractValue.result_type = result_type; return v; } - ssaValue *ssa_make_instr_binary_op(ssaProcedure *p, TokenKind op, ssaValue *left, ssaValue *right, Type *type) { ssaValue *v = ssa_alloc_instr(p, ssaInstr_BinaryOp); ssaInstr *i = &v->Instr; @@ -941,12 +944,12 @@ ssaValue *ssa_make_instr_jump(ssaProcedure *p, ssaBlock *block) { i->Jump.block = block; return v; } -ssaValue *ssa_make_instr_cond_jump(ssaProcedure *p, ssaValue *cond, ssaBlock *true_block, ssaBlock *false_block) { - ssaValue *v = ssa_alloc_instr(p, ssaInstr_CondJump); +ssaValue *ssa_make_instr_if(ssaProcedure *p, ssaValue *cond, ssaBlock *true_block, ssaBlock *false_block) { + ssaValue *v = ssa_alloc_instr(p, ssaInstr_If); ssaInstr *i = &v->Instr; - i->CondJump.cond = cond; - i->CondJump.true_block = true_block; - i->CondJump.false_block = false_block; + i->If.cond = cond; + i->If.true_block = true_block; + i->If.false_block = false_block; return v; } @@ -1398,7 +1401,7 @@ void ssa_emit_if(ssaProcedure *proc, ssaValue *cond, ssaBlock *true_block, ssaBl if (b == NULL) { return; } - ssa_emit(proc, ssa_make_instr_cond_jump(proc, cond, true_block, false_block)); + ssa_emit(proc, ssa_make_instr_if(proc, cond, true_block, false_block)); ssa_add_edge(b, true_block); ssa_add_edge(b, false_block); proc->curr_block = NULL; @@ -1607,7 +1610,7 @@ ssaValue *ssa_emit_comp(ssaProcedure *proc, TokenKind op_kind, ssaValue *left, s return ssa_emit(proc, ssa_make_instr_binary_op(proc, op_kind, left, right, result)); } -ssaValue *ssa_emit_array_gep(ssaProcedure *proc, ssaValue *s, ssaValue *index) { +ssaValue *ssa_emit_array_ep(ssaProcedure *proc, ssaValue *s, ssaValue *index) { ssaValue *gep = NULL; Type *st = base_type(type_deref(ssa_type(s))); GB_ASSERT(is_type_array(st)); @@ -1617,8 +1620,8 @@ ssaValue *ssa_emit_array_gep(ssaProcedure *proc, ssaValue *s, ssaValue *index) { return ssa_emit(proc, ssa_make_instr_array_element_ptr(proc, s, index)); } -ssaValue *ssa_emit_array_gep(ssaProcedure *proc, ssaValue *s, i32 index) { - return ssa_emit_array_gep(proc, s, ssa_make_const_i32(proc->module->allocator, index)); +ssaValue *ssa_emit_array_ep(ssaProcedure *proc, ssaValue *s, i32 index) { + return ssa_emit_array_ep(proc, s, ssa_make_const_i32(proc->module->allocator, index)); } @@ -1677,6 +1680,14 @@ ssaValue *ssa_emit_struct_ep(ssaProcedure *proc, ssaValue *s, i32 index) { } + +ssaValue *ssa_emit_array_ev(ssaProcedure *proc, ssaValue *s, i32 index) { + ssaValue *gep = NULL; + Type *st = base_type(ssa_type(s)); + GB_ASSERT(is_type_array(st)); + return ssa_emit(proc, ssa_make_instr_array_extract_value(proc, s, index)); +} + ssaValue *ssa_emit_struct_ev(ssaProcedure *proc, ssaValue *s, i32 index) { // NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32 @@ -1728,7 +1739,7 @@ ssaValue *ssa_emit_struct_ev(ssaProcedure *proc, ssaValue *s, i32 index) { GB_ASSERT(result_type != NULL); - return ssa_emit(proc, ssa_make_instr_extract_value(proc, s, index, result_type)); + return ssa_emit(proc, ssa_make_instr_struct_extract_value(proc, s, index, result_type)); } @@ -1821,7 +1832,7 @@ isize ssa_type_info_index(CheckerInfo *info, Type *type) { // TODO(bill): This is O(n) and can be very slow for_array(i, info->type_info_map.entries){ auto *e = &info->type_info_map.entries[i]; - Type *prev_type = cast(Type *)cast(uintptr)e->key.key; + Type *prev_type = cast(Type *)e->key.ptr; if (are_types_identical(prev_type, type)) { entry_index = e->value; // NOTE(bill): Add it to the search map @@ -1830,6 +1841,7 @@ isize ssa_type_info_index(CheckerInfo *info, Type *type) { } } } + if (entry_index < 0) { compiler_error("Type_Info for `%s` could not be found", type_to_string(type)); } @@ -1843,7 +1855,7 @@ ssaValue *ssa_type_info(ssaProcedure *proc, Type *type) { CheckerInfo *info = proc->module->info; ssaValue *entry_index = ssa_make_const_i32(proc->module->allocator, ssa_type_info_index(info, type)); - return ssa_emit_array_gep(proc, type_info_data, entry_index); + return ssa_emit_array_ep(proc, type_info_data, entry_index); } @@ -1853,7 +1865,7 @@ ssaValue *ssa_type_info(ssaProcedure *proc, Type *type) { ssaValue *ssa_array_elem(ssaProcedure *proc, ssaValue *array) { - return ssa_emit_array_gep(proc, array, v_zero32); + return ssa_emit_array_ep(proc, array, v_zero32); } ssaValue *ssa_array_len(ssaProcedure *proc, ssaValue *array) { Type *t = ssa_type(array); @@ -2792,7 +2804,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue 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_array_gep(proc, v, i); + ssaValue *gep = ssa_emit_array_ep(proc, v, i); ssa_emit_store(proc, gep, ev); } } @@ -2806,7 +2818,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue ssaValue *slice = ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr)); GB_ASSERT(slice->kind == ssaValue_ConstantSlice); - ssaValue *data = ssa_emit_array_gep(proc, slice->ConstantSlice.backing_array, v_zero32); + ssaValue *data = ssa_emit_array_ep(proc, slice->ConstantSlice.backing_array, v_zero32); for_array(i, cl->elems) { AstNode *elem = cl->elems[i]; @@ -3245,11 +3257,11 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue ssaValue *base_array = ssa_add_local_generated(proc, make_type_array(allocator, elem_type, slice_len)); for (isize i = type->param_count-1, j = 0; i < arg_count; i++, j++) { - ssaValue *addr = ssa_emit_array_gep(proc, base_array, j); + ssaValue *addr = ssa_emit_array_ep(proc, base_array, j); ssa_emit_store(proc, addr, args[i]); } - ssaValue *base_elem = ssa_emit_array_gep(proc, base_array, 0); + ssaValue *base_elem = ssa_emit_array_ep(proc, base_array, 0); ssaValue *slice_elem = ssa_emit_struct_ep(proc, slice, 0); ssa_emit_store(proc, slice_elem, base_elem); ssaValue *len = ssa_make_const_int(allocator, slice_len); @@ -3492,7 +3504,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) { } } ssaValue *index = ssa_emit_conv(proc, ssa_build_expr(proc, ie->index), t_int); - ssaValue *elem = ssa_emit_array_gep(proc, array, index); + ssaValue *elem = ssa_emit_array_ep(proc, array, index); ssaValue *len = ssa_make_const_int(a, t->Vector.count); ssa_array_bounds_check(proc, ast_node_token(ie->index), index, len); return ssa_make_addr(elem, expr); |