Browse Source

Add `missing_procedures_to_check` to `lbModule`

gingerBill 4 years ago
parent
commit
b036cc9013
2 changed files with 66 additions and 47 deletions
  1. 65 47
      src/llvm_backend.cpp
  2. 1 0
      src/llvm_backend.hpp

+ 65 - 47
src/llvm_backend.cpp

@@ -1,7 +1,7 @@
 #define MULTITHREAD_OBJECT_GENERATION 1
 #define MULTITHREAD_OBJECT_GENERATION 1
 
 
-#ifndef USE_SEPARTE_MODULES
-#define USE_SEPARTE_MODULES build_context.use_separate_modules
+#ifndef USE_SEPARATE_MODULES
+#define USE_SEPARATE_MODULES build_context.use_separate_modules
 #endif
 #endif
 
 
 #ifndef MULTITHREAD_OBJECT_GENERATION
 #ifndef MULTITHREAD_OBJECT_GENERATION
@@ -2877,7 +2877,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body)
 			LLVMAddTargetDependentFunctionAttr(p->value, "wasm-export-name", export_name);
 			LLVMAddTargetDependentFunctionAttr(p->value, "wasm-export-name", export_name);
 		}
 		}
 	} else if (!p->is_foreign) {
 	} else if (!p->is_foreign) {
-		if (!USE_SEPARTE_MODULES) {
+		if (!USE_SEPARATE_MODULES) {
 			LLVMSetLinkage(p->value, LLVMInternalLinkage);
 			LLVMSetLinkage(p->value, LLVMInternalLinkage);
 
 
 			// NOTE(bill): if a procedure is defined in package runtime and uses a custom link name,
 			// NOTE(bill): if a procedure is defined in package runtime and uses a custom link name,
@@ -6295,19 +6295,25 @@ lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) {
 	GB_ASSERT(is_type_proc(e->type));
 	GB_ASSERT(is_type_proc(e->type));
 	e = strip_entity_wrapping(e);
 	e = strip_entity_wrapping(e);
 	GB_ASSERT(e != nullptr);
 	GB_ASSERT(e != nullptr);
+
 	auto *found = map_get(&m->values, hash_entity(e));
 	auto *found = map_get(&m->values, hash_entity(e));
 	if (found) {
 	if (found) {
 		return *found;
 		return *found;
 	}
 	}
 
 
+	gb_printf_err("%.*s\n", LIT(e->token.string));
+
 	bool ignore_body = false;
 	bool ignore_body = false;
 
 
-	if (USE_SEPARTE_MODULES) {
+	if (USE_SEPARATE_MODULES) {
 		lbModule *other_module = lb_pkg_module(m->gen, e->pkg);
 		lbModule *other_module = lb_pkg_module(m->gen, e->pkg);
 		ignore_body = other_module != m;
 		ignore_body = other_module != m;
 	}
 	}
 
 
 	lbProcedure *missing_proc = lb_create_procedure(m, e, ignore_body);
 	lbProcedure *missing_proc = lb_create_procedure(m, e, ignore_body);
+	if (!ignore_body) {
+		array_add(&m->missing_procedures_to_check, missing_proc);
+	}
 	found = map_get(&m->values, hash_entity(e));
 	found = map_get(&m->values, hash_entity(e));
 	if (found) {
 	if (found) {
 		return *found;
 		return *found;
@@ -6349,7 +6355,7 @@ lbValue lb_find_value_from_entity(lbModule *m, Entity *e) {
 		return *found;
 		return *found;
 	}
 	}
 
 
-	if (USE_SEPARTE_MODULES) {
+	if (USE_SEPARATE_MODULES) {
 		lbModule *other_module = lb_pkg_module(m->gen, e->pkg);
 		lbModule *other_module = lb_pkg_module(m->gen, e->pkg);
 
 
 		// TODO(bill): correct this logic
 		// TODO(bill): correct this logic
@@ -12459,7 +12465,7 @@ lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *expr) {
 	if (e->kind == Entity_Procedure) {
 	if (e->kind == Entity_Procedure) {
 		return lb_find_procedure_value_from_entity(m, e);
 		return lb_find_procedure_value_from_entity(m, e);
 	}
 	}
-	if (USE_SEPARTE_MODULES) {
+	if (USE_SEPARATE_MODULES) {
 		lbModule *other_module = lb_pkg_module(m->gen, e->pkg);
 		lbModule *other_module = lb_pkg_module(m->gen, e->pkg);
 		if (other_module != m) {
 		if (other_module != m) {
 
 
@@ -14316,7 +14322,7 @@ void lb_init_module(lbModule *m, Checker *c) {
 	if (m->pkg) {
 	if (m->pkg) {
 		module_name = gb_string_appendc(module_name, "-");
 		module_name = gb_string_appendc(module_name, "-");
 		module_name = gb_string_append_length(module_name, m->pkg->name.text, m->pkg->name.len);
 		module_name = gb_string_append_length(module_name, m->pkg->name.text, m->pkg->name.len);
-	} else if (USE_SEPARTE_MODULES) {
+	} else if (USE_SEPARATE_MODULES) {
 		module_name = gb_string_appendc(module_name, "-builtin");
 		module_name = gb_string_appendc(module_name, "-builtin");
 	}
 	}
 
 
@@ -14363,6 +14369,7 @@ void lb_init_module(lbModule *m, Checker *c) {
 	map_init(&m->hasher_procs, a);
 	map_init(&m->hasher_procs, a);
 	array_init(&m->procedures_to_generate, a, 0, 1024);
 	array_init(&m->procedures_to_generate, a, 0, 1024);
 	array_init(&m->foreign_library_paths,  a, 0, 1024);
 	array_init(&m->foreign_library_paths,  a, 0, 1024);
+	array_init(&m->missing_procedures_to_check, a, 0, 16);
 
 
 	map_init(&m->debug_values, a);
 	map_init(&m->debug_values, a);
 	array_init(&m->debug_incomplete_types, a, 0, 1024);
 	array_init(&m->debug_incomplete_types, a, 0, 1024);
@@ -14422,7 +14429,7 @@ bool lb_init_generator(lbGenerator *gen, Checker *c) {
 
 
 	gb_mutex_init(&gen->mutex);
 	gb_mutex_init(&gen->mutex);
 
 
-	if (USE_SEPARTE_MODULES) {
+	if (USE_SEPARATE_MODULES) {
 		for_array(i, gen->info->packages.entries) {
 		for_array(i, gen->info->packages.entries) {
 			AstPackage *pkg = gen->info->packages.entries[i].value;
 			AstPackage *pkg = gen->info->packages.entries[i].value;
 
 
@@ -15530,7 +15537,7 @@ String lb_filepath_ll_for_module(lbModule *m) {
 	String path = m->gen->output_base;
 	String path = m->gen->output_base;
 	if (m->pkg) {
 	if (m->pkg) {
 		path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name);
 		path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name);
-	} else if (USE_SEPARTE_MODULES) {
+	} else if (USE_SEPARATE_MODULES) {
 		path = concatenate_strings(permanent_allocator(), path, STR_LIT("-builtin"));
 		path = concatenate_strings(permanent_allocator(), path, STR_LIT("-builtin"));
 	}
 	}
 	path = concatenate_strings(permanent_allocator(), path, STR_LIT(".ll"));
 	path = concatenate_strings(permanent_allocator(), path, STR_LIT(".ll"));
@@ -15705,6 +15712,46 @@ WORKER_TASK_PROC(lb_llvm_module_pass_worker_proc) {
 }
 }
 
 
 
 
+void lb_generate_procedure(lbModule *m, lbProcedure *p) {
+	if (p->is_done) {
+		return;
+	}
+	if (p->body != nullptr) { // Build Procedure
+		m->curr_procedure = p;
+		lb_begin_procedure_body(p);
+		lb_build_stmt(p, p->body);
+		lb_end_procedure_body(p);
+		p->is_done = true;
+		m->curr_procedure = nullptr;
+	}
+	lb_end_procedure(p);
+
+	// Add Flags
+	if (p->body != nullptr) {
+		if (p->name == "memcpy" || p->name == "memmove" ||
+		    p->name == "runtime.mem_copy" || p->name == "mem_copy_non_overlapping" ||
+		    string_starts_with(p->name, str_lit("llvm.memcpy")) ||
+		    string_starts_with(p->name, str_lit("llvm.memmove"))) {
+			p->flags |= lbProcedureFlag_WithoutMemcpyPass;
+		}
+	}
+
+	if (!m->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) {
+		char *llvm_error = nullptr;
+
+		gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %.*s\n", LIT(p->name));
+		LLVMDumpValue(p->value);
+		gb_printf_err("\n\n\n\n");
+		String filepath_ll = lb_filepath_ll_for_module(m);
+		if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
+			gb_printf_err("LLVM Error: %s\n", llvm_error);
+		}
+		LLVMVerifyFunction(p->value, LLVMPrintMessageAction);
+		gb_exit(1);
+	}
+}
+
+
 void lb_generate_code(lbGenerator *gen) {
 void lb_generate_code(lbGenerator *gen) {
 	#define TIME_SECTION(str) do { if (build_context.show_more_timings) timings_start_section(&global_timings, str_lit(str)); } while (0)
 	#define TIME_SECTION(str) do { if (build_context.show_more_timings) timings_start_section(&global_timings, str_lit(str)); } while (0)
 	#define TIME_SECTION_WITH_LEN(str, len) do { if (build_context.show_more_timings) timings_start_section(&global_timings, make_string((u8 *)str, len)); } while (0)
 	#define TIME_SECTION_WITH_LEN(str, len) do { if (build_context.show_more_timings) timings_start_section(&global_timings, make_string((u8 *)str, len)); } while (0)
@@ -15714,7 +15761,7 @@ void lb_generate_code(lbGenerator *gen) {
 	isize thread_count = gb_max(build_context.thread_count, 1);
 	isize thread_count = gb_max(build_context.thread_count, 1);
 	isize worker_count = thread_count-1;
 	isize worker_count = thread_count-1;
 
 
-	LLVMBool do_threading = (LLVMIsMultithreaded() && USE_SEPARTE_MODULES && MULTITHREAD_OBJECT_GENERATION && worker_count > 0);
+	LLVMBool do_threading = (LLVMIsMultithreaded() && USE_SEPARATE_MODULES && MULTITHREAD_OBJECT_GENERATION && worker_count > 0);
 
 
 	thread_pool_init(&lb_thread_pool, heap_allocator(), worker_count, "LLVMBackend");
 	thread_pool_init(&lb_thread_pool, heap_allocator(), worker_count, "LLVMBackend");
 	defer (thread_pool_destroy(&lb_thread_pool));
 	defer (thread_pool_destroy(&lb_thread_pool));
@@ -15851,7 +15898,7 @@ void lb_generate_code(lbGenerator *gen) {
 			Type *t = alloc_type_array(t_type_info, max_type_info_count);
 			Type *t = alloc_type_array(t_type_info, max_type_info_count);
 			LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), LB_TYPE_INFO_DATA_NAME);
 			LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), LB_TYPE_INFO_DATA_NAME);
 			LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
 			LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
-			if (!USE_SEPARTE_MODULES) {
+			if (!USE_SEPARATE_MODULES) {
 				LLVMSetLinkage(g, LLVMInternalLinkage);
 				LLVMSetLinkage(g, LLVMInternalLinkage);
 			}
 			}
 
 
@@ -16026,7 +16073,7 @@ void lb_generate_code(lbGenerator *gen) {
 			LLVMSetLinkage(g.value, LLVMDLLExportLinkage);
 			LLVMSetLinkage(g.value, LLVMDLLExportLinkage);
 			LLVMSetDLLStorageClass(g.value, LLVMDLLExportStorageClass);
 			LLVMSetDLLStorageClass(g.value, LLVMDLLExportStorageClass);
 		} else if (!is_foreign) {
 		} else if (!is_foreign) {
-			if (USE_SEPARTE_MODULES) {
+			if (USE_SEPARATE_MODULES) {
 				LLVMSetLinkage(g.value, LLVMExternalLinkage);
 				LLVMSetLinkage(g.value, LLVMExternalLinkage);
 			} else {
 			} else {
 				LLVMSetLinkage(g.value, LLVMInternalLinkage);
 				LLVMSetLinkage(g.value, LLVMInternalLinkage);
@@ -16135,7 +16182,7 @@ void lb_generate_code(lbGenerator *gen) {
 		}
 		}
 
 
 		lbModule *m = &gen->default_module;
 		lbModule *m = &gen->default_module;
-		if (USE_SEPARTE_MODULES) {
+		if (USE_SEPARATE_MODULES) {
 			m = lb_pkg_module(gen, e->pkg);
 			m = lb_pkg_module(gen, e->pkg);
 		}
 		}
 
 
@@ -16167,40 +16214,11 @@ void lb_generate_code(lbGenerator *gen) {
 		lbModule *m = gen->modules.entries[j].value;
 		lbModule *m = gen->modules.entries[j].value;
 		for_array(i, m->procedures_to_generate) {
 		for_array(i, m->procedures_to_generate) {
 			lbProcedure *p = m->procedures_to_generate[i];
 			lbProcedure *p = m->procedures_to_generate[i];
-			if (p->is_done) {
-				continue;
-			}
-			if (p->body != nullptr) { // Build Procedure
-				m->curr_procedure = p;
-				lb_begin_procedure_body(p);
-				lb_build_stmt(p, p->body);
-				lb_end_procedure_body(p);
-				p->is_done = true;
-				m->curr_procedure = nullptr;
-			}
-			lb_end_procedure(p);
-
-			// Add Flags
-			if (p->body != nullptr) {
-				if (p->name == "memcpy" || p->name == "memmove" ||
-				    p->name == "runtime.mem_copy" || p->name == "mem_copy_non_overlapping" ||
-				    string_starts_with(p->name, str_lit("llvm.memcpy")) ||
-				    string_starts_with(p->name, str_lit("llvm.memmove"))) {
-					p->flags |= lbProcedureFlag_WithoutMemcpyPass;
-				}
-			}
-
-			if (!m->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) {
-				gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %.*s\n", LIT(p->name));
-				LLVMDumpValue(p->value);
-				gb_printf_err("\n\n\n\n");
-				String filepath_ll = lb_filepath_ll_for_module(m);
-				if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
-					gb_printf_err("LLVM Error: %s\n", llvm_error);
-				}
-				LLVMVerifyFunction(p->value, LLVMPrintMessageAction);
-				gb_exit(1);
-			}
+			lb_generate_procedure(m, p);
+		}
+		for_array(i, m->missing_procedures_to_check) {
+			lbProcedure *p = m->missing_procedures_to_check[i];
+			lb_generate_procedure(m, p);
 		}
 		}
 	}
 	}
 
 

+ 1 - 0
src/llvm_backend.hpp

@@ -104,6 +104,7 @@ struct lbModule {
 	StringMap<lbValue>  members;
 	StringMap<lbValue>  members;
 	StringMap<lbProcedure *> procedures;
 	StringMap<lbProcedure *> procedures;
 	Map<Entity *> procedure_values; // Key: LLVMValueRef
 	Map<Entity *> procedure_values; // Key: LLVMValueRef
+	Array<lbProcedure *> missing_procedures_to_check;
 
 
 	StringMap<LLVMValueRef> const_strings;
 	StringMap<LLVMValueRef> const_strings;