Skip to content

Commit d021321

Browse files
authored
[SandboxIR] Implement CleanupReturnInst (#105750)
This patch implements sandboxir::CleanupReturnInst mirroring llvm::CleanupReturnInst.
1 parent e439fdf commit d021321

File tree

5 files changed

+215
-0
lines changed

5 files changed

+215
-0
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class FuncletPadInst;
131131
class CatchPadInst;
132132
class CleanupPadInst;
133133
class CatchReturnInst;
134+
class CleanupReturnInst;
134135
class GetElementPtrInst;
135136
class CastInst;
136137
class PtrToIntInst;
@@ -266,6 +267,7 @@ class Value {
266267
friend class CatchReturnInst; // For getting `Val`.
267268
friend class GetElementPtrInst; // For getting `Val`.
268269
friend class CatchSwitchInst; // For getting `Val`.
270+
friend class CleanupReturnInst; // For getting `Val`.
269271
friend class SwitchInst; // For getting `Val`.
270272
friend class UnaryOperator; // For getting `Val`.
271273
friend class BinaryOperator; // For getting `Val`.
@@ -690,6 +692,7 @@ class Instruction : public sandboxir::User {
690692
friend class CatchPadInst; // For getTopmostLLVMInstruction().
691693
friend class CleanupPadInst; // For getTopmostLLVMInstruction().
692694
friend class CatchReturnInst; // For getTopmostLLVMInstruction().
695+
friend class CleanupReturnInst; // For getTopmostLLVMInstruction().
693696
friend class GetElementPtrInst; // For getTopmostLLVMInstruction().
694697
friend class CatchSwitchInst; // For getTopmostLLVMInstruction().
695698
friend class SwitchInst; // For getTopmostLLVMInstruction().
@@ -1941,6 +1944,36 @@ class CatchReturnInst
19411944
}
19421945
};
19431946

1947+
class CleanupReturnInst
1948+
: public SingleLLVMInstructionImpl<llvm::CleanupReturnInst> {
1949+
CleanupReturnInst(llvm::CleanupReturnInst *CRI, Context &Ctx)
1950+
: SingleLLVMInstructionImpl(ClassID::CleanupRet, Opcode::CleanupRet, CRI,
1951+
Ctx) {}
1952+
friend class Context; // For constructor.
1953+
1954+
public:
1955+
static CleanupReturnInst *create(CleanupPadInst *CleanupPad,
1956+
BasicBlock *UnwindBB, BBIterator WhereIt,
1957+
BasicBlock *WhereBB, Context &Ctx);
1958+
bool hasUnwindDest() const {
1959+
return cast<llvm::CleanupReturnInst>(Val)->hasUnwindDest();
1960+
}
1961+
bool unwindsToCaller() const {
1962+
return cast<llvm::CleanupReturnInst>(Val)->unwindsToCaller();
1963+
}
1964+
CleanupPadInst *getCleanupPad() const;
1965+
void setCleanupPad(CleanupPadInst *CleanupPad);
1966+
unsigned getNumSuccessors() const {
1967+
return cast<llvm::CleanupReturnInst>(Val)->getNumSuccessors();
1968+
}
1969+
BasicBlock *getUnwindDest() const;
1970+
void setUnwindDest(BasicBlock *NewDest);
1971+
1972+
static bool classof(const Value *From) {
1973+
return From->getSubclassID() == ClassID::CleanupRet;
1974+
}
1975+
};
1976+
19441977
class GetElementPtrInst final
19451978
: public SingleLLVMInstructionImpl<llvm::GetElementPtrInst> {
19461979
/// Use Context::createGetElementPtrInst(). Don't call
@@ -2849,6 +2882,8 @@ class Context {
28492882
friend CleanupPadInst; // For createCleanupPadInst()
28502883
CatchReturnInst *createCatchReturnInst(llvm::CatchReturnInst *I);
28512884
friend CatchReturnInst; // For createCatchReturnInst()
2885+
CleanupReturnInst *createCleanupReturnInst(llvm::CleanupReturnInst *I);
2886+
friend CleanupReturnInst; // For createCleanupReturnInst()
28522887
GetElementPtrInst *createGetElementPtrInst(llvm::GetElementPtrInst *I);
28532888
friend GetElementPtrInst; // For createGetElementPtrInst()
28542889
CatchSwitchInst *createCatchSwitchInst(llvm::CatchSwitchInst *I);

llvm/include/llvm/SandboxIR/SandboxIRValues.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ DEF_INSTR(CallBr, OP(CallBr), CallBrInst)
4949
DEF_INSTR(CatchPad, OP(CatchPad), CatchPadInst)
5050
DEF_INSTR(CleanupPad, OP(CleanupPad), CleanupPadInst)
5151
DEF_INSTR(CatchRet, OP(CatchRet), CatchReturnInst)
52+
DEF_INSTR(CleanupRet, OP(CleanupRet), CleanupReturnInst)
5253
DEF_INSTR(GetElementPtr, OP(GetElementPtr), GetElementPtrInst)
5354
DEF_INSTR(CatchSwitch, OP(CatchSwitch), CatchSwitchInst)
5455
DEF_INSTR(Switch, OP(Switch), SwitchInst)

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,51 @@ Value *CatchReturnInst::getCatchSwitchParentPad() const {
11491149
cast<llvm::CatchReturnInst>(Val)->getCatchSwitchParentPad());
11501150
}
11511151

1152+
CleanupReturnInst *CleanupReturnInst::create(CleanupPadInst *CleanupPad,
1153+
BasicBlock *UnwindBB,
1154+
BBIterator WhereIt,
1155+
BasicBlock *WhereBB,
1156+
Context &Ctx) {
1157+
auto &Builder = Ctx.getLLVMIRBuilder();
1158+
if (WhereIt != WhereBB->end())
1159+
Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1160+
else
1161+
Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1162+
auto *LLVMUnwindBB =
1163+
UnwindBB != nullptr ? cast<llvm::BasicBlock>(UnwindBB->Val) : nullptr;
1164+
llvm::CleanupReturnInst *LLVMI = Builder.CreateCleanupRet(
1165+
cast<llvm::CleanupPadInst>(CleanupPad->Val), LLVMUnwindBB);
1166+
return Ctx.createCleanupReturnInst(LLVMI);
1167+
}
1168+
1169+
CleanupPadInst *CleanupReturnInst::getCleanupPad() const {
1170+
return cast<CleanupPadInst>(
1171+
Ctx.getValue(cast<llvm::CleanupReturnInst>(Val)->getCleanupPad()));
1172+
}
1173+
1174+
void CleanupReturnInst::setCleanupPad(CleanupPadInst *CleanupPad) {
1175+
Ctx.getTracker()
1176+
.emplaceIfTracking<GenericSetter<&CleanupReturnInst::getCleanupPad,
1177+
&CleanupReturnInst::setCleanupPad>>(
1178+
this);
1179+
cast<llvm::CleanupReturnInst>(Val)->setCleanupPad(
1180+
cast<llvm::CleanupPadInst>(CleanupPad->Val));
1181+
}
1182+
1183+
BasicBlock *CleanupReturnInst::getUnwindDest() const {
1184+
return cast_or_null<BasicBlock>(
1185+
Ctx.getValue(cast<llvm::CleanupReturnInst>(Val)->getUnwindDest()));
1186+
}
1187+
1188+
void CleanupReturnInst::setUnwindDest(BasicBlock *NewDest) {
1189+
Ctx.getTracker()
1190+
.emplaceIfTracking<GenericSetter<&CleanupReturnInst::getUnwindDest,
1191+
&CleanupReturnInst::setUnwindDest>>(
1192+
this);
1193+
cast<llvm::CleanupReturnInst>(Val)->setUnwindDest(
1194+
cast<llvm::BasicBlock>(NewDest->Val));
1195+
}
1196+
11521197
Value *GetElementPtrInst::create(Type *Ty, Value *Ptr,
11531198
ArrayRef<Value *> IdxList,
11541199
BasicBlock::iterator WhereIt,
@@ -2188,6 +2233,12 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
21882233
std::unique_ptr<CatchReturnInst>(new CatchReturnInst(LLVMCRI, *this));
21892234
return It->second.get();
21902235
}
2236+
case llvm::Instruction::CleanupRet: {
2237+
auto *LLVMCRI = cast<llvm::CleanupReturnInst>(LLVMV);
2238+
It->second = std::unique_ptr<CleanupReturnInst>(
2239+
new CleanupReturnInst(LLVMCRI, *this));
2240+
return It->second.get();
2241+
}
21912242
case llvm::Instruction::GetElementPtr: {
21922243
auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV);
21932244
It->second = std::unique_ptr<GetElementPtrInst>(
@@ -2376,6 +2427,12 @@ CatchReturnInst *Context::createCatchReturnInst(llvm::CatchReturnInst *I) {
23762427
auto NewPtr = std::unique_ptr<CatchReturnInst>(new CatchReturnInst(I, *this));
23772428
return cast<CatchReturnInst>(registerValue(std::move(NewPtr)));
23782429
}
2430+
CleanupReturnInst *
2431+
Context::createCleanupReturnInst(llvm::CleanupReturnInst *I) {
2432+
auto NewPtr =
2433+
std::unique_ptr<CleanupReturnInst>(new CleanupReturnInst(I, *this));
2434+
return cast<CleanupReturnInst>(registerValue(std::move(NewPtr)));
2435+
}
23792436
GetElementPtrInst *
23802437
Context::createGetElementPtrInst(llvm::GetElementPtrInst *I) {
23812438
auto NewPtr =

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2022,6 +2022,77 @@ define void @foo() {
20222022
EXPECT_EQ(CRI->getSuccessor(), Catch);
20232023
}
20242024

2025+
TEST_F(SandboxIRTest, CleanupReturnInst) {
2026+
parseIR(C, R"IR(
2027+
define void @foo() {
2028+
dispatch:
2029+
invoke void @foo()
2030+
to label %throw unwind label %cleanup
2031+
throw:
2032+
ret void
2033+
cleanup:
2034+
%cleanuppad = cleanuppad within none []
2035+
cleanupret from %cleanuppad unwind label %cleanup2
2036+
cleanup2:
2037+
%cleanuppad2 = cleanuppad within none []
2038+
ret void
2039+
}
2040+
)IR");
2041+
Function &LLVMF = *M->getFunction("foo");
2042+
BasicBlock *LLVMCleanup = getBasicBlockByName(LLVMF, "cleanup");
2043+
auto LLVMIt = LLVMCleanup->begin();
2044+
[[maybe_unused]] auto *LLVMCP = cast<llvm::CleanupPadInst>(&*LLVMIt++);
2045+
auto *LLVMCRI = cast<llvm::CleanupReturnInst>(&*LLVMIt++);
2046+
2047+
sandboxir::Context Ctx(C);
2048+
[[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
2049+
auto *Throw = cast<sandboxir::BasicBlock>(
2050+
Ctx.getValue(getBasicBlockByName(LLVMF, "throw")));
2051+
auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCleanup));
2052+
auto *Cleanup2 = cast<sandboxir::BasicBlock>(
2053+
Ctx.getValue(getBasicBlockByName(LLVMF, "cleanup2")));
2054+
auto It = Cleanup->begin();
2055+
[[maybe_unused]] auto *CP = cast<sandboxir::CleanupPadInst>(&*It++);
2056+
auto *CRI = cast<sandboxir::CleanupReturnInst>(&*It++);
2057+
It = Cleanup2->begin();
2058+
auto *CP2 = cast<sandboxir::CleanupPadInst>(&*It++);
2059+
auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
2060+
2061+
// Check hasUnwindDest().
2062+
EXPECT_EQ(CRI->hasUnwindDest(), LLVMCRI->hasUnwindDest());
2063+
// Check unwindsToCaller().
2064+
EXPECT_EQ(CRI->unwindsToCaller(), LLVMCRI->unwindsToCaller());
2065+
// Check getCleanupPad().
2066+
EXPECT_EQ(CRI->getCleanupPad(), Ctx.getValue(LLVMCRI->getCleanupPad()));
2067+
// Check setCleanupPad().
2068+
auto *OrigCleanupPad = CRI->getCleanupPad();
2069+
auto *NewCleanupPad = CP2;
2070+
EXPECT_NE(NewCleanupPad, OrigCleanupPad);
2071+
CRI->setCleanupPad(NewCleanupPad);
2072+
EXPECT_EQ(CRI->getCleanupPad(), NewCleanupPad);
2073+
CRI->setCleanupPad(OrigCleanupPad);
2074+
EXPECT_EQ(CRI->getCleanupPad(), OrigCleanupPad);
2075+
// Check setNumSuccessors().
2076+
EXPECT_EQ(CRI->getNumSuccessors(), LLVMCRI->getNumSuccessors());
2077+
// Check getUnwindDest().
2078+
EXPECT_EQ(CRI->getUnwindDest(), Ctx.getValue(LLVMCRI->getUnwindDest()));
2079+
// Check setUnwindDest().
2080+
auto *OrigUnwindDest = CRI->getUnwindDest();
2081+
auto *NewUnwindDest = Throw;
2082+
EXPECT_NE(NewUnwindDest, OrigUnwindDest);
2083+
CRI->setUnwindDest(NewUnwindDest);
2084+
EXPECT_EQ(CRI->getUnwindDest(), NewUnwindDest);
2085+
CRI->setUnwindDest(OrigUnwindDest);
2086+
EXPECT_EQ(CRI->getUnwindDest(), OrigUnwindDest);
2087+
// Check create().
2088+
auto *UnwindBB = Cleanup;
2089+
auto *NewCRI = sandboxir::CleanupReturnInst::create(
2090+
CP2, UnwindBB, Ret->getIterator(), Ret->getParent(), Ctx);
2091+
EXPECT_EQ(NewCRI->getCleanupPad(), CP2);
2092+
EXPECT_EQ(NewCRI->getUnwindDest(), UnwindBB);
2093+
EXPECT_EQ(NewCRI->getNextNode(), Ret);
2094+
}
2095+
20252096
TEST_F(SandboxIRTest, GetElementPtrInstruction) {
20262097
parseIR(C, R"IR(
20272098
define void @foo(ptr %ptr, <2 x ptr> %ptrs) {

llvm/unittests/SandboxIR/TrackerTest.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,57 @@ define void @foo() {
763763
EXPECT_EQ(CR->getSuccessor(), OrigSucc);
764764
}
765765

766+
TEST_F(TrackerTest, CleanupReturnInstSetters) {
767+
parseIR(C, R"IR(
768+
define void @foo() {
769+
dispatch:
770+
invoke void @foo()
771+
to label %throw unwind label %cleanup
772+
throw:
773+
ret void
774+
cleanup:
775+
%cleanuppad = cleanuppad within none []
776+
cleanupret from %cleanuppad unwind label %cleanup2
777+
cleanup2:
778+
%cleanuppad2 = cleanuppad within none []
779+
ret void
780+
}
781+
)IR");
782+
Function &LLVMF = *M->getFunction("foo");
783+
BasicBlock *LLVMCleanup = getBasicBlockByName(LLVMF, "cleanup");
784+
785+
sandboxir::Context Ctx(C);
786+
[[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
787+
auto *Throw = cast<sandboxir::BasicBlock>(
788+
Ctx.getValue(getBasicBlockByName(LLVMF, "throw")));
789+
auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCleanup));
790+
auto *Cleanup2 = cast<sandboxir::BasicBlock>(
791+
Ctx.getValue(getBasicBlockByName(LLVMF, "cleanup2")));
792+
auto It = Cleanup->begin();
793+
[[maybe_unused]] auto *CP = cast<sandboxir::CleanupPadInst>(&*It++);
794+
auto *CRI = cast<sandboxir::CleanupReturnInst>(&*It++);
795+
auto *CP2 = cast<sandboxir::CleanupPadInst>(&*Cleanup2->begin());
796+
797+
// Check setCleanupPad().
798+
auto *OrigCleanupPad = CRI->getCleanupPad();
799+
auto *NewCleanupPad = CP2;
800+
EXPECT_NE(NewCleanupPad, OrigCleanupPad);
801+
Ctx.save();
802+
CRI->setCleanupPad(NewCleanupPad);
803+
EXPECT_EQ(CRI->getCleanupPad(), NewCleanupPad);
804+
Ctx.revert();
805+
EXPECT_EQ(CRI->getCleanupPad(), OrigCleanupPad);
806+
// Check setUnwindDest().
807+
auto *OrigUnwindDest = CRI->getUnwindDest();
808+
auto *NewUnwindDest = Throw;
809+
EXPECT_NE(NewUnwindDest, OrigUnwindDest);
810+
Ctx.save();
811+
CRI->setUnwindDest(NewUnwindDest);
812+
EXPECT_EQ(CRI->getUnwindDest(), NewUnwindDest);
813+
Ctx.revert();
814+
EXPECT_EQ(CRI->getUnwindDest(), OrigUnwindDest);
815+
}
816+
766817
TEST_F(TrackerTest, SwitchInstSetters) {
767818
parseIR(C, R"IR(
768819
define void @foo(i32 %cond0, i32 %cond1) {

0 commit comments

Comments
 (0)