Add an atomic fence intrinsic
This commit is contained in:
parent
9325535b41
commit
4a1a0fbed5
@ -1594,6 +1594,9 @@ pub mod llvm {
|
||||
Order: AtomicOrdering)
|
||||
-> ValueRef;
|
||||
|
||||
pub unsafe fn LLVMBuildAtomicFence(B: BuilderRef, Order: AtomicOrdering);
|
||||
|
||||
|
||||
/* Selected entries from the downcasts. */
|
||||
#[fast_ffi]
|
||||
pub unsafe fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef;
|
||||
|
@ -660,6 +660,11 @@ pub fn CallWithConv(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef],
|
||||
B(cx).call_with_conv(Fn, Args, Conv)
|
||||
}
|
||||
|
||||
pub fn AtomicFence(cx: @mut Block, order: AtomicOrdering) {
|
||||
if cx.unreachable { return; }
|
||||
B(cx).atomic_fence(order)
|
||||
}
|
||||
|
||||
pub fn Select(cx: @mut Block, If: ValueRef, Then: ValueRef, Else: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(Then); }
|
||||
B(cx).select(If, Then, Else)
|
||||
|
@ -943,4 +943,10 @@ impl Builder {
|
||||
llvm::LLVMBuildAtomicRMW(self.llbuilder, op, dst, src, order)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn atomic_fence(&self, order: AtomicOrdering) {
|
||||
unsafe {
|
||||
llvm::LLVMBuildAtomicFence(self.llbuilder, order);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -661,6 +661,10 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
|
||||
order);
|
||||
RetVoid(bcx);
|
||||
}
|
||||
"fence" => {
|
||||
AtomicFence(bcx, order);
|
||||
RetVoid(bcx);
|
||||
}
|
||||
op => {
|
||||
// These are all AtomicRMW ops
|
||||
let atom_op = match op {
|
||||
|
@ -3521,7 +3521,9 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
|
||||
ty::re_bound(ty::br_anon(0)),
|
||||
ty::mk_int()), ty::mk_int() ], ty::mk_int())
|
||||
}
|
||||
|
||||
"fence" => {
|
||||
(0, ~[], ty::mk_nil())
|
||||
}
|
||||
op => {
|
||||
tcx.sess.span_err(it.span,
|
||||
fmt!("unrecognized atomic operation function: `%s`",
|
||||
|
@ -569,6 +569,33 @@ pub unsafe fn atomic_umin<T>(dst: &mut T, val: T, order: Ordering) -> T {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* An atomic fence.
|
||||
*
|
||||
* A fence 'A' which has `Release` ordering semantics, synchronizes with a
|
||||
* fence 'B' with (at least) `Aquire` semantics, if and only if there exists
|
||||
* atomic operations X and Y, bother operating on some atomic object 'M' such
|
||||
* that A is sequenced before X, Y is synchronized before B and Y obsevers
|
||||
* the change to M. This provides a happens-before dependence between A and B.
|
||||
*
|
||||
* Atomic operations with `Release` or `Acquire` semantics can also synchronize
|
||||
* with a fence.
|
||||
*
|
||||
* A fence with has `SeqCst` ordering, in addition to having both `Acquire` and
|
||||
* `Release` semantics, participates in the global program order of the other
|
||||
* `SeqCst` operations and/or fences.
|
||||
*
|
||||
* Accepts `Acquire`, `Release`, `AcqRel` and `SeqCst` orderings.
|
||||
*/
|
||||
#[inline] #[cfg(not(stage0))]
|
||||
pub fn fence(order: Ordering) {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_fence_acq(),
|
||||
Release => intrinsics::atomic_fence_rel(),
|
||||
AcqRel => intrinsics::atomic_fence_rel(),
|
||||
_ => intrinsics::atomic_fence(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
@ -256,6 +256,15 @@ extern "rust-intrinsic" {
|
||||
pub fn atomic_umax_acqrel(dst: &mut int, src: int) -> int;
|
||||
pub fn atomic_umax_relaxed(dst: &mut int, src: int) -> int;
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
pub fn atomic_fence();
|
||||
#[cfg(not(stage0))]
|
||||
pub fn atomic_fence_acq();
|
||||
#[cfg(not(stage0))]
|
||||
pub fn atomic_fence_rel();
|
||||
#[cfg(not(stage0))]
|
||||
pub fn atomic_fence_acqrel();
|
||||
|
||||
/// The size of a type in bytes.
|
||||
///
|
||||
/// This is the exact number of bytes in memory taken up by a
|
||||
|
@ -513,6 +513,9 @@ extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B,
|
||||
return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(target), unwrap(old),
|
||||
unwrap(source), order));
|
||||
}
|
||||
extern "C" LLVMValueRef LLVMBuildAtomicFence(LLVMBuilderRef B, AtomicOrdering order) {
|
||||
return wrap(unwrap(B)->CreateFence(order));
|
||||
}
|
||||
extern "C" LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,
|
||||
AtomicRMWInst::BinOp op,
|
||||
LLVMValueRef target,
|
||||
@ -838,4 +841,4 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateUnionType(
|
||||
Flags,
|
||||
unwrapDI<DIArray>(Elements),
|
||||
RunTimeLang));
|
||||
}
|
||||
}
|
||||
|
@ -90,6 +90,7 @@ LLVMBuildAtomicLoad
|
||||
LLVMBuildAtomicStore
|
||||
LLVMBuildAtomicCmpXchg
|
||||
LLVMBuildAtomicRMW
|
||||
LLVMBuildAtomicFence
|
||||
LLVMBuildAdd
|
||||
LLVMBuildAggregateRet
|
||||
LLVMBuildAlloca
|
||||
|
Loading…
x
Reference in New Issue
Block a user