diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 83467bba20f1..e09f22b4e693 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -488,10 +488,20 @@ impl BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock> } } - fn atomic_load(&self, ptr: &'ll Value, order: AtomicOrdering, size: Size) -> &'ll Value { + fn atomic_load( + &self, + ptr: &'ll Value, + order: traits::AtomicOrdering, + size: Size, + ) -> &'ll Value { self.count_insn("load.atomic"); unsafe { - let load = llvm::LLVMRustBuildAtomicLoad(self.llbuilder, ptr, noname(), order); + let load = llvm::LLVMRustBuildAtomicLoad( + self.llbuilder, + ptr, + noname(), + AtomicOrdering::from_generic(order), + ); // LLVM requires the alignment of atomic loads to be at least the size of the type. llvm::LLVMSetAlignment(load, size.bytes() as c_uint); load @@ -568,12 +578,17 @@ impl BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock> } fn atomic_store(&self, val: &'ll Value, ptr: &'ll Value, - order: AtomicOrdering, size: Size) { + order: traits::AtomicOrdering, size: Size) { debug!("Store {:?} -> {:?}", val, ptr); self.count_insn("store.atomic"); let ptr = self.check_store(val, ptr); unsafe { - let store = llvm::LLVMRustBuildAtomicStore(self.llbuilder, val, ptr, order); + let store = llvm::LLVMRustBuildAtomicStore( + self.llbuilder, + val, + ptr, + AtomicOrdering::from_generic(order), + ); // LLVM requires the alignment of atomic stores to be at least the size of the type. llvm::LLVMSetAlignment(store, size.bytes() as c_uint); } @@ -1047,14 +1062,21 @@ impl BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock> dst: &'ll Value, cmp: &'ll Value, src: &'ll Value, - order: AtomicOrdering, - failure_order: AtomicOrdering, + order: traits::AtomicOrdering, + failure_order: traits::AtomicOrdering, weak: bool, ) -> &'ll Value { let weak = if weak { llvm::True } else { llvm::False }; unsafe { - llvm::LLVMRustBuildAtomicCmpXchg(self.llbuilder, dst, cmp, src, - order, failure_order, weak) + llvm::LLVMRustBuildAtomicCmpXchg( + self.llbuilder, + dst, + cmp, + src, + AtomicOrdering::from_generic(order), + AtomicOrdering::from_generic(failure_order), + weak + ) } } fn atomic_rmw( @@ -1062,7 +1084,7 @@ impl BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock> op: traits::AtomicRmwBinOp, dst: &'ll Value, src: &'ll Value, - order: AtomicOrdering, + order: traits::AtomicOrdering, ) -> &'ll Value { unsafe { llvm::LLVMBuildAtomicRMW( @@ -1070,14 +1092,18 @@ impl BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock> AtomicRmwBinOp::from_generic(op), dst, src, - order, + AtomicOrdering::from_generic(order), False) } } - fn atomic_fence(&self, order: AtomicOrdering, scope: SynchronizationScope) { + fn atomic_fence(&self, order: traits::AtomicOrdering, scope: SynchronizationScope) { unsafe { - llvm::LLVMRustBuildAtomicFence(self.llbuilder, order, scope); + llvm::LLVMRustBuildAtomicFence( + self.llbuilder, + AtomicOrdering::from_generic(order), + scope + ); } } diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 6893adc51379..7db8fa4bd2ee 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -439,7 +439,7 @@ pub fn codegen_intrinsic_call( // This requires that atomic intrinsics follow a specific naming pattern: // "atomic_[_]", and no ordering means SeqCst name if name.starts_with("atomic_") => { - use llvm::AtomicOrdering::*; + use traits::AtomicOrdering::*; let split: Vec<&str> = name.split('_').collect(); diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index b44b611f439c..677c108edc37 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -277,6 +277,22 @@ pub enum AtomicOrdering { SequentiallyConsistent = 7, } +impl AtomicOrdering { + pub fn from_generic(ao : traits::AtomicOrdering) -> Self { + match ao { + traits::AtomicOrdering::NotAtomic => AtomicOrdering::NotAtomic, + traits::AtomicOrdering::Unordered => AtomicOrdering::Unordered, + traits::AtomicOrdering::Monotonic => AtomicOrdering::Monotonic, + traits::AtomicOrdering::Acquire => AtomicOrdering::Acquire, + traits::AtomicOrdering::Release => AtomicOrdering::Release, + traits::AtomicOrdering::AcquireRelease => AtomicOrdering::AcquireRelease, + traits::AtomicOrdering::SequentiallyConsistent => + AtomicOrdering::SequentiallyConsistent + } + } +} + + /// LLVMRustSynchronizationScope #[derive(Copy, Clone)] #[repr(C)] diff --git a/src/librustc_codegen_llvm/traits.rs b/src/librustc_codegen_llvm/traits.rs index c647fceb994b..315c273dd2dc 100644 --- a/src/librustc_codegen_llvm/traits.rs +++ b/src/librustc_codegen_llvm/traits.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use llvm::{AtomicOrdering, SynchronizationScope, AsmDialect}; +use llvm::{SynchronizationScope, AsmDialect}; use common::*; use type_::Type; use libc::c_char; @@ -82,6 +82,19 @@ pub enum AtomicRmwBinOp { AtomicUMin } +pub enum AtomicOrdering { + #[allow(dead_code)] + NotAtomic, + Unordered, + Monotonic, + // Consume, // Not specified yet. + Acquire, + Release, + AcquireRelease, + SequentiallyConsistent, +} + + pub trait BuilderMethods<'a, 'll :'a, 'tcx: 'll, Value : ?Sized, BasicBlock: ?Sized