From: Mehdi Amini Date: Sat, 19 Mar 2016 21:28:28 +0000 (+0000) Subject: Expose IRBuilder::CreateAtomicCmpXchg as LLVMBuildAtomicCmpXchg in the C API. X-Git-Tag: android-x86-7.1-r4~36362 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=e6cda0e9bc5f413814bb25f532ff97e90283106d;p=android-x86%2Fexternal-llvm.git Expose IRBuilder::CreateAtomicCmpXchg as LLVMBuildAtomicCmpXchg in the C API. Summary: Also expose getters and setters in the C API, so that the change can be tested. Reviewers: nhaehnle, axw, joker.eph Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D18260 From: Bas Nieuwenhuizen git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@263886 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index a09c92282a6..db7e3b1244f 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -2940,6 +2940,21 @@ LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B, LLVMAtomicRMWBinOp op, LLVMValueRef PTR, LLVMValueRef Val, LLVMAtomicOrdering ordering, LLVMBool singleThread); +LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Ptr, + LLVMValueRef Cmp, LLVMValueRef New, + LLVMAtomicOrdering SuccessOrdering, + LLVMAtomicOrdering FailureOrdering, + LLVMBool SingleThread); + +LLVMBool LLVMIsAtomicSingleThread(LLVMValueRef AtomicInst); +void LLVMSetAtomicSingleThread(LLVMValueRef AtomicInst, LLVMBool SingleThread); + +LLVMAtomicOrdering LLVMGetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst); +void LLVMSetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst, + LLVMAtomicOrdering Ordering); +LLVMAtomicOrdering LLVMGetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst); +void LLVMSetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst, + LLVMAtomicOrdering Ordering); /** * @} diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp index 55d719cd002..8de8a82c809 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -2908,6 +2908,61 @@ LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,LLVMAtomicRMWBinOp op, mapFromLLVMOrdering(ordering), singleThread ? SingleThread : CrossThread)); } +LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Ptr, + LLVMValueRef Cmp, LLVMValueRef New, + LLVMAtomicOrdering SuccessOrdering, + LLVMAtomicOrdering FailureOrdering, + LLVMBool singleThread) { + + return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(Ptr), unwrap(Cmp), + unwrap(New), mapFromLLVMOrdering(SuccessOrdering), + mapFromLLVMOrdering(FailureOrdering), + singleThread ? SingleThread : CrossThread)); +} + + +LLVMBool LLVMIsAtomicSingleThread(LLVMValueRef AtomicInst) { + Value *P = unwrap(AtomicInst); + + if (AtomicRMWInst *I = dyn_cast(P)) + return I->getSynchScope() == SingleThread; + return cast(P)->getSynchScope() == SingleThread; +} + +void LLVMSetAtomicSingleThread(LLVMValueRef AtomicInst, LLVMBool NewValue) { + Value *P = unwrap(AtomicInst); + SynchronizationScope Sync = NewValue ? SingleThread : CrossThread; + + if (AtomicRMWInst *I = dyn_cast(P)) + return I->setSynchScope(Sync); + return cast(P)->setSynchScope(Sync); +} + +LLVMAtomicOrdering LLVMGetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst) { + Value *P = unwrap(CmpXchgInst); + return mapToLLVMOrdering(cast(P)->getSuccessOrdering()); +} + +void LLVMSetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst, + LLVMAtomicOrdering Ordering) { + Value *P = unwrap(CmpXchgInst); + AtomicOrdering O = mapFromLLVMOrdering(Ordering); + + return cast(P)->setSuccessOrdering(O); +} + +LLVMAtomicOrdering LLVMGetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst) { + Value *P = unwrap(CmpXchgInst); + return mapToLLVMOrdering(cast(P)->getFailureOrdering()); +} + +void LLVMSetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst, + LLVMAtomicOrdering Ordering) { + Value *P = unwrap(CmpXchgInst); + AtomicOrdering O = mapFromLLVMOrdering(Ordering); + + return cast(P)->setFailureOrdering(O); +} /*===-- Module providers --------------------------------------------------===*/ diff --git a/test/Bindings/llvm-c/atomics.ll b/test/Bindings/llvm-c/atomics.ll new file mode 100644 index 00000000000..4fe62b07d48 --- /dev/null +++ b/test/Bindings/llvm-c/atomics.ll @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | llvm-dis > %t.orig +; RUN: llvm-as < %s | llvm-c-test --echo > %t.echo +; RUN: diff -w %t.orig %t.echo + +define i32 @main() { + %1 = alloca i32 + %2 = cmpxchg i32* %1, i32 2, i32 3 seq_cst acquire + %3 = extractvalue { i32, i1 } %2, 0 + ret i32 %3 +} diff --git a/tools/llvm-c-test/echo.cpp b/tools/llvm-c-test/echo.cpp index a8f9baf1a39..5a2102a1579 100644 --- a/tools/llvm-c-test/echo.cpp +++ b/tools/llvm-c-test/echo.cpp @@ -522,6 +522,17 @@ struct FunCloner { Dst = LLVMBuildGEP(Builder, Ptr, Idx.data(), NumIdx, Name); break; } + case LLVMAtomicCmpXchg: { + LLVMValueRef Ptr = CloneValue(LLVMGetOperand(Src, 0)); + LLVMValueRef Cmp = CloneValue(LLVMGetOperand(Src, 1)); + LLVMValueRef New = CloneValue(LLVMGetOperand(Src, 2)); + LLVMAtomicOrdering Succ = LLVMGetCmpXchgSuccessOrdering(Src); + LLVMAtomicOrdering Fail = LLVMGetCmpXchgFailureOrdering(Src); + LLVMBool SingleThread = LLVMIsAtomicSingleThread(Src); + + Dst = LLVMBuildAtomicCmpXchg(Builder, Ptr, Cmp, New, Succ, Fail, + SingleThread); + } break; case LLVMBitCast: { LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 0)); Dst = LLVMBuildBitCast(Builder, V, CloneType(Src), Name);