Skip to content

Commit 0601a77

Browse files
committedApr 17, 2016
NFC: unify clang / LLVM atomic ordering
Summary: Depends on http://reviews.llvm.org/D18875 This makes the C11 / C++11 *ABI* atomic ordering accessible from LLVM, as discussed in http://reviews.llvm.org/D18200#inline-151433 Reviewers: jyknight, reames Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D18876 llvm-svn: 266574
1 parent 6ef3aa2 commit 0601a77

File tree

3 files changed

+81
-110
lines changed

3 files changed

+81
-110
lines changed
 

Diff for: ‎clang/include/clang/AST/Expr.h

+1-10
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "llvm/ADT/APSInt.h"
3030
#include "llvm/ADT/SmallVector.h"
3131
#include "llvm/ADT/StringRef.h"
32+
#include "llvm/Support/AtomicOrdering.h"
3233
#include "llvm/Support/Compiler.h"
3334

3435
namespace clang {
@@ -4830,16 +4831,6 @@ class AtomicExpr : public Expr {
48304831
BI_First = 0
48314832
};
48324833

4833-
// The ABI values for various atomic memory orderings.
4834-
enum AtomicOrderingKind {
4835-
AO_ABI_memory_order_relaxed = 0,
4836-
AO_ABI_memory_order_consume = 1,
4837-
AO_ABI_memory_order_acquire = 2,
4838-
AO_ABI_memory_order_release = 3,
4839-
AO_ABI_memory_order_acq_rel = 4,
4840-
AO_ABI_memory_order_seq_cst = 5
4841-
};
4842-
48434834
private:
48444835
enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR };
48454836
Stmt* SubExprs[END_EXPR];

Diff for: ‎clang/lib/CodeGen/CGAtomic.cpp

+73-93
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,6 @@ namespace {
243243
/// Materialize an atomic r-value in atomic-layout memory.
244244
Address materializeRValue(RValue rvalue) const;
245245

246-
/// \brief Translates LLVM atomic ordering to GNU atomic ordering for
247-
/// libcalls.
248-
static AtomicExpr::AtomicOrderingKind
249-
translateAtomicOrdering(const llvm::AtomicOrdering AO);
250-
251246
/// \brief Creates temp alloca for intermediate operations on atomic value.
252247
Address CreateTempAlloca() const;
253248
private:
@@ -292,25 +287,6 @@ namespace {
292287
};
293288
}
294289

