Browse Source

Improve min-dep for Type Info

gingerBill 7 years ago
parent
commit
b66e7bed45
5 changed files with 112 additions and 40 deletions
  1. 82 19
      core/_preload.odin
  2. 5 0
      core/os.odin
  3. 22 17
      src/checker.cpp
  4. 1 1
      src/checker.hpp
  5. 2 3
      src/ir.cpp

+ 82 - 19
core/_preload.odin

@@ -1,7 +1,7 @@
 #shared_global_scope
 
 import "core:os.odin"
-import "core:fmt.odin" // TODO(bill): Remove the need for `fmt` here
+// import "core:fmt.odin" // TODO(bill): Remove the need for `fmt` here
 import "core:utf8.odin"
 import "core:raw.odin"
 
@@ -599,22 +599,55 @@ nil_allocator :: proc() -> Allocator {
 }
 
 
-assert :: proc "contextless" (condition: bool, message := "", args: ...any, using loc := #caller_location) -> bool {
+__print_u64 :: proc(fd: os.Handle, u: u64) {
+	digits := "0123456789";
+
+	a: [129]byte;
+	i := len(a);
+	b := u64(10);
+	for u >= b {
+		i -= 1; a[i] = digits[u % b];
+		u /= b;
+	}
+	i -= 1; a[i] = digits[u % b];
+
+	os.write(fd, a[i..]);
+}
+
+__print_caller_location :: proc(fd: os.Handle, using loc: Source_Code_Location) {
+	os.write_string(fd, file_path);
+	os.write_byte(fd, '(');
+	__print_u64(fd, u64(line));
+	os.write_byte(fd, ':');
+	__print_u64(fd, u64(column));
+	os.write_byte(fd, ')');
+}
+
+
+assert :: proc "contextless" (condition: bool, message := "", using loc := #caller_location) -> bool {
 	if !condition {
-		fmt.fprintf(os.stderr, "%s(%d:%d) Runtime assertion", file_path, line, column);
-		if len(message) > 0 do fmt.fprint(os.stderr, ": ");
-		fmt.fprintf(os.stderr, message, ...args);
-		fmt.fprintf(os.stderr, "\n");
+		fd := os.stderr;
+		__print_caller_location(fd, loc);
+		os.write_string(fd, " Runtime assertion");
+		if len(message) > 0 {
+			os.write_string(fd, ": ");
+			os.write_string(fd, message);
+			os.write_byte(fd, '\n');
+		}
 		__debug_trap();
 	}
 	return condition;
 }
 
-panic :: proc "contextless" (message := "", args: ...any, using loc := #caller_location) {
-	fmt.fprintf(os.stderr, "%s(%d:%d) Panic", file_path, line, column);
-	if len(message) > 0 do fmt.fprint(os.stderr, ": ");
-	fmt.fprintf(os.stderr, message, ...args);
-	fmt.fprintf(os.stderr, "\n");
+panic :: proc "contextless" (message := "", using loc := #caller_location) {
+	fd := os.stderr;
+	__print_caller_location(fd, loc);
+	os.write_string(fd, " Panic");
+	if len(message) > 0 {
+		os.write_string(fd, ": ");
+		os.write_string(fd, message);
+		os.write_byte(fd, '\n');
+	}
 	__debug_trap();
 }
 
@@ -672,29 +705,59 @@ __complex128_ne :: inline proc "contextless" (a, b: complex128) -> bool { return
 
 __bounds_check_error :: proc "contextless" (file: string, line, column: int, index, count: int) {
 	if 0 <= index && index < count do return;
-	fmt.fprintf(os.stderr, "%s(%d:%d) Index %d is out of bounds range 0..%d\n",
-	            file, line, column, index, count);
+
+	fd := os.stderr;
+	__print_caller_location(fd, Source_Code_Location{file, line, column, ""});
+	os.write_string(fd, " Index ");
+	__print_u64(fd, u64(index));
+	os.write_string(fd, " is out of bounds range 0..");
+	__print_u64(fd, u64(count));
+	os.write_byte(fd, '\n');
 	__debug_trap();
 }
 
 __slice_expr_error :: proc "contextless" (file: string, line, column: int, low, high: int) {
 	if 0 <= low && low <= high do return;
-	fmt.fprintf(os.stderr, "%s(%d:%d) Invalid slice indices: %d..%d\n",
-	            file, line, column, low, high);
+
+
+	fd := os.stderr;
+	__print_caller_location(fd, Source_Code_Location{file, line, column, ""});
+	os.write_string(fd, " Invalid slice indices: ");
+	__print_u64(fd, u64(low));
+	os.write_string(fd, "..");
+	__print_u64(fd, u64(high));
+	os.write_byte(fd, '\n');
+	__debug_trap();
+
+	// fmt.fprintf(os.stderr, "%s(%d:%d) Invalid slice indices: %d..%d\n",
+	            // file, line, column, low, high);
 	__debug_trap();
 }
 
 __dynamic_array_expr_error :: proc "contextless" (file: string, line, column: int, low, high, max: int) {
 	if 0 <= low && low <= high && high <= max do return;
-	fmt.fprintf(os.stderr, "%s(%d:%d) Invalid slice indices: %d..%d..%d\n",
-	            file, line, column, low, high, max);
+
+	fd := os.stderr;
+	__print_caller_location(fd, Source_Code_Location{file, line, column, ""});
+	os.write_string(fd, " Invalid slice indices: ");
+	__print_u64(fd, u64(low));
+	os.write_string(fd, "..");
+	__print_u64(fd, u64(high));
+	os.write_string(fd, "..");
+	__print_u64(fd, u64(max));
+	os.write_byte(fd, '\n');
+	__debug_trap();
 	__debug_trap();
 }
 
 __type_assertion_check :: proc "contextless" (ok: bool, file: string, line, column: int, from, to: ^Type_Info) {
 	if ok do return;
-	fmt.fprintf(os.stderr, "%s(%d:%d) Invalid type_assertion from %T to %T\n",
-	            file, line, column, from, to);
+
+	fd := os.stderr;
+	__print_caller_location(fd, Source_Code_Location{file, line, column, ""});
+	os.write_string(fd, " Invalid type assertion");
+	// fmt.fprintf(os.stderr, "%s(%d:%d) Invalid type_assertion from %T to %T\n",
+	            // file, line, column, from, to);
 	__debug_trap();
 }
 

+ 5 - 0
core/os.odin

@@ -9,6 +9,11 @@ write_string :: proc(fd: Handle, str: string) -> (int, Errno) {
 	return write(fd, cast([]byte)str);
 }
 
+write_byte :: proc(fd: Handle, b: byte) -> (int, Errno) {
+	return write(fd, []byte{b});
+}
+
+
 read_entire_file :: proc(name: string) -> (data: []byte, success: bool) {
 	fd, err := open(name, O_RDONLY, 0);
 	if err != 0 {

+ 22 - 17
src/checker.cpp

@@ -576,18 +576,17 @@ void init_universal_scope(void) {
 
 void init_checker_info(CheckerInfo *i) {
 	gbAllocator a = heap_allocator();
-	map_init(&i->types,         a);
-	array_init(&i->definitions, a);
-	array_init(&i->entities,    a);
-	map_init(&i->untyped,       a);
-	map_init(&i->foreigns,      a);
-	map_init(&i->gen_procs,     a);
-	map_init(&i->gen_types,     a);
-	map_init(&i->type_info_map, a);
-	map_init(&i->files,         a);
+	map_init(&i->types,           a);
+	array_init(&i->definitions,   a);
+	array_init(&i->entities,      a);
+	map_init(&i->untyped,         a);
+	map_init(&i->foreigns,        a);
+	map_init(&i->gen_procs,       a);
+	map_init(&i->gen_types,       a);
+	array_init(&i->type_info_types, a);
+	map_init(&i->type_info_map,   a);
+	map_init(&i->files,           a);
 	array_init(&i->variable_init_order, a);
-
-	i->type_info_count = 0;
 }
 
 void destroy_checker_info(CheckerInfo *i) {
@@ -598,6 +597,7 @@ void destroy_checker_info(CheckerInfo *i) {
 	map_destroy(&i->foreigns);
 	map_destroy(&i->gen_procs);
 	map_destroy(&i->gen_types);
+	array_free(&i->type_info_types);
 	map_destroy(&i->type_info_map);
 	map_destroy(&i->files);
 	array_free(&i->variable_init_order);
@@ -922,6 +922,7 @@ void add_type_info_type(Checker *c, Type *t) {
 		return;
 	}
 
+	bool prev = false;
 	isize ti_index = -1;
 	for_array(i, c->info.type_info_map.entries) {
 		auto *e = &c->info.type_info_map.entries[i];
@@ -929,19 +930,22 @@ void add_type_info_type(Checker *c, Type *t) {
 		if (are_types_identical(t, prev_type)) {
 			// Duplicate entry
 			ti_index = e->value;
+			prev = true;
 			break;
 		}
 	}
 	if (ti_index < 0) {
 		// Unique entry
 		// NOTE(bill): map entries grow linearly and in order
-		ti_index = c->info.type_info_count;
-		c->info.type_info_count++;
+		ti_index = c->info.type_info_types.count;
+		array_add(&c->info.type_info_types, t);
 	}
 	map_set(&c->info.type_info_map, hash_type(t), ti_index);
 
-
-
+	if (prev) {
+		// NOTE(bill): If a previous one exists already, no need to continue
+		return;
+	}
 
 	// Add nested types
 
@@ -3053,7 +3057,8 @@ void check_parsed_files(Checker *c) {
 	// Add "Basic" type information
 	for (isize i = 0; i < gb_count_of(basic_types)-1; i++) {
 		Type *t = &basic_types[i];
-		if (t->Basic.size > 0 && t->Basic.kind != Basic_llvm_bool)  {
+		if (t->Basic.size > 0 &&
+		    t->Basic.kind != Basic_llvm_bool) {
 			add_type_info_type(c, t);
 		}
 	}
@@ -3064,7 +3069,7 @@ void check_parsed_files(Checker *c) {
 		if (e->kind == Entity_TypeName && e->type != nullptr) {
 			// i64 size  = type_size_of(c->allocator, e->type);
 			i64 align = type_align_of(c->allocator, e->type);
-			if (align > 0) {
+			if (align > 0 && ptr_set_exists(&c->info.minimum_dependency_set, e)) {
 				add_type_info_type(c, e->type);
 			}
 		}

+ 1 - 1
src/checker.hpp

@@ -298,8 +298,8 @@ struct CheckerInfo {
 	Map<Array<Entity *> > gen_procs;       // Key: AstNode * | Identifier -> Entity
 	Map<Array<Entity *> > gen_types;       // Key: Type *
 
+	Array<Type *>         type_info_types;
 	Map<isize>            type_info_map;   // Key: Type *
-	isize                 type_info_count;
 
 	Scope *               init_scope;
 	Entity *              entry_point;

+ 2 - 3
src/ir.cpp

@@ -7838,9 +7838,8 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
 	i32 type_info_member_names_index = 0;
 	i32 type_info_member_offsets_index = 0;
 
-	for_array(type_info_map_index, info->type_info_map.entries) {
-		auto *entry = &info->type_info_map.entries[type_info_map_index];
-		Type *t = cast(Type *)entry->key.ptr;
+	for_array(type_info_type_index, info->type_info_types) {
+		Type *t = info->type_info_types[type_info_type_index];
 		t = default_type(t);
 		if (t == t_invalid) {
 			continue;