Spawn function passes as procedures are generated for the module

This commit is contained in:
gingerBill
2025-09-12 17:17:22 +01:00
parent 96e42b25c1
commit a2d9c79508
7 changed files with 60 additions and 10 deletions

View File

@@ -166,6 +166,8 @@ struct Entity {
std::atomic<EntityState> state;
std::atomic<i32> min_dep_count;
Token token;
u32 name_hash;
Scope * scope;
Type * type;
std::atomic<Ast *> identifier; // Can be nullptr
@@ -345,6 +347,9 @@ gb_internal Entity *alloc_entity(EntityKind kind, Scope *scope, Token token, Typ
entity->state = EntityState_Unresolved;
entity->scope = scope;
entity->token = token;
if (token.string.len > 0) {
entity->name_hash = string_hash(token.string);
}
entity->type = type;
entity->id = 1 + global_entity_id.fetch_add(1);
if (token.pos.file_id) {

View File

@@ -2063,7 +2063,11 @@ gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProc
wd->global_variables = global_variables;
// TODO(bill): determine whether or not this is better multithreaded or not
lb_create_startup_runtime_worker_proc(wd);
if (main_module->gen->do_threading) {
thread_pool_add_task(lb_create_startup_runtime_worker_proc, wd);
} else {
lb_create_startup_runtime_worker_proc(wd);
}
return p;
}
@@ -2267,7 +2271,9 @@ gb_internal void lb_llvm_function_pass_per_function_internal(lbModule *module, l
gb_internal WORKER_TASK_PROC(lb_llvm_function_pass_per_module) {
lbModule *m = cast(lbModule *)data;
{
if (m->function_pass_managers[0] == nullptr) {
GB_ASSERT(m->function_pass_managers[lbFunctionPassManager_default] == nullptr);
for (i32 i = 0; i < lbFunctionPassManager_COUNT; i++) {
@@ -2445,6 +2451,10 @@ gb_internal WORKER_TASK_PROC(lb_generate_procedures_in_a_module_worker_proc) {
lb_module_timing_end(&module_timing);
if (m->gen->do_threading && !build_context.ODIN_DEBUG) {
thread_pool_add_task(lb_llvm_function_pass_per_module, m);
}
return 0;
}
@@ -2478,6 +2488,10 @@ gb_internal WORKER_TASK_PROC(lb_generate_missing_procedures_to_check_worker_proc
lb_module_timing_end(&module_timing);
if (m->gen->do_threading && !build_context.ODIN_DEBUG) {
thread_pool_add_task(lb_llvm_function_pass_per_module, m);
}
return 0;
}
@@ -3506,7 +3520,9 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
}
TIME_SECTION("LLVM Function Pass");
lb_llvm_function_passes(gen, gen->do_threading && !build_context.ODIN_DEBUG);
if (!(gen->do_threading && !build_context.ODIN_DEBUG)) {
lb_llvm_function_passes(gen, gen->do_threading && !build_context.ODIN_DEBUG);
}
TIME_SECTION("LLVM Module Pass and Verification");
lb_llvm_module_passes_and_verification(gen, gen->do_threading);

View File

@@ -368,6 +368,7 @@ struct lbProcedure {
bool is_export;
bool is_entry_point;
bool is_startup;
bool has_had_passes;
lbFunctionType *abi_function_type;

View File

@@ -244,7 +244,24 @@ gb_internal lbValue lb_const_undef(lbModule *m, Type *type) {
return lbValue{v, type};
}
gb_internal lbValue lb_const_string_with_hash(lbModule *m, String const &value, u32 hash) {
isize len = value.len;
LLVMValueRef ptr = nullptr;
if (len == 0) {
ptr = LLVMConstNull(lb_type(m, t_u8_ptr));
} else {
ptr = lb_find_or_add_entity_string_ptr(m, value, false, hash);
}
LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), len, true);
lbValue res = {};
res.type = t_string;
res.value = llvm_const_string_internal(m, t_string, ptr, str_len);
return res;
}
gb_internal lbValue lb_const_int(lbModule *m, Type *type, u64 value) {
lbValue res = {};

View File

@@ -2710,12 +2710,17 @@ general_end:;
gb_internal LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str, bool custom_link_section) {
gb_internal LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str, bool custom_link_section, u32 hash=0) {
StringHashKey key = {};
LLVMValueRef *found = nullptr;
if (!custom_link_section) {
key = string_hash_string(str);
if (hash) {
key.hash = hash;
key.string = str;
} else {
key = string_hash_string(str);
}
found = string_map_get(&m->const_strings, key);
}
if (found != nullptr) {

View File

@@ -479,6 +479,10 @@ gb_internal void lb_run_function_pass_manager(LLVMPassManagerRef fpm, lbProcedur
if (p == nullptr) {
return;
}
if (p->has_had_passes) {
return;
}
// NOTE(bill): LLVMAddDCEPass doesn't seem to be exported in the official DLL's for LLVM
// which means we cannot rely upon it
// This is also useful for read the .ll for debug purposes because a lot of instructions
@@ -499,6 +503,8 @@ gb_internal void lb_run_function_pass_manager(LLVMPassManagerRef fpm, lbProcedur
}
LLVMRunFunctionPassManager(fpm, p->value);
p->has_had_passes = true;
}
gb_internal void llvm_delete_function(LLVMValueRef func) {

View File

@@ -403,7 +403,7 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ
lbValue loc = lb_const_source_code_location_as_global_ptr(m, proc_name, pos);
LLVMValueRef vals[4] = {
lb_const_string(m, t->Named.type_name->token.string).value,
lb_const_string_with_hash(m, t->Named.type_name->token.string, t->Named.type_name->name_hash).value,
get_type_info_ptr(m, t->Named.base),
pkg_name,
loc.value
@@ -705,7 +705,7 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ
lb_global_type_info_member_types_values[type_offset+i] = get_type_info_ptr(m, f->type);
if (f->token.string.len > 0) {
lb_global_type_info_member_names_values[name_offset+i] = lb_const_string(m, f->token.string).value;
lb_global_type_info_member_names_values[name_offset+i] = lb_const_string_with_hash(m, f->token.string, f->name_hash).value;
}
}
@@ -747,7 +747,7 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ
GB_ASSERT(is_type_integer(t->Enum.base_type));
for_array(i, fields) {
name_values[i] = lb_const_string(m, fields[i]->token.string).value;
name_values [i] = lb_const_string_with_hash(m, fields[i]->token.string, fields[i]->name_hash).value;
value_values[i] = lb_const_value(m, t_i64, fields[i]->Constant.value).value;
}
@@ -884,7 +884,7 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ
lb_global_type_info_member_usings_values[usings_offset+source_index] = lb_const_bool(m, t_bool, (f->flags&EntityFlag_Using) != 0).value;
if (f->token.string.len > 0) {
lb_global_type_info_member_names_values[names_offset+source_index] = lb_const_string(m, f->token.string).value;
lb_global_type_info_member_names_values[names_offset+source_index] = lb_const_string_with_hash(m, f->token.string, f->name_hash).value;
}
if (t->Struct.tags != nullptr) {
@@ -1007,7 +1007,7 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ
lbValue index = lb_const_int(m, t_int, source_index);
if (f->token.string.len > 0) {
lb_global_type_info_member_names_values[names_offset+source_index] = lb_const_string(m, f->token.string).value;
lb_global_type_info_member_names_values[names_offset+source_index] = lb_const_string_with_hash(m, f->token.string, f->name_hash).value;
}
lb_global_type_info_member_types_values[types_offset+source_index] = get_type_info_ptr(m, f->type);