[llvm] [SandboxIR] Implement FenceInst (PR #105920)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 23 20:23:10 PDT 2024
https://github.com/vporpo created https://github.com/llvm/llvm-project/pull/105920
This patch implements sandboxir::FenceInst mirroring llvm::FenceInst.
>From b682c709c63cf16a2038cd8a26474aa8c2e6c466 Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Thu, 15 Aug 2024 12:39:23 -0700
Subject: [PATCH] [SandboxIR] Implement FenceInst
This patch implements sandboxir::FenceInst mirroring llvm::FenceInst.
---
llvm/include/llvm/SandboxIR/SandboxIR.h | 32 +++++++++++++
.../llvm/SandboxIR/SandboxIRValues.def | 1 +
llvm/lib/SandboxIR/SandboxIR.cpp | 37 +++++++++++++++
llvm/unittests/SandboxIR/SandboxIRTest.cpp | 46 +++++++++++++++++++
llvm/unittests/SandboxIR/TrackerTest.cpp | 34 ++++++++++++++
5 files changed, 150 insertions(+)
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index b8a28669cdd074..32e23ddfcafeed 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -111,6 +111,7 @@ class ConstantInt;
class Context;
class Function;
class Instruction;
+class FenceInst;
class SelectInst;
class ExtractElementInst;
class InsertElementInst;
@@ -249,6 +250,7 @@ class Value {
friend class Context; // For getting `Val`.
friend class User; // For getting `Val`.
friend class Use; // For getting `Val`.
+ friend class FenceInst; // For getting `Val`.
friend class SelectInst; // For getting `Val`.
friend class ExtractElementInst; // For getting `Val`.
friend class InsertElementInst; // For getting `Val`.
@@ -678,6 +680,7 @@ class Instruction : public sandboxir::User {
/// A SandboxIR Instruction may map to multiple LLVM IR Instruction. This
/// returns its topmost LLVM IR instruction.
llvm::Instruction *getTopmostLLVMInstruction() const;
+ friend class FenceInst; // For getTopmostLLVMInstruction().
friend class SelectInst; // For getTopmostLLVMInstruction().
friend class ExtractElementInst; // For getTopmostLLVMInstruction().
friend class InsertElementInst; // For getTopmostLLVMInstruction().
@@ -882,6 +885,33 @@ template <typename LLVMT> class SingleLLVMInstructionImpl : public Instruction {
#endif
};
+class FenceInst : public SingleLLVMInstructionImpl<llvm::SelectInst> {
+ FenceInst(llvm::FenceInst *FI, Context &Ctx)
+ : SingleLLVMInstructionImpl(ClassID::Fence, Opcode::Fence, FI, Ctx) {}
+ friend Context; // For constructor;
+
+public:
+ static FenceInst *create(AtomicOrdering Ordering, BBIterator WhereIt,
+ BasicBlock *WhereBB, Context &Ctx,
+ SyncScope::ID SSID = SyncScope::System);
+ /// Returns the ordering constraint of this fence instruction.
+ AtomicOrdering getOrdering() const {
+ return cast<llvm::FenceInst>(Val)->getOrdering();
+ }
+ /// Sets the ordering constraint of this fence instruction. May only be
+ /// Acquire, Release, AcquireRelease, or SequentiallyConsistent.
+ void setOrdering(AtomicOrdering Ordering);
+ /// Returns the synchronization scope ID of this fence instruction.
+ SyncScope::ID getSyncScopeID() const {
+ return cast<llvm::FenceInst>(Val)->getSyncScopeID();
+ }
+ /// Sets the synchronization scope ID of this fence instruction.
+ void setSyncScopeID(SyncScope::ID SSID);
+ static bool classof(const Value *From) {
+ return From->getSubclassID() == ClassID::Fence;
+ }
+};
+
class SelectInst : public SingleLLVMInstructionImpl<llvm::SelectInst> {
/// Use Context::createSelectInst(). Don't call the
/// constructor directly.
@@ -2854,6 +2884,8 @@ class Context {
IRBuilder<ConstantFolder> LLVMIRBuilder;
auto &getLLVMIRBuilder() { return LLVMIRBuilder; }
+ FenceInst *createFenceInst(llvm::FenceInst *SI);
+ friend FenceInst; // For createFenceInst()
SelectInst *createSelectInst(llvm::SelectInst *SI);
friend SelectInst; // For createSelectInst()
InsertElementInst *createInsertElementInst(llvm::InsertElementInst *IEI);
diff --git a/llvm/include/llvm/SandboxIR/SandboxIRValues.def b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
index 14cb2d72ad3af6..7bac00fb2918a4 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIRValues.def
+++ b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
@@ -37,6 +37,7 @@ DEF_USER(ConstantInt, ConstantInt)
DEF_INSTR(Opaque, OP(Opaque), OpaqueInst)
DEF_INSTR(ExtractElement, OP(ExtractElement), ExtractElementInst)
DEF_INSTR(InsertElement, OP(InsertElement), InsertElementInst)
+DEF_INSTR(Fence, OP(Fence), FenceInst)
DEF_INSTR(ShuffleVector, OP(ShuffleVector), ShuffleVectorInst)
DEF_INSTR(Select, OP(Select), SelectInst)
DEF_INSTR(Br, OP(Br), BranchInst)
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index f92e9d38125139..559fb4d10fff52 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -575,6 +575,33 @@ void Instruction::dumpOS(raw_ostream &OS) const {
}
#endif // NDEBUG
+FenceInst *FenceInst::create(AtomicOrdering Ordering, BBIterator WhereIt,
+ BasicBlock *WhereBB, Context &Ctx,
+ SyncScope::ID SSID) {
+ auto &Builder = Ctx.getLLVMIRBuilder();
+ if (WhereIt != WhereBB->end())
+ Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
+ else
+ Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
+ llvm::FenceInst *LLVMI = Builder.CreateFence(Ordering, SSID);
+ return Ctx.createFenceInst(LLVMI);
+}
+
+void FenceInst::setOrdering(AtomicOrdering Ordering) {
+ Ctx.getTracker()
+ .emplaceIfTracking<
+ GenericSetter<&FenceInst::getOrdering, &FenceInst::setOrdering>>(
+ this);
+ cast<llvm::FenceInst>(Val)->setOrdering(Ordering);
+}
+
+void FenceInst::setSyncScopeID(SyncScope::ID SSID) {
+ Ctx.getTracker()
+ .emplaceIfTracking<GenericSetter<&FenceInst::getSyncScopeID,
+ &FenceInst::setSyncScopeID>>(this);
+ cast<llvm::FenceInst>(Val)->setSyncScopeID(SSID);
+}
+
Value *SelectInst::createCommon(Value *Cond, Value *True, Value *False,
const Twine &Name, IRBuilder<> &Builder,
Context &Ctx) {
@@ -2157,6 +2184,11 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction");
switch (cast<llvm::Instruction>(LLVMV)->getOpcode()) {
+ case llvm::Instruction::Fence: {
+ auto *LLVMFence = cast<llvm::FenceInst>(LLVMV);
+ It->second = std::unique_ptr<FenceInst>(new FenceInst(LLVMFence, *this));
+ return It->second.get();
+ }
case llvm::Instruction::Select: {
auto *LLVMSel = cast<llvm::SelectInst>(LLVMV);
It->second = std::unique_ptr<SelectInst>(new SelectInst(LLVMSel, *this));
@@ -2349,6 +2381,11 @@ BasicBlock *Context::createBasicBlock(llvm::BasicBlock *LLVMBB) {
return BB;
}
+FenceInst *Context::createFenceInst(llvm::FenceInst *SI) {
+ auto NewPtr = std::unique_ptr<FenceInst>(new FenceInst(SI, *this));
+ return cast<FenceInst>(registerValue(std::move(NewPtr)));
+}
+
SelectInst *Context::createSelectInst(llvm::SelectInst *SI) {
auto NewPtr = std::unique_ptr<SelectInst>(new SelectInst(SI, *this));
return cast<SelectInst>(registerValue(std::move(NewPtr)));
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 83edd954080e9f..a7192ac98af41a 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -580,6 +580,52 @@ define void @foo(i8 %v1) {
EXPECT_EQ(I0->getNextNode(), Ret);
}
+TEST_F(SandboxIRTest, FenceInst) {
+ parseIR(C, R"IR(
+define void @foo() {
+ fence syncscope("singlethread") seq_cst
+ ret void
+}
+)IR");
+ llvm::Function *LLVMF = &*M->getFunction("foo");
+ llvm::BasicBlock *LLVMBB = &*LLVMF->begin();
+ auto *LLVMFence = cast<llvm::FenceInst>(&*LLVMBB->begin());
+ sandboxir::Context Ctx(C);
+ sandboxir::Function *F = Ctx.createFunction(LLVMF);
+ auto *BB = &*F->begin();
+ auto It = BB->begin();
+ auto *Fence = cast<sandboxir::FenceInst>(&*It++);
+ auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
+
+ // Check getOrdering().
+ EXPECT_EQ(Fence->getOrdering(), LLVMFence->getOrdering());
+ // Check setOrdering().
+ auto OrigOrdering = Fence->getOrdering();
+ auto NewOrdering = AtomicOrdering::Release;
+ EXPECT_NE(NewOrdering, OrigOrdering);
+ Fence->setOrdering(NewOrdering);
+ EXPECT_EQ(Fence->getOrdering(), NewOrdering);
+ Fence->setOrdering(OrigOrdering);
+ EXPECT_EQ(Fence->getOrdering(), OrigOrdering);
+ // Check getSyncScopeID().
+ EXPECT_EQ(Fence->getSyncScopeID(), LLVMFence->getSyncScopeID());
+ // Check setSyncScopeID().
+ auto OrigSSID = Fence->getSyncScopeID();
+ auto NewSSID = SyncScope::System;
+ EXPECT_NE(NewSSID, OrigSSID);
+ Fence->setSyncScopeID(NewSSID);
+ EXPECT_EQ(Fence->getSyncScopeID(), NewSSID);
+ Fence->setSyncScopeID(OrigSSID);
+ EXPECT_EQ(Fence->getSyncScopeID(), OrigSSID);
+ // Check create().
+ auto *NewFence =
+ sandboxir::FenceInst::create(AtomicOrdering::Release, Ret->getIterator(),
+ BB, Ctx, SyncScope::SingleThread);
+ EXPECT_EQ(NewFence->getNextNode(), Ret);
+ EXPECT_EQ(NewFence->getOrdering(), AtomicOrdering::Release);
+ EXPECT_EQ(NewFence->getSyncScopeID(), SyncScope::SingleThread);
+}
+
TEST_F(SandboxIRTest, SelectInst) {
parseIR(C, R"IR(
define void @foo(i1 %c0, i8 %v0, i8 %v1, i1 %c1) {
diff --git a/llvm/unittests/SandboxIR/TrackerTest.cpp b/llvm/unittests/SandboxIR/TrackerTest.cpp
index f0d6a0d57b8c3e..5f04cbd5840ba5 100644
--- a/llvm/unittests/SandboxIR/TrackerTest.cpp
+++ b/llvm/unittests/SandboxIR/TrackerTest.cpp
@@ -542,6 +542,40 @@ define void @foo(ptr %ptr) {
EXPECT_EQ(It, BB->end());
}
+TEST_F(TrackerTest, FenceInstSetters) {
+ parseIR(C, R"IR(
+define void @foo() {
+ fence syncscope("singlethread") seq_cst
+ ret void
+}
+)IR");
+ llvm::Function *LLVMF = &*M->getFunction("foo");
+ sandboxir::Context Ctx(C);
+ sandboxir::Function *F = Ctx.createFunction(LLVMF);
+ auto *BB = &*F->begin();
+ auto It = BB->begin();
+ auto *Fence = cast<sandboxir::FenceInst>(&*It++);
+
+ // Check setOrdering().
+ auto OrigOrdering = Fence->getOrdering();
+ auto NewOrdering = AtomicOrdering::Release;
+ EXPECT_NE(NewOrdering, OrigOrdering);
+ Ctx.save();
+ Fence->setOrdering(NewOrdering);
+ EXPECT_EQ(Fence->getOrdering(), NewOrdering);
+ Ctx.revert();
+ EXPECT_EQ(Fence->getOrdering(), OrigOrdering);
+ // Check setSyncScopeID().
+ auto OrigSSID = Fence->getSyncScopeID();
+ auto NewSSID = SyncScope::System;
+ EXPECT_NE(NewSSID, OrigSSID);
+ Ctx.save();
+ Fence->setSyncScopeID(NewSSID);
+ EXPECT_EQ(Fence->getSyncScopeID(), NewSSID);
+ Ctx.revert();
+ EXPECT_EQ(Fence->getSyncScopeID(), OrigSSID);
+}
+
TEST_F(TrackerTest, CallBaseSetters) {
parseIR(C, R"IR(
declare void @bar1(i8)
More information about the llvm-commits
mailing list