Skip to content

Commit d88876e

Browse files
authored
[SandboxIR] Implement FenceInst (#105920)
This patch implements sandboxir::FenceInst mirroring llvm::FenceInst.
1 parent 9b00ef5 commit d88876e

File tree

5 files changed

+150
-0
lines changed

5 files changed

+150
-0
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ class ConstantInt;
111111
class Context;
112112
class Function;
113113
class Instruction;
114+
class FenceInst;
114115
class SelectInst;
115116
class ExtractElementInst;
116117
class InsertElementInst;
@@ -249,6 +250,7 @@ class Value {
249250
friend class Context; // For getting `Val`.
250251
friend class User; // For getting `Val`.
251252
friend class Use; // For getting `Val`.
253+
friend class FenceInst; // For getting `Val`.
252254
friend class SelectInst; // For getting `Val`.
253255
friend class ExtractElementInst; // For getting `Val`.
254256
friend class InsertElementInst; // For getting `Val`.
@@ -678,6 +680,7 @@ class Instruction : public sandboxir::User {
678680
/// A SandboxIR Instruction may map to multiple LLVM IR Instruction. This
679681
/// returns its topmost LLVM IR instruction.
680682
llvm::Instruction *getTopmostLLVMInstruction() const;
683+
friend class FenceInst; // For getTopmostLLVMInstruction().
681684
friend class SelectInst; // For getTopmostLLVMInstruction().
682685
friend class ExtractElementInst; // For getTopmostLLVMInstruction().
683686
friend class InsertElementInst; // For getTopmostLLVMInstruction().
@@ -882,6 +885,33 @@ template <typename LLVMT> class SingleLLVMInstructionImpl : public Instruction {
882885
#endif
883886
};
884887

888+
class FenceInst : public SingleLLVMInstructionImpl<llvm::SelectInst> {
889+
FenceInst(llvm::FenceInst *FI, Context &Ctx)
890+
: SingleLLVMInstructionImpl(ClassID::Fence, Opcode::Fence, FI, Ctx) {}
891+
friend Context; // For constructor;
892+
893+
public:
894+
static FenceInst *create(AtomicOrdering Ordering, BBIterator WhereIt,
895+
BasicBlock *WhereBB, Context &Ctx,
896+
SyncScope::ID SSID = SyncScope::System);
897+
/// Returns the ordering constraint of this fence instruction.
898+
AtomicOrdering getOrdering() const {
899+
return cast<llvm::FenceInst>(Val)->getOrdering();
900+
}
901+
/// Sets the ordering constraint of this fence instruction. May only be
902+
/// Acquire, Release, AcquireRelease, or SequentiallyConsistent.
903+
void setOrdering(AtomicOrdering Ordering);
904+
/// Returns the synchronization scope ID of this fence instruction.
905+
SyncScope::ID getSyncScopeID() const {
906+
return cast<llvm::FenceInst>(Val)->getSyncScopeID();
907+
}
908+
/// Sets the synchronization scope ID of this fence instruction.
909+
void setSyncScopeID(SyncScope::ID SSID);
910+
static bool classof(const Value *From) {
911+
return From->getSubclassID() == ClassID::Fence;
912+
}
913+
};
914+
885915
class SelectInst : public SingleLLVMInstructionImpl<llvm::SelectInst> {
886916
/// Use Context::createSelectInst(). Don't call the
887917
/// constructor directly.
@@ -2854,6 +2884,8 @@ class Context {
28542884
IRBuilder<ConstantFolder> LLVMIRBuilder;
28552885
auto &getLLVMIRBuilder() { return LLVMIRBuilder; }
28562886

2887+
FenceInst *createFenceInst(llvm::FenceInst *SI);
2888+
friend FenceInst; // For createFenceInst()
28572889
SelectInst *createSelectInst(llvm::SelectInst *SI);
28582890
friend SelectInst; // For createSelectInst()
28592891
InsertElementInst *createInsertElementInst(llvm::InsertElementInst *IEI);

llvm/include/llvm/SandboxIR/SandboxIRValues.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ DEF_USER(ConstantInt, ConstantInt)
3737
DEF_INSTR(Opaque, OP(Opaque), OpaqueInst)
3838
DEF_INSTR(ExtractElement, OP(ExtractElement), ExtractElementInst)
3939
DEF_INSTR(InsertElement, OP(InsertElement), InsertElementInst)
40+
DEF_INSTR(Fence, OP(Fence), FenceInst)
4041
DEF_INSTR(ShuffleVector, OP(ShuffleVector), ShuffleVectorInst)
4142
DEF_INSTR(Select, OP(Select), SelectInst)
4243
DEF_INSTR(Br, OP(Br), BranchInst)

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,33 @@ void Instruction::dumpOS(raw_ostream &OS) const {
575575
}
576576
#endif // NDEBUG
577577

578+
FenceInst *FenceInst::create(AtomicOrdering Ordering, BBIterator WhereIt,
579+
BasicBlock *WhereBB, Context &Ctx,
580+
SyncScope::ID SSID) {
581+
auto &Builder = Ctx.getLLVMIRBuilder();
582+
if (WhereIt != WhereBB->end())
583+
Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
584+
else
585+
Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
586+
llvm::FenceInst *LLVMI = Builder.CreateFence(Ordering, SSID);
587+
return Ctx.createFenceInst(LLVMI);
588+
}
589+
590+
void FenceInst::setOrdering(AtomicOrdering Ordering) {
591+
Ctx.getTracker()
592+
.emplaceIfTracking<
593+
GenericSetter<&FenceInst::getOrdering, &FenceInst::setOrdering>>(
594+
this);
595+
cast<llvm::FenceInst>(Val)->setOrdering(Ordering);
596+
}
597+
598+
void FenceInst::setSyncScopeID(SyncScope::ID SSID) {
599+
Ctx.getTracker()
600+
.emplaceIfTracking<GenericSetter<&FenceInst::getSyncScopeID,
601+
&FenceInst::setSyncScopeID>>(this);
602+
cast<llvm::FenceInst>(Val)->setSyncScopeID(SSID);
603+
}
604+
578605
Value *SelectInst::createCommon(Value *Cond, Value *True, Value *False,
579606
const Twine &Name, IRBuilder<> &Builder,
580607
Context &Ctx) {
@@ -2157,6 +2184,11 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
21572184
assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction");
21582185

21592186
switch (cast<llvm::Instruction>(LLVMV)->getOpcode()) {
2187+
case llvm::Instruction::Fence: {
2188+
auto *LLVMFence = cast<llvm::FenceInst>(LLVMV);
2189+
It->second = std::unique_ptr<FenceInst>(new FenceInst(LLVMFence, *this));
2190+
return It->second.get();
2191+
}
21602192
case llvm::Instruction::Select: {
21612193
auto *LLVMSel = cast<llvm::SelectInst>(LLVMV);
21622194
It->second = std::unique_ptr<SelectInst>(new SelectInst(LLVMSel, *this));
@@ -2349,6 +2381,11 @@ BasicBlock *Context::createBasicBlock(llvm::BasicBlock *LLVMBB) {
23492381
return BB;
23502382
}
23512383

2384+
FenceInst *Context::createFenceInst(llvm::FenceInst *SI) {
2385+
auto NewPtr = std::unique_ptr<FenceInst>(new FenceInst(SI, *this));
2386+
return cast<FenceInst>(registerValue(std::move(NewPtr)));
2387+
}
2388+
23522389
SelectInst *Context::createSelectInst(llvm::SelectInst *SI) {
23532390
auto NewPtr = std::unique_ptr<SelectInst>(new SelectInst(SI, *this));
23542391
return cast<SelectInst>(registerValue(std::move(NewPtr)));

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,52 @@ define void @foo(i8 %v1) {
580580
EXPECT_EQ(I0->getNextNode(), Ret);
581581
}
582582

583+
TEST_F(SandboxIRTest, FenceInst) {
584+
parseIR(C, R"IR(
585+
define void @foo() {
586+
fence syncscope("singlethread") seq_cst
587+
ret void
588+
}
589+
)IR");
590+
llvm::Function *LLVMF = &*M->getFunction("foo");
591+
llvm::BasicBlock *LLVMBB = &*LLVMF->begin();
592+
auto *LLVMFence = cast<llvm::FenceInst>(&*LLVMBB->begin());
593+
sandboxir::Context Ctx(C);
594+
sandboxir::Function *F = Ctx.createFunction(LLVMF);
595+
auto *BB = &*F->begin();
596+
auto It = BB->begin();
597+
auto *Fence = cast<sandboxir::FenceInst>(&*It++);
598+
auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
599+
600+
// Check getOrdering().
601+
EXPECT_EQ(Fence->getOrdering(), LLVMFence->getOrdering());
602+
// Check setOrdering().
603+
auto OrigOrdering = Fence->getOrdering();
604+
auto NewOrdering = AtomicOrdering::Release;
605+
EXPECT_NE(NewOrdering, OrigOrdering);
606+
Fence->setOrdering(NewOrdering);
607+
EXPECT_EQ(Fence->getOrdering(), NewOrdering);
608+
Fence->setOrdering(OrigOrdering);
609+
EXPECT_EQ(Fence->getOrdering(), OrigOrdering);
610+
// Check getSyncScopeID().
611+
EXPECT_EQ(Fence->getSyncScopeID(), LLVMFence->getSyncScopeID());
612+
// Check setSyncScopeID().
613+
auto OrigSSID = Fence->getSyncScopeID();
614+
auto NewSSID = SyncScope::System;
615+
EXPECT_NE(NewSSID, OrigSSID);
616+
Fence->setSyncScopeID(NewSSID);
617+
EXPECT_EQ(Fence->getSyncScopeID(), NewSSID);
618+
Fence->setSyncScopeID(OrigSSID);
619+
EXPECT_EQ(Fence->getSyncScopeID(), OrigSSID);
620+
// Check create().
621+
auto *NewFence =
622+
sandboxir::FenceInst::create(AtomicOrdering::Release, Ret->getIterator(),
623+
BB, Ctx, SyncScope::SingleThread);
624+
EXPECT_EQ(NewFence->getNextNode(), Ret);
625+
EXPECT_EQ(NewFence->getOrdering(), AtomicOrdering::Release);
626+
EXPECT_EQ(NewFence->getSyncScopeID(), SyncScope::SingleThread);
627+
}
628+
583629
TEST_F(SandboxIRTest, SelectInst) {
584630
parseIR(C, R"IR(
585631
define void @foo(i1 %c0, i8 %v0, i8 %v1, i1 %c1) {

llvm/unittests/SandboxIR/TrackerTest.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,40 @@ define void @foo(ptr %ptr) {
542542
EXPECT_EQ(It, BB->end());
543543
}
544544

545+
TEST_F(TrackerTest, FenceInstSetters) {
546+
parseIR(C, R"IR(
547+
define void @foo() {
548+
fence syncscope("singlethread") seq_cst
549+
ret void
550+
}
551+
)IR");
552+
llvm::Function *LLVMF = &*M->getFunction("foo");
553+
sandboxir::Context Ctx(C);
554+
sandboxir::Function *F = Ctx.createFunction(LLVMF);
555+
auto *BB = &*F->begin();
556+
auto It = BB->begin();
557+
auto *Fence = cast<sandboxir::FenceInst>(&*It++);
558+
559+
// Check setOrdering().
560+
auto OrigOrdering = Fence->getOrdering();
561+
auto NewOrdering = AtomicOrdering::Release;
562+
EXPECT_NE(NewOrdering, OrigOrdering);
563+
Ctx.save();
564+
Fence->setOrdering(NewOrdering);
565+
EXPECT_EQ(Fence->getOrdering(), NewOrdering);
566+
Ctx.revert();
567+
EXPECT_EQ(Fence->getOrdering(), OrigOrdering);
568+
// Check setSyncScopeID().
569+
auto OrigSSID = Fence->getSyncScopeID();
570+
auto NewSSID = SyncScope::System;
571+
EXPECT_NE(NewSSID, OrigSSID);
572+
Ctx.save();
573+
Fence->setSyncScopeID(NewSSID);
574+
EXPECT_EQ(Fence->getSyncScopeID(), NewSSID);
575+
Ctx.revert();
576+
EXPECT_EQ(Fence->getSyncScopeID(), OrigSSID);
577+
}
578+
545579
TEST_F(TrackerTest, CallBaseSetters) {
546580
parseIR(C, R"IR(
547581
declare void @bar1(i8)

0 commit comments

Comments
 (0)