Skip to content

Commit b9f896c

Browse files
committed
[SandboxIR] Implement AtomicCmpXchgInst
This patch implements sandboxir::AtomicCmpXchgInst which mirrors llvm::AtomiCmpXchgInst.
1 parent 5351723 commit b9f896c

File tree

5 files changed

+489
-0
lines changed

5 files changed

+489
-0
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ class CastInst;
129129
class PtrToIntInst;
130130
class BitCastInst;
131131
class AllocaInst;
132+
class AtomicCmpXchgInst;
132133

133134
/// Iterator for the `Use` edges of a User's operands.
134135
/// \Returns the operand `Use` when dereferenced.
@@ -246,6 +247,7 @@ class Value {
246247
friend class InvokeInst; // For getting `Val`.
247248
friend class CallBrInst; // For getting `Val`.
248249
friend class GetElementPtrInst; // For getting `Val`.
250+
friend class AtomicCmpXchgInst; // For getting `Val`.
249251
friend class AllocaInst; // For getting `Val`.
250252
friend class CastInst; // For getting `Val`.
251253
friend class PHINode; // For getting `Val`.
@@ -625,6 +627,7 @@ class Instruction : public sandboxir::User {
625627
friend class InvokeInst; // For getTopmostLLVMInstruction().
626628
friend class CallBrInst; // For getTopmostLLVMInstruction().
627629
friend class GetElementPtrInst; // For getTopmostLLVMInstruction().
630+
friend class AtomicCmpXchgInst; // For getTopmostLLVMInstruction().
628631
friend class AllocaInst; // For getTopmostLLVMInstruction().
629632
friend class CastInst; // For getTopmostLLVMInstruction().
630633
friend class PHINode; // For getTopmostLLVMInstruction().
@@ -1303,6 +1306,104 @@ class GetElementPtrInst final
13031306
// TODO: Add missing member functions.
13041307
};
13051308

1309+
class AtomicCmpXchgInst
1310+
: public SingleLLVMInstructionImpl<llvm::AtomicCmpXchgInst> {
1311+
AtomicCmpXchgInst(llvm::AtomicCmpXchgInst *Atomic, Context &Ctx)
1312+
: SingleLLVMInstructionImpl(ClassID::AtomicCmpXchg,
1313+
Instruction::Opcode::AtomicCmpXchg, Atomic,
1314+
Ctx) {}
1315+
friend class Context; // For constructor.
1316+
1317+
public:
1318+
/// Return the alignment of the memory that is being allocated by the
1319+
/// instruction.
1320+
Align getAlign() const {
1321+
return cast<llvm::AtomicCmpXchgInst>(Val)->getAlign();
1322+
}
1323+
1324+
void setAlignment(Align Align);
1325+
/// Return true if this is a cmpxchg from a volatile memory
1326+
/// location.
1327+
bool isVolatile() const {
1328+
return cast<llvm::AtomicCmpXchgInst>(Val)->isVolatile();
1329+
}
1330+
/// Specify whether this is a volatile cmpxchg.
1331+
void setVolatile(bool V);
1332+
/// Return true if this cmpxchg may spuriously fail.
1333+
bool isWeak() const { return cast<llvm::AtomicCmpXchgInst>(Val)->isWeak(); }
1334+
void setWeak(bool IsWeak);
1335+
static bool isValidSuccessOrdering(AtomicOrdering Ordering) {
1336+
return llvm::AtomicCmpXchgInst::isValidSuccessOrdering(Ordering);
1337+
}
1338+
static bool isValidFailureOrdering(AtomicOrdering Ordering) {
1339+
return llvm::AtomicCmpXchgInst::isValidFailureOrdering(Ordering);
1340+
}
1341+
AtomicOrdering getSuccessOrdering() const {
1342+
return cast<llvm::AtomicCmpXchgInst>(Val)->getSuccessOrdering();
1343+
}
1344+
void setSuccessOrdering(AtomicOrdering Ordering);
1345+
1346+
AtomicOrdering getFailureOrdering() const {
1347+
return cast<llvm::AtomicCmpXchgInst>(Val)->getFailureOrdering();
1348+
}
1349+
void setFailureOrdering(AtomicOrdering Ordering);
1350+
AtomicOrdering getMergedOrdering() const {
1351+
return cast<llvm::AtomicCmpXchgInst>(Val)->getMergedOrdering();
1352+
}
1353+
SyncScope::ID getSyncScopeID() const {
1354+
return cast<llvm::AtomicCmpXchgInst>(Val)->getSyncScopeID();
1355+
}
1356+
void setSyncScopeID(SyncScope::ID SSID);
1357+
Value *getPointerOperand();
1358+
const Value *getPointerOperand() const {
1359+
return const_cast<AtomicCmpXchgInst *>(this)->getPointerOperand();
1360+
}
1361+
1362+
Value *getCompareOperand();
1363+
const Value *getCompareOperand() const {
1364+
return const_cast<AtomicCmpXchgInst *>(this)->getCompareOperand();
1365+
}
1366+
1367+
Value *getNewValOperand();
1368+
const Value *getNewValOperand() const {
1369+
return const_cast<AtomicCmpXchgInst *>(this)->getNewValOperand();
1370+
}
1371+
1372+
/// Returns the address space of the pointer operand.
1373+
unsigned getPointerAddressSpace() const {
1374+
return cast<llvm::AtomicCmpXchgInst>(Val)->getPointerAddressSpace();
1375+
}
1376+
1377+
/// Returns the strongest permitted ordering on failure, given the
1378+
/// desired ordering on success.
1379+
///
1380+
/// If the comparison in a cmpxchg operation fails, there is no atomic store
1381+
/// so release semantics cannot be provided. So this function drops explicit
1382+
/// Release requests from the AtomicOrdering. A SequentiallyConsistent
1383+
/// operation would remain SequentiallyConsistent.
1384+
static AtomicOrdering
1385+
getStrongestFailureOrdering(AtomicOrdering SuccessOrdering) {
1386+
return llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(
1387+
SuccessOrdering);
1388+
}
1389+
1390+
static AtomicCmpXchgInst *
1391+
create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
1392+
AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
1393+
BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx,
1394+
SyncScope::ID SSID = SyncScope::System, const Twine &Name = "");
1395+
static AtomicCmpXchgInst *
1396+
create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
1397+
AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
1398+
Instruction *InsertBefore, Context &Ctx,
1399+
SyncScope::ID SSID = SyncScope::System, const Twine &Name = "");
1400+
static AtomicCmpXchgInst *
1401+
create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
1402+
AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
1403+
BasicBlock *InsertAtEnd, Context &Ctx,
1404+
SyncScope::ID SSID = SyncScope::System, const Twine &Name = "");
1405+
};
1406+
13061407
class AllocaInst final : public UnaryInstruction {
13071408
AllocaInst(llvm::AllocaInst *AI, Context &Ctx)
13081409
: UnaryInstruction(ClassID::Alloca, Instruction::Opcode::Alloca, AI,
@@ -1660,6 +1761,8 @@ class Context {
16601761
friend CallBrInst; // For createCallBrInst()
16611762
GetElementPtrInst *createGetElementPtrInst(llvm::GetElementPtrInst *I);
16621763
friend GetElementPtrInst; // For createGetElementPtrInst()
1764+
AtomicCmpXchgInst *createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I);
1765+
friend AtomicCmpXchgInst; // For createAtomicCmpXchgInst()
16631766
AllocaInst *createAllocaInst(llvm::AllocaInst *I);
16641767
friend AllocaInst; // For createAllocaInst()
16651768
CastInst *createCastInst(llvm::CastInst *I);

llvm/include/llvm/SandboxIR/SandboxIRValues.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ DEF_INSTR(Call, OP(Call), CallInst)
4444
DEF_INSTR(Invoke, OP(Invoke), InvokeInst)
4545
DEF_INSTR(CallBr, OP(CallBr), CallBrInst)
4646
DEF_INSTR(GetElementPtr, OP(GetElementPtr), GetElementPtrInst)
47+
DEF_INSTR(AtomicCmpXchg, OP(AtomicCmpXchg), AtomicCmpXchgInst)
4748
DEF_INSTR(Alloca, OP(Alloca), AllocaInst)
4849
DEF_INSTR(Cast, OPCODES(\
4950
OP(ZExt) \

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,104 @@ static llvm::Instruction::CastOps getLLVMCastOp(Instruction::Opcode Opc) {
11221122
}
11231123
}
11241124

1125+
void AtomicCmpXchgInst::setSyncScopeID(SyncScope::ID SSID) {
1126+
Ctx.getTracker()
1127+
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSyncScopeID,
1128+
&AtomicCmpXchgInst::setSyncScopeID>>(
1129+
this);
1130+
cast<llvm::AtomicCmpXchgInst>(Val)->setSyncScopeID(SSID);
1131+
}
1132+
1133+
Value *AtomicCmpXchgInst::getPointerOperand() {
1134+
return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getPointerOperand());
1135+
}
1136+
1137+
Value *AtomicCmpXchgInst::getCompareOperand() {
1138+
return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getCompareOperand());
1139+
}
1140+
1141+
Value *AtomicCmpXchgInst::getNewValOperand() {
1142+
return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getNewValOperand());
1143+
}
1144+
1145+
AtomicCmpXchgInst *
1146+
AtomicCmpXchgInst::create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
1147+
AtomicOrdering SuccessOrdering,
1148+
AtomicOrdering FailureOrdering, BBIterator WhereIt,
1149+
BasicBlock *WhereBB, Context &Ctx, SyncScope::ID SSID,
1150+
const Twine &Name) {
1151+
auto &Builder = Ctx.getLLVMIRBuilder();
1152+
if (WhereIt == WhereBB->end())
1153+
Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1154+
else
1155+
Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1156+
auto *LLVMAtomicCmpXchg =
1157+
Builder.CreateAtomicCmpXchg(Ptr->Val, Cmp->Val, New->Val, Align,
1158+
SuccessOrdering, FailureOrdering, SSID);
1159+
LLVMAtomicCmpXchg->setName(Name);
1160+
return Ctx.createAtomicCmpXchgInst(LLVMAtomicCmpXchg);
1161+
}
1162+
1163+
AtomicCmpXchgInst *AtomicCmpXchgInst::create(Value *Ptr, Value *Cmp, Value *New,
1164+
MaybeAlign Align,
1165+
AtomicOrdering SuccessOrdering,
1166+
AtomicOrdering FailureOrdering,
1167+
Instruction *InsertBefore,
1168+
Context &Ctx, SyncScope::ID SSID,
1169+
const Twine &Name) {
1170+
return create(Ptr, Cmp, New, Align, SuccessOrdering, FailureOrdering,
1171+
InsertBefore->getIterator(), InsertBefore->getParent(), Ctx,
1172+
SSID, Name);
1173+
}
1174+
1175+
AtomicCmpXchgInst *AtomicCmpXchgInst::create(Value *Ptr, Value *Cmp, Value *New,
1176+
MaybeAlign Align,
1177+
AtomicOrdering SuccessOrdering,
1178+
AtomicOrdering FailureOrdering,
1179+
BasicBlock *InsertAtEnd,
1180+
Context &Ctx, SyncScope::ID SSID,
1181+
const Twine &Name) {
1182+
return create(Ptr, Cmp, New, Align, SuccessOrdering, FailureOrdering,
1183+
InsertAtEnd->end(), InsertAtEnd, Ctx, SSID, Name);
1184+
}
1185+
1186+
void AtomicCmpXchgInst::setAlignment(Align Align) {
1187+
Ctx.getTracker()
1188+
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getAlign,
1189+
&AtomicCmpXchgInst::setAlignment>>(this);
1190+
cast<llvm::AtomicCmpXchgInst>(Val)->setAlignment(Align);
1191+
}
1192+
1193+
void AtomicCmpXchgInst::setVolatile(bool V) {
1194+
Ctx.getTracker()
1195+
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isVolatile,
1196+
&AtomicCmpXchgInst::setVolatile>>(this);
1197+
cast<llvm::AtomicCmpXchgInst>(Val)->setVolatile(V);
1198+
}
1199+
1200+
void AtomicCmpXchgInst::setWeak(bool IsWeak) {
1201+
Ctx.getTracker()
1202+
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isWeak,
1203+
&AtomicCmpXchgInst::setWeak>>(this);
1204+
cast<llvm::AtomicCmpXchgInst>(Val)->setWeak(IsWeak);
1205+
}
1206+
1207+
void AtomicCmpXchgInst::setSuccessOrdering(AtomicOrdering Ordering) {
1208+
Ctx.getTracker()
1209+
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSuccessOrdering,
1210+
&AtomicCmpXchgInst::setSuccessOrdering>>(
1211+
this);
1212+
cast<llvm::AtomicCmpXchgInst>(Val)->setSuccessOrdering(Ordering);
1213+
}
1214+
1215+
void AtomicCmpXchgInst::setFailureOrdering(AtomicOrdering Ordering) {
1216+
Ctx.getTracker()
1217+
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getFailureOrdering,
1218+
&AtomicCmpXchgInst::setFailureOrdering>>(
1219+
this);
1220+
cast<llvm::AtomicCmpXchgInst>(Val)->setFailureOrdering(Ordering);
1221+
}
1222+
11251223
AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace, BBIterator WhereIt,
11261224
BasicBlock *WhereBB, Context &Ctx,
11271225
Value *ArraySize, const Twine &Name) {
@@ -1403,6 +1501,12 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
14031501
new GetElementPtrInst(LLVMGEP, *this));
14041502
return It->second.get();
14051503
}
1504+
case llvm::Instruction::AtomicCmpXchg: {
1505+
auto *LLVMAtomicCmpXchg = cast<llvm::AtomicCmpXchgInst>(LLVMV);
1506+
It->second = std::unique_ptr<AtomicCmpXchgInst>(
1507+
new AtomicCmpXchgInst(LLVMAtomicCmpXchg, *this));
1508+
return It->second.get();
1509+
}
14061510
case llvm::Instruction::Alloca: {
14071511
auto *LLVMAlloca = cast<llvm::AllocaInst>(LLVMV);
14081512
It->second = std::unique_ptr<AllocaInst>(new AllocaInst(LLVMAlloca, *this));
@@ -1513,6 +1617,12 @@ Context::createGetElementPtrInst(llvm::GetElementPtrInst *I) {
15131617
std::unique_ptr<GetElementPtrInst>(new GetElementPtrInst(I, *this));
15141618
return cast<GetElementPtrInst>(registerValue(std::move(NewPtr)));
15151619
}
1620+
AtomicCmpXchgInst *
1621+
Context::createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I) {
1622+
auto NewPtr =
1623+
std::unique_ptr<AtomicCmpXchgInst>(new AtomicCmpXchgInst(I, *this));
1624+
return cast<AtomicCmpXchgInst>(registerValue(std::move(NewPtr)));
1625+
}
15161626
AllocaInst *Context::createAllocaInst(llvm::AllocaInst *I) {
15171627
auto NewPtr = std::unique_ptr<AllocaInst>(new AllocaInst(I, *this));
15181628
return cast<AllocaInst>(registerValue(std::move(NewPtr)));

0 commit comments

Comments
 (0)