295-
AtomicExpr::AtomicOrderingKind
296-
AtomicInfo::translateAtomicOrdering(const llvm::AtomicOrdering AO) {
297-
switch (AO) {
298-
case llvm::AtomicOrdering::Unordered:
299-
case llvm::AtomicOrdering::NotAtomic:
300-
case llvm::AtomicOrdering::Monotonic:
301-
return AtomicExpr::AO_ABI_memory_order_relaxed;
302-
case llvm::AtomicOrdering::Acquire:
303-
return AtomicExpr::AO_ABI_memory_order_acquire;
304-
case llvm::AtomicOrdering::Release:
305-
return AtomicExpr::AO_ABI_memory_order_release;
306-
case llvm::AtomicOrdering::AcquireRelease:
307-
return AtomicExpr::AO_ABI_memory_order_acq_rel;
308-
case llvm::AtomicOrdering::SequentiallyConsistent:
309-
return AtomicExpr::AO_ABI_memory_order_seq_cst;
310-
}
311-
llvm_unreachable("Unhandled AtomicOrdering");
312-
}
313-
314290
Address AtomicInfo::CreateTempAlloca() const {
315291
Address TempAlloca = CGF.CreateMemTemp(
316292
(LVal.isBitField() && ValueSizeInBits > AtomicSizeInBits) ? ValueTy
@@ -427,34 +403,39 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
427403
/// instructions to cope with the provided (but possibly only dynamically known)
428404
/// FailureOrder.
429405
static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
430-
bool IsWeak, Address Dest,
431-
Address Ptr, Address Val1,
432-
Address Val2,
406+
bool IsWeak, Address Dest, Address Ptr,
407+
Address Val1, Address Val2,
433408
llvm::Value *FailureOrderVal,
434409
uint64_t Size,
435410
llvm::AtomicOrdering SuccessOrder) {
436411
llvm::AtomicOrdering FailureOrder;
437412
if (llvm::ConstantInt *FO = dyn_cast<llvm::ConstantInt>(FailureOrderVal)) {
438-
switch (FO->getSExtValue()) {
439-
default:
413+
auto FOS = FO->getSExtValue();
414+
if (!llvm::isValidAtomicOrderingCABI(FOS))
440415
FailureOrder = llvm::AtomicOrdering::Monotonic;
441-
break;
442-
case AtomicExpr::AO_ABI_memory_order_consume:
443-
case AtomicExpr::AO_ABI_memory_order_acquire:
444-
FailureOrder = llvm::AtomicOrdering::Acquire;
445-
break;
446-
case AtomicExpr::AO_ABI_memory_order_seq_cst:
447-
FailureOrder = llvm::AtomicOrdering::SequentiallyConsistent;
448-
break;
449-
}
416+
else
417+
switch ((llvm::AtomicOrderingCABI)FOS) {
418+
case llvm::AtomicOrderingCABI::relaxed:
419+
case llvm::AtomicOrderingCABI::release:
420+
case llvm::AtomicOrderingCABI::acq_rel:
421+
FailureOrder = llvm::AtomicOrdering::Monotonic;
422+
break;
423+
case llvm::AtomicOrderingCABI::consume:
424+
case llvm::AtomicOrderingCABI::acquire:
425+
FailureOrder = llvm::AtomicOrdering::Acquire;
426+
break;
427+
case llvm::AtomicOrderingCABI::seq_cst:
428+
FailureOrder = llvm::AtomicOrdering::SequentiallyConsistent;
429+
break;
430+
}
450431
if (isStrongerThan(FailureOrder, SuccessOrder)) {
451432
// Don't assert on undefined behavior "failure argument shall be no
452433
// stronger than the success argument".
453434
FailureOrder =
454-
llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrder);
435+
llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrder);
455436
}
456-
emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size,
457-
SuccessOrder, FailureOrder);
437+
emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
438+
FailureOrder);
458439
return;
459440
}
460441

@@ -487,17 +468,17 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
487468
emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
488469
Size, SuccessOrder, llvm::AtomicOrdering::Acquire);
489470
CGF.Builder.CreateBr(ContBB);
490-
SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_consume),
471+
SI->addCase(CGF.Builder.getInt32((int)llvm::AtomicOrderingCABI::consume),
491472
AcquireBB);
492-
SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acquire),
473+
SI->addCase(CGF.Builder.getInt32((int)llvm::AtomicOrderingCABI::acquire),
493474
AcquireBB);
494475
}
495476
if (SeqCstBB) {
496477
CGF.Builder.SetInsertPoint(SeqCstBB);
497478
emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
498479
llvm::AtomicOrdering::SequentiallyConsistent);
499480
CGF.Builder.CreateBr(ContBB);
500-
SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_seq_cst),
481+
SI->addCase(CGF.Builder.getInt32((int)llvm::AtomicOrderingCABI::seq_cst),
501482
SeqCstBB);
502483
}
503484

@@ -1044,40 +1025,39 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
10441025
E->getOp() == AtomicExpr::AO__atomic_load_n;
10451026

