Skip to content

Commit

Permalink
Rollup merge of #102001 - cuviper:build-atomic-capi, r=nikic
Browse files Browse the repository at this point in the history
Use LLVM C-API to build atomic cmpxchg and fence

We don't need C++ wrappers because the LLVM C API can build these.
  • Loading branch information
notriddle committed Sep 20, 2022
2 parents 0d2e57c + fac12e2 commit 2c57a5b
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 76 deletions.
26 changes: 16 additions & 10 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use crate::attributes;
use crate::common::Funclet;
use crate::context::CodegenCx;
use crate::llvm::{self, BasicBlock, False};
use crate::llvm::{AtomicOrdering, AtomicRmwBinOp, SynchronizationScope};
use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock};
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
use cstr::cstr;
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::place::PlaceRef;
use rustc_codegen_ssa::traits::*;
Expand Down Expand Up @@ -1042,15 +1041,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
) -> &'ll Value {
let weak = if weak { llvm::True } else { llvm::False };
unsafe {
llvm::LLVMRustBuildAtomicCmpXchg(
let value = llvm::LLVMBuildAtomicCmpXchg(
self.llbuilder,
dst,
cmp,
src,
AtomicOrdering::from_generic(order),
AtomicOrdering::from_generic(failure_order),
weak,
)
llvm::False, // SingleThreaded
);
llvm::LLVMSetWeak(value, weak);
value
}
}
fn atomic_rmw(
Expand All @@ -1067,21 +1068,26 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
dst,
src,
AtomicOrdering::from_generic(order),
False,
llvm::False, // SingleThreaded
)
}
}

fn atomic_fence(
&mut self,
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 {
llvm::LLVMRustBuildAtomicFence(
llvm::LLVMBuildFence(
self.llbuilder,
AtomicOrdering::from_generic(order),
SynchronizationScope::from_generic(scope),
single_threaded,
UNNAMED,
);
}
}
Expand Down
36 changes: 9 additions & 27 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
#[derive(Copy, Clone)]
#[repr(C)]
Expand Down Expand Up @@ -1782,16 +1761,18 @@ extern "C" {
Order: AtomicOrdering,
) -> &'a Value;

pub fn LLVMRustBuildAtomicCmpXchg<'a>(
pub fn LLVMBuildAtomicCmpXchg<'a>(
B: &Builder<'a>,
LHS: &'a Value,
CMP: &'a Value,
RHS: &'a Value,
Order: AtomicOrdering,
FailureOrder: AtomicOrdering,
Weak: Bool,
SingleThreaded: Bool,
) -> &'a Value;

pub fn LLVMSetWeak(CmpXchgInst: &Value, IsWeak: Bool);

pub fn LLVMBuildAtomicRMW<'a>(
B: &Builder<'a>,
Op: AtomicRmwBinOp,
Expand All @@ -1801,11 +1782,12 @@ extern "C" {
SingleThreaded: Bool,
) -> &'a Value;

pub fn LLVMRustBuildAtomicFence(
B: &Builder<'_>,
pub fn LLVMBuildFence<'a>(
B: &Builder<'a>,
Order: AtomicOrdering,
Scope: SynchronizationScope,
);
SingleThreaded: Bool,
Name: *const c_char,
) -> &'a Value;

/// Writes a module to the specified path. Returns 0 on success.
pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int;
Expand Down
39 changes: 0 additions & 39 deletions compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,45 +406,6 @@ extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
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 {
Att,
Intel,
Expand Down

0 comments on commit 2c57a5b

Please sign in to comment.