diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/checker.cpp | 10 | ||||
| -rw-r--r-- | src/llvm_backend.cpp | 1 | ||||
| -rw-r--r-- | src/llvm_backend_opt.cpp | 68 |
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; } } |