Skip to content

[SandboxIR] Implement AtomicCmpXchgInst #102710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading