aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-07-04 01:57:38 +0100
committergingerBill <bill@gingerbill.org>2021-07-04 01:57:38 +0100
commita01d6dcea729fd39df306a3f9743a78fe9258cd7 (patch)
tree917dff412e8f5df8910a9fd4eae03014dfc864f0
parent01a15f78e67fe81e3b70225fbb30353d28cb3400 (diff)
Refactor `return` logic to be more reusable with `lb_emit_try`
-rw-r--r--src/llvm_backend.cpp68
1 files changed, 24 insertions, 44 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index 3dccaeefd..a3561056c 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -5339,6 +5339,28 @@ void lb_build_assignment(lbProcedure *p, Array<lbAddr> &lvals, Slice<Ast *> cons
}
}
+void lb_build_return_stmt_internal(lbProcedure *p, bool return_by_pointer, lbValue const &res) {
+ if (return_by_pointer) {
+ if (res.value != nullptr) {
+ LLVMBuildStore(p->builder, res.value, p->return_ptr.addr.value);
+ } else {
+ LLVMBuildStore(p->builder, LLVMConstNull(p->abi_function_type->ret.type), p->return_ptr.addr.value);
+ }
+
+ lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
+
+ LLVMBuildRetVoid(p->builder);
+ } else {
+ LLVMValueRef ret_val = res.value;
+ ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.type);
+ if (p->abi_function_type->ret.cast_type != nullptr) {
+ ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.cast_type);
+ }
+
+ lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
+ LLVMBuildRet(p->builder, ret_val);
+ }
+}
void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return_results) {
lb_ensure_abi_function_type(p->module, p);
@@ -5461,28 +5483,7 @@ void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return_results) {
res = lb_emit_load(p, res);
}
-
-
- if (return_by_pointer) {
- if (res.value != nullptr) {
- LLVMBuildStore(p->builder, res.value, p->return_ptr.addr.value);
- } else {
- LLVMBuildStore(p->builder, LLVMConstNull(p->abi_function_type->ret.type), p->return_ptr.addr.value);
- }
-
- lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
-
- LLVMBuildRetVoid(p->builder);
- } else {
- LLVMValueRef ret_val = res.value;
- ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.type);
- if (p->abi_function_type->ret.cast_type != nullptr) {
- ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.cast_type);
- }
-
- lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
- LLVMBuildRet(p->builder, ret_val);
- }
+ lb_build_return_stmt_internal(p, return_by_pointer, res);
}
void lb_build_if_stmt(lbProcedure *p, Ast *node) {
@@ -9624,28 +9625,7 @@ lbValue lb_emit_try(lbProcedure *p, AstCallExpr *ce, TypeAndValue const &tv) {
} else {
GB_ASSERT(return_count == 1);
Entity *e = tuple->variables[0];
- lbValue res = lb_emit_conv(p, rhs, e->type);
-
- if (return_by_pointer) {
- if (res.value != nullptr) {
- LLVMBuildStore(p->builder, res.value, p->return_ptr.addr.value);
- } else {
- LLVMBuildStore(p->builder, LLVMConstNull(p->abi_function_type->ret.type), p->return_ptr.addr.value);
- }
-
- lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
-
- LLVMBuildRetVoid(p->builder);
- } else {
- LLVMValueRef ret_val = res.value;
- ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.type);
- if (p->abi_function_type->ret.cast_type != nullptr) {
- ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.cast_type);
- }
-
- lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
- LLVMBuildRet(p->builder, ret_val);
- }
+ lb_build_return_stmt_internal(p, return_by_pointer, lb_emit_conv(p, rhs, e->type));
}
}