aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_opt.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-11-13 22:55:32 +0000
committergingerBill <bill@gingerbill.org>2022-11-13 22:55:32 +0000
commita705a2e38bee035d6800999ba6eddd82792594f7 (patch)
tree9beece2552d41ad12489e7cfaf73df80bbf6fb95 /src/llvm_backend_opt.cpp
parent7dfbda58d9c51932fa91a04727b821860358289d (diff)
Minor improvement to multi return value reducing stack usage
Diffstat (limited to 'src/llvm_backend_opt.cpp')
-rw-r--r--src/llvm_backend_opt.cpp35
1 files changed, 34 insertions, 1 deletions
diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp
index e2f51b868..ba5a41871 100644
--- a/src/llvm_backend_opt.cpp
+++ b/src/llvm_backend_opt.cpp
@@ -267,6 +267,8 @@ void lb_populate_module_pass_manager(LLVMTargetMachineRef target_machine, LLVMPa
**************************************************************************/
void lb_run_remove_dead_instruction_pass(lbProcedure *p) {
+ LLVMTypeRef llvm_void = LLVMVoidTypeInContext(p->module->ctx);
+
isize removal_count = 0;
isize pass_count = 0;
isize const max_pass_count = 10;
@@ -322,7 +324,7 @@ void lb_run_remove_dead_instruction_pass(lbProcedure *p) {
case LLVMOr:
case LLVMXor:
case LLVMAlloca:
- case LLVMLoad:
+ case LLVMLoad: // TODO: should LLVMLoad be removed?
case LLVMGetElementPtr:
case LLVMTrunc:
case LLVMZExt:
@@ -347,6 +349,37 @@ void lb_run_remove_dead_instruction_pass(lbProcedure *p) {
LLVMInstructionEraseFromParent(curr_instr);
was_dead_instructions = true;
break;
+
+ case LLVMCall:
+ if (LLVMTypeOf(curr_instr) == llvm_void) {
+ LLVMValueRef the_proc = LLVMGetCalledValue(curr_instr);
+ unsigned id = LLVMGetIntrinsicID(the_proc);
+ if (id != 0) {
+ size_t text_len = 0;
+ char const *text = LLVMIntrinsicGetName(id, &text_len);
+ String name = make_string(cast(u8 const *)text, cast(isize)text_len);
+ if (name == "llvm.memmove" || name == "llvm.memcpy") {
+ LLVMValueRef dst = LLVMGetOperand(curr_instr, 0);
+ LLVMValueRef src = LLVMGetOperand(curr_instr, 1);
+ LLVMValueRef sz = LLVMGetOperand(curr_instr, 2);
+ if ((dst == src) || (LLVMIsConstant(sz) && LLVMConstIntGetZExtValue(sz) == 0)) {
+ removal_count += 1;
+ LLVMInstructionEraseFromParent(curr_instr);
+ was_dead_instructions = true;
+ break;
+ }
+ } else if (name == "llvm.memset") {
+ LLVMValueRef sz = LLVMGetOperand(curr_instr, 2);
+ if (LLVMIsConstant(sz) && LLVMConstIntGetZExtValue(sz) == 0) {
+ removal_count += 1;
+ LLVMInstructionEraseFromParent(curr_instr);
+ was_dead_instructions = true;
+ break;
+ }
+ }
+ }
+ }
+ break;
}
}
}