10461027
if (isa<llvm::ConstantInt>(Order)) {
1047-
int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
1048-
switch (ord) {
1049-
case AtomicExpr::AO_ABI_memory_order_relaxed:
1050-
EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
1051-
Size, llvm::AtomicOrdering::Monotonic);
1052-
break;
1053-
case AtomicExpr::AO_ABI_memory_order_consume:
1054-
case AtomicExpr::AO_ABI_memory_order_acquire:
1055-
if (IsStore)
1056-
break; // Avoid crashing on code with undefined behavior
1057-
EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
1058-
Size, llvm::AtomicOrdering::Acquire);
1059-
break;
1060-
case AtomicExpr::AO_ABI_memory_order_release:
1061-
if (IsLoad)
1062-
break; // Avoid crashing on code with undefined behavior
1063-
EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
1064-
Size, llvm::AtomicOrdering::Release);
1065-
break;
1066-
case AtomicExpr::AO_ABI_memory_order_acq_rel:
1067-
if (IsLoad || IsStore)
1068-
break; // Avoid crashing on code with undefined behavior
1069-
EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
1070-
Size, llvm::AtomicOrdering::AcquireRelease);
1071-
break;
1072-
case AtomicExpr::AO_ABI_memory_order_seq_cst:
1073-
EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
1074-
Size, llvm::AtomicOrdering::SequentiallyConsistent);
1075-
break;
1076-
default: // invalid order
1077-
// We should not ever get here normally, but it's hard to
1078-
// enforce that in general.
1079-
break;
1080-
}
1028+
auto ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
1029+
// We should not ever get to a case where the ordering isn't a valid C ABI
1030+
// value, but it's hard to enforce that in general.
1031+
if (llvm::isValidAtomicOrderingCABI(ord))
1032+
switch ((llvm::AtomicOrderingCABI)ord) {
1033+
case llvm::AtomicOrderingCABI::relaxed:
1034+
EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1035+
llvm::AtomicOrdering::Monotonic);
1036+
break;
1037+
case llvm::AtomicOrderingCABI::consume:
1038+
case llvm::AtomicOrderingCABI::acquire:
1039+
if (IsStore)
1040+
break; // Avoid crashing on code with undefined behavior
1041+
EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1042+
llvm::AtomicOrdering::Acquire);
1043+
break;
1044+
case llvm::AtomicOrderingCABI::release:
1045+
if (IsLoad)
1046+
break; // Avoid crashing on code with undefined behavior
1047+
EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1048+
llvm::AtomicOrdering::Release);
1049+
break;
1050+
case llvm::AtomicOrderingCABI::acq_rel:
1051+
if (IsLoad || IsStore)
1052+
break; // Avoid crashing on code with undefined behavior
1053+
EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1054+
llvm::AtomicOrdering::AcquireRelease);
1055+
break;
1056+
case llvm::AtomicOrderingCABI::seq_cst:
1057+
EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1058+
llvm::AtomicOrdering::SequentiallyConsistent);
1059+
break;
1060+
}
10811061
if (RValTy->isVoidType())
10821062
return RValue::get(nullptr);
10831063

@@ -1119,32 +1099,32 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
11191099
EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
11201100
Size, llvm::AtomicOrdering::Acquire);
11211101
Builder.CreateBr(ContBB);
1122-
SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_consume),
1102+
SI->addCase(Builder.getInt32((int)llvm::AtomicOrderingCABI::consume),
11231103
AcquireBB);
1124-
SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acquire),
1104+
SI->addCase(Builder.getInt32((int)llvm::AtomicOrderingCABI::acquire),
11251105
AcquireBB);
11261106
}
11271107
if (!IsLoad) {
11281108
Builder.SetInsertPoint(ReleaseBB);
11291109
EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
11301110
Size, llvm::AtomicOrdering::Release);
11311111
Builder.CreateBr(ContBB);
1132-
SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_release),
1112+
SI->addCase(Builder.getInt32((int)llvm::AtomicOrderingCABI::release),
11331113
ReleaseBB);
11341114
}
11351115
if (!IsLoad && !IsStore) {
11361116
Builder.SetInsertPoint(AcqRelBB);
11371117
EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
11381118
Size, llvm::AtomicOrdering::AcquireRelease);
11391119
Builder.CreateBr(ContBB);
1140-
SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acq_rel),
1120+
SI->addCase(Builder.getInt32((int)llvm::AtomicOrderingCABI::acq_rel),
11411121
AcqRelBB);
11421122
}
11431123
Builder.SetInsertPoint(SeqCstBB);
11441124
EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
11451125
Size, llvm::AtomicOrdering::SequentiallyConsistent);
11461126
Builder.CreateBr(ContBB);
1147-
SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_seq_cst),
1127+
SI->addCase(Builder.getInt32((int)llvm::AtomicOrderingCABI::seq_cst),
11481128
SeqCstBB);
11491129

