aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-03-01 15:14:21 +0000
committergingerBill <bill@gingerbill.org>2021-03-01 15:14:21 +0000
commitb428e9ee142659de62064a0c6829b998b9446375 (patch)
treed71e5173929816bb79f4da93d911240c01e5fa5e /src/llvm_backend.cpp
parent868117cddda5915020b94d2be00b6ab1ff5f171b (diff)
Improve `lb_end_procedure_body` logic
Diffstat (limited to 'src/llvm_backend.cpp')
-rw-r--r--src/llvm_backend.cpp46
1 files changed, 35 insertions, 11 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index 408d6f659..7237504ce 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -2549,22 +2549,46 @@ void lb_end_procedure_body(lbProcedure *p) {
LLVMBuildBr(p->builder, p->entry_block->block);
LLVMPositionBuilderAtEnd(p->builder, p->curr_block->block);
+ // Make sure there is a "ret void" at the end of a procedure with no return type
if (p->type->Proc.result_count == 0) {
- LLVMValueRef instr = LLVMGetLastInstruction(p->curr_block->block);
- if (!lb_is_instr_terminating(instr)) {
- lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
+ LLVMValueRef instr = LLVMGetLastInstruction(p->curr_block->block);
+ if (!lb_is_instr_terminating(instr)) {
+ lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
LLVMBuildRetVoid(p->builder);
}
- } else {
- if (p->curr_block->preds.count == 0) {
- LLVMValueRef instr = LLVMGetLastInstruction(p->curr_block->block);
- if (instr == nullptr) {
- // NOTE(bill): Remove dead trailing block
- LLVMDeleteBasicBlock(p->curr_block->block);
- }
+ }
+
+ LLVMBasicBlockRef block = nullptr;
+ LLVMBasicBlockRef first_block = LLVMGetFirstBasicBlock(p->value);
+
+ // Remove dead blocks with no code
+ for (block = first_block;
+ block != nullptr;
+ /**/) {
+ LLVMBasicBlockRef next_block = LLVMGetNextBasicBlock(block);
+ LLVMValueRef instr = LLVMGetLastInstruction(block);
+ if (instr == nullptr) {
+ LLVMDeleteBasicBlock(block);
+ }
+ block = next_block;
+ }
+
+
+ // Make sure every block terminates, and if not, make it unreachable
+ for (block = first_block;
+ block != nullptr;
+ block = LLVMGetNextBasicBlock(block)) {
+ LLVMValueRef instr = LLVMGetLastInstruction(block);
+ if (!lb_is_instr_terminating(instr)) {
+ // NOTE(bill): This is a sanity check
+ LLVMBasicBlockRef prev_block = block;
+ LLVMPositionBuilderAtEnd(p->builder, block);
+ LLVMBuildUnreachable(p->builder);
+ LLVMPositionBuilderAtEnd(p->builder, prev_block);
}
}
+
p->curr_block = nullptr;
p->module->state_flags = 0;
}
@@ -12907,7 +12931,7 @@ void lb_generate_code(lbGenerator *gen) {
TIME_SECTION("LLVM Function Pass");
- {
+ if (false) {
for_array(i, m->procedures_to_generate) {
lbProcedure *p = m->procedures_to_generate[i];
if (p->body != nullptr) { // Build Procedure