Skip to content

Commit

Permalink
[SandboxIR] Implement AtomicCmpXchgInst (#102710)
Browse files Browse the repository at this point in the history
This patch implements sandboxir::AtomicCmpXchgInst which mirrors
llvm::AtomiCmpXchgInst.
  • Loading branch information
vporpo committed Aug 13, 2024
1 parent f58f92c commit 00a4042
Show file tree
Hide file tree
Showing 5 changed files with 468 additions and 0 deletions.
90 changes: 90 additions & 0 deletions llvm/include/llvm/SandboxIR/SandboxIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ class CastInst;
class PtrToIntInst;
class BitCastInst;
class AllocaInst;
class AtomicCmpXchgInst;

/// Iterator for the `Use` edges of a User's operands.
/// \Returns the operand `Use` when dereferenced.
Expand Down Expand Up @@ -248,6 +249,7 @@ class Value {
friend class InvokeInst; // For getting `Val`.
friend class CallBrInst; // For getting `Val`.
friend class GetElementPtrInst; // For getting `Val`.
friend class AtomicCmpXchgInst; // For getting `Val`.
friend class AllocaInst; // For getting `Val`.
friend class CastInst; // For getting `Val`.
friend class PHINode; // For getting `Val`.
Expand Down Expand Up @@ -628,6 +630,7 @@ class Instruction : public sandboxir::User {
friend class InvokeInst; // For getTopmostLLVMInstruction().
friend class CallBrInst; // For getTopmostLLVMInstruction().
friend class GetElementPtrInst; // For getTopmostLLVMInstruction().
friend class AtomicCmpXchgInst; // For getTopmostLLVMInstruction().
friend class AllocaInst; // For getTopmostLLVMInstruction().
friend class CastInst; // For getTopmostLLVMInstruction().
friend class PHINode; // For getTopmostLLVMInstruction().
Expand Down Expand Up @@ -1337,6 +1340,91 @@ class GetElementPtrInst final
// TODO: Add missing member functions.
};

class AtomicCmpXchgInst
: public SingleLLVMInstructionImpl<llvm::AtomicCmpXchgInst> {
AtomicCmpXchgInst(llvm::AtomicCmpXchgInst *Atomic, Context &Ctx)
: SingleLLVMInstructionImpl(ClassID::AtomicCmpXchg,
Instruction::Opcode::AtomicCmpXchg, Atomic,
Ctx) {}
friend class Context; // For constructor.

public:
/// Return the alignment of the memory that is being allocated by the
/// instruction.
Align getAlign() const {
return cast<llvm::AtomicCmpXchgInst>(Val)->getAlign();
}

void setAlignment(Align Align);
/// Return true if this is a cmpxchg from a volatile memory
/// location.
bool isVolatile() const {
return cast<llvm::AtomicCmpXchgInst>(Val)->isVolatile();
}
/// Specify whether this is a volatile cmpxchg.
void setVolatile(bool V);
/// Return true if this cmpxchg may spuriously fail.
bool isWeak() const { return cast<llvm::AtomicCmpXchgInst>(Val)->isWeak(); }
void setWeak(bool IsWeak);
static bool isValidSuccessOrdering(AtomicOrdering Ordering) {
return llvm::AtomicCmpXchgInst::isValidSuccessOrdering(Ordering);
}
static bool isValidFailureOrdering(AtomicOrdering Ordering) {
return llvm::AtomicCmpXchgInst::isValidFailureOrdering(Ordering);
}
AtomicOrdering getSuccessOrdering() const {
return cast<llvm::AtomicCmpXchgInst>(Val)->getSuccessOrdering();
}
void setSuccessOrdering(AtomicOrdering Ordering);

AtomicOrdering getFailureOrdering() const {
return cast<llvm::AtomicCmpXchgInst>(Val)->getFailureOrdering();
}
void setFailureOrdering(AtomicOrdering Ordering);
AtomicOrdering getMergedOrdering() const {
return cast<llvm::AtomicCmpXchgInst>(Val)->getMergedOrdering();
}
SyncScope::ID getSyncScopeID() const {
return cast<llvm::AtomicCmpXchgInst>(Val)->getSyncScopeID();
}
void setSyncScopeID(SyncScope::ID SSID);
Value *getPointerOperand();
const Value *getPointerOperand() const {
return const_cast<AtomicCmpXchgInst *>(this)->getPointerOperand();
}

Value *getCompareOperand();
const Value *getCompareOperand() const {
return const_cast<AtomicCmpXchgInst *>(this)->getCompareOperand();
}

Value *getNewValOperand();
const Value *getNewValOperand() const {
return const_cast<AtomicCmpXchgInst *>(this)->getNewValOperand();
}

/// Returns the address space of the pointer operand.
unsigned getPointerAddressSpace() const {
return cast<llvm::AtomicCmpXchgInst>(Val)->getPointerAddressSpace();
}

static AtomicCmpXchgInst *
create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx,
SyncScope::ID SSID = SyncScope::System, const Twine &Name = "");
static AtomicCmpXchgInst *
create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
Instruction *InsertBefore, Context &Ctx,
SyncScope::ID SSID = SyncScope::System, const Twine &Name = "");
static AtomicCmpXchgInst *
create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
BasicBlock *InsertAtEnd, Context &Ctx,
SyncScope::ID SSID = SyncScope::System, const Twine &Name = "");
};