11501130
// Cleanup and return
@@ -1264,9 +1244,9 @@ void AtomicInfo::EmitAtomicLoadLibcall(llvm::Value *AddForLoaded,
12641244
CGF.getContext().VoidPtrTy);
12651245
Args.add(RValue::get(CGF.EmitCastToVoidPtr(AddForLoaded)),
12661246
CGF.getContext().VoidPtrTy);
1267-
Args.add(RValue::get(
1268-
llvm::ConstantInt::get(CGF.IntTy, translateAtomicOrdering(AO))),
1269-
CGF.getContext().IntTy);
1247+
Args.add(
1248+
RValue::get(llvm::ConstantInt::get(CGF.IntTy, (int)llvm::toCABI(AO))),
1249+
CGF.getContext().IntTy);
12701250
emitAtomicLibcall(CGF, "__atomic_load", CGF.getContext().VoidTy, Args);
12711251
}
12721252

@@ -1482,11 +1462,11 @@ AtomicInfo::EmitAtomicCompareExchangeLibcall(llvm::Value *ExpectedAddr,
14821462
CGF.getContext().VoidPtrTy);
14831463
Args.add(RValue::get(CGF.EmitCastToVoidPtr(DesiredAddr)),
14841464
CGF.getContext().VoidPtrTy);
1485-
Args.add(RValue::get(llvm::ConstantInt::get(
1486-
CGF.IntTy, translateAtomicOrdering(Success))),
1465+
Args.add(RValue::get(
1466+
llvm::ConstantInt::get(CGF.IntTy, (int)llvm::toCABI(Success))),
14871467
CGF.getContext().IntTy);
1488-
Args.add(RValue::get(llvm::ConstantInt::get(
1489-
CGF.IntTy, translateAtomicOrdering(Failure))),
1468+
Args.add(RValue::get(
1469+
llvm::ConstantInt::get(CGF.IntTy, (int)llvm::toCABI(Failure))),
14901470
CGF.getContext().IntTy);
14911471
auto SuccessFailureRVal = emitAtomicLibcall(CGF, "__atomic_compare_exchange",
14921472
CGF.getContext().BoolTy, Args);
@@ -1793,9 +1773,9 @@ void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest,
17931773
getContext().VoidPtrTy);
17941774
args.add(RValue::get(EmitCastToVoidPtr(srcAddr.getPointer())),
17951775
getContext().VoidPtrTy);
1796-
args.add(RValue::get(llvm::ConstantInt::get(
1797-
IntTy, AtomicInfo::translateAtomicOrdering(AO))),
1798-
getContext().IntTy);
1776+
args.add(
1777+
RValue::get(llvm::ConstantInt::get(IntTy, (int)llvm::toCABI(AO))),
1778+
getContext().IntTy);
17991779
emitAtomicLibcall(*this, "__atomic_store", getContext().VoidTy, args);
18001780
return;
18011781
}

Diff for: ‎clang/lib/Sema/SemaChecking.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -1791,26 +1791,26 @@ bool Sema::CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto) {
17911791
}
17921792

17931793
static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op) {
1794-
if (Ordering < AtomicExpr::AO_ABI_memory_order_relaxed ||
1795-
Ordering > AtomicExpr::AO_ABI_memory_order_seq_cst)
1794+
if (!llvm::isValidAtomicOrderingCABI(Ordering))
17961795
return false;
17971796

1797+
auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
17981798
switch (Op) {
17991799
case AtomicExpr::AO__c11_atomic_init:
18001800
llvm_unreachable("There is no ordering argument for an init");
18011801

18021802
case AtomicExpr::AO__c11_atomic_load:
18031803
case AtomicExpr::AO__atomic_load_n:
18041804
case AtomicExpr::AO__atomic_load:
1805-
return Ordering != AtomicExpr::AO_ABI_memory_order_release &&
1806-
Ordering != AtomicExpr::AO_ABI_memory_order_acq_rel;
1805+
return OrderingCABI != llvm::AtomicOrderingCABI::release &&
1806+
OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
18071807

18081808
case AtomicExpr::AO__c11_atomic_store:
18091809
case AtomicExpr::AO__atomic_store:
18101810
case AtomicExpr::AO__atomic_store_n:
1811-
return Ordering != AtomicExpr::AO_ABI_memory_order_consume &&
1812-
Ordering != AtomicExpr::AO_ABI_memory_order_acquire &&
1813-
Ordering != AtomicExpr::AO_ABI_memory_order_acq_rel;
1811+
return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
1812+
OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
1813+
OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
18141814

18151815
default:
18161816
return true;

0 commit comments

Comments
 (0)
Please sign in to comment.