aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-10-06 23:30:22 +0100
committerGinger Bill <bill@gingerbill.org>2016-10-06 23:30:22 +0100
commitf40482aa29f687b4630744457844bad7f45ec614 (patch)
treef9d4cdec95d29197ce5a657c370eb3461e2cbbf4 /src/codegen
parent50301557b2425fc0b4dd213ad03fb635cbd6e454 (diff)
Maybe types; value, ok := maybe_value(x)
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/codegen.cpp5
-rw-r--r--src/codegen/print_llvm.cpp16
-rw-r--r--src/codegen/ssa.cpp39
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);
}