class AllocaInst final : public UnaryInstruction {
AllocaInst(llvm::AllocaInst *AI, Context &Ctx)
: UnaryInstruction(ClassID::Alloca, Instruction::Opcode::Alloca, AI,
Expand Down Expand Up @@ -1696,6 +1784,8 @@ class Context {
friend CallBrInst; // For createCallBrInst()
GetElementPtrInst *createGetElementPtrInst(llvm::GetElementPtrInst *I);
friend GetElementPtrInst; // For createGetElementPtrInst()
AtomicCmpXchgInst *createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I);
friend AtomicCmpXchgInst; // For createAtomicCmpXchgInst()
AllocaInst *createAllocaInst(llvm::AllocaInst *I);
friend AllocaInst; // For createAllocaInst()
CastInst *createCastInst(llvm::CastInst *I);
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/SandboxIR/SandboxIRValues.def
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ DEF_INSTR(Call, OP(Call), CallInst)
DEF_INSTR(Invoke, OP(Invoke), InvokeInst)
DEF_INSTR(CallBr, OP(CallBr), CallBrInst)
DEF_INSTR(GetElementPtr, OP(GetElementPtr), GetElementPtrInst)
DEF_INSTR(AtomicCmpXchg, OP(AtomicCmpXchg), AtomicCmpXchgInst)
DEF_INSTR(Alloca, OP(Alloca), AllocaInst)
DEF_INSTR(Cast, OPCODES(\
OP(ZExt) \
Expand Down
110 changes: 110 additions & 0 deletions llvm/lib/SandboxIR/SandboxIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1122,6 +1122,104 @@ static llvm::Instruction::CastOps getLLVMCastOp(Instruction::Opcode Opc) {
}
}

void AtomicCmpXchgInst::setSyncScopeID(SyncScope::ID SSID) {
Ctx.getTracker()
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSyncScopeID,
&AtomicCmpXchgInst::setSyncScopeID>>(
this);
cast<llvm::AtomicCmpXchgInst>(Val)->setSyncScopeID(SSID);
}

Value *AtomicCmpXchgInst::getPointerOperand() {
return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getPointerOperand());
}

Value *AtomicCmpXchgInst::getCompareOperand() {
return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getCompareOperand());
}

Value *AtomicCmpXchgInst::getNewValOperand() {
return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getNewValOperand());
}

AtomicCmpXchgInst *
AtomicCmpXchgInst::create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
AtomicOrdering SuccessOrdering,
AtomicOrdering FailureOrdering, BBIterator WhereIt,
BasicBlock *WhereBB, Context &Ctx, SyncScope::ID SSID,
const Twine &Name) {
auto &Builder = Ctx.getLLVMIRBuilder();
if (WhereIt == WhereBB->end())
Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
else
Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
auto *LLVMAtomicCmpXchg =
Builder.CreateAtomicCmpXchg(Ptr->Val, Cmp->Val, New->Val, Align,
SuccessOrdering, FailureOrdering, SSID);
LLVMAtomicCmpXchg->setName(Name);
return Ctx.createAtomicCmpXchgInst(LLVMAtomicCmpXchg);
}

AtomicCmpXchgInst *AtomicCmpXchgInst::create(Value *Ptr, Value *Cmp, Value *New,
MaybeAlign Align,
AtomicOrdering SuccessOrdering,
AtomicOrdering FailureOrdering,
Instruction *InsertBefore,
Context &Ctx, SyncScope::ID SSID,
const Twine &Name) {
return create(Ptr, Cmp, New, Align, SuccessOrdering, FailureOrdering,
InsertBefore->getIterator(), InsertBefore->getParent(), Ctx,
SSID, Name);
}

AtomicCmpXchgInst *AtomicCmpXchgInst::create(Value *Ptr, Value *Cmp, Value *New,
MaybeAlign Align,
AtomicOrdering SuccessOrdering,
AtomicOrdering FailureOrdering,
BasicBlock *InsertAtEnd,
Context &Ctx, SyncScope::ID SSID,
const Twine &Name) {
return create(Ptr, Cmp, New, Align, SuccessOrdering, FailureOrdering,
InsertAtEnd->end(), InsertAtEnd, Ctx, SSID, Name);
}

void AtomicCmpXchgInst::setAlignment(Align Align) {
Ctx.getTracker()
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getAlign,
&AtomicCmpXchgInst::setAlignment>>(this);
cast<llvm::AtomicCmpXchgInst>(Val)->setAlignment(Align);
}

void AtomicCmpXchgInst::setVolatile(bool V) {
Ctx.getTracker()
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isVolatile,
&AtomicCmpXchgInst::setVolatile>>(this);
cast<llvm::AtomicCmpXchgInst>(Val)->setVolatile(V);
}

void AtomicCmpXchgInst::setWeak(bool IsWeak) {
Ctx.getTracker()
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isWeak,
&AtomicCmpXchgInst::setWeak>>(this);
cast<llvm::AtomicCmpXchgInst>(Val)->setWeak(IsWeak);
}

void AtomicCmpXchgInst::setSuccessOrdering(AtomicOrdering Ordering) {
Ctx.getTracker()
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSuccessOrdering,
&AtomicCmpXchgInst::setSuccessOrdering>>(
this);
cast<llvm::AtomicCmpXchgInst>(Val)->setSuccessOrdering(Ordering);
}

void AtomicCmpXchgInst::setFailureOrdering(AtomicOrdering Ordering) {
Ctx.getTracker()
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getFailureOrdering,
&AtomicCmpXchgInst::setFailureOrdering>>(
this);
cast<llvm::AtomicCmpXchgInst>(Val)->setFailureOrdering(Ordering);
}

AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace, BBIterator WhereIt,
BasicBlock *WhereBB, Context &Ctx,
Value *ArraySize, const Twine &Name) {
Expand Down Expand Up @@ -1433,6 +1531,12 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
new GetElementPtrInst(LLVMGEP, *this));
return It->second.get();
}
case llvm::Instruction::AtomicCmpXchg: {
auto *LLVMAtomicCmpXchg = cast<llvm::AtomicCmpXchgInst>(LLVMV);
It->second = std::unique_ptr<AtomicCmpXchgInst>(
new AtomicCmpXchgInst(LLVMAtomicCmpXchg, *this));
return It->second.get();
}
case llvm::Instruction::Alloca: {
auto *LLVMAlloca = cast<llvm::AllocaInst>(LLVMV);
It->second = std::unique_ptr<AllocaInst>(new AllocaInst(LLVMAlloca, *this));
Expand Down Expand Up @@ -1550,6 +1654,12 @@ Context::createGetElementPtrInst(llvm::GetElementPtrInst *I) {
std::unique_ptr<GetElementPtrInst>(new GetElementPtrInst(I, *this));
return cast<GetElementPtrInst>(registerValue(std::move(NewPtr)));
}
AtomicCmpXchgInst *
Context::createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I) {
auto NewPtr =
std::unique_ptr<AtomicCmpXchgInst>(new AtomicCmpXchgInst(I, *this));
return cast<AtomicCmpXchgInst>(registerValue(std::move(NewPtr)));
}
AllocaInst *Context::createAllocaInst(llvm::AllocaInst *I) {
auto NewPtr = std::unique_ptr<AllocaInst>(new AllocaInst(I, *this));
return cast<AllocaInst>(registerValue(std::move(NewPtr)));
Expand Down
Loading

0 comments on commit 00a4042

Please sign in to comment.