aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-08-24 15:06:36 +0100
committerGinger Bill <bill@gingerbill.org>2016-08-24 15:06:36 +0100
commit6bd898e552392b1bd11ad16c7476833261c1d4b7 (patch)
treeadd523b133a1c4e0d2189d437ad7a1616c024050 /src/codegen
parent975705f1fc68af73b25ff135733c57d8cfd62912 (diff)
Untagged (unsafe) unions and unambiguous in|postfix notation.
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/print_llvm.cpp62
-rw-r--r--src/codegen/ssa.cpp92
2 files changed, 84 insertions, 70 deletions
diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp
index cb2e1e3ad..c5571712c 100644
--- a/src/codegen/print_llvm.cpp
+++ b/src/codegen/print_llvm.cpp
@@ -99,7 +99,7 @@ void ssa_print_type(gbFile *f, BaseTypeSizes s, Type *t) {
switch (t->kind) {
case Type_Basic:
- switch (t->basic.kind) {
+ switch (t->Basic.kind) {
case Basic_bool: ssa_fprintf(f, "i1"); break;
case Basic_i8: ssa_fprintf(f, "i8"); break;
case Basic_i16: ssa_fprintf(f, "i16"); break;
@@ -120,74 +120,78 @@ void ssa_print_type(gbFile *f, BaseTypeSizes s, Type *t) {
}
break;
case Type_Array:
- ssa_fprintf(f, "[%lld x ", t->array.count);
- ssa_print_type(f, s, t->array.elem);
+ ssa_fprintf(f, "[%lld x ", t->Array.count);
+ ssa_print_type(f, s, t->Array.elem);
ssa_fprintf(f, "]");
break;
case Type_Vector: {
// TODO(bill): actually do correctly
- ssa_fprintf(f, "<%lld x ", t->vector.count);
- ssa_print_type(f, s, t->vector.elem);
+ ssa_fprintf(f, "<%lld x ", t->Vector.count);
+ ssa_print_type(f, s, t->Vector.elem);
ssa_fprintf(f, ">");
} break;
case Type_Slice:
ssa_fprintf(f, "{");
- ssa_print_type(f, s, t->slice.elem);
+ ssa_print_type(f, s, t->Slice.elem);
ssa_fprintf(f, "*, i%lld, i%lld}", word_bits, word_bits);
break;
- case Type_Structure:
- if (t->structure.is_packed) {
+ case Type_Struct:
+ if (t->Struct.is_packed) {
ssa_fprintf(f, "<");
}
ssa_fprintf(f, "{");
- for (isize i = 0; i < t->structure.field_count; i++) {
+ for (isize i = 0; i < t->Struct.field_count; i++) {
if (i > 0) {
ssa_fprintf(f, ", ");
}
- Type *ft = t->structure.fields[i]->type;
+ Type *ft = t->Struct.fields[i]->type;
Type *bft = get_base_type(ft);
- if (bft->kind != Type_Structure) {
+ if (bft->kind != Type_Struct) {
ft = bft;
}
ssa_print_type(f, s, ft);
}
ssa_fprintf(f, "}");
- if (t->structure.is_packed) {
+ if (t->Struct.is_packed) {
ssa_fprintf(f, ">");
}
break;
- case Type_Enumeration:
- ssa_print_type(f, s, t->enumeration.base);
+ case Type_Union: {
+ i64 size = type_size_of(s, gb_heap_allocator(), t);
+ ssa_fprintf(f, "[%lld x i8]", size);
+ } break;
+ case Type_Enum:
+ ssa_print_type(f, s, t->Enum.base);
break;
case Type_Pointer:
- ssa_print_type(f, s, t->pointer.elem);
+ ssa_print_type(f, s, t->Pointer.elem);
ssa_fprintf(f, "*");
break;
case Type_Named:
- ssa_print_encoded_local(f, t->named.name);
+ ssa_print_encoded_local(f, t->Named.name);
break;
case Type_Tuple:
- if (t->tuple.variable_count == 1) {
- ssa_print_type(f, s, t->tuple.variables[0]->type);
+ if (t->Tuple.variable_count == 1) {
+ ssa_print_type(f, s, t->Tuple.variables[0]->type);
} else {
ssa_fprintf(f, "{");
- for (isize i = 0; i < t->tuple.variable_count; i++) {
+ for (isize i = 0; i < t->Tuple.variable_count; i++) {
if (i > 0) ssa_fprintf(f, ", ");
- ssa_print_type(f, s, t->tuple.variables[i]->type);
+ ssa_print_type(f, s, t->Tuple.variables[i]->type);
}
ssa_fprintf(f, "}");
}
break;
case Type_Proc: {
- if (t->proc.result_count == 0) {
+ if (t->Proc.result_count == 0) {
ssa_fprintf(f, "void");
} else {
- ssa_print_type(f, s, t->proc.results);
+ ssa_print_type(f, s, t->Proc.results);
}
ssa_fprintf(f, " (");
- auto *params = &t->proc.params->tuple;
- for (isize i = 0; i < t->proc.param_count; i++) {
+ auto *params = &t->Proc.params->Tuple;
+ for (isize i = 0; i < t->Proc.param_count; i++) {
if (i > 0) {
ssa_fprintf(f, ", ");
}
@@ -234,7 +238,7 @@ void ssa_print_exact_value(gbFile *f, ssaModule *m, ExactValue value, Type *type
} break;
case ExactValue_Float: {
u64 u = *cast(u64*)&value.value_float;
- if (is_type_float(type) && type->basic.kind == Basic_f32) {
+ 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 29 bits
@@ -437,7 +441,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
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);
+ elem_type = get_base_type(elem_type->Vector.elem);
}
ssa_fprintf(f, "%%%d = ", value->id);
@@ -558,7 +562,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
if (call->arg_count > 0) {
Type *proc_type = get_base_type(ssa_type(call->value));
GB_ASSERT(proc_type->kind == Type_Proc);
- auto *params = &proc_type->proc.params->tuple;
+ auto *params = &proc_type->Proc.params->Tuple;
for (isize i = 0; i < call->arg_count; i++) {
Entity *e = params->variables[i];
GB_ASSERT(e != NULL);
@@ -682,7 +686,7 @@ void ssa_print_proc(gbFile *f, ssaModule *m, ssaProcedure *proc) {
ssa_fprintf(f, "\ndefine ");
}
- auto *proc_type = &proc->type->proc;
+ auto *proc_type = &proc->type->Proc;
if (proc_type->result_count == 0) {
ssa_fprintf(f, "void");
@@ -696,7 +700,7 @@ void ssa_print_proc(gbFile *f, ssaModule *m, ssaProcedure *proc) {
ssa_fprintf(f, "(");
if (proc_type->param_count > 0) {
- auto *params = &proc_type->params->tuple;
+ auto *params = &proc_type->params->Tuple;
for (isize i = 0; i < params->variable_count; i++) {
Entity *e = params->variables[i];
if (i > 0)
diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp
index ad5e997ed..c346f39b3 100644
--- a/src/codegen/ssa.cpp
+++ b/src/codegen/ssa.cpp
@@ -347,8 +347,8 @@ Type *ssa_type(ssaInstr *instr) {
case ssaInstr_Call: {
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;
+ if (pt->kind == Type_Tuple && pt->Tuple.variable_count == 1)
+ return pt->Tuple.variables[0]->type;
return pt;
}
return NULL;
@@ -536,7 +536,7 @@ ssaValue *ssa_make_instr_extract_value(ssaProcedure *p, ssaValue *address, i32 i
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);
+ GB_ASSERT(et->kind == Type_Struct || et->kind == Type_Array || et->kind == Type_Tuple);
return v;
}
@@ -628,7 +628,7 @@ ssaValue *ssa_make_instr_shuffle_vector(ssaProcedure *p, ssaValue *vector, i32 *
v->Instr.ShuffleVector.index_count = 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);
+ v->Instr.ShuffleVector.type = make_type_vector(p->module->allocator, vt->Vector.elem, index_count);
return v;
}
@@ -865,7 +865,7 @@ ssaValue *ssa_lvalue_store(ssaProcedure *proc, ssaAddr lval, ssaValue *value) {
if (lval.is_vector) {
// HACK(bill): Fix how lvalues for vectors work
ssaValue *v = ssa_emit_load(proc, lval.addr);
- Type *elem_type = get_base_type(ssa_type(v))->vector.elem;
+ 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.addr, out);
@@ -901,8 +901,8 @@ void ssa_begin_procedure_body(ssaProcedure *proc) {
gb_array_init(proc->defer_stmts, gb_heap_allocator());
proc->curr_block = ssa_add_block(proc, proc->type_expr, make_string("entry"));
- if (proc->type->proc.params != NULL) {
- auto *params = &proc->type->proc.params->tuple;
+ if (proc->type->Proc.params != NULL) {
+ auto *params = &proc->type->Proc.params->Tuple;
for (isize i = 0; i < params->variable_count; i++) {
Entity *e = params->variables[i];
ssa_add_param(proc, e);
@@ -911,7 +911,7 @@ void ssa_begin_procedure_body(ssaProcedure *proc) {
}
void ssa_end_procedure_body(ssaProcedure *proc) {
- if (proc->type->proc.result_count == 0) {
+ if (proc->type->Proc.result_count == 0) {
ssa_emit_ret(proc, NULL);
}
@@ -1005,7 +1005,7 @@ ssaValue *ssa_emit_comp(ssaProcedure *proc, Token op, ssaValue *left, ssaValue *
ssaValue *v = ssa_make_instr_binary_op(proc, op, left, right);
Type *result = t_bool;
if (is_type_vector(a)) {
- result = make_type_vector(proc->module->allocator, t_bool, a->vector.count);
+ result = make_type_vector(proc->module->allocator, t_bool, a->Vector.count);
}
ssa_set_type(v, result);
return ssa_emit(proc, v);
@@ -1057,7 +1057,7 @@ ssaValue *ssa_emit_struct_ev(ssaProcedure *proc, ssaValue *s, i32 index, Type *r
ssaValue *ssa_array_elem(ssaProcedure *proc, ssaValue *array) {
Type *t = ssa_type(array);
GB_ASSERT(t->kind == Type_Array);
- Type *base_type = t->array.elem;
+ 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.GetElementPtr.elem_type = t;
@@ -1067,7 +1067,7 @@ ssaValue *ssa_array_elem(ssaProcedure *proc, ssaValue *array) {
ssaValue *ssa_array_len(ssaProcedure *proc, ssaValue *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));
+ return ssa_make_value_constant(proc->module->allocator, t_int, make_exact_value_integer(t->Array.count));
}
ssaValue *ssa_array_cap(ssaProcedure *proc, ssaValue *array) {
return ssa_array_len(proc, array);
@@ -1077,7 +1077,7 @@ ssaValue *ssa_slice_elem(ssaProcedure *proc, ssaValue *slice) {
Type *t = ssa_type(slice);
GB_ASSERT(t->kind == Type_Slice);
- Type *result_type = make_type_pointer(proc->module->allocator, t->slice.elem);
+ 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) {
@@ -1093,7 +1093,7 @@ ssaValue *ssa_slice_cap(ssaProcedure *proc, ssaValue *slice) {
ssaValue *ssa_string_elem(ssaProcedure *proc, ssaValue *string) {
Type *t = ssa_type(string);
- GB_ASSERT(t->kind == Type_Basic && t->basic.kind == Basic_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);
@@ -1103,7 +1103,7 @@ ssaValue *ssa_string_elem(ssaProcedure *proc, ssaValue *string) {
}
ssaValue *ssa_string_len(ssaProcedure *proc, ssaValue *string) {
Type *t = ssa_type(string);
- GB_ASSERT(t->kind == Type_Basic && t->basic.kind == Basic_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));
}
@@ -1217,7 +1217,7 @@ ssaValue *ssa_emit_string(ssaProcedure *proc, ssaValue *elem, ssaValue *len) {
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));
+ GB_ASSERT(is_type_u8(t_u8_ptr->Pointer.elem));
ssaValue *str = ssa_add_local_generated(proc, t_string);
ssaValue *str_elem = ssa_emit_struct_gep(proc, str, v_zero32, t_u8_ptr);
@@ -1293,8 +1293,8 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) {
// float -> float
if (is_type_float(src) && is_type_float(dst)) {
- i64 sz = basic_type_sizes[src->basic.kind];
- i64 dz = basic_type_sizes[dst->basic.kind];
+ i64 sz = basic_type_sizes[src->Basic.kind];
+ i64 dz = basic_type_sizes[dst->Basic.kind];
ssaConvKind kind = ssaConv_fptrunc;
if (dz >= sz) {
kind = ssaConv_fpext;
@@ -1368,13 +1368,13 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) {
}
if (is_type_vector(dst)) {
- Type *dst_elem = dst->vector.elem;
+ 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;
+ 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;
@@ -1557,9 +1557,9 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
Type *et = NULL;
switch (base_type->kind) {
- case Type_Vector: et = base_type->vector.elem; break;
- case Type_Array: et = base_type->array.elem; break;
- case Type_Slice: et = base_type->slice.elem; break;
+ case Type_Vector: et = base_type->Vector.elem; break;
+ case Type_Array: et = base_type->Array.elem; break;
+ case Type_Slice: et = base_type->Slice.elem; break;
}
switch (base_type->kind) {
@@ -1578,8 +1578,8 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssaValue *i = ssa_make_value_constant(proc->module->allocator, t_int, make_exact_value_integer(index));
result = ssa_emit(proc, ssa_make_instr_insert_element(proc, result, ev, i));
}
- if (index == 1 && base_type->vector.count > 1) {
- isize index_count = base_type->vector.count;
+ if (index == 1 && base_type->Vector.count > 1) {
+ isize index_count = base_type->Vector.count;
i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count);
for (isize i = 0; i < index_count; i++) {
indices[i] = 0;
@@ -1592,8 +1592,8 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
return result;
} break;
- case Type_Structure: {
- auto *st = &base_type->structure;
+ case Type_Struct: {
+ auto *st = &base_type->Struct;
if (cl->elem_list != NULL) {
isize index = 0;
AstNode *elem = cl->elem_list;
@@ -1699,7 +1699,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
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;
+ Type *elem_type = slice_type->Slice.elem;
i64 size_of_elem = type_size_of(proc->module->sizes, proc->module->allocator, elem_type);
ssaValue *dst = ssa_emit_conv(proc, ssa_slice_elem(proc, dst_slice), t_rawptr);
@@ -1803,7 +1803,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssaValue *value = ssa_build_expr(proc, ce->proc);
Type *proc_type_ = get_base_type(ssa_type(value));
GB_ASSERT(proc_type_->kind == Type_Proc);
- auto *type = &proc_type_->proc;
+ auto *type = &proc_type_->Proc;
isize arg_index = 0;
isize arg_count = type->param_count;
@@ -1813,8 +1813,8 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssaValue *a = ssa_build_expr(proc, arg);
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];
+ for (isize i = 0; i < at->Tuple.variable_count; i++) {
+ Entity *e = at->Tuple.variables[i];
ssaValue *v = ssa_emit_struct_ev(proc, a, i, e->type);
args[arg_index++] = v;
}
@@ -1823,7 +1823,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
}
}
- auto *pt = &proc_type_->proc.params->tuple;
+ auto *pt = &proc_type_->Proc.params->Tuple;
for (isize i = 0; i < arg_count; i++) {
args[i] = ssa_emit_conv(proc, args[i], pt->variables[i]->type);
}
@@ -1914,8 +1914,18 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
ssa_set_type(e, type_deref(type));
}
- ssaValue *v = ssa_emit_struct_gep(proc, e, field_index, entity->type);
- return ssa_make_addr(v, expr);
+ if (type->kind == Type_Union) {
+ ssaValue *v = ssa_emit_ptr_offset(proc, e, v_zero);
+ ssa_set_type(v, make_type_pointer(proc->module->allocator, type));
+ ssaValue *f = ssa_emit_conv(proc, v, make_type_pointer(proc->module->allocator, entity->type));
+ f = ssa_emit_ptr_offset(proc, f, v_zero);
+ ssa_set_type(f, entity->type);
+ return ssa_make_addr(f, expr);
+
+ } else {
+ ssaValue *v = ssa_emit_struct_gep(proc, e, field_index, entity->type);
+ return ssa_make_addr(v, expr);
+ }
case_end;
case_ast_node(ue, UnaryExpr, expr);
@@ -2159,8 +2169,8 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
ssaValue *init = ssa_build_expr(proc, value);
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];
+ for (isize i = 0; i < t->Tuple.variable_count; i++) {
+ Entity *e = t->Tuple.variables[i];
ssaValue *v = ssa_emit_struct_ev(proc, init, i, e->type);
gb_array_append(inits, v);
}
@@ -2239,7 +2249,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
ssaValue *value = ssa_make_value_type_name(proc->module->allocator,
name, e->type);
// HACK(bill): Override name of type so printer prints it correctly
- e->type->named.name = name;
+ e->type->Named.name = name;
ssa_module_add_value(proc->module, e, value);
gb_array_append(proc->module->nested_type_names, value);
case_end;
@@ -2303,8 +2313,8 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
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++) {
- Entity *e = t->tuple.variables[i];
+ for (isize i = 0; i < t->Tuple.variable_count; i++) {
+ Entity *e = t->Tuple.variables[i];
ssaValue *v = ssa_emit_struct_ev(proc, init, i, e->type);
gb_array_append(inits, v);
}
@@ -2356,8 +2366,8 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
case_ast_node(rs, ReturnStmt, node);
ssaValue *v = NULL;
- auto *return_type_tuple = &proc->type->proc.results->tuple;
- isize return_count = proc->type->proc.result_count;
+ auto *return_type_tuple = &proc->type->Proc.results->Tuple;
+ isize return_count = proc->type->Proc.result_count;
if (rs->result_count == 1 && return_count > 1) {
GB_PANIC("ReturnStmt tuple return statement");
} else if (return_count == 1) {
@@ -2368,7 +2378,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
// No return values
} else {
// 1:1 multiple return values
- Type *ret_type = proc->type->proc.results;
+ Type *ret_type = proc->type->Proc.results;
v = ssa_add_local_generated(proc, ret_type);
isize i = 0;
AstNode *r = rs->result_list;