Fix array pointer as iterators; Remove stack allocations in startup_runtime

This commit is contained in:
Ginger Bill
2017-01-06 15:47:07 +00:00
parent fc1af0a04b
commit b1e35b6da3
5 changed files with 89 additions and 37 deletions
+1 -2
View File
@@ -123,7 +123,6 @@ String get_fullpath_core(gbAllocator a, String path) {
return res; return res;
} }
String get_filepath_extension(String path) { String get_filepath_extension(String path) {
isize dot = 0; isize dot = 0;
bool seen_slash = false; bool seen_slash = false;
@@ -149,7 +148,7 @@ String get_filepath_extension(String path) {
void init_build_context(BuildContext *bc) { void init_build_context(BuildContext *bc) {
bc->ODIN_VENDOR = str_lit("odin"); bc->ODIN_VENDOR = str_lit("odin");
bc->ODIN_VERSION = str_lit("0.0.5c"); bc->ODIN_VERSION = str_lit("0.0.5d");
bc->ODIN_ROOT = odin_root_dir(); bc->ODIN_ROOT = odin_root_dir();
#if defined(GB_SYSTEM_WINDOWS) #if defined(GB_SYSTEM_WINDOWS)
+18
View File
@@ -1045,6 +1045,24 @@ void init_preload(Checker *c) {
t_type_info_union = record->fields[15]->type; t_type_info_union = record->fields[15]->type;
t_type_info_raw_union = record->fields[16]->type; t_type_info_raw_union = record->fields[16]->type;
t_type_info_enum = record->fields[17]->type; t_type_info_enum = record->fields[17]->type;
t_type_info_named_ptr = make_type_pointer(heap_allocator(), t_type_info_named);
t_type_info_integer_ptr = make_type_pointer(heap_allocator(), t_type_info_integer);
t_type_info_float_ptr = make_type_pointer(heap_allocator(), t_type_info_float);
t_type_info_any_ptr = make_type_pointer(heap_allocator(), t_type_info_any);
t_type_info_string_ptr = make_type_pointer(heap_allocator(), t_type_info_string);
t_type_info_boolean_ptr = make_type_pointer(heap_allocator(), t_type_info_boolean);
t_type_info_pointer_ptr = make_type_pointer(heap_allocator(), t_type_info_pointer);
t_type_info_maybe_ptr = make_type_pointer(heap_allocator(), t_type_info_maybe);
t_type_info_procedure_ptr = make_type_pointer(heap_allocator(), t_type_info_procedure);
t_type_info_array_ptr = make_type_pointer(heap_allocator(), t_type_info_array);
t_type_info_slice_ptr = make_type_pointer(heap_allocator(), t_type_info_slice);
t_type_info_vector_ptr = make_type_pointer(heap_allocator(), t_type_info_vector);
t_type_info_tuple_ptr = make_type_pointer(heap_allocator(), t_type_info_tuple);
t_type_info_struct_ptr = make_type_pointer(heap_allocator(), t_type_info_struct);
t_type_info_union_ptr = make_type_pointer(heap_allocator(), t_type_info_union);
t_type_info_raw_union_ptr = make_type_pointer(heap_allocator(), t_type_info_raw_union);
t_type_info_enum_ptr = make_type_pointer(heap_allocator(), t_type_info_enum);
} }
if (t_allocator == NULL) { if (t_allocator == NULL) {
+21
View File
@@ -277,6 +277,27 @@ gb_global Type *t_type_info_union = NULL;
gb_global Type *t_type_info_raw_union = NULL; gb_global Type *t_type_info_raw_union = NULL;
gb_global Type *t_type_info_enum = NULL; gb_global Type *t_type_info_enum = NULL;
gb_global Type *t_type_info_named_ptr = NULL;
gb_global Type *t_type_info_integer_ptr = NULL;
gb_global Type *t_type_info_float_ptr = NULL;
gb_global Type *t_type_info_any_ptr = NULL;
gb_global Type *t_type_info_string_ptr = NULL;
gb_global Type *t_type_info_boolean_ptr = NULL;
gb_global Type *t_type_info_pointer_ptr = NULL;
gb_global Type *t_type_info_maybe_ptr = NULL;
gb_global Type *t_type_info_procedure_ptr = NULL;
gb_global Type *t_type_info_array_ptr = NULL;
gb_global Type *t_type_info_slice_ptr = NULL;
gb_global Type *t_type_info_vector_ptr = NULL;
gb_global Type *t_type_info_tuple_ptr = NULL;
gb_global Type *t_type_info_struct_ptr = NULL;
gb_global Type *t_type_info_union_ptr = NULL;
gb_global Type *t_type_info_raw_union_ptr = NULL;
gb_global Type *t_type_info_enum_ptr = NULL;
gb_global Type *t_allocator = NULL; gb_global Type *t_allocator = NULL;
gb_global Type *t_allocator_ptr = NULL; gb_global Type *t_allocator_ptr = NULL;
gb_global Type *t_context = NULL; gb_global Type *t_context = NULL;
+47 -35
View File
@@ -708,21 +708,21 @@ irValueArray *ir_value_referrers(irValue *v) {
// //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
void ir_module_add_value (irModule *m, Entity *e, irValue *v); void ir_module_add_value (irModule *m, Entity *e, irValue *v);
irValue *ir_emit_zero_init (irProcedure *p, irValue *address); irValue *ir_emit_zero_init (irProcedure *p, irValue *address);
irValue *ir_emit_comment (irProcedure *p, String text); irValue *ir_emit_comment (irProcedure *p, String text);
irValue *ir_emit_store (irProcedure *p, irValue *address, irValue *value); irValue *ir_emit_store (irProcedure *p, irValue *address, irValue *value);
irValue *ir_emit_load (irProcedure *p, irValue *address); irValue *ir_emit_load (irProcedure *p, irValue *address);
void ir_emit_jump (irProcedure *proc, irBlock *block); void ir_emit_jump (irProcedure *proc, irBlock *block);
irValue *ir_emit_conv (irProcedure *proc, irValue *value, Type *t); irValue *ir_emit_conv (irProcedure *proc, irValue *value, Type *t);
irValue *ir_type_info (irProcedure *proc, Type *type); irValue *ir_type_info (irProcedure *proc, Type *type);
irValue *ir_build_expr (irProcedure *proc, AstNode *expr); irValue *ir_build_expr (irProcedure *proc, AstNode *expr);
void ir_build_stmt (irProcedure *proc, AstNode *node); void ir_build_stmt (irProcedure *proc, AstNode *node);
irValue *ir_build_cond (irProcedure *proc, AstNode *cond, irBlock *true_block, irBlock *false_block); irValue *ir_build_cond (irProcedure *proc, AstNode *cond, irBlock *true_block, irBlock *false_block);
void ir_build_defer_stmt (irProcedure *proc, irDefer d); void ir_build_defer_stmt (irProcedure *proc, irDefer d);
irAddr ir_build_addr (irProcedure *proc, AstNode *expr); irAddr ir_build_addr (irProcedure *proc, AstNode *expr);
void ir_build_proc (irValue *value, irProcedure *parent); void ir_build_proc (irValue *value, irProcedure *parent);
void ir_gen_global_type_name(irModule *m, Entity *e, String name); void ir_gen_global_type_name(irModule *m, Entity *e, String name);
@@ -817,7 +817,7 @@ irValue *ir_make_instr_array_element_ptr(irProcedure *p, irValue *address, irVal
irValue *v = ir_alloc_instr(p, irInstr_ArrayElementPtr); irValue *v = ir_alloc_instr(p, irInstr_ArrayElementPtr);
irInstr *i = &v->Instr; irInstr *i = &v->Instr;
Type *t = ir_type(address); Type *t = ir_type(address);
GB_ASSERT(is_type_pointer(t)); GB_ASSERT_MSG(is_type_pointer(t), "%s", type_to_string(t));
t = base_type(type_deref(t)); t = base_type(type_deref(t));
GB_ASSERT(is_type_array(t) || is_type_vector(t)); GB_ASSERT(is_type_array(t) || is_type_vector(t));
@@ -1561,7 +1561,9 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal
irValue *ir_emit_array_ep(irProcedure *proc, irValue *s, irValue *index) { irValue *ir_emit_array_ep(irProcedure *proc, irValue *s, irValue *index) {
GB_ASSERT(index != NULL); GB_ASSERT(index != NULL);
Type *st = base_type(type_deref(ir_type(s))); Type *t = ir_type(s);
GB_ASSERT(is_type_pointer(t));
Type *st = base_type(type_deref(t));
GB_ASSERT(is_type_array(st) || is_type_vector(st)); GB_ASSERT(is_type_array(st) || is_type_vector(st));
// NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32 // NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32
@@ -3871,9 +3873,9 @@ void ir_emit_increment(irProcedure *proc, irValue *addr) {
} }
void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type,
irValue **val_, irValue **idx_, irBlock **loop_, irBlock **done_) { irValue **val_, irValue **idx_, irBlock **loop_, irBlock **done_) {
irValue *count = NULL; irValue *count = NULL;
Type *expr_type = base_type(ir_type(expr)); Type *expr_type = base_type(type_deref(ir_type(expr)));
switch (expr_type->kind) { switch (expr_type->kind) {
case Type_Array: case Type_Array:
count = ir_make_const_int(proc->module->allocator, expr_type->Array.count); count = ir_make_const_int(proc->module->allocator, expr_type->Array.count);
@@ -4454,25 +4456,24 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
} else { } else {
Type *expr_type = type_of_expr(proc->module->info, rs->expr); Type *expr_type = type_of_expr(proc->module->info, rs->expr);
Type *et = base_type(type_deref(expr_type)); Type *et = base_type(type_deref(expr_type));
bool deref = is_type_pointer(expr_type);
switch (et->kind) { switch (et->kind) {
case Type_Array: { case Type_Array: {
irValue *array = ir_build_addr(proc, rs->expr).addr; irValue *array = ir_build_addr(proc, rs->expr).addr;
if (deref) { if (is_type_pointer(type_deref(ir_type(array)))) {
array = ir_emit_load(proc, array); array = ir_emit_load(proc, array);
} }
ir_build_range_indexed(proc, array, val_type, &val, &index, &loop, &done); ir_build_range_indexed(proc, array, val_type, &val, &index, &loop, &done);
} break; } break;
case Type_Slice: { case Type_Slice: {
irValue *slice = ir_build_expr(proc, rs->expr); irValue *slice = ir_build_expr(proc, rs->expr);
if (deref) { if (is_type_pointer(ir_type(slice))) {
slice = ir_emit_load(proc, slice); slice = ir_emit_load(proc, slice);
} }
ir_build_range_indexed(proc, slice, val_type, &val, &index, &loop, &done); ir_build_range_indexed(proc, slice, val_type, &val, &index, &loop, &done);
} break; } break;
case Type_Basic: { case Type_Basic: {
irValue *string = ir_build_expr(proc, rs->expr); irValue *string = ir_build_expr(proc, rs->expr);
if (deref) { if (is_type_pointer(ir_type(string))) {
string = ir_emit_load(proc, string); string = ir_emit_load(proc, string);
} }
if (is_type_untyped(expr_type)) { if (is_type_untyped(expr_type)) {
@@ -5463,10 +5464,11 @@ void ir_gen_tree(irGen *s) {
isize entry_index = entry->value; isize entry_index = entry->value;
irValue *tag = NULL; irValue *tag = NULL;
irValue *ti_ptr = ir_emit_array_epi(proc, type_info_data, entry_index);
switch (t->kind) { switch (t->kind) {
case Type_Named: { case Type_Named: {
tag = ir_add_local_generated(proc, t_type_info_named); tag = ir_emit_conv(proc, ti_ptr, t_type_info_named_ptr);
// TODO(bill): Which is better? The mangled name or actual name? // TODO(bill): Which is better? The mangled name or actual name?
irValue *name = ir_make_const_string(a, t->Named.type_name->token.string); irValue *name = ir_make_const_string(a, t->Named.type_name->token.string);
@@ -5479,7 +5481,7 @@ void ir_gen_tree(irGen *s) {
case Type_Basic: case Type_Basic:
switch (t->Basic.kind) { switch (t->Basic.kind) {
case Basic_bool: case Basic_bool:
tag = ir_add_local_generated(proc, t_type_info_boolean); tag = ir_emit_conv(proc, ti_ptr, t_type_info_boolean_ptr);
break; break;
case Basic_i8: case Basic_i8:
case Basic_u8: case Basic_u8:
@@ -5493,7 +5495,7 @@ void ir_gen_tree(irGen *s) {
// case Basic_u128: // case Basic_u128:
case Basic_int: case Basic_int:
case Basic_uint: { case Basic_uint: {
tag = ir_add_local_generated(proc, t_type_info_integer); tag = ir_emit_conv(proc, ti_ptr, t_type_info_integer_ptr);
bool is_unsigned = (t->Basic.flags & BasicFlag_Unsigned) != 0; bool is_unsigned = (t->Basic.flags & BasicFlag_Unsigned) != 0;
irValue *bits = ir_make_const_int(a, type_size_of(m->sizes, a, t)); irValue *bits = ir_make_const_int(a, type_size_of(m->sizes, a, t));
irValue *is_signed = ir_make_const_bool(a, !is_unsigned); irValue *is_signed = ir_make_const_bool(a, !is_unsigned);
@@ -5506,37 +5508,37 @@ void ir_gen_tree(irGen *s) {
case Basic_f64: case Basic_f64:
// case Basic_f128: // case Basic_f128:
{ {
tag = ir_add_local_generated(proc, t_type_info_float); tag = ir_emit_conv(proc, ti_ptr, t_type_info_float_ptr);
irValue *bits = ir_make_const_int(a, type_size_of(m->sizes, a, t)); irValue *bits = ir_make_const_int(a, type_size_of(m->sizes, a, t));
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), bits); ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), bits);
} break; } break;
case Basic_rawptr: case Basic_rawptr:
tag = ir_add_local_generated(proc, t_type_info_pointer); tag = ir_emit_conv(proc, ti_ptr, t_type_info_pointer_ptr);
break; break;
case Basic_string: case Basic_string:
tag = ir_add_local_generated(proc, t_type_info_string); tag = ir_emit_conv(proc, ti_ptr, t_type_info_string_ptr);
break; break;
case Basic_any: case Basic_any:
tag = ir_add_local_generated(proc, t_type_info_any); tag = ir_emit_conv(proc, ti_ptr, t_type_info_any_ptr);
break; break;
} }
break; break;
case Type_Pointer: { case Type_Pointer: {
tag = ir_add_local_generated(proc, t_type_info_pointer); tag = ir_emit_conv(proc, ti_ptr, t_type_info_pointer_ptr);
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Pointer.elem); irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Pointer.elem);
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep); ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
} break; } break;
case Type_Maybe: { case Type_Maybe: {
tag = ir_add_local_generated(proc, t_type_info_maybe); tag = ir_emit_conv(proc, ti_ptr, t_type_info_maybe_ptr);
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Maybe.elem); irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Maybe.elem);
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep); ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
} break; } break;
case Type_Array: { case Type_Array: {
tag = ir_add_local_generated(proc, t_type_info_array); tag = ir_emit_conv(proc, ti_ptr, t_type_info_array_ptr);
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Array.elem); irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Array.elem);
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep); ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
@@ -5549,7 +5551,7 @@ void ir_gen_tree(irGen *s) {
} break; } break;
case Type_Slice: { case Type_Slice: {
tag = ir_add_local_generated(proc, t_type_info_slice); tag = ir_emit_conv(proc, ti_ptr, t_type_info_slice_ptr);
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Slice.elem); irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Slice.elem);
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep); ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
@@ -5559,7 +5561,7 @@ void ir_gen_tree(irGen *s) {
} break; } break;
case Type_Vector: { case Type_Vector: {
tag = ir_add_local_generated(proc, t_type_info_vector); tag = ir_emit_conv(proc, ti_ptr, t_type_info_vector_ptr);
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Vector.elem); irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Vector.elem);
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep); ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
@@ -5572,7 +5574,7 @@ void ir_gen_tree(irGen *s) {
case Type_Record: { case Type_Record: {
switch (t->Record.kind) { switch (t->Record.kind) {
case TypeRecord_Struct: { case TypeRecord_Struct: {
tag = ir_add_local_generated(proc, t_type_info_struct); tag = ir_emit_conv(proc, ti_ptr, t_type_info_struct_ptr);
{ {
irValue *packed = ir_make_const_bool(a, t->Record.struct_is_packed); irValue *packed = ir_make_const_bool(a, t->Record.struct_is_packed);
@@ -5621,7 +5623,7 @@ void ir_gen_tree(irGen *s) {
ir_emit_store(proc, cap, field_count); ir_emit_store(proc, cap, field_count);
} break; } break;
case TypeRecord_Union: case TypeRecord_Union:
tag = ir_add_local_generated(proc, t_type_info_union); tag = ir_emit_conv(proc, ti_ptr, t_type_info_union_ptr);
{ {
irValue *size = ir_make_const_int(a, type_size_of(m->sizes, a, t)); irValue *size = ir_make_const_int(a, type_size_of(m->sizes, a, t));
irValue *align = ir_make_const_int(a, type_align_of(m->sizes, a, t)); irValue *align = ir_make_const_int(a, type_align_of(m->sizes, a, t));
@@ -5630,7 +5632,7 @@ void ir_gen_tree(irGen *s) {
} }
break; break;
case TypeRecord_RawUnion: { case TypeRecord_RawUnion: {
tag = ir_add_local_generated(proc, t_type_info_raw_union); tag = ir_emit_conv(proc, ti_ptr, t_type_info_raw_union_ptr);
{ {
irValue *size = ir_make_const_int(a, type_size_of(m->sizes, a, t)); irValue *size = ir_make_const_int(a, type_size_of(m->sizes, a, t));
irValue *align = ir_make_const_int(a, type_align_of(m->sizes, a, t)); irValue *align = ir_make_const_int(a, type_align_of(m->sizes, a, t));
@@ -5670,7 +5672,7 @@ void ir_gen_tree(irGen *s) {
ir_emit_store(proc, cap, field_count); ir_emit_store(proc, cap, field_count);
} break; } break;
case TypeRecord_Enum: case TypeRecord_Enum:
tag = ir_add_local_generated(proc, t_type_info_enum); tag = ir_emit_conv(proc, ti_ptr, t_type_info_enum_ptr);
{ {
GB_ASSERT(t->Record.enum_base_type != NULL); GB_ASSERT(t->Record.enum_base_type != NULL);
irValue *base = ir_type_info(proc, t->Record.enum_base_type); irValue *base = ir_type_info(proc, t->Record.enum_base_type);
@@ -5716,7 +5718,7 @@ void ir_gen_tree(irGen *s) {
} break; } break;
case Type_Tuple: { case Type_Tuple: {
tag = ir_add_local_generated(proc, t_type_info_tuple); tag = ir_emit_conv(proc, ti_ptr, t_type_info_tuple_ptr);
{ {
irValue *align = ir_make_const_int(a, type_align_of(m->sizes, a, t)); irValue *align = ir_make_const_int(a, type_align_of(m->sizes, a, t));
@@ -5755,7 +5757,7 @@ void ir_gen_tree(irGen *s) {
} break; } break;
case Type_Proc: { case Type_Proc: {
tag = ir_add_local_generated(proc, t_type_info_procedure); tag = ir_emit_conv(proc, ti_ptr, t_type_info_procedure_ptr);
irValue *params = ir_emit_struct_ep(proc, tag, 0); irValue *params = ir_emit_struct_ep(proc, tag, 0);
irValue *results = ir_emit_struct_ep(proc, tag, 1); irValue *results = ir_emit_struct_ep(proc, tag, 1);
@@ -5774,9 +5776,19 @@ void ir_gen_tree(irGen *s) {
} }
if (tag != NULL) { if (tag != NULL) {
irValue *gep = ir_emit_array_epi(proc, type_info_data, entry_index); Type *tag_type = type_deref(ir_type(tag));
irValue *val = ir_emit_conv(proc, ir_emit_load(proc, tag), t_type_info); Type *ti = base_type(t_type_info);
ir_emit_store(proc, gep, val); bool found = false;
for (isize i = 1; i < ti->Record.field_count; i++) {
Entity *f = ti->Record.fields[i];
if (are_types_identical(f->type, tag_type)) {
found = true;
irValue *tag = ir_make_const_int(proc->module->allocator, i);
ir_emit_store(proc, ir_emit_union_tag_ptr(proc, ti_ptr), tag);
break;
}
}
GB_ASSERT(found);
} }
} }
} }
+2
View File
@@ -249,6 +249,8 @@ int main(int argc, char **argv) {
if (build_context.is_dll) { if (build_context.is_dll) {
output_ext = "dll"; output_ext = "dll";
link_settings = "/DLL"; link_settings = "/DLL";
} else {
link_settings = "/ENTRY:mainCRTStartup";
} }
exit_code = win32_exec_command_line_app("msvc-link", true, exit_code = win32_exec_command_line_app("msvc-link", true,