Skip to content

Commit c664d7d

Browse files
authored
[SandboxIR] Implement ResumeInst (#106152)
This patch implements sandboxir::ResumeInst mirroring llvm::ResumeInst.
1 parent 9671ed1 commit c664d7d

File tree

4 files changed

+86
-0
lines changed

4 files changed

+86
-0
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ class PossiblyNonNegInst;
141141
class PtrToIntInst;
142142
class BitCastInst;
143143
class AllocaInst;
144+
class ResumeInst;
144145
class CatchSwitchInst;
145146
class SwitchInst;
146147
class UnaryOperator;
@@ -274,6 +275,7 @@ class Value {
274275
friend class CleanupPadInst; // For getting `Val`.
275276
friend class CatchReturnInst; // For getting `Val`.
276277
friend class GetElementPtrInst; // For getting `Val`.
278+
friend class ResumeInst; // For getting `Val`.
277279
friend class CatchSwitchInst; // For getting `Val`.
278280
friend class CleanupReturnInst; // For getting `Val`.
279281
friend class SwitchInst; // For getting `Val`.
@@ -705,6 +707,7 @@ class Instruction : public sandboxir::User {
705707
friend class CatchReturnInst; // For getTopmostLLVMInstruction().
706708
friend class CleanupReturnInst; // For getTopmostLLVMInstruction().
707709
friend class GetElementPtrInst; // For getTopmostLLVMInstruction().
710+
friend class ResumeInst; // For getTopmostLLVMInstruction().
708711
friend class CatchSwitchInst; // For getTopmostLLVMInstruction().
709712
friend class SwitchInst; // For getTopmostLLVMInstruction().
710713
friend class UnaryOperator; // For getTopmostLLVMInstruction().
@@ -2249,6 +2252,22 @@ class CatchSwitchInst
22492252
}
22502253
};
22512254

2255+
class ResumeInst : public SingleLLVMInstructionImpl<llvm::ResumeInst> {
2256+
public:
2257+
ResumeInst(llvm::ResumeInst *CSI, Context &Ctx)
2258+
: SingleLLVMInstructionImpl(ClassID::Resume, Opcode::Resume, CSI, Ctx) {}
2259+
2260+
static ResumeInst *create(Value *Exn, BBIterator WhereIt, BasicBlock *WhereBB,
2261+
Context &Ctx);
2262+
Value *getValue() const;
2263+
unsigned getNumSuccessors() const {
2264+
return cast<llvm::ResumeInst>(Val)->getNumSuccessors();
2265+
}
2266+
static bool classof(const Value *From) {
2267+
return From->getSubclassID() == ClassID::Resume;
2268+
}
2269+
};
2270+
22522271
class SwitchInst : public SingleLLVMInstructionImpl<llvm::SwitchInst> {
22532272
public:
22542273
SwitchInst(llvm::SwitchInst *SI, Context &Ctx)
@@ -3027,6 +3046,8 @@ class Context {
30273046
friend GetElementPtrInst; // For createGetElementPtrInst()
30283047
CatchSwitchInst *createCatchSwitchInst(llvm::CatchSwitchInst *I);
30293048
friend CatchSwitchInst; // For createCatchSwitchInst()
3049+
ResumeInst *createResumeInst(llvm::ResumeInst *I);
3050+
friend ResumeInst; // For createResumeInst()
30303051
SwitchInst *createSwitchInst(llvm::SwitchInst *I);
30313052
friend SwitchInst; // For createSwitchInst()
30323053
UnaryOperator *createUnaryOperator(llvm::UnaryOperator *I);

llvm/include/llvm/SandboxIR/SandboxIRValues.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ DEF_INSTR(CleanupPad, OP(CleanupPad), CleanupPadInst)
5454
DEF_INSTR(CatchRet, OP(CatchRet), CatchReturnInst)
5555
DEF_INSTR(CleanupRet, OP(CleanupRet), CleanupReturnInst)
5656
DEF_INSTR(GetElementPtr, OP(GetElementPtr), GetElementPtrInst)
57+
DEF_INSTR(Resume, OP(Resume), ResumeInst)
5758
DEF_INSTR(CatchSwitch, OP(CatchSwitch), CatchSwitchInst)
5859
DEF_INSTR(Switch, OP(Switch), SwitchInst)
5960
DEF_INSTR(UnOp, OPCODES( \

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,6 +1496,21 @@ void CatchSwitchInst::addHandler(BasicBlock *Dest) {
14961496
cast<llvm::BasicBlock>(Dest->Val));
14971497
}
14981498

1499+
ResumeInst *ResumeInst::create(Value *Exn, BBIterator WhereIt,
1500+
BasicBlock *WhereBB, Context &Ctx) {
1501+
auto &Builder = Ctx.getLLVMIRBuilder();
1502+
if (WhereIt != WhereBB->end())
1503+
Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1504+
else
1505+
Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1506+
auto *LLVMI = cast<llvm::ResumeInst>(Builder.CreateResume(Exn->Val));
1507+
return Ctx.createResumeInst(LLVMI);
1508+
}
1509+
1510+
Value *ResumeInst::getValue() const {
1511+
return Ctx.getValue(cast<llvm::ResumeInst>(Val)->getValue());
1512+
}
1513+
14991514
SwitchInst *SwitchInst::create(Value *V, BasicBlock *Dest, unsigned NumCases,
15001515
BasicBlock::iterator WhereIt,
15011516
BasicBlock *WhereBB, Context &Ctx,
@@ -2346,6 +2361,12 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
23462361
new CatchSwitchInst(LLVMCatchSwitchInst, *this));
23472362
return It->second.get();
23482363
}
2364+
case llvm::Instruction::Resume: {
2365+
auto *LLVMResumeInst = cast<llvm::ResumeInst>(LLVMV);
2366+
It->second =
2367+
std::unique_ptr<ResumeInst>(new ResumeInst(LLVMResumeInst, *this));
2368+
return It->second.get();
2369+
}
23492370
case llvm::Instruction::Switch: {
23502371
auto *LLVMSwitchInst = cast<llvm::SwitchInst>(LLVMV);
23512372
It->second =
@@ -2552,6 +2573,10 @@ CatchSwitchInst *Context::createCatchSwitchInst(llvm::CatchSwitchInst *I) {
25522573
auto NewPtr = std::unique_ptr<CatchSwitchInst>(new CatchSwitchInst(I, *this));
25532574
return cast<CatchSwitchInst>(registerValue(std::move(NewPtr)));
25542575
}
2576+
ResumeInst *Context::createResumeInst(llvm::ResumeInst *I) {
2577+
auto NewPtr = std::unique_ptr<ResumeInst>(new ResumeInst(I, *this));
2578+
return cast<ResumeInst>(registerValue(std::move(NewPtr)));
2579+
}
25552580
SwitchInst *Context::createSwitchInst(llvm::SwitchInst *I) {
25562581
auto NewPtr = std::unique_ptr<SwitchInst>(new SwitchInst(I, *this));
25572582
return cast<SwitchInst>(registerValue(std::move(NewPtr)));

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2523,6 +2523,45 @@ define void @foo(i32 %cond0, i32 %cond1) {
25232523
EXPECT_EQ(NewCSI->getParentPad(), CS0);
25242524
}
25252525

2526+
TEST_F(SandboxIRTest, ResumeInst) {
2527+
parseIR(C, R"IR(
2528+
define void @foo() {
2529+
entry:
2530+
invoke void @foo()
2531+
to label %bb unwind label %unwind
2532+
bb:
2533+
ret void
2534+
unwind:
2535+
%lpad = landingpad { ptr, i32 }
2536+
cleanup
2537+
resume { ptr, i32 } %lpad
2538+
}
2539+
)IR");
2540+
Function &LLVMF = *M->getFunction("foo");
2541+
auto *LLVMUnwindBB = getBasicBlockByName(LLVMF, "unwind");
2542+
auto LLVMIt = LLVMUnwindBB->begin();
2543+
[[maybe_unused]] auto *LLVMLPad = cast<llvm::LandingPadInst>(&*LLVMIt++);
2544+
auto *LLVMResume = cast<llvm::ResumeInst>(&*LLVMIt++);
2545+
2546+
sandboxir::Context Ctx(C);
2547+
[[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
2548+
auto *UnwindBB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMUnwindBB));
2549+
auto It = UnwindBB->begin();
2550+
auto *LPad = cast<sandboxir::LandingPadInst>(&*It++);
2551+
auto *Resume = cast<sandboxir::ResumeInst>(&*It++);
2552+
// Check getValue().
2553+
EXPECT_EQ(Resume->getValue(), LPad);
2554+
EXPECT_EQ(Resume->getValue(), Ctx.getValue(LLVMResume->getValue()));
2555+
// Check getNumSuccessors().
2556+
EXPECT_EQ(Resume->getNumSuccessors(), LLVMResume->getNumSuccessors());
2557+
// Check create().
2558+
auto *NewResume =
2559+
sandboxir::ResumeInst::create(LPad, UnwindBB->end(), UnwindBB, Ctx);
2560+
EXPECT_EQ(NewResume->getValue(), LPad);
2561+
EXPECT_EQ(NewResume->getParent(), UnwindBB);
2562+
EXPECT_EQ(NewResume->getNextNode(), nullptr);
2563+
}
2564+
25262565
TEST_F(SandboxIRTest, SwitchInst) {
25272566
parseIR(C, R"IR(
25282567
define void @foo(i32 %cond0, i32 %cond1) {

0 commit comments

Comments
 (0)