Rollup merge of #102001 - cuviper:build-atomic-capi, r=nikic
Use LLVM C-API to build atomic cmpxchg and fence We don't need C++ wrappers because the LLVM C API can build these.
This commit is contained in:
commit
2c57a5b166
3 changed files with 25 additions and 76 deletions
|
@ -1,14 +1,13 @@
|
||||||
use crate::attributes;
|
use crate::attributes;
|
||||||
use crate::common::Funclet;
|
use crate::common::Funclet;
|
||||||
use crate::context::CodegenCx;
|
use crate::context::CodegenCx;
|
||||||
use crate::llvm::{self, BasicBlock, False};
|
use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock};
|
||||||
use crate::llvm::{AtomicOrdering, AtomicRmwBinOp, SynchronizationScope};
|
|
||||||
use crate::type_::Type;
|
use crate::type_::Type;
|
||||||
use crate::type_of::LayoutLlvmExt;
|
use crate::type_of::LayoutLlvmExt;
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
use cstr::cstr;
|
use cstr::cstr;
|
||||||
use libc::{c_char, c_uint};
|
use libc::{c_char, c_uint};
|
||||||
use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, TypeKind};
|
use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, SynchronizationScope, TypeKind};
|
||||||
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
|
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
|
||||||
use rustc_codegen_ssa::mir::place::PlaceRef;
|
use rustc_codegen_ssa::mir::place::PlaceRef;
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
|
@ -1042,15 +1041,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
) -> &'ll Value {
|
) -> &'ll Value {
|
||||||
let weak = if weak { llvm::True } else { llvm::False };
|
let weak = if weak { llvm::True } else { llvm::False };
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustBuildAtomicCmpXchg(
|
let value = llvm::LLVMBuildAtomicCmpXchg(
|
||||||
self.llbuilder,
|
self.llbuilder,
|
||||||
dst,
|
dst,
|
||||||
cmp,
|
cmp,
|
||||||
src,
|
src,
|
||||||
AtomicOrdering::from_generic(order),
|
AtomicOrdering::from_generic(order),
|
||||||
AtomicOrdering::from_generic(failure_order),
|
AtomicOrdering::from_generic(failure_order),
|
||||||
weak,
|
llvm::False, // SingleThreaded
|
||||||
)
|
);
|
||||||
|
llvm::LLVMSetWeak(value, weak);
|
||||||
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn atomic_rmw(
|
fn atomic_rmw(
|
||||||
|
@ -1067,7 +1068,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
dst,
|
dst,
|
||||||
src,
|
src,
|
||||||
AtomicOrdering::from_generic(order),
|
AtomicOrdering::from_generic(order),
|
||||||
False,
|
llvm::False, // SingleThreaded
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1075,13 +1076,18 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
fn atomic_fence(
|
fn atomic_fence(
|
||||||
&mut self,
|
&mut self,
|
||||||
order: rustc_codegen_ssa::common::AtomicOrdering,
|
order: rustc_codegen_ssa::common::AtomicOrdering,
|
||||||
scope: rustc_codegen_ssa::common::SynchronizationScope,
|
scope: SynchronizationScope,
|
||||||
) {
|
) {
|
||||||
|
let single_threaded = match scope {
|
||||||
|
SynchronizationScope::SingleThread => llvm::True,
|
||||||
|
SynchronizationScope::CrossThread => llvm::False,
|
||||||
|
};
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustBuildAtomicFence(
|
llvm::LLVMBuildFence(
|
||||||
self.llbuilder,
|
self.llbuilder,
|
||||||
AtomicOrdering::from_generic(order),
|
AtomicOrdering::from_generic(order),
|
||||||
SynchronizationScope::from_generic(scope),
|
single_threaded,
|
||||||
|
UNNAMED,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -400,27 +400,6 @@ impl AtomicOrdering {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// LLVMRustSynchronizationScope
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub enum SynchronizationScope {
|
|
||||||
SingleThread,
|
|
||||||
CrossThread,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SynchronizationScope {
|
|
||||||
pub fn from_generic(sc: rustc_codegen_ssa::common::SynchronizationScope) -> Self {
|
|
||||||
match sc {
|
|
||||||
rustc_codegen_ssa::common::SynchronizationScope::SingleThread => {
|
|
||||||
SynchronizationScope::SingleThread
|
|
||||||
}
|
|
||||||
rustc_codegen_ssa::common::SynchronizationScope::CrossThread => {
|
|
||||||
SynchronizationScope::CrossThread
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// LLVMRustFileType
|
/// LLVMRustFileType
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -1782,16 +1761,18 @@ extern "C" {
|
||||||
Order: AtomicOrdering,
|
Order: AtomicOrdering,
|
||||||
) -> &'a Value;
|
) -> &'a Value;
|
||||||
|
|
||||||
pub fn LLVMRustBuildAtomicCmpXchg<'a>(
|
pub fn LLVMBuildAtomicCmpXchg<'a>(
|
||||||
B: &Builder<'a>,
|
B: &Builder<'a>,
|
||||||
LHS: &'a Value,
|
LHS: &'a Value,
|
||||||
CMP: &'a Value,
|
CMP: &'a Value,
|
||||||
RHS: &'a Value,
|
RHS: &'a Value,
|
||||||
Order: AtomicOrdering,
|
Order: AtomicOrdering,
|
||||||
FailureOrder: AtomicOrdering,
|
FailureOrder: AtomicOrdering,
|
||||||
Weak: Bool,
|
SingleThreaded: Bool,
|
||||||
) -> &'a Value;
|
) -> &'a Value;
|
||||||
|
|
||||||
|
pub fn LLVMSetWeak(CmpXchgInst: &Value, IsWeak: Bool);
|
||||||
|
|
||||||
pub fn LLVMBuildAtomicRMW<'a>(
|
pub fn LLVMBuildAtomicRMW<'a>(
|
||||||
B: &Builder<'a>,
|
B: &Builder<'a>,
|
||||||
Op: AtomicRmwBinOp,
|
Op: AtomicRmwBinOp,
|
||||||
|
@ -1801,11 +1782,12 @@ extern "C" {
|
||||||
SingleThreaded: Bool,
|
SingleThreaded: Bool,
|
||||||
) -> &'a Value;
|
) -> &'a Value;
|
||||||
|
|
||||||
pub fn LLVMRustBuildAtomicFence(
|
pub fn LLVMBuildFence<'a>(
|
||||||
B: &Builder<'_>,
|
B: &Builder<'a>,
|
||||||
Order: AtomicOrdering,
|
Order: AtomicOrdering,
|
||||||
Scope: SynchronizationScope,
|
SingleThreaded: Bool,
|
||||||
);
|
Name: *const c_char,
|
||||||
|
) -> &'a Value;
|
||||||
|
|
||||||
/// Writes a module to the specified path. Returns 0 on success.
|
/// Writes a module to the specified path. Returns 0 on success.
|
||||||
pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int;
|
pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int;
|
||||||
|
|
|
@ -406,45 +406,6 @@ extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
|
||||||
return wrap(SI);
|
return wrap(SI);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Use the C-API LLVMBuildAtomicCmpXchg and LLVMSetWeak
|
|
||||||
// once we raise our minimum support to LLVM 10.
|
|
||||||
extern "C" LLVMValueRef
|
|
||||||
LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
|
|
||||||
LLVMValueRef Old, LLVMValueRef Source,
|
|
||||||
LLVMAtomicOrdering Order,
|
|
||||||
LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
|
|
||||||
// Rust probably knows the alignment of the target value and should be able to
|
|
||||||
// specify something more precise than MaybeAlign here. See also
|
|
||||||
// https://reviews.llvm.org/D97224 which may be a useful reference.
|
|
||||||
AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
|
|
||||||
unwrap(Target), unwrap(Old), unwrap(Source), llvm::MaybeAlign(), fromRust(Order),
|
|
||||||
fromRust(FailureOrder));
|
|
||||||
ACXI->setWeak(Weak);
|
|
||||||
return wrap(ACXI);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class LLVMRustSynchronizationScope {
|
|
||||||
SingleThread,
|
|
||||||
CrossThread,
|
|
||||||
};
|
|
||||||
|
|
||||||
static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
|
|
||||||
switch (Scope) {
|
|
||||||
case LLVMRustSynchronizationScope::SingleThread:
|
|
||||||
return SyncScope::SingleThread;
|
|
||||||
case LLVMRustSynchronizationScope::CrossThread:
|
|
||||||
return SyncScope::System;
|
|
||||||
default:
|
|
||||||
report_fatal_error("bad SynchronizationScope.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" LLVMValueRef
|
|
||||||
LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
|
|
||||||
LLVMRustSynchronizationScope Scope) {
|
|
||||||
return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class LLVMRustAsmDialect {
|
enum class LLVMRustAsmDialect {
|
||||||
Att,
|
Att,
|
||||||
Intel,
|
Intel,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue