Skip to content

Commit fac12e2

Browse files
committed
Use LLVM C-API to build atomic cmpxchg and fence
1 parent a37499a commit fac12e2

File tree

3 files changed

+25
-76
lines changed

3 files changed

+25
-76
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

+16-10
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
use crate::attributes;
22
use crate::common::Funclet;
33
use crate::context::CodegenCx;
4-
use crate::llvm::{self, BasicBlock, False};
5-
use crate::llvm::{AtomicOrdering, AtomicRmwBinOp, SynchronizationScope};
4+
use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock};
65
use crate::type_::Type;
76
use crate::type_of::LayoutLlvmExt;
87
use crate::value::Value;
98
use cstr::cstr;
109
use libc::{c_char, c_uint};
11-
use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, TypeKind};
10+
use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, SynchronizationScope, TypeKind};
1211
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
1312
use rustc_codegen_ssa::mir::place::PlaceRef;
1413
use rustc_codegen_ssa::traits::*;
@@ -1042,15 +1041,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
10421041
) -> &'ll Value {
10431042
let weak = if weak { llvm::True } else { llvm::False };
10441043
unsafe {
1045-
llvm::LLVMRustBuildAtomicCmpXchg(
1044+
let value = llvm::LLVMBuildAtomicCmpXchg(
10461045
self.llbuilder,
10471046
dst,
10481047
cmp,
10491048
src,
10501049
AtomicOrdering::from_generic(order),
10511050
AtomicOrdering::from_generic(failure_order),
1052-
weak,
1053-
)
1051+
llvm::False, // SingleThreaded
1052+
);
1053+
llvm::LLVMSetWeak(value, weak);
1054+
value
10541055
}
10551056
}
10561057
fn atomic_rmw(
@@ -1067,21 +1068,26 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
10671068
dst,
10681069
src,
10691070
AtomicOrdering::from_generic(order),
1070-
False,
1071+
llvm::False, // SingleThreaded
10711072
)
10721073
}
10731074
}
10741075

10751076
fn atomic_fence(
10761077
&mut self,
10771078
order: rustc_codegen_ssa::common::AtomicOrdering,
1078-
scope: rustc_codegen_ssa::common::SynchronizationScope,
1079+
scope: SynchronizationScope,
10791080
) {
1081+
let single_threaded = match scope {
1082+
SynchronizationScope::SingleThread => llvm::True,
1083+
SynchronizationScope::CrossThread => llvm::False,
1084+
};
10801085
unsafe {
1081-
llvm::LLVMRustBuildAtomicFence(
1086+
llvm::LLVMBuildFence(
10821087
self.llbuilder,
10831088
AtomicOrdering::from_generic(order),
1084-
SynchronizationScope::from_generic(scope),
1089+
single_threaded,
1090+
UNNAMED,
10851091
);
10861092
}
10871093
}

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+9-27
Original file line numberDiff line numberDiff line change
@@ -400,27 +400,6 @@ impl AtomicOrdering {
400400
}
401401
}
402402

403-
/// LLVMRustSynchronizationScope
404-
#[derive(Copy, Clone)]
405-
#[repr(C)]
406-
pub enum SynchronizationScope {
407-
SingleThread,
408-
CrossThread,
409-
}
410-
411-
impl SynchronizationScope {
412-
pub fn from_generic(sc: rustc_codegen_ssa::common::SynchronizationScope) -> Self {
413-
match sc {
414-
rustc_codegen_ssa::common::SynchronizationScope::SingleThread => {
415-
SynchronizationScope::SingleThread
416-
}
417-
rustc_codegen_ssa::common::SynchronizationScope::CrossThread => {
418-
SynchronizationScope::CrossThread
419-
}
420-
}
421-
}
422-
}
423-
424403
/// LLVMRustFileType
425404
#[derive(Copy, Clone)]
426405
#[repr(C)]
@@ -1782,16 +1761,18 @@ extern "C" {
17821761
Order: AtomicOrdering,
17831762
) -> &'a Value;
17841763

1785-
pub fn LLVMRustBuildAtomicCmpXchg<'a>(
1764+
pub fn LLVMBuildAtomicCmpXchg<'a>(
17861765
B: &Builder<'a>,
17871766
LHS: &'a Value,
17881767
CMP: &'a Value,
17891768
RHS: &'a Value,
17901769
Order: AtomicOrdering,
17911770
FailureOrder: AtomicOrdering,
1792-
Weak: Bool,
1771+
SingleThreaded: Bool,
17931772
) -> &'a Value;
17941773

1774+
pub fn LLVMSetWeak(CmpXchgInst: &Value, IsWeak: Bool);
1775+
17951776
pub fn LLVMBuildAtomicRMW<'a>(
17961777
B: &Builder<'a>,
17971778
Op: AtomicRmwBinOp,
@@ -1801,11 +1782,12 @@ extern "C" {
18011782
SingleThreaded: Bool,
18021783
) -> &'a Value;
18031784

1804-
pub fn LLVMRustBuildAtomicFence(
1805-
B: &Builder<'_>,
1785+
pub fn LLVMBuildFence<'a>(
1786+
B: &Builder<'a>,
18061787
Order: AtomicOrdering,
1807-
Scope: SynchronizationScope,
1808-
);
1788+
SingleThreaded: Bool,
1789+
Name: *const c_char,
1790+
) -> &'a Value;
18091791

18101792
/// Writes a module to the specified path. Returns 0 on success.
18111793
pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int;

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

-39
Original file line numberDiff line numberDiff line change
@@ -406,45 +406,6 @@ extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
406406
return wrap(SI);
407407
}
408408

409-
// FIXME: Use the C-API LLVMBuildAtomicCmpXchg and LLVMSetWeak
410-
// once we raise our minimum support to LLVM 10.
411-
extern "C" LLVMValueRef
412-
LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
413-
LLVMValueRef Old, LLVMValueRef Source,
414-
LLVMAtomicOrdering Order,
415-
LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
416-
// Rust probably knows the alignment of the target value and should be able to
417-
// specify something more precise than MaybeAlign here. See also
418-
// https://reviews.llvm.org/D97224 which may be a useful reference.
419-
AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
420-
unwrap(Target), unwrap(Old), unwrap(Source), llvm::MaybeAlign(), fromRust(Order),
421-
fromRust(FailureOrder));
422-
ACXI->setWeak(Weak);
423-
return wrap(ACXI);
424-
}
425-
426-
enum class LLVMRustSynchronizationScope {
427-
SingleThread,
428-
CrossThread,
429-
};
430-
431-
static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
432-
switch (Scope) {
433-
case LLVMRustSynchronizationScope::SingleThread:
434-
return SyncScope::SingleThread;
435-
case LLVMRustSynchronizationScope::CrossThread:
436-
return SyncScope::System;
437-
default:
438-
report_fatal_error("bad SynchronizationScope.");
439-
}
440-
}
441-
442-
extern "C" LLVMValueRef
443-
LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
444-
LLVMRustSynchronizationScope Scope) {
445-
return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
446-
}
447-
448409
enum class LLVMRustAsmDialect {
449410
Att,
450411
Intel,

0 commit comments

Comments
 (0)