mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-20 12:44:59 -07:00
Compile wasm64; Add lb_run_remove_unused_function_pass
This commit is contained in:
@@ -895,7 +895,11 @@ void init_build_context(TargetMetrics *cross_target) {
|
||||
}
|
||||
|
||||
} else if (is_arch_wasm()) {
|
||||
bc->link_flags = str_lit("--no-entry --export-table --export-all --allow-undefined ");
|
||||
if (bc->metrics.arch == TargetArch_wasm32) {
|
||||
bc->link_flags = str_lit("--no-entry --export-table --export-all --allow-undefined ");
|
||||
} else {
|
||||
bc->link_flags = str_lit("--no-entry --export-table --export-all --allow-undefined -mwasm64 ");
|
||||
}
|
||||
} else {
|
||||
gb_printf_err("Compiler Error: Unsupported architecture\n");;
|
||||
gb_exit(1);
|
||||
|
||||
@@ -899,6 +899,10 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
|
||||
mutex_unlock(&ctx->info->foreign_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
if (e->Procedure.link_name.len > 0 ) {
|
||||
e->flags |= EntityFlag_CustomLinkName;
|
||||
}
|
||||
}
|
||||
|
||||
void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, Ast *init_expr) {
|
||||
@@ -990,6 +994,10 @@ void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr,
|
||||
string_map_set(fp, key, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (e->Variable.link_name.len > 0) {
|
||||
e->flags |= EntityFlag_CustomLinkName;
|
||||
}
|
||||
|
||||
if (init_expr == nullptr) {
|
||||
if (type_expr == nullptr) {
|
||||
|
||||
+2
-1
@@ -74,9 +74,10 @@ enum EntityFlag : u64 {
|
||||
|
||||
EntityFlag_Test = 1ull<<30,
|
||||
EntityFlag_Init = 1ull<<31,
|
||||
|
||||
EntityFlag_CustomLinkName = 1ull<<40,
|
||||
|
||||
EntityFlag_Overridden = 1ull<<63,
|
||||
|
||||
};
|
||||
|
||||
enum EntityState : u32 {
|
||||
|
||||
+11
-5
@@ -1064,14 +1064,10 @@ struct lbLLVMModulePassWorkerData {
|
||||
};
|
||||
|
||||
WORKER_TASK_PROC(lb_llvm_module_pass_worker_proc) {
|
||||
GB_ASSERT(MULTITHREAD_OBJECT_GENERATION);
|
||||
|
||||
auto wd = cast(lbLLVMModulePassWorkerData *)data;
|
||||
|
||||
LLVMPassManagerRef module_pass_manager = LLVMCreatePassManager();
|
||||
lb_populate_module_pass_manager(wd->target_machine, module_pass_manager, build_context.optimization_level);
|
||||
LLVMRunPassManager(module_pass_manager, wd->m->mod);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1661,6 +1657,8 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
|
||||
for_array(i, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[i].value;
|
||||
|
||||
lb_run_remove_unused_function_pass(m->mod);
|
||||
|
||||
auto wd = gb_alloc_item(permanent_allocator(), lbLLVMModulePassWorkerData);
|
||||
wd->m = m;
|
||||
@@ -1738,8 +1736,16 @@ void lb_generate_code(lbGenerator *gen) {
|
||||
}
|
||||
|
||||
TIME_SECTION("LLVM Object Generation");
|
||||
|
||||
isize non_empty_module_count = 0;
|
||||
for_array(j, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[j].value;
|
||||
if (!lb_is_module_empty(m)) {
|
||||
non_empty_module_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_threading) {
|
||||
if (do_threading && non_empty_module_count > 1) {
|
||||
for_array(j, gen->modules.entries) {
|
||||
lbModule *m = gen->modules.entries[j].value;
|
||||
if (lb_is_module_empty(m)) {
|
||||
|
||||
@@ -585,3 +585,24 @@ enum : LLVMAttributeIndex {
|
||||
LLVMAttributeIndex_FunctionIndex = ~0u,
|
||||
LLVMAttributeIndex_FirstArgIndex = 1,
|
||||
};
|
||||
|
||||
|
||||
char const *llvm_linkage_strings[] = {
|
||||
"external linkage",
|
||||
"available externally linkage",
|
||||
"link once any linkage",
|
||||
"link once odr linkage",
|
||||
"link once odr auto hide linkage",
|
||||
"weak any linkage",
|
||||
"weak odr linkage",
|
||||
"appending linkage",
|
||||
"internal linkage",
|
||||
"private linkage",
|
||||
"dllimport linkage",
|
||||
"dllexport linkage",
|
||||
"external weak linkage",
|
||||
"ghost linkage",
|
||||
"common linkage",
|
||||
"linker private linkage",
|
||||
"linker private weak linkage"
|
||||
};
|
||||
@@ -355,3 +355,52 @@ void lb_run_function_pass_manager(LLVMPassManagerRef fpm, lbProcedure *p) {
|
||||
// are not removed
|
||||
lb_run_remove_dead_instruction_pass(p);
|
||||
}
|
||||
|
||||
|
||||
void lb_run_remove_unused_function_pass(LLVMModuleRef mod) {
|
||||
isize removal_count = 0;
|
||||
isize pass_count = 0;
|
||||
isize const max_pass_count = 10;
|
||||
// Custom remove dead function pass
|
||||
for (; pass_count < max_pass_count; pass_count++) {
|
||||
bool was_dead_function = false;
|
||||
for (LLVMValueRef func = LLVMGetFirstFunction(mod);
|
||||
func != nullptr;
|
||||
/**/
|
||||
) {
|
||||
LLVMValueRef curr_func = func;
|
||||
func = LLVMGetNextFunction(func);
|
||||
|
||||
LLVMUseRef first_use = LLVMGetFirstUse(curr_func);
|
||||
if (first_use != nullptr) {
|
||||
continue;
|
||||
}
|
||||
String name = {};
|
||||
name.text = cast(u8 *)LLVMGetValueName2(curr_func, cast(size_t *)&name.len);
|
||||
|
||||
if (LLVMIsDeclaration(curr_func)) {
|
||||
// Ignore for the time being
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
LLVMLinkage linkage = LLVMGetLinkage(curr_func);
|
||||
|
||||
switch (linkage) {
|
||||
case LLVMExternalLinkage:
|
||||
case LLVMDLLImportLinkage:
|
||||
case LLVMDLLExportLinkage:
|
||||
default:
|
||||
continue;
|
||||
case LLVMInternalLinkage:
|
||||
break;
|
||||
}
|
||||
LLVMDeleteFunction(curr_func);
|
||||
was_dead_function = true;
|
||||
removal_count += 1;
|
||||
}
|
||||
if (!was_dead_function) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,13 +195,19 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body)
|
||||
// then it is very likely it is required by LLVM and thus cannot have internal linkage
|
||||
if (entity->pkg != nullptr && entity->pkg->kind == Package_Runtime && p->body != nullptr) {
|
||||
GB_ASSERT(entity->kind == Entity_Procedure);
|
||||
if (entity->Procedure.link_name != "") {
|
||||
LLVMSetLinkage(p->value, LLVMExternalLinkage);
|
||||
String link_name = entity->Procedure.link_name;
|
||||
if (entity->flags & EntityFlag_CustomLinkName &&
|
||||
link_name != "") {
|
||||
if (string_starts_with(link_name, str_lit("__"))) {
|
||||
LLVMSetLinkage(p->value, LLVMExternalLinkage);
|
||||
} else {
|
||||
LLVMSetLinkage(p->value, LLVMInternalLinkage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (p->is_foreign) {
|
||||
if (is_arch_wasm()) {
|
||||
char const *import_name = alloc_cstring(permanent_allocator(), p->name);
|
||||
@@ -217,6 +223,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body)
|
||||
LLVMAddTargetDependentFunctionAttr(p->value, "wasm-import-module", module_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// NOTE(bill): offset==0 is the return value
|
||||
isize offset = 1;
|
||||
|
||||
+6
-13
@@ -135,19 +135,12 @@ i32 linker_stage(lbGenerator *gen) {
|
||||
|
||||
if (is_arch_wasm()) {
|
||||
timings_start_section(timings, str_lit("wasm-ld"));
|
||||
|
||||
if (build_context.metrics.arch == TargetArch_wasm32) {
|
||||
result = system_exec_command_line_app("wasm-ld",
|
||||
"\"%.*s\\bin\\wasm-ld\" \"%.*s.wasm.o\" -o \"%.*s.wasm\" %.*s %.*s",
|
||||
LIT(build_context.ODIN_ROOT),
|
||||
LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags));
|
||||
} else {
|
||||
GB_ASSERT(build_context.metrics.arch == TargetArch_wasm64);
|
||||
result = system_exec_command_line_app("wasm-ld",
|
||||
"\"%.*s\\bin\\wasm-ld\" \"%.*s.wasm.o\" -o \"%.*s.wasm\" %.*s %.*s",
|
||||
LIT(build_context.ODIN_ROOT),
|
||||
LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags));
|
||||
}
|
||||
|
||||
GB_ASSERT(build_context.metrics.arch == TargetArch_wasm64);
|
||||
result = system_exec_command_line_app("wasm-ld",
|
||||
"\"%.*s\\bin\\wasm-ld\" \"%.*s.wasm.o\" -o \"%.*s.wasm\" %.*s %.*s",
|
||||
LIT(build_context.ODIN_ROOT),
|
||||
LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user