mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 23:28:48 +00:00
Begin multithreading the llvm backend when -use-separate-modules is enabled
This commit is contained in:
+31
-15
@@ -730,6 +730,8 @@ gb_internal lbValue lb_map_set_proc_for_type(lbModule *m, Type *type) {
|
|||||||
|
|
||||||
|
|
||||||
gb_internal lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent) {
|
gb_internal lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent) {
|
||||||
|
MUTEX_GUARD(&m->gen->anonymous_proc_lits_mutex);
|
||||||
|
|
||||||
lbProcedure **found = map_get(&m->gen->anonymous_proc_lits, expr);
|
lbProcedure **found = map_get(&m->gen->anonymous_proc_lits, expr);
|
||||||
if (found) {
|
if (found) {
|
||||||
return lb_find_procedure_value_from_entity(m, (*found)->entity);
|
return lb_find_procedure_value_from_entity(m, (*found)->entity);
|
||||||
@@ -1526,6 +1528,10 @@ struct lbLLVMModulePassWorkerData {
|
|||||||
|
|
||||||
gb_internal WORKER_TASK_PROC(lb_llvm_module_pass_worker_proc) {
|
gb_internal WORKER_TASK_PROC(lb_llvm_module_pass_worker_proc) {
|
||||||
auto wd = cast(lbLLVMModulePassWorkerData *)data;
|
auto wd = cast(lbLLVMModulePassWorkerData *)data;
|
||||||
|
|
||||||
|
lb_run_remove_unused_function_pass(wd->m);
|
||||||
|
lb_run_remove_unused_globals_pass(wd->m);
|
||||||
|
|
||||||
LLVMPassManagerRef module_pass_manager = LLVMCreatePassManager();
|
LLVMPassManagerRef module_pass_manager = LLVMCreatePassManager();
|
||||||
lb_populate_module_pass_manager(wd->target_machine, module_pass_manager, build_context.optimization_level);
|
lb_populate_module_pass_manager(wd->target_machine, module_pass_manager, build_context.optimization_level);
|
||||||
LLVMRunPassManager(module_pass_manager, wd->m->mod);
|
LLVMRunPassManager(module_pass_manager, wd->m->mod);
|
||||||
@@ -2155,29 +2161,47 @@ gb_internal void lb_generate_code(lbGenerator *gen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isize non_empty_module_count = 0;
|
||||||
|
for (auto const &entry : gen->modules) {
|
||||||
|
lbModule *m = entry.value;
|
||||||
|
if (!lb_is_module_empty(m)) {
|
||||||
|
non_empty_module_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (non_empty_module_count <= 1) {
|
||||||
|
do_threading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TIME_SECTION("LLVM Function Pass");
|
TIME_SECTION("LLVM Function Pass");
|
||||||
for (auto const &entry : gen->modules) {
|
for (auto const &entry : gen->modules) {
|
||||||
lbModule *m = entry.value;
|
lbModule *m = entry.value;
|
||||||
lb_llvm_function_pass_worker_proc(m);
|
// if (do_threading) {
|
||||||
|
// thread_pool_add_task(lb_llvm_function_pass_worker_proc, m);
|
||||||
|
// } else {
|
||||||
|
lb_llvm_function_pass_worker_proc(m);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
thread_pool_wait();
|
||||||
|
|
||||||
TIME_SECTION("LLVM Module Pass");
|
TIME_SECTION("LLVM Module Pass");
|
||||||
|
|
||||||
for (auto const &entry : gen->modules) {
|
for (auto const &entry : gen->modules) {
|
||||||
lbModule *m = entry.value;
|
lbModule *m = entry.value;
|
||||||
lb_run_remove_unused_function_pass(m);
|
|
||||||
lb_run_remove_unused_globals_pass(m);
|
|
||||||
|
|
||||||
auto wd = gb_alloc_item(permanent_allocator(), lbLLVMModulePassWorkerData);
|
auto wd = gb_alloc_item(permanent_allocator(), lbLLVMModulePassWorkerData);
|
||||||
wd->m = m;
|
wd->m = m;
|
||||||
wd->target_machine = m->target_machine;
|
wd->target_machine = m->target_machine;
|
||||||
|
|
||||||
lb_llvm_module_pass_worker_proc(wd);
|
if (do_threading) {
|
||||||
|
thread_pool_add_task(lb_llvm_module_pass_worker_proc, wd);
|
||||||
|
} else {
|
||||||
|
lb_llvm_module_pass_worker_proc(wd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
thread_pool_wait();
|
||||||
|
|
||||||
|
|
||||||
|
TIME_SECTION("LLVM Module Verification");
|
||||||
|
|
||||||
llvm_error = nullptr;
|
llvm_error = nullptr;
|
||||||
defer (LLVMDisposeMessage(llvm_error));
|
defer (LLVMDisposeMessage(llvm_error));
|
||||||
|
|
||||||
@@ -2245,21 +2269,13 @@ gb_internal void lb_generate_code(lbGenerator *gen) {
|
|||||||
|
|
||||||
TIME_SECTION("LLVM Object Generation");
|
TIME_SECTION("LLVM Object Generation");
|
||||||
|
|
||||||
isize non_empty_module_count = 0;
|
|
||||||
for (auto const &entry : gen->modules) {
|
|
||||||
lbModule *m = entry.value;
|
|
||||||
if (!lb_is_module_empty(m)) {
|
|
||||||
non_empty_module_count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (build_context.ignore_llvm_build) {
|
if (build_context.ignore_llvm_build) {
|
||||||
gb_printf_err("LLVM SUCCESS!\n");
|
gb_printf_err("LLVM SUCCESS!\n");
|
||||||
gb_exit(1);
|
gb_exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_threading && non_empty_module_count > 1) {
|
if (do_threading) {
|
||||||
for (auto const &entry : gen->modules) {
|
for (auto const &entry : gen->modules) {
|
||||||
lbModule *m = entry.value;
|
lbModule *m = entry.value;
|
||||||
if (lb_is_module_empty(m)) {
|
if (lb_is_module_empty(m)) {
|
||||||
|
|||||||
@@ -132,6 +132,8 @@ struct lbModule {
|
|||||||
PtrMap<void *, lbStructFieldRemapping> struct_field_remapping; // Key: LLVMTypeRef or Type *
|
PtrMap<void *, lbStructFieldRemapping> struct_field_remapping; // Key: LLVMTypeRef or Type *
|
||||||
i32 internal_type_level;
|
i32 internal_type_level;
|
||||||
|
|
||||||
|
RecursiveMutex values_mutex;
|
||||||
|
|
||||||
PtrMap<Entity *, lbValue> values;
|
PtrMap<Entity *, lbValue> values;
|
||||||
PtrMap<Entity *, lbAddr> soa_values;
|
PtrMap<Entity *, lbAddr> soa_values;
|
||||||
StringMap<lbValue> members;
|
StringMap<lbValue> members;
|
||||||
@@ -178,6 +180,7 @@ struct lbGenerator {
|
|||||||
PtrMap<LLVMContextRef, lbModule *> modules_through_ctx;
|
PtrMap<LLVMContextRef, lbModule *> modules_through_ctx;
|
||||||
lbModule default_module;
|
lbModule default_module;
|
||||||
|
|
||||||
|
BlockingMutex anonymous_proc_lits_mutex;
|
||||||
PtrMap<Ast *, lbProcedure *> anonymous_proc_lits;
|
PtrMap<Ast *, lbProcedure *> anonymous_proc_lits;
|
||||||
|
|
||||||
BlockingMutex foreign_mutex;
|
BlockingMutex foreign_mutex;
|
||||||
|
|||||||
@@ -316,6 +316,7 @@ gb_internal bool lb_is_instr_terminating(LLVMValueRef instr) {
|
|||||||
|
|
||||||
|
|
||||||
gb_internal lbModule *lb_pkg_module(lbGenerator *gen, AstPackage *pkg) {
|
gb_internal lbModule *lb_pkg_module(lbGenerator *gen, AstPackage *pkg) {
|
||||||
|
// NOTE(bill): no need for a mutex since it's immutable
|
||||||
auto *found = map_get(&gen->modules, pkg);
|
auto *found = map_get(&gen->modules, pkg);
|
||||||
if (found) {
|
if (found) {
|
||||||
return *found;
|
return *found;
|
||||||
@@ -1354,7 +1355,7 @@ gb_internal String lb_mangle_name(lbModule *m, Entity *e) {
|
|||||||
return mangled_name;
|
return mangled_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedure *p) {
|
gb_internal String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedure *p, lbModule *module) {
|
||||||
// NOTE(bill, 2020-03-08): A polymorphic procedure may take a nested type declaration
|
// NOTE(bill, 2020-03-08): A polymorphic procedure may take a nested type declaration
|
||||||
// and as a result, the declaration does not have time to determine what it should be
|
// and as a result, the declaration does not have time to determine what it should be
|
||||||
|
|
||||||
@@ -1421,7 +1422,7 @@ gb_internal String lb_get_entity_name(lbModule *m, Entity *e, String default_nam
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (e->kind == Entity_TypeName && (e->scope->flags & ScopeFlag_File) == 0) {
|
if (e->kind == Entity_TypeName && (e->scope->flags & ScopeFlag_File) == 0) {
|
||||||
return lb_set_nested_type_name_ir_mangled_name(e, nullptr);
|
return lb_set_nested_type_name_ir_mangled_name(e, nullptr, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
String name = {};
|
String name = {};
|
||||||
@@ -2164,19 +2165,25 @@ gb_internal void lb_ensure_abi_function_type(lbModule *m, lbProcedure *p) {
|
|||||||
|
|
||||||
gb_internal void lb_add_entity(lbModule *m, Entity *e, lbValue val) {
|
gb_internal void lb_add_entity(lbModule *m, Entity *e, lbValue val) {
|
||||||
if (e != nullptr) {
|
if (e != nullptr) {
|
||||||
|
mutex_lock(&m->values_mutex);
|
||||||
map_set(&m->values, e, val);
|
map_set(&m->values, e, val);
|
||||||
|
mutex_unlock(&m->values_mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gb_internal void lb_add_member(lbModule *m, String const &name, lbValue val) {
|
gb_internal void lb_add_member(lbModule *m, String const &name, lbValue val) {
|
||||||
if (name.len > 0) {
|
if (name.len > 0) {
|
||||||
|
mutex_lock(&m->values_mutex);
|
||||||
string_map_set(&m->members, name, val);
|
string_map_set(&m->members, name, val);
|
||||||
|
mutex_unlock(&m->values_mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gb_internal void lb_add_procedure_value(lbModule *m, lbProcedure *p) {
|
gb_internal void lb_add_procedure_value(lbModule *m, lbProcedure *p) {
|
||||||
|
mutex_lock(&m->values_mutex);
|
||||||
if (p->entity != nullptr) {
|
if (p->entity != nullptr) {
|
||||||
map_set(&m->procedure_values, p->value, p->entity);
|
map_set(&m->procedure_values, p->value, p->entity);
|
||||||
}
|
}
|
||||||
string_map_set(&m->procedures, p->name, p);
|
string_map_set(&m->procedures, p->name, p);
|
||||||
|
mutex_unlock(&m->values_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2519,6 +2526,8 @@ gb_internal lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *e
|
|||||||
return *found;
|
return *found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mutex_lock(&m->values_mutex);
|
||||||
|
defer (mutex_unlock(&m->values_mutex));
|
||||||
|
|
||||||
auto *found = map_get(&m->values, e);
|
auto *found = map_get(&m->values, e);
|
||||||
if (found) {
|
if (found) {
|
||||||
@@ -2538,7 +2547,6 @@ gb_internal lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *e
|
|||||||
if (USE_SEPARATE_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) {
|
||||||
|
|
||||||
String name = lb_get_entity_name(other_module, e);
|
String name = lb_get_entity_name(other_module, e);
|
||||||
|
|
||||||
lb_set_entity_from_other_modules_linkage_correctly(other_module, e, name);
|
lb_set_entity_from_other_modules_linkage_correctly(other_module, e, name);
|
||||||
@@ -2569,6 +2577,9 @@ gb_internal lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e)
|
|||||||
e = strip_entity_wrapping(e);
|
e = strip_entity_wrapping(e);
|
||||||
GB_ASSERT(e != nullptr);
|
GB_ASSERT(e != nullptr);
|
||||||
|
|
||||||
|
mutex_lock(&m->values_mutex);
|
||||||
|
defer (mutex_unlock(&m->values_mutex));
|
||||||
|
|
||||||
auto *found = map_get(&m->values, e);
|
auto *found = map_get(&m->values, e);
|
||||||
if (found) {
|
if (found) {
|
||||||
return *found;
|
return *found;
|
||||||
@@ -2657,6 +2668,10 @@ gb_internal lbValue lb_find_value_from_entity(lbModule *m, Entity *e) {
|
|||||||
return lb_find_procedure_value_from_entity(m, e);
|
return lb_find_procedure_value_from_entity(m, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&m->values_mutex);
|
||||||
|
defer (mutex_unlock(&m->values_mutex));
|
||||||
|
|
||||||
|
|
||||||
auto *found = map_get(&m->values, e);
|
auto *found = map_get(&m->values, e);
|
||||||
if (found) {
|
if (found) {
|
||||||
return *found;
|
return *found;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
lb_set_nested_type_name_ir_mangled_name(e, p);
|
lb_set_nested_type_name_ir_mangled_name(e, p, p->module);
|
||||||
}
|
}
|
||||||
|
|
||||||
for_array(i, vd->names) {
|
for_array(i, vd->names) {
|
||||||
|
|||||||
Reference in New Issue
Block a user