diff options
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/codegen.cpp | 5 | ||||
| -rw-r--r-- | src/codegen/print_llvm.cpp | 16 | ||||
| -rw-r--r-- | src/codegen/ssa.cpp | 39 |
3 files changed, 55 insertions, 5 deletions
diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp index bb9b999ee..a843da551 100644 --- a/src/codegen/codegen.cpp +++ b/src/codegen/codegen.cpp @@ -389,6 +389,11 @@ void ssa_gen_tree(ssaGen *s) { ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Pointer.elem); ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_zero32, t_type_info_ptr_ptr), gep); } break; + case Type_Maybe: { + tag = ssa_add_local_generated(proc, t_type_info_maybe); + ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Maybe.elem); + ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_zero32, t_type_info_ptr_ptr), gep); + } break; case Type_Array: { tag = ssa_add_local_generated(proc, t_type_info_array); ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Array.elem); diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index f565e3570..1abbdb0d1 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -160,6 +160,17 @@ void ssa_print_type(ssaFileBuffer *f, ssaModule *m, Type *t) { case Basic_any: ssa_fprintf(f, "%%..any"); break; } break; + case Type_Pointer: + ssa_print_type(f, m, t->Pointer.elem); + ssa_fprintf(f, "*"); + break; + case Type_Maybe: + ssa_fprintf(f, "{"); + ssa_print_type(f, m, t->Maybe.elem); + ssa_fprintf(f, ", "); + ssa_print_type(f, m, t_bool); + ssa_fprintf(f, "}"); + break; case Type_Array: ssa_fprintf(f, "[%lld x ", t->Array.count); ssa_print_type(f, m, t->Array.elem); @@ -212,10 +223,7 @@ void ssa_print_type(ssaFileBuffer *f, ssaModule *m, Type *t) { } } break; - case Type_Pointer: - ssa_print_type(f, m, t->Pointer.elem); - ssa_fprintf(f, "*"); - break; + case Type_Named: if (is_type_struct(t) || is_type_union(t)) { String *name = map_get(&m->type_names, hash_pointer(t)); diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index cb7c8c380..03879509b 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -561,6 +561,10 @@ Type *ssa_type(ssaValue *value) { } ssaDebugInfo *ssa_add_debug_info_file(ssaProcedure *proc, AstFile *file) { + if (!proc->module->generate_debug_info) { + return NULL; + } + GB_ASSERT(file != NULL); ssaDebugInfo *di = ssa_alloc_debug_info(proc->module->allocator, ssaDebugInfo_File); di->File.file = file; @@ -589,6 +593,10 @@ ssaDebugInfo *ssa_add_debug_info_file(ssaProcedure *proc, AstFile *file) { ssaDebugInfo *ssa_add_debug_info_proc(ssaProcedure *proc, Entity *entity, String name, ssaDebugInfo *file) { + if (!proc->module->generate_debug_info) { + return NULL; + } + GB_ASSERT(entity != NULL); ssaDebugInfo *di = ssa_alloc_debug_info(proc->module->allocator, ssaDebugInfo_Proc); di->Proc.entity = entity; @@ -1719,6 +1727,17 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg return value; } + if (is_type_maybe(dst)) { + gbAllocator a = proc->module->allocator; + Type *elem = base_type(dst)->Maybe.elem; + ssaValue *maybe = ssa_add_local_generated(proc, dst); + ssaValue *val = ssa_emit_struct_gep(proc, maybe, v_zero32, make_type_pointer(a, elem)); + ssaValue *set = ssa_emit_struct_gep(proc, maybe, v_one32, make_type_pointer(a, t_bool)); + ssa_emit_store(proc, val, value); + ssa_emit_store(proc, set, v_true); + return ssa_emit_load(proc, maybe); + } + // integer -> integer if (is_type_integer(src) && is_type_integer(dst)) { GB_ASSERT(src->kind == Type_Basic && @@ -2658,7 +2677,6 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue return ssa_emit_select(proc, cond, neg_x, x); } break; - case BuiltinProc_enum_to_string: { ssa_emit_comment(proc, make_string("enum_to_string")); ssaValue *x = ssa_build_expr(proc, ce->args[0]); @@ -2671,6 +2689,24 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue args[1] = ssa_emit_conv(proc, x, t_i64); return ssa_emit_global_call(proc, "__enum_to_string", args, 2); } break; + + case BuiltinProc_maybe_value: { + ssa_emit_comment(proc, make_string("maybe_value")); + ssaValue *maybe = ssa_build_expr(proc, ce->args[0]); + Type *t = default_type(type_of_expr(proc->module->info, expr)); + GB_ASSERT(is_type_tuple(t)); + + Type *elem = ssa_type(maybe); + GB_ASSERT(is_type_maybe(elem)); + elem = base_type(elem)->Maybe.elem; + + ssaValue *result = ssa_add_local_generated(proc, t); + ssaValue *gep0 = ssa_emit_struct_gep(proc, result, v_zero32, make_type_pointer(proc->module->allocator, elem)); + ssaValue *gep1 = ssa_emit_struct_gep(proc, result, v_one32, make_type_pointer(proc->module->allocator, t_bool)); + ssa_emit_store(proc, gep0, ssa_emit_struct_ev(proc, maybe, 0, elem)); + ssa_emit_store(proc, gep1, ssa_emit_struct_ev(proc, maybe, 1, t_bool)); + return ssa_emit_load(proc, result); + } break; } } } @@ -3214,6 +3250,7 @@ void ssa_build_cond(ssaProcedure *proc, AstNode *cond, ssaBlock *true_block, ssa } ssaValue *expr = ssa_build_expr(proc, cond); + expr = ssa_emit_conv(proc, expr, t_bool); ssa_emit_if(proc, expr, true_block, false_block); } |