aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-11-07 16:19:27 +0000
committergingerBill <bill@gingerbill.org>2021-11-07 16:19:27 +0000
commitdc2edd3e7904d76bd6e4e4eb02e27a1f3cb4b305 (patch)
tree4ad3bff8503be9ae9a257a506dc205932c07cab4 /src
parente9c903f1ea480b9f873c81c4acc43fcb1e437d48 (diff)
Improve support for `freestanding_wasm32`
Diffstat (limited to 'src')
-rw-r--r--src/checker.cpp10
-rw-r--r--src/llvm_backend.cpp1
-rw-r--r--src/llvm_backend_opt.cpp68
3 files changed, 72 insertions, 7 deletions
diff --git a/src/checker.cpp b/src/checker.cpp
index 5d8d6dcdc..f544ea5e6 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -2660,10 +2660,14 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
}
return true;
} else if (name == "require") {
- if (value != nullptr) {
- error(elem, "'require' does not have any parameters");
+ ExactValue ev = check_decl_attribute_value(c, value);
+ if (ev.kind == ExactValue_Invalid) {
+ ac->require_declaration = true;
+ } else if (ev.kind == ExactValue_Bool) {
+ ac->require_declaration = ev.value_bool;
+ } else {
+ error(value, "Expected either a boolean or no parameter for 'require'");
}
- ac->require_declaration = true;
return true;
} else if (name == "init") {
if (value != nullptr) {
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index c002bfc5e..e468f3032 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -1676,6 +1676,7 @@ void lb_generate_code(lbGenerator *gen) {
lbModule *m = gen->modules.entries[i].value;
lb_run_remove_unused_function_pass(m);
+ lb_run_remove_unused_globals_pass(m);
auto wd = gb_alloc_item(permanent_allocator(), lbLLVMModulePassWorkerData);
wd->m = m;
diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp
index e592243cc..de925655f 100644
--- a/src/llvm_backend_opt.cpp
+++ b/src/llvm_backend_opt.cpp
@@ -373,6 +373,20 @@ void lb_run_function_pass_manager(LLVMPassManagerRef fpm, lbProcedure *p) {
lb_run_remove_dead_instruction_pass(p);
}
+void llvm_delete_function(LLVMValueRef func) {
+ // for (LLVMBasicBlockRef block = LLVMGetFirstBasicBlock(func); block != nullptr; /**/) {
+ // LLVMBasicBlockRef curr_block = block;
+ // block = LLVMGetNextBasicBlock(block);
+ // for (LLVMValueRef instr = LLVMGetFirstInstruction(curr_block); instr != nullptr; /**/) {
+ // LLVMValueRef curr_instr = instr;
+ // instr = LLVMGetNextInstruction(instr);
+
+ // LLVMInstructionEraseFromParent(curr_instr);
+ // }
+ // LLVMRemoveBasicBlockFromParent(curr_block);
+ // }
+ LLVMDeleteFunction(func);
+}
void lb_run_remove_unused_function_pass(lbModule *m) {
isize removal_count = 0;
@@ -380,7 +394,7 @@ void lb_run_remove_unused_function_pass(lbModule *m) {
isize const max_pass_count = 10;
// Custom remove dead function pass
for (; pass_count < max_pass_count; pass_count++) {
- bool was_dead_function = false;
+ bool was_dead = false;
for (LLVMValueRef func = LLVMGetFirstFunction(m->mod);
func != nullptr;
/**/
@@ -412,12 +426,58 @@ void lb_run_remove_unused_function_pass(lbModule *m) {
continue;
}
}
+
+ llvm_delete_function(curr_func);
+ was_dead = true;
+ removal_count += 1;
+ }
+ if (!was_dead) {
+ break;
+ }
+ }
+}
+
+
+void lb_run_remove_unused_globals_pass(lbModule *m) {
+ 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 = false;
+ for (LLVMValueRef global = LLVMGetFirstGlobal(m->mod);
+ global != nullptr;
+ /**/
+ ) {
+ LLVMValueRef curr_global = global;
+ global = LLVMGetNextGlobal(global);
+
+ LLVMUseRef first_use = LLVMGetFirstUse(curr_global);
+ if (first_use != nullptr) {
+ continue;
+ }
+ String name = {};
+ name.text = cast(u8 *)LLVMGetValueName2(curr_global, cast(size_t *)&name.len);
+
+ LLVMLinkage linkage = LLVMGetLinkage(curr_global);
+ if (linkage != LLVMInternalLinkage) {
+ continue;
+ }
+
+ Entity **found = map_get(&m->procedure_values, curr_global);
+ if (found && *found) {
+ Entity *e = *found;
+ bool is_required = (e->flags & EntityFlag_Require) == EntityFlag_Require;
+ if (is_required) {
+ continue;
+ }
+ }
- LLVMDeleteFunction(curr_func);
- was_dead_function = true;
+ LLVMDeleteGlobal(curr_global);
+ was_dead = true;
removal_count += 1;
}
- if (!was_dead_function) {
+ if (!was_dead) {
break;
}
}