diff options
| author | gingerBill <bill@gingerbill.org> | 2021-03-01 15:14:21 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-03-01 15:14:21 +0000 |
| commit | b428e9ee142659de62064a0c6829b998b9446375 (patch) | |
| tree | d71e5173929816bb79f4da93d911240c01e5fa5e /src/llvm_backend.cpp | |
| parent | 868117cddda5915020b94d2be00b6ab1ff5f171b (diff) | |
Improve `lb_end_procedure_body` logic
Diffstat (limited to 'src/llvm_backend.cpp')
| -rw-r--r-- | src/llvm_backend.cpp | 46 |
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 |