aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_proc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/llvm_backend_proc.cpp')
-rw-r--r--src/llvm_backend_proc.cpp47
1 files changed, 42 insertions, 5 deletions
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index b2ba4a864..b9f2c2db2 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -1045,9 +1045,25 @@ gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> c
} else if (is_odin_cc) {
// NOTE(bill): Odin parameters are immutable so the original value can be passed if possible
// i.e. `T const &` in C++
- ptr = lb_address_from_load_or_generate_local(p, x);
+ if (LLVMIsConstant(x.value)) {
+ // NOTE(bill): if the value is already constant, then just it as a global variable
+ // and pass it by pointer
+ lbAddr addr = lb_add_global_generated(p->module, original_type, x);
+ lb_make_global_private_const(addr);
+ ptr = addr.addr;
+ } else {
+ ptr = lb_address_from_load_or_generate_local(p, x);
+ }
} else {
- ptr = lb_copy_value_to_ptr(p, x, original_type, 16);
+ if (LLVMIsConstant(x.value)) {
+ // NOTE(bill): if the value is already constant, then just it as a global variable
+ // and pass it by pointer
+ lbAddr addr = lb_add_global_generated(p->module, original_type, x);
+ lb_make_global_private_const(addr);
+ ptr = addr.addr;
+ } else {
+ ptr = lb_copy_value_to_ptr(p, x, original_type, 16);
+ }
}
array_add(&processed_args, ptr);
}
@@ -2288,7 +2304,15 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
break;
case BuiltinProc_volatile_store: LLVMSetVolatile(instr, true); break;
case BuiltinProc_atomic_store: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break;
- case BuiltinProc_atomic_store_explicit: LLVMSetOrdering(instr, llvm_atomic_ordering_from_odin(ce->args[2])); break;
+ case BuiltinProc_atomic_store_explicit:
+ {
+ auto ordering = llvm_atomic_ordering_from_odin(ce->args[2]);
+ LLVMSetOrdering(instr, ordering);
+ if (ordering == LLVMAtomicOrderingUnordered) {
+ LLVMSetVolatile(instr, true);
+ }
+ }
+ break;
}
LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type)));
@@ -2314,7 +2338,15 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
break;
case BuiltinProc_volatile_load: LLVMSetVolatile(instr, true); break;
case BuiltinProc_atomic_load: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break;
- case BuiltinProc_atomic_load_explicit: LLVMSetOrdering(instr, llvm_atomic_ordering_from_odin(ce->args[1])); break;
+ case BuiltinProc_atomic_load_explicit:
+ {
+ auto ordering = llvm_atomic_ordering_from_odin(ce->args[1]);
+ LLVMSetOrdering(instr, ordering);
+ if (ordering == LLVMAtomicOrderingUnordered) {
+ LLVMSetVolatile(instr, true);
+ }
+ }
+ break;
}
LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type)));
@@ -2384,6 +2416,9 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
lbValue res = {};
res.value = LLVMBuildAtomicRMW(p->builder, op, dst.value, val.value, ordering, false);
res.type = tv.type;
+ if (ordering == LLVMAtomicOrderingUnordered) {
+ LLVMSetVolatile(res.value, true);
+ }
return res;
}
@@ -2409,7 +2444,6 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
case BuiltinProc_atomic_compare_exchange_weak_explicit: success_ordering = llvm_atomic_ordering_from_odin(ce->args[3]); failure_ordering = llvm_atomic_ordering_from_odin(ce->args[4]); weak = true; break;
}
- // TODO(bill): Figure out how to make it weak
LLVMBool single_threaded = false;
LLVMValueRef value = LLVMBuildAtomicCmpXchg(
@@ -2420,6 +2454,9 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
single_threaded
);
LLVMSetWeak(value, weak);
+ if (success_ordering == LLVMAtomicOrderingUnordered || failure_ordering == LLVMAtomicOrderingUnordered) {
+ LLVMSetVolatile(value, true);
+ }
if (is_type_tuple(tv.type)) {
Type *fix_typed = alloc_type_tuple();