Skip to content

Commit 00a4042

Browse files
authored
[SandboxIR] Implement AtomicCmpXchgInst (#102710)
This patch implements sandboxir::AtomicCmpXchgInst which mirrors llvm::AtomiCmpXchgInst.
1 parent f58f92c commit 00a4042

File tree

5 files changed

+468
-0
lines changed

5 files changed

+468
-0
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ class CastInst;
130130
class PtrToIntInst;
131131
class BitCastInst;
132132
class AllocaInst;
133+
class AtomicCmpXchgInst;
133134

134135
/// Iterator for the `Use` edges of a User's operands.
135136
/// \Returns the operand `Use` when dereferenced.
@@ -248,6 +249,7 @@ class Value {
248249
friend class InvokeInst; // For getting `Val`.
249250
friend class CallBrInst; // For getting `Val`.
250251
friend class GetElementPtrInst; // For getting `Val`.
252+
friend class AtomicCmpXchgInst; // For getting `Val`.
251253
friend class AllocaInst; // For getting `Val`.
252254
friend class CastInst; // For getting `Val`.
253255
friend class PHINode; // For getting `Val`.
@@ -628,6 +630,7 @@ class Instruction : public sandboxir::User {
628630
friend class InvokeInst; // For getTopmostLLVMInstruction().
629631
friend class CallBrInst; // For getTopmostLLVMInstruction().
630632
friend class GetElementPtrInst; // For getTopmostLLVMInstruction().
633+
friend class AtomicCmpXchgInst; // For getTopmostLLVMInstruction().
631634
friend class AllocaInst; // For getTopmostLLVMInstruction().
632635
friend class CastInst; // For getTopmostLLVMInstruction().
633636
friend class PHINode; // For getTopmostLLVMInstruction().
@@ -1337,6 +1340,91 @@ class GetElementPtrInst final
13371340
// TODO: Add missing member functions.
13381341
};
13391342

1343+
class AtomicCmpXchgInst
1344+
: public SingleLLVMInstructionImpl<llvm::AtomicCmpXchgInst> {
1345+
AtomicCmpXchgInst(llvm::AtomicCmpXchgInst *Atomic, Context &Ctx)
1346+
: SingleLLVMInstructionImpl(ClassID::AtomicCmpXchg,
1347+
Instruction::Opcode::AtomicCmpXchg, Atomic,
1348+
Ctx) {}
1349+
friend class Context; // For constructor.
1350+
1351+
public:
1352+
/// Return the alignment of the memory that is being allocated by the
1353+
/// instruction.
1354+
Align getAlign() const {
1355+
return cast<llvm::AtomicCmpXchgInst>(Val)->getAlign();
1356+
}
1357+
1358+
void setAlignment(Align Align);
1359+
/// Return true if this is a cmpxchg from a volatile memory
1360+
/// location.
1361+
bool isVolatile() const {
1362+
return cast<llvm::AtomicCmpXchgInst>(Val)->isVolatile();
1363+
}
1364+
/// Specify whether this is a volatile cmpxchg.
1365+
void setVolatile(bool V);
1366+
/// Return true if this cmpxchg may spuriously fail.
1367+
bool isWeak() const { return cast<llvm::AtomicCmpXchgInst>(Val)->isWeak(); }
1368+
void setWeak(bool IsWeak);
1369+
static bool isValidSuccessOrdering(AtomicOrdering Ordering) {
1370+
return llvm::AtomicCmpXchgInst::isValidSuccessOrdering(Ordering);
1371+
}
1372+
static bool isValidFailureOrdering(AtomicOrdering Ordering) {
1373+
return llvm::AtomicCmpXchgInst::isValidFailureOrdering(Ordering);
1374+
}
1375+
AtomicOrdering getSuccessOrdering() const {
1376+
return cast<llvm::AtomicCmpXchgInst>(Val)->getSuccessOrdering();
1377+
}
1378+
void setSuccessOrdering(AtomicOrdering Ordering);
1379+
1380+
AtomicOrdering getFailureOrdering() const {
1381+
return cast<llvm::AtomicCmpXchgInst>(Val)->getFailureOrdering();
1382+
}
1383+
void setFailureOrdering(AtomicOrdering Ordering);
1384+
AtomicOrdering getMergedOrdering() const {
1385+
return cast<llvm::AtomicCmpXchgInst>(Val)->getMergedOrdering();
1386+
}
1387+
SyncScope::ID getSyncScopeID() const {
1388+
return cast<llvm::AtomicCmpXchgInst>(Val)->getSyncScopeID();
1389+
}
1390+
void setSyncScopeID(SyncScope::ID SSID);
1391+
Value *getPointerOperand();
1392+
const Value *getPointerOperand() const {
1393+
return const_cast<AtomicCmpXchgInst *>(this)->getPointerOperand();
1394+
}
1395+
1396+
Value *getCompareOperand();
1397+
const Value *getCompareOperand() const {
1398+
return const_cast<AtomicCmpXchgInst *>(this)->getCompareOperand();
1399+
}
1400+
1401+
Value *getNewValOperand();
1402+
const Value *getNewValOperand() const {
1403+
return const_cast<AtomicCmpXchgInst *>(this)->getNewValOperand();
1404+
}
1405+
1406+
/// Returns the address space of the pointer operand.
1407+
unsigned getPointerAddressSpace() const {
1408+
return cast<llvm::AtomicCmpXchgInst>(Val)->getPointerAddressSpace();
1409+
}
1410+
1411+
static AtomicCmpXchgInst *
1412+
create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
1413+
AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
1414+
BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx,
1415+
SyncScope::ID SSID = SyncScope::System, const Twine &Name = "");
1416+
static AtomicCmpXchgInst *
1417+
create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
1418+
AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
1419+
Instruction *InsertBefore, Context &Ctx,
1420+
SyncScope::ID SSID = SyncScope::System, const Twine &Name = "");
1421+
static AtomicCmpXchgInst *
1422+
create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
1423+
AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
1424+
BasicBlock *InsertAtEnd, Context &Ctx,
1425+
SyncScope::ID SSID = SyncScope::System, const Twine &Name = "");
1426+
};
1427+
13401428
class AllocaInst final : public UnaryInstruction {
13411429
AllocaInst(llvm::AllocaInst *AI, Context &Ctx)
13421430
: UnaryInstruction(ClassID::Alloca, Instruction::Opcode::Alloca, AI,
@@ -1696,6 +1784,8 @@ class Context {
16961784
friend CallBrInst; // For createCallBrInst()
16971785
GetElementPtrInst *createGetElementPtrInst(llvm::GetElementPtrInst *I);
16981786
friend GetElementPtrInst; // For createGetElementPtrInst()
1787+
AtomicCmpXchgInst *createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I);
1788+
friend AtomicCmpXchgInst; // For createAtomicCmpXchgInst()
16991789
AllocaInst *createAllocaInst(llvm::AllocaInst *I);
17001790
friend AllocaInst; // For createAllocaInst()
17011791
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
@@ -45,6 +45,7 @@ DEF_INSTR(Call, OP(Call), CallInst)
4545
DEF_INSTR(Invoke, OP(Invoke), InvokeInst)
4646
DEF_INSTR(CallBr, OP(CallBr), CallBrInst)
4747
DEF_INSTR(GetElementPtr, OP(GetElementPtr), GetElementPtrInst)
48+
DEF_INSTR(AtomicCmpXchg, OP(AtomicCmpXchg), AtomicCmpXchgInst)
4849
DEF_INSTR(Alloca, OP(Alloca), AllocaInst)
4950
DEF_INSTR(Cast, OPCODES(\
5051
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) {
@@ -1433,6 +1531,12 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
14331531
new GetElementPtrInst(LLVMGEP, *this));
14341532
return It->second.get();
14351533
}
1534+
case llvm::Instruction::AtomicCmpXchg: {
1535+
auto *LLVMAtomicCmpXchg = cast<llvm::AtomicCmpXchgInst>(LLVMV);
1536+
It->second = std::unique_ptr<AtomicCmpXchgInst>(
1537+
new AtomicCmpXchgInst(LLVMAtomicCmpXchg, *this));
1538+
return It->second.get();
1539+
}
14361540
case llvm::Instruction::Alloca: {
14371541
auto *LLVMAlloca = cast<llvm::AllocaInst>(LLVMV);
14381542
It->second = std::unique_ptr<AllocaInst>(new AllocaInst(LLVMAlloca, *this));
@@ -1550,6 +1654,12 @@ Context::createGetElementPtrInst(llvm::GetElementPtrInst *I) {
15501654
std::unique_ptr<GetElementPtrInst>(new GetElementPtrInst(I, *this));
15511655
return cast<GetElementPtrInst>(registerValue(std::move(NewPtr)));
15521656
}
1657+
AtomicCmpXchgInst *
1658+
Context::createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I) {
1659+
auto NewPtr =
1660+
std::unique_ptr<AtomicCmpXchgInst>(new AtomicCmpXchgInst(I, *this));
1661+
return cast<AtomicCmpXchgInst>(registerValue(std::move(NewPtr)));
1662+
}
15531663
AllocaInst *Context::createAllocaInst(llvm::AllocaInst *I) {
15541664
auto NewPtr = std::unique_ptr<AllocaInst>(new AllocaInst(I, *this));
15551665
return cast<AllocaInst>(registerValue(std::move(NewPtr)));

0 commit comments

Comments
 (0)