[llvm] d021321 - [SandboxIR] Implement CleanupReturnInst (#105750)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 23 20:14:00 PDT 2024
Author: vporpo
Date: 2024-08-23T20:13:56-07:00
New Revision: d02132166a6ce56d54d6c8b2ca39e81b6466eb55
URL: https://github.com/llvm/llvm-project/commit/d02132166a6ce56d54d6c8b2ca39e81b6466eb55
DIFF: https://github.com/llvm/llvm-project/commit/d02132166a6ce56d54d6c8b2ca39e81b6466eb55.diff
LOG: [SandboxIR] Implement CleanupReturnInst (#105750)
This patch implements sandboxir::CleanupReturnInst mirroring
llvm::CleanupReturnInst.
Added:
Modified:
llvm/include/llvm/SandboxIR/SandboxIR.h
llvm/include/llvm/SandboxIR/SandboxIRValues.def
llvm/lib/SandboxIR/SandboxIR.cpp
llvm/unittests/SandboxIR/SandboxIRTest.cpp
llvm/unittests/SandboxIR/TrackerTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index c09e167d67bb1c..b8a28669cdd074 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -131,6 +131,7 @@ class FuncletPadInst;
class CatchPadInst;
class CleanupPadInst;
class CatchReturnInst;
+class CleanupReturnInst;
class GetElementPtrInst;
class CastInst;
class PtrToIntInst;
@@ -266,6 +267,7 @@ class Value {
friend class CatchReturnInst; // For getting `Val`.
friend class GetElementPtrInst; // For getting `Val`.
friend class CatchSwitchInst; // For getting `Val`.
+ friend class CleanupReturnInst; // For getting `Val`.
friend class SwitchInst; // For getting `Val`.
friend class UnaryOperator; // For getting `Val`.
friend class BinaryOperator; // For getting `Val`.
@@ -690,6 +692,7 @@ class Instruction : public sandboxir::User {
friend class CatchPadInst; // For getTopmostLLVMInstruction().
friend class CleanupPadInst; // For getTopmostLLVMInstruction().
friend class CatchReturnInst; // For getTopmostLLVMInstruction().
+ friend class CleanupReturnInst; // For getTopmostLLVMInstruction().
friend class GetElementPtrInst; // For getTopmostLLVMInstruction().
friend class CatchSwitchInst; // For getTopmostLLVMInstruction().
friend class SwitchInst; // For getTopmostLLVMInstruction().
@@ -1941,6 +1944,36 @@ class CatchReturnInst
}
};
+class CleanupReturnInst
+ : public SingleLLVMInstructionImpl<llvm::CleanupReturnInst> {
+ CleanupReturnInst(llvm::CleanupReturnInst *CRI, Context &Ctx)
+ : SingleLLVMInstructionImpl(ClassID::CleanupRet, Opcode::CleanupRet, CRI,
+ Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ static CleanupReturnInst *create(CleanupPadInst *CleanupPad,
+ BasicBlock *UnwindBB, BBIterator WhereIt,
+ BasicBlock *WhereBB, Context &Ctx);
+ bool hasUnwindDest() const {
+ return cast<llvm::CleanupReturnInst>(Val)->hasUnwindDest();
+ }
+ bool unwindsToCaller() const {
+ return cast<llvm::CleanupReturnInst>(Val)->unwindsToCaller();
+ }
+ CleanupPadInst *getCleanupPad() const;
+ void setCleanupPad(CleanupPadInst *CleanupPad);
+ unsigned getNumSuccessors() const {
+ return cast<llvm::CleanupReturnInst>(Val)->getNumSuccessors();
+ }
+ BasicBlock *getUnwindDest() const;
+ void setUnwindDest(BasicBlock *NewDest);
+
+ static bool classof(const Value *From) {
+ return From->getSubclassID() == ClassID::CleanupRet;
+ }
+};
+
class GetElementPtrInst final
: public SingleLLVMInstructionImpl<llvm::GetElementPtrInst> {
/// Use Context::createGetElementPtrInst(). Don't call
@@ -2849,6 +2882,8 @@ class Context {
friend CleanupPadInst; // For createCleanupPadInst()
CatchReturnInst *createCatchReturnInst(llvm::CatchReturnInst *I);
friend CatchReturnInst; // For createCatchReturnInst()
+ CleanupReturnInst *createCleanupReturnInst(llvm::CleanupReturnInst *I);
+ friend CleanupReturnInst; // For createCleanupReturnInst()
GetElementPtrInst *createGetElementPtrInst(llvm::GetElementPtrInst *I);
friend GetElementPtrInst; // For createGetElementPtrInst()
CatchSwitchInst *createCatchSwitchInst(llvm::CatchSwitchInst *I);
diff --git a/llvm/include/llvm/SandboxIR/SandboxIRValues.def b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
index b7b396e30dc3ca..14cb2d72ad3af6 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIRValues.def
+++ b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
@@ -49,6 +49,7 @@ DEF_INSTR(CallBr, OP(CallBr), CallBrInst)
DEF_INSTR(CatchPad, OP(CatchPad), CatchPadInst)
DEF_INSTR(CleanupPad, OP(CleanupPad), CleanupPadInst)
DEF_INSTR(CatchRet, OP(CatchRet), CatchReturnInst)
+DEF_INSTR(CleanupRet, OP(CleanupRet), CleanupReturnInst)
DEF_INSTR(GetElementPtr, OP(GetElementPtr), GetElementPtrInst)
DEF_INSTR(CatchSwitch, OP(CatchSwitch), CatchSwitchInst)
DEF_INSTR(Switch, OP(Switch), SwitchInst)
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index b953e68c33180e..f92e9d38125139 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -1149,6 +1149,51 @@ Value *CatchReturnInst::getCatchSwitchParentPad() const {
cast<llvm::CatchReturnInst>(Val)->getCatchSwitchParentPad());
}
+CleanupReturnInst *CleanupReturnInst::create(CleanupPadInst *CleanupPad,
+ BasicBlock *UnwindBB,
+ BBIterator WhereIt,
+ BasicBlock *WhereBB,
+ Context &Ctx) {
+ auto &Builder = Ctx.getLLVMIRBuilder();
+ if (WhereIt != WhereBB->end())
+ Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
+ else
+ Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
+ auto *LLVMUnwindBB =
+ UnwindBB != nullptr ? cast<llvm::BasicBlock>(UnwindBB->Val) : nullptr;
+ llvm::CleanupReturnInst *LLVMI = Builder.CreateCleanupRet(
+ cast<llvm::CleanupPadInst>(CleanupPad->Val), LLVMUnwindBB);
+ return Ctx.createCleanupReturnInst(LLVMI);
+}
+
+CleanupPadInst *CleanupReturnInst::getCleanupPad() const {
+ return cast<CleanupPadInst>(
+ Ctx.getValue(cast<llvm::CleanupReturnInst>(Val)->getCleanupPad()));
+}
+
+void CleanupReturnInst::setCleanupPad(CleanupPadInst *CleanupPad) {
+ Ctx.getTracker()
+ .emplaceIfTracking<GenericSetter<&CleanupReturnInst::getCleanupPad,
+ &CleanupReturnInst::setCleanupPad>>(
+ this);
+ cast<llvm::CleanupReturnInst>(Val)->setCleanupPad(
+ cast<llvm::CleanupPadInst>(CleanupPad->Val));
+}
+
+BasicBlock *CleanupReturnInst::getUnwindDest() const {
+ return cast_or_null<BasicBlock>(
+ Ctx.getValue(cast<llvm::CleanupReturnInst>(Val)->getUnwindDest()));
+}
+
+void CleanupReturnInst::setUnwindDest(BasicBlock *NewDest) {
+ Ctx.getTracker()
+ .emplaceIfTracking<GenericSetter<&CleanupReturnInst::getUnwindDest,
+ &CleanupReturnInst::setUnwindDest>>(
+ this);
+ cast<llvm::CleanupReturnInst>(Val)->setUnwindDest(
+ cast<llvm::BasicBlock>(NewDest->Val));
+}
+
Value *GetElementPtrInst::create(Type *Ty, Value *Ptr,
ArrayRef<Value *> IdxList,
BasicBlock::iterator WhereIt,
@@ -2188,6 +2233,12 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
std::unique_ptr<CatchReturnInst>(new CatchReturnInst(LLVMCRI, *this));
return It->second.get();
}
+ case llvm::Instruction::CleanupRet: {
+ auto *LLVMCRI = cast<llvm::CleanupReturnInst>(LLVMV);
+ It->second = std::unique_ptr<CleanupReturnInst>(
+ new CleanupReturnInst(LLVMCRI, *this));
+ return It->second.get();
+ }
case llvm::Instruction::GetElementPtr: {
auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV);
It->second = std::unique_ptr<GetElementPtrInst>(
@@ -2376,6 +2427,12 @@ CatchReturnInst *Context::createCatchReturnInst(llvm::CatchReturnInst *I) {
auto NewPtr = std::unique_ptr<CatchReturnInst>(new CatchReturnInst(I, *this));
return cast<CatchReturnInst>(registerValue(std::move(NewPtr)));
}
+CleanupReturnInst *
+Context::createCleanupReturnInst(llvm::CleanupReturnInst *I) {
+ auto NewPtr =
+ std::unique_ptr<CleanupReturnInst>(new CleanupReturnInst(I, *this));
+ return cast<CleanupReturnInst>(registerValue(std::move(NewPtr)));
+}
GetElementPtrInst *
Context::createGetElementPtrInst(llvm::GetElementPtrInst *I) {
auto NewPtr =
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 76ca64caeeeb07..83edd954080e9f 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -2022,6 +2022,77 @@ define void @foo() {
EXPECT_EQ(CRI->getSuccessor(), Catch);
}
+TEST_F(SandboxIRTest, CleanupReturnInst) {
+ parseIR(C, R"IR(
+define void @foo() {
+dispatch:
+ invoke void @foo()
+ to label %throw unwind label %cleanup
+throw:
+ ret void
+cleanup:
+ %cleanuppad = cleanuppad within none []
+ cleanupret from %cleanuppad unwind label %cleanup2
+cleanup2:
+ %cleanuppad2 = cleanuppad within none []
+ ret void
+}
+)IR");
+ Function &LLVMF = *M->getFunction("foo");
+ BasicBlock *LLVMCleanup = getBasicBlockByName(LLVMF, "cleanup");
+ auto LLVMIt = LLVMCleanup->begin();
+ [[maybe_unused]] auto *LLVMCP = cast<llvm::CleanupPadInst>(&*LLVMIt++);
+ auto *LLVMCRI = cast<llvm::CleanupReturnInst>(&*LLVMIt++);
+
+ sandboxir::Context Ctx(C);
+ [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
+ auto *Throw = cast<sandboxir::BasicBlock>(
+ Ctx.getValue(getBasicBlockByName(LLVMF, "throw")));
+ auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCleanup));
+ auto *Cleanup2 = cast<sandboxir::BasicBlock>(
+ Ctx.getValue(getBasicBlockByName(LLVMF, "cleanup2")));
+ auto It = Cleanup->begin();
+ [[maybe_unused]] auto *CP = cast<sandboxir::CleanupPadInst>(&*It++);
+ auto *CRI = cast<sandboxir::CleanupReturnInst>(&*It++);
+ It = Cleanup2->begin();
+ auto *CP2 = cast<sandboxir::CleanupPadInst>(&*It++);
+ auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
+
+ // Check hasUnwindDest().
+ EXPECT_EQ(CRI->hasUnwindDest(), LLVMCRI->hasUnwindDest());
+ // Check unwindsToCaller().
+ EXPECT_EQ(CRI->unwindsToCaller(), LLVMCRI->unwindsToCaller());
+ // Check getCleanupPad().
+ EXPECT_EQ(CRI->getCleanupPad(), Ctx.getValue(LLVMCRI->getCleanupPad()));
+ // Check setCleanupPad().
+ auto *OrigCleanupPad = CRI->getCleanupPad();
+ auto *NewCleanupPad = CP2;
+ EXPECT_NE(NewCleanupPad, OrigCleanupPad);
+ CRI->setCleanupPad(NewCleanupPad);
+ EXPECT_EQ(CRI->getCleanupPad(), NewCleanupPad);
+ CRI->setCleanupPad(OrigCleanupPad);
+ EXPECT_EQ(CRI->getCleanupPad(), OrigCleanupPad);
+ // Check setNumSuccessors().
+ EXPECT_EQ(CRI->getNumSuccessors(), LLVMCRI->getNumSuccessors());
+ // Check getUnwindDest().
+ EXPECT_EQ(CRI->getUnwindDest(), Ctx.getValue(LLVMCRI->getUnwindDest()));
+ // Check setUnwindDest().
+ auto *OrigUnwindDest = CRI->getUnwindDest();
+ auto *NewUnwindDest = Throw;
+ EXPECT_NE(NewUnwindDest, OrigUnwindDest);
+ CRI->setUnwindDest(NewUnwindDest);
+ EXPECT_EQ(CRI->getUnwindDest(), NewUnwindDest);
+ CRI->setUnwindDest(OrigUnwindDest);
+ EXPECT_EQ(CRI->getUnwindDest(), OrigUnwindDest);
+ // Check create().
+ auto *UnwindBB = Cleanup;
+ auto *NewCRI = sandboxir::CleanupReturnInst::create(
+ CP2, UnwindBB, Ret->getIterator(), Ret->getParent(), Ctx);
+ EXPECT_EQ(NewCRI->getCleanupPad(), CP2);
+ EXPECT_EQ(NewCRI->getUnwindDest(), UnwindBB);
+ EXPECT_EQ(NewCRI->getNextNode(), Ret);
+}
+
TEST_F(SandboxIRTest, GetElementPtrInstruction) {
parseIR(C, R"IR(
define void @foo(ptr %ptr, <2 x ptr> %ptrs) {
diff --git a/llvm/unittests/SandboxIR/TrackerTest.cpp b/llvm/unittests/SandboxIR/TrackerTest.cpp
index 6614ab7fa248e1..f0d6a0d57b8c3e 100644
--- a/llvm/unittests/SandboxIR/TrackerTest.cpp
+++ b/llvm/unittests/SandboxIR/TrackerTest.cpp
@@ -763,6 +763,57 @@ define void @foo() {
EXPECT_EQ(CR->getSuccessor(), OrigSucc);
}
+TEST_F(TrackerTest, CleanupReturnInstSetters) {
+ parseIR(C, R"IR(
+define void @foo() {
+dispatch:
+ invoke void @foo()
+ to label %throw unwind label %cleanup
+throw:
+ ret void
+cleanup:
+ %cleanuppad = cleanuppad within none []
+ cleanupret from %cleanuppad unwind label %cleanup2
+cleanup2:
+ %cleanuppad2 = cleanuppad within none []
+ ret void
+}
+)IR");
+ Function &LLVMF = *M->getFunction("foo");
+ BasicBlock *LLVMCleanup = getBasicBlockByName(LLVMF, "cleanup");
+
+ sandboxir::Context Ctx(C);
+ [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
+ auto *Throw = cast<sandboxir::BasicBlock>(
+ Ctx.getValue(getBasicBlockByName(LLVMF, "throw")));
+ auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCleanup));
+ auto *Cleanup2 = cast<sandboxir::BasicBlock>(
+ Ctx.getValue(getBasicBlockByName(LLVMF, "cleanup2")));
+ auto It = Cleanup->begin();
+ [[maybe_unused]] auto *CP = cast<sandboxir::CleanupPadInst>(&*It++);
+ auto *CRI = cast<sandboxir::CleanupReturnInst>(&*It++);
+ auto *CP2 = cast<sandboxir::CleanupPadInst>(&*Cleanup2->begin());
+
+ // Check setCleanupPad().
+ auto *OrigCleanupPad = CRI->getCleanupPad();
+ auto *NewCleanupPad = CP2;
+ EXPECT_NE(NewCleanupPad, OrigCleanupPad);
+ Ctx.save();
+ CRI->setCleanupPad(NewCleanupPad);
+ EXPECT_EQ(CRI->getCleanupPad(), NewCleanupPad);
+ Ctx.revert();
+ EXPECT_EQ(CRI->getCleanupPad(), OrigCleanupPad);
+ // Check setUnwindDest().
+ auto *OrigUnwindDest = CRI->getUnwindDest();
+ auto *NewUnwindDest = Throw;
+ EXPECT_NE(NewUnwindDest, OrigUnwindDest);
+ Ctx.save();
+ CRI->setUnwindDest(NewUnwindDest);
+ EXPECT_EQ(CRI->getUnwindDest(), NewUnwindDest);
+ Ctx.revert();
+ EXPECT_EQ(CRI->getUnwindDest(), OrigUnwindDest);
+}
+
TEST_F(TrackerTest, SwitchInstSetters) {
parseIR(C, R"IR(
define void @foo(i32 %cond0, i32 %cond1) {
More information about the llvm-commits
mailing list