mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Tagged unions memory layout change; begin demo 002
This commit is contained in:
+26
-15
@@ -1934,9 +1934,11 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
|
|||||||
switch (id) {
|
switch (id) {
|
||||||
case BuiltinProc_new: {
|
case BuiltinProc_new: {
|
||||||
// new :: proc(Type) -> ^Type
|
// new :: proc(Type) -> ^Type
|
||||||
Type *type = check_type(c, ce->arg_list);
|
Operand op = {};
|
||||||
if (type == NULL || type == t_invalid) {
|
check_expr_or_type(c, &op, ce->arg_list);
|
||||||
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `size_of`");
|
Type *type = op.type;
|
||||||
|
if (op.mode != Addressing_Type && type == NULL || type == t_invalid) {
|
||||||
|
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `new`");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
operand->mode = Addressing_Value;
|
operand->mode = Addressing_Value;
|
||||||
@@ -1944,16 +1946,17 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
|
|||||||
} break;
|
} break;
|
||||||
case BuiltinProc_new_slice: {
|
case BuiltinProc_new_slice: {
|
||||||
// new_slice :: proc(Type, len: int[, cap: int]) -> []Type
|
// new_slice :: proc(Type, len: int[, cap: int]) -> []Type
|
||||||
Type *type = check_type(c, ce->arg_list);
|
Operand op = {};
|
||||||
if (type == NULL || type == t_invalid) {
|
check_expr_or_type(c, &op, ce->arg_list);
|
||||||
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `size_of`");
|
Type *type = op.type;
|
||||||
|
if (op.mode != Addressing_Type && type == NULL || type == t_invalid) {
|
||||||
|
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `new_slice`");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode *len = ce->arg_list->next;
|
AstNode *len = ce->arg_list->next;
|
||||||
AstNode *cap = len->next;
|
AstNode *cap = len->next;
|
||||||
|
|
||||||
Operand op = {};
|
|
||||||
check_expr(c, &op, len);
|
check_expr(c, &op, len);
|
||||||
if (op.mode == Addressing_Invalid)
|
if (op.mode == Addressing_Invalid)
|
||||||
return false;
|
return false;
|
||||||
@@ -1967,7 +1970,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cap != NULL) {
|
if (cap != NULL) {
|
||||||
check_expr(c, &op, len);
|
check_expr(c, &op, cap);
|
||||||
if (op.mode == Addressing_Invalid)
|
if (op.mode == Addressing_Invalid)
|
||||||
return false;
|
return false;
|
||||||
if (!is_type_integer(op.type)) {
|
if (!is_type_integer(op.type)) {
|
||||||
@@ -2006,7 +2009,9 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
|
|||||||
|
|
||||||
case BuiltinProc_size_of: {
|
case BuiltinProc_size_of: {
|
||||||
// size_of :: proc(Type) -> int
|
// size_of :: proc(Type) -> int
|
||||||
Type *type = check_type(c, ce->arg_list);
|
Operand op = {};
|
||||||
|
check_expr_or_type(c, &op, ce->arg_list);
|
||||||
|
Type *type = op.type;
|
||||||
if (!type) {
|
if (!type) {
|
||||||
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `size_of`");
|
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `size_of`");
|
||||||
return false;
|
return false;
|
||||||
@@ -2031,7 +2036,9 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
|
|||||||
|
|
||||||
case BuiltinProc_align_of: {
|
case BuiltinProc_align_of: {
|
||||||
// align_of :: proc(Type) -> int
|
// align_of :: proc(Type) -> int
|
||||||
Type *type = check_type(c, ce->arg_list);
|
Operand op = {};
|
||||||
|
check_expr_or_type(c, &op, ce->arg_list);
|
||||||
|
Type *type = op.type;
|
||||||
if (!type) {
|
if (!type) {
|
||||||
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `align_of`");
|
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `align_of`");
|
||||||
return false;
|
return false;
|
||||||
@@ -2054,9 +2061,14 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
|
|||||||
|
|
||||||
case BuiltinProc_offset_of: {
|
case BuiltinProc_offset_of: {
|
||||||
// offset_val :: proc(Type, field) -> int
|
// offset_val :: proc(Type, field) -> int
|
||||||
Type *type = get_base_type(check_type(c, ce->arg_list));
|
Operand op = {};
|
||||||
|
check_expr_or_type(c, &op, ce->arg_list);
|
||||||
|
Type *type = get_base_type(op.type);
|
||||||
AstNode *field_arg = unparen_expr(ce->arg_list->next);
|
AstNode *field_arg = unparen_expr(ce->arg_list->next);
|
||||||
if (type) {
|
if (type != NULL) {
|
||||||
|
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `offset_of`");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (!is_type_struct(type)) {
|
if (!is_type_struct(type)) {
|
||||||
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a structure type for `offset_of`");
|
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a structure type for `offset_of`");
|
||||||
return false;
|
return false;
|
||||||
@@ -2066,7 +2078,6 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
|
|||||||
error(&c->error_collector, ast_node_token(field_arg), "Expected an identifier for field argument");
|
error(&c->error_collector, ast_node_token(field_arg), "Expected an identifier for field argument");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ast_node(arg, Ident, field_arg);
|
ast_node(arg, Ident, field_arg);
|
||||||
@@ -2145,7 +2156,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
|
|||||||
gbString str = expr_to_string(ce->arg_list);
|
gbString str = expr_to_string(ce->arg_list);
|
||||||
defer (gb_string_free(str));
|
defer (gb_string_free(str));
|
||||||
error(&c->error_collector, ast_node_token(call),
|
error(&c->error_collector, ast_node_token(call),
|
||||||
"Static assertion: `%s`", str);
|
"Compile time assertion: `%s`", str);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (operand->mode != Addressing_Constant) {
|
if (operand->mode != Addressing_Constant) {
|
||||||
@@ -2468,7 +2479,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cap != NULL) {
|
if (cap != NULL) {
|
||||||
check_expr(c, &op, len);
|
check_expr(c, &op, cap);
|
||||||
if (op.mode == Addressing_Invalid)
|
if (op.mode == Addressing_Invalid)
|
||||||
return false;
|
return false;
|
||||||
if (!is_type_integer(op.type)) {
|
if (!is_type_integer(op.type)) {
|
||||||
|
|||||||
+12
-17
@@ -1238,22 +1238,10 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
|
|||||||
switch (e->kind) {
|
switch (e->kind) {
|
||||||
case Entity_TypeName: {
|
case Entity_TypeName: {
|
||||||
Type *t = get_base_type(e->type);
|
Type *t = get_base_type(e->type);
|
||||||
if (is_type_enum(t)) {
|
if (is_type_struct(t) || is_type_enum(t)) {
|
||||||
for (isize i = 0; i < t->Record.other_field_count; i++) {
|
for (isize i = 0; i < t->Record.other_field_count; i++) {
|
||||||
Entity *f = t->Record.other_fields[i];
|
Entity *f = t->Record.other_fields[i];
|
||||||
Entity *found = scope_insert_entity(c->context.scope, f);
|
Entity *found = scope_insert_entity(c->context.scope, f);
|
||||||
if (found != NULL) {
|
|
||||||
error(&c->error_collector, us->token, "Namespace collision while `using` `%s` of the constant: %.*s", expr_str, LIT(found->token.string));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
f->using_parent = e;
|
|
||||||
}
|
|
||||||
} else if (is_type_struct(t)) {
|
|
||||||
Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
|
|
||||||
GB_ASSERT(found != NULL);
|
|
||||||
gb_for_array(i, (*found)->elements.entries) {
|
|
||||||
Entity *f = (*found)->elements.entries[i].value;
|
|
||||||
Entity *found = scope_insert_entity(c->context.scope, f);
|
|
||||||
if (found != NULL) {
|
if (found != NULL) {
|
||||||
error(&c->error_collector, us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
|
error(&c->error_collector, us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
|
||||||
return;
|
return;
|
||||||
@@ -1261,10 +1249,17 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
|
|||||||
f->using_parent = e;
|
f->using_parent = e;
|
||||||
}
|
}
|
||||||
} else if (is_type_union(t)) {
|
} else if (is_type_union(t)) {
|
||||||
Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
|
for (isize i = 0; i < t->Record.field_count; i++) {
|
||||||
GB_ASSERT(found != NULL);
|
Entity *f = t->Record.fields[i];
|
||||||
gb_for_array(i, (*found)->elements.entries) {
|
Entity *found = scope_insert_entity(c->context.scope, f);
|
||||||
Entity *f = (*found)->elements.entries[i].value;
|
if (found != NULL) {
|
||||||
|
error(&c->error_collector, us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
f->using_parent = e;
|
||||||
|
}
|
||||||
|
for (isize i = 0; i < t->Record.other_field_count; i++) {
|
||||||
|
Entity *f = t->Record.other_fields[i];
|
||||||
Entity *found = scope_insert_entity(c->context.scope, f);
|
Entity *found = scope_insert_entity(c->context.scope, f);
|
||||||
if (found != NULL) {
|
if (found != NULL) {
|
||||||
error(&c->error_collector, us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
|
error(&c->error_collector, us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
|
||||||
|
|||||||
@@ -117,8 +117,8 @@ struct Type {
|
|||||||
|
|
||||||
// All record types
|
// All record types
|
||||||
// Theses are arrays
|
// Theses are arrays
|
||||||
Entity **fields; // Entity_Variable
|
Entity **fields; // Entity_Variable (otherwise Entity_TypeName if union)
|
||||||
isize field_count; // == offset_count
|
isize field_count; // == offset_count is struct
|
||||||
AstNode *node;
|
AstNode *node;
|
||||||
|
|
||||||
// enum only
|
// enum only
|
||||||
@@ -909,7 +909,7 @@ i64 type_size_of(BaseTypeSizes s, gbAllocator allocator, Type *t) {
|
|||||||
if (max < size)
|
if (max < size)
|
||||||
max = size;
|
max = size;
|
||||||
}
|
}
|
||||||
return type_size_of(s, allocator, t_int) + max;
|
return align_formula(max, s.max_align) + type_size_of(s, allocator, t_int);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case TypeRecord_RawUnion: {
|
case TypeRecord_RawUnion: {
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ struct ssaGlobalVariable {
|
|||||||
DeclInfo *decl;
|
DeclInfo *decl;
|
||||||
};
|
};
|
||||||
|
|
||||||
void ssa_gen_code(ssaGen *s) {
|
void ssa_gen_tree(ssaGen *s) {
|
||||||
if (v_zero == NULL) {
|
if (v_zero == NULL) {
|
||||||
v_zero = ssa_make_value_constant(gb_heap_allocator(), t_int, make_exact_value_integer(0));
|
v_zero = ssa_make_value_constant(gb_heap_allocator(), t_int, make_exact_value_integer(0));
|
||||||
v_one = ssa_make_value_constant(gb_heap_allocator(), t_int, make_exact_value_integer(1));
|
v_one = ssa_make_value_constant(gb_heap_allocator(), t_int, make_exact_value_integer(1));
|
||||||
@@ -203,7 +203,10 @@ void ssa_gen_code(ssaGen *s) {
|
|||||||
|
|
||||||
// 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");
|
// 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");
|
||||||
|
|
||||||
ssa_print_llvm_ir(&s->output_file, &s->module);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ssa_gen_ir(ssaGen *s) {
|
||||||
|
ssa_print_llvm_ir(&s->output_file, &s->module);
|
||||||
|
}
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ void ssa_print_type(gbFile *f, BaseTypeSizes s, Type *t) {
|
|||||||
break;
|
break;
|
||||||
case TypeRecord_Union: {
|
case TypeRecord_Union: {
|
||||||
i64 size_of_union = type_size_of(s, gb_heap_allocator(), t) - s.word_size;
|
i64 size_of_union = type_size_of(s, gb_heap_allocator(), t) - s.word_size;
|
||||||
ssa_fprintf(f, "{i%lld, [%lld x i8]}", word_bits, size_of_union);
|
ssa_fprintf(f, "{[%lld x i8], i%lld}", size_of_union, word_bits);
|
||||||
} break;
|
} break;
|
||||||
case TypeRecord_RawUnion:
|
case TypeRecord_RawUnion:
|
||||||
ssa_fprintf(f, "[%lld x i8]", type_size_of(s, gb_heap_allocator(), t));
|
ssa_fprintf(f, "[%lld x i8]", type_size_of(s, gb_heap_allocator(), t));
|
||||||
|
|||||||
+53
-34
@@ -313,8 +313,8 @@ void ssa_module_init(ssaModule *m, Checker *c) {
|
|||||||
m->info = &c->info;
|
m->info = &c->info;
|
||||||
m->sizes = c->sizes;
|
m->sizes = c->sizes;
|
||||||
|
|
||||||
map_init(&m->values, m->allocator);
|
map_init(&m->values, gb_heap_allocator());
|
||||||
map_init(&m->members, m->allocator);
|
map_init(&m->members, gb_heap_allocator());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ssa_module_destroy(ssaModule *m) {
|
void ssa_module_destroy(ssaModule *m) {
|
||||||
@@ -1394,20 +1394,13 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg
|
|||||||
gbAllocator allocator = proc->module->allocator;
|
gbAllocator allocator = proc->module->allocator;
|
||||||
ssaValue *parent = ssa_add_local_generated(proc, t);
|
ssaValue *parent = ssa_add_local_generated(proc, t);
|
||||||
ssaValue *tag = ssa_make_value_constant(allocator, t_int, make_exact_value_integer(i));
|
ssaValue *tag = ssa_make_value_constant(allocator, t_int, make_exact_value_integer(i));
|
||||||
ssa_emit_store(proc, ssa_emit_struct_gep(proc, parent, v_zero32, t_int), tag);
|
ssa_emit_store(proc, ssa_emit_struct_gep(proc, parent, v_one32, t_int), tag);
|
||||||
|
|
||||||
i64 tag_size = proc->module->sizes.word_size;
|
ssaValue *data = ssa_emit_conv(proc, parent, t_rawptr);
|
||||||
i64 underlying_array_size = type_size_of(proc->module->sizes, allocator, t);
|
|
||||||
underlying_array_size -= tag_size;
|
|
||||||
Type *array_type = make_type_array(allocator, t_u8, underlying_array_size);
|
|
||||||
Type *array_type_ptr = make_type_pointer(allocator, array_type);
|
|
||||||
ssaValue *data = ssa_emit_struct_gep(proc, parent, v_one32, array_type_ptr);
|
|
||||||
data = ssa_array_elem(proc, data);
|
|
||||||
|
|
||||||
Type *tag_type = src_type;
|
Type *tag_type = src_type;
|
||||||
Type *t_u8_ptr = make_type_pointer(allocator, t_u8);
|
|
||||||
Type *tag_type_ptr = make_type_pointer(allocator, tag_type);
|
Type *tag_type_ptr = make_type_pointer(allocator, tag_type);
|
||||||
ssaValue *underlying = ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_bitcast, data, t_u8_ptr, tag_type_ptr));
|
ssaValue *underlying = ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_bitcast, data, t_rawptr, tag_type_ptr));
|
||||||
ssa_emit_store(proc, underlying, value);
|
ssa_emit_store(proc, underlying, value);
|
||||||
|
|
||||||
return ssa_emit_load(proc, parent);
|
return ssa_emit_load(proc, parent);
|
||||||
@@ -1534,14 +1527,13 @@ ssaValue *ssa_emit_down_cast(ssaProcedure *proc, ssaValue *value, Type *t) {
|
|||||||
GB_ASSERT(is_type_pointer(ssa_type(value)));
|
GB_ASSERT(is_type_pointer(ssa_type(value)));
|
||||||
gbAllocator allocator = proc->module->allocator;
|
gbAllocator allocator = proc->module->allocator;
|
||||||
|
|
||||||
// String field_name = check_down_cast_name(t, ssa_type(value));
|
|
||||||
String field_name = check_down_cast_name(t, type_deref(ssa_type(value)));
|
String field_name = check_down_cast_name(t, type_deref(ssa_type(value)));
|
||||||
GB_ASSERT(field_name.len > 0);
|
GB_ASSERT(field_name.len > 0);
|
||||||
Selection sel = lookup_field(t, field_name, false);
|
Selection sel = lookup_field(t, field_name, false);
|
||||||
Type *t_u8_ptr = make_type_pointer(allocator, t_u8);
|
Type *t_u8_ptr = make_type_pointer(allocator, t_u8);
|
||||||
ssaValue *bytes = ssa_emit_conv(proc, value, t_u8_ptr);
|
ssaValue *bytes = ssa_emit_conv(proc, value, t_u8_ptr);
|
||||||
|
|
||||||
// IMPORTANT TODO(bill): THIS ONLY DOES ONE LAY DEEP!!! FUCKING HELL THIS IS NOT WHAT I SIGNED UP FOR!
|
// IMPORTANT TODO(bill): THIS ONLY DOES ONE LAYER DEEP!!! FUCKING HELL THIS IS NOT WHAT I SIGNED UP FOR!
|
||||||
|
|
||||||
i64 offset_ = type_offset_of_from_selection(proc->module->sizes, allocator, type_deref(t), sel);
|
i64 offset_ = type_offset_of_from_selection(proc->module->sizes, allocator, type_deref(t), sel);
|
||||||
ssaValue *offset = ssa_make_value_constant(allocator, t_int, make_exact_value_integer(-offset_));
|
ssaValue *offset = ssa_make_value_constant(allocator, t_int, make_exact_value_integer(-offset_));
|
||||||
@@ -1549,6 +1541,32 @@ ssaValue *ssa_emit_down_cast(ssaProcedure *proc, ssaValue *value, Type *t) {
|
|||||||
return ssa_emit_conv(proc, head, t);
|
return ssa_emit_conv(proc, head, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ssa_build_cond(ssaProcedure *proc, AstNode *cond, ssaBlock *true_block, ssaBlock *false_block);
|
||||||
|
|
||||||
|
ssaValue *ssa_emit_logical_binary_expr(ssaProcedure *proc, AstNode *expr) {
|
||||||
|
ast_node(be, BinaryExpr, expr);
|
||||||
|
ssaBlock *true_ = ssa_add_block(proc, NULL, make_string("logical.cmp.true"));
|
||||||
|
ssaBlock *false_ = ssa_add_block(proc, NULL, make_string("logical.cmp.false"));
|
||||||
|
ssaBlock *done = ssa__make_block(proc, NULL, make_string("logical.cmp.done"));
|
||||||
|
|
||||||
|
ssaValue *result = ssa_add_local_generated(proc, t_bool);
|
||||||
|
ssa_build_cond(proc, expr, true_, false_);
|
||||||
|
|
||||||
|
proc->curr_block = true_;
|
||||||
|
ssa_emit_store(proc, result, v_true);
|
||||||
|
ssa_emit_jump(proc, done);
|
||||||
|
|
||||||
|
proc->curr_block = false_;
|
||||||
|
ssa_emit_store(proc, result, v_false);
|
||||||
|
ssa_emit_jump(proc, done);
|
||||||
|
|
||||||
|
gb_array_append(proc->blocks, done);
|
||||||
|
proc->curr_block = done;
|
||||||
|
|
||||||
|
return ssa_emit_load(proc, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue *tv) {
|
ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue *tv) {
|
||||||
switch (expr->kind) {
|
switch (expr->kind) {
|
||||||
@@ -1644,6 +1662,10 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
|||||||
return ssa_emit_conv(proc, cmp, default_type(tv->type));
|
return ssa_emit_conv(proc, cmp, default_type(tv->type));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case Token_CmpAnd:
|
||||||
|
case Token_CmpOr:
|
||||||
|
return ssa_emit_logical_binary_expr(proc, expr);
|
||||||
|
|
||||||
case Token_as:
|
case Token_as:
|
||||||
ssa_emit_comment(proc, make_string("cast - as"));
|
ssa_emit_comment(proc, make_string("cast - as"));
|
||||||
return ssa_emit_conv(proc, ssa_build_expr(proc, be->left), tv->type);
|
return ssa_emit_conv(proc, ssa_build_expr(proc, be->left), tv->type);
|
||||||
@@ -1917,13 +1939,15 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
|||||||
err_len += 2;
|
err_len += 2;
|
||||||
// HACK(bill): memory leaks
|
// HACK(bill): memory leaks
|
||||||
u8 *err_str = gb_alloc_array(gb_heap_allocator(), u8, err_len);
|
u8 *err_str = gb_alloc_array(gb_heap_allocator(), u8, err_len);
|
||||||
isize len = gb_snprintf(cast(char *)err_str, err_len,
|
err_len = gb_snprintf(cast(char *)err_str, err_len,
|
||||||
"%.*s(%td:%td) Runtime assertion: %s\n",
|
"%.*s(%td:%td) Runtime assertion: %s\n",
|
||||||
LIT(pos.file), pos.line, pos.column, expr);
|
LIT(pos.file), pos.line, pos.column, expr);
|
||||||
|
err_len--;
|
||||||
|
|
||||||
ssaValue *array = ssa_add_global_string_array(proc, make_exact_value_string(make_string(err_str, len-1)));
|
ssaValue *array = ssa_add_global_string_array(proc, make_exact_value_string(make_string(err_str, err_len)));
|
||||||
ssaValue *elem = ssa_array_elem(proc, array);
|
ssaValue *elem = ssa_array_elem(proc, array);
|
||||||
ssaValue *string = ssa_emit_load(proc, ssa_emit_string(proc, elem, ssa_array_len(proc, array)));
|
ssaValue *len = ssa_make_value_constant(proc->module->allocator, t_int, make_exact_value_integer(err_len));
|
||||||
|
ssaValue *string = ssa_emit_string(proc, elem, len);
|
||||||
|
|
||||||
ssaValue **args = gb_alloc_array(proc->module->allocator, ssaValue *, 1);
|
ssaValue **args = gb_alloc_array(proc->module->allocator, ssaValue *, 1);
|
||||||
args[0] = string;
|
args[0] = string;
|
||||||
@@ -2224,8 +2248,9 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
|||||||
ssa_emit_store(proc, addr, args[i]);
|
ssa_emit_store(proc, addr, args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssaValue *base_elem = ssa_emit_struct_gep(proc, base_array, v_zero32, elem_type);
|
ssaValue *base_elem = ssa_emit_struct_gep(proc, base_array, v_zero32, elem_ptr_type);
|
||||||
ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_zero32, elem_ptr_type), base_elem);
|
ssaValue *slice_elem = ssa_emit_struct_gep(proc, slice, v_zero32, elem_ptr_type);
|
||||||
|
ssa_emit_store(proc, slice_elem, base_elem);
|
||||||
ssaValue *len = ssa_make_value_constant(allocator, t_int, make_exact_value_integer(slice_len));
|
ssaValue *len = ssa_make_value_constant(allocator, t_int, make_exact_value_integer(slice_len));
|
||||||
ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_one32, t_int), len);
|
ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_one32, t_int), len);
|
||||||
ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_two32, t_int), len);
|
ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_two32, t_int), len);
|
||||||
@@ -2425,7 +2450,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case Type_Pointer: {
|
case Type_Pointer: {
|
||||||
ssaValue *array = ssa_emit_load(proc, ssa_build_expr(proc, ie->expr));
|
ssaValue *array = ssa_build_expr(proc, ie->expr);
|
||||||
elem = ssa_array_elem(proc, array);
|
elem = ssa_array_elem(proc, array);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@@ -2545,13 +2570,13 @@ void ssa_build_cond(ssaProcedure *proc, AstNode *cond, ssaBlock *true_block, ssa
|
|||||||
|
|
||||||
case_ast_node(be, BinaryExpr, cond);
|
case_ast_node(be, BinaryExpr, cond);
|
||||||
if (be->op.kind == Token_CmpAnd) {
|
if (be->op.kind == Token_CmpAnd) {
|
||||||
ssaBlock *block = ssa_add_block(proc, NULL, make_string("cmp-and"));
|
ssaBlock *block = ssa_add_block(proc, NULL, make_string("cmp.and"));
|
||||||
ssa_build_cond(proc, be->left, block, false_block);
|
ssa_build_cond(proc, be->left, block, false_block);
|
||||||
proc->curr_block = block;
|
proc->curr_block = block;
|
||||||
ssa_build_cond(proc, be->right, true_block, false_block);
|
ssa_build_cond(proc, be->right, true_block, false_block);
|
||||||
return;
|
return;
|
||||||
} else if (be->op.kind == Token_CmpOr) {
|
} else if (be->op.kind == Token_CmpOr) {
|
||||||
ssaBlock *block = ssa_add_block(proc, NULL, make_string("cmp-or"));
|
ssaBlock *block = ssa_add_block(proc, NULL, make_string("cmp.or"));
|
||||||
ssa_build_cond(proc, be->left, true_block, block);
|
ssa_build_cond(proc, be->left, true_block, block);
|
||||||
proc->curr_block = block;
|
proc->curr_block = block;
|
||||||
ssa_build_cond(proc, be->right, true_block, false_block);
|
ssa_build_cond(proc, be->right, true_block, false_block);
|
||||||
@@ -3123,18 +3148,12 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
|
|||||||
Type *union_type = type_deref(ssa_type(parent));
|
Type *union_type = type_deref(ssa_type(parent));
|
||||||
GB_ASSERT(is_type_union(union_type));
|
GB_ASSERT(is_type_union(union_type));
|
||||||
|
|
||||||
ssaValue *tag_index = ssa_emit_struct_gep(proc, parent, v_zero32, make_type_pointer(allocator, t_int));
|
ssaValue *tag_index = ssa_emit_struct_gep(proc, parent, v_one32, make_type_pointer(allocator, t_int));
|
||||||
tag_index = ssa_emit_load(proc, tag_index);
|
tag_index = ssa_emit_load(proc, tag_index);
|
||||||
|
|
||||||
i64 tag_size = proc->module->sizes.word_size;
|
ssaValue *data = ssa_emit_conv(proc, parent, t_rawptr);
|
||||||
i64 underlying_array_size = type_size_of(proc->module->sizes, allocator, union_type);
|
|
||||||
underlying_array_size -= tag_size;
|
|
||||||
Type *array_type = make_type_array(allocator, t_u8, underlying_array_size);
|
|
||||||
Type *array_type_ptr = make_type_pointer(allocator, array_type);
|
|
||||||
ssaValue *data = ssa_emit_struct_gep(proc, parent, v_one32, array_type_ptr);
|
|
||||||
data = ssa_array_elem(proc, data);
|
|
||||||
|
|
||||||
ssaBlock *done = ssa__make_block(proc, node, make_string("type.match.done")); // NOTE(bill): Append later
|
ssaBlock *done = ssa__make_block(proc, node, make_string("type-match.done")); // NOTE(bill): Append later
|
||||||
|
|
||||||
ast_node(body, BlockStmt, ms->body);
|
ast_node(body, BlockStmt, ms->body);
|
||||||
|
|
||||||
@@ -3157,9 +3176,9 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
|
|||||||
if (body == NULL) {
|
if (body == NULL) {
|
||||||
append_body = true;
|
append_body = true;
|
||||||
if (cc->list == NULL) {
|
if (cc->list == NULL) {
|
||||||
body = ssa__make_block(proc, clause, make_string("type.match.dflt.body"));
|
body = ssa__make_block(proc, clause, make_string("type-match.dflt.body"));
|
||||||
} else {
|
} else {
|
||||||
body = ssa__make_block(proc, clause, make_string("type.match.case.body"));
|
body = ssa__make_block(proc, clause, make_string("type-match.case.body"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3189,7 +3208,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
|
|||||||
}
|
}
|
||||||
GB_ASSERT(index != NULL);
|
GB_ASSERT(index != NULL);
|
||||||
|
|
||||||
ssaBlock *next_cond = ssa__make_block(proc, clause, make_string("type.match.case.next"));
|
ssaBlock *next_cond = ssa__make_block(proc, clause, make_string("type-match.case.next"));
|
||||||
Token eq = {Token_CmpEq};
|
Token eq = {Token_CmpEq};
|
||||||
ssaValue *cond = ssa_emit_comp(proc, eq, tag_index, index);
|
ssaValue *cond = ssa_emit_comp(proc, eq, tag_index, index);
|
||||||
ssa_emit_if(proc, cond, body, next_cond);
|
ssa_emit_if(proc, cond, body, next_cond);
|
||||||
|
|||||||
+32
-1
@@ -46,6 +46,9 @@ int main(int argc, char **argv) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 start_time, end_time;
|
||||||
|
start_time = gb_utc_time_now();
|
||||||
|
|
||||||
init_universal_scope();
|
init_universal_scope();
|
||||||
|
|
||||||
char *init_filename = argv[1];
|
char *init_filename = argv[1];
|
||||||
@@ -64,6 +67,10 @@ int main(int argc, char **argv) {
|
|||||||
if (parse_files(&parser, init_filename) != ParseFile_None)
|
if (parse_files(&parser, init_filename) != ParseFile_None)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
end_time = gb_utc_time_now();
|
||||||
|
gb_printf_err("Parser: %lld ms\n", (end_time - start_time)/1000);
|
||||||
|
start_time = gb_utc_time_now();
|
||||||
|
|
||||||
// print_ast(parser.files[0].decls, 0);
|
// print_ast(parser.files[0].decls, 0);
|
||||||
|
|
||||||
Checker checker = {};
|
Checker checker = {};
|
||||||
@@ -73,13 +80,30 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
check_parsed_files(&checker);
|
check_parsed_files(&checker);
|
||||||
|
|
||||||
|
|
||||||
|
// end_time = gb_utc_time_now();
|
||||||
|
// gb_printf_err("Checker: %lld ms\n", (end_time - start_time)/1000);
|
||||||
|
// start_time = gb_utc_time_now();
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
ssaGen ssa = {};
|
ssaGen ssa = {};
|
||||||
if (!ssa_gen_init(&ssa, &checker))
|
if (!ssa_gen_init(&ssa, &checker))
|
||||||
return 1;
|
return 1;
|
||||||
defer (ssa_gen_destroy(&ssa));
|
defer (ssa_gen_destroy(&ssa));
|
||||||
|
|
||||||
ssa_gen_code(&ssa);
|
ssa_gen_tree(&ssa);
|
||||||
|
|
||||||
|
// end_time = gb_utc_time_now();
|
||||||
|
// gb_printf_err("ssa tree: %lld ms\n", (end_time - start_time)/1000);
|
||||||
|
// start_time = gb_utc_time_now();
|
||||||
|
|
||||||
|
// TODO(bill): Speedup writing to file for IR code
|
||||||
|
ssa_gen_ir(&ssa);
|
||||||
|
|
||||||
|
// end_time = gb_utc_time_now();
|
||||||
|
// gb_printf_err("ssa ir: %lld ms\n", (end_time - start_time)/1000);
|
||||||
|
// start_time = gb_utc_time_now();
|
||||||
|
|
||||||
|
|
||||||
char const *output_name = ssa.output_file.filename;
|
char const *output_name = ssa.output_file.filename;
|
||||||
isize base_name_len = gb_path_extension(output_name)-1 - output_name;
|
isize base_name_len = gb_path_extension(output_name)-1 - output_name;
|
||||||
@@ -93,6 +117,10 @@ int main(int argc, char **argv) {
|
|||||||
if (exit_code != 0)
|
if (exit_code != 0)
|
||||||
return exit_code;
|
return exit_code;
|
||||||
|
|
||||||
|
// end_time = gb_utc_time_now();
|
||||||
|
// gb_printf_err("llvm-opt: %lld ms\n", (end_time - start_time)/1000);
|
||||||
|
// start_time = gb_utc_time_now();
|
||||||
|
|
||||||
gbString lib_str = gb_string_make(gb_heap_allocator(), "-lKernel32.lib");
|
gbString lib_str = gb_string_make(gb_heap_allocator(), "-lKernel32.lib");
|
||||||
char lib_str_buf[1024] = {};
|
char lib_str_buf[1024] = {};
|
||||||
gb_for_array(i, parser.system_libraries) {
|
gb_for_array(i, parser.system_libraries) {
|
||||||
@@ -116,6 +144,9 @@ int main(int argc, char **argv) {
|
|||||||
if (exit_code != 0)
|
if (exit_code != 0)
|
||||||
return exit_code;
|
return exit_code;
|
||||||
|
|
||||||
|
// end_time = gb_utc_time_now();
|
||||||
|
// gb_printf_err("clang: %lld ms\n\n\n", (end_time - start_time)/1000);
|
||||||
|
|
||||||
if (run_output) {
|
if (run_output) {
|
||||||
win32_exec_command_line_app("%.*s.exe", cast(int)base_name_len, output_name);
|
win32_exec_command_line_app("%.*s.exe", cast(int)base_name_len, output_name);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user