[llvm] [SandboxIR] Implement ResumeInst (PR #106152)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 26 15:34:40 PDT 2024
https://github.com/vporpo created https://github.com/llvm/llvm-project/pull/106152
This patch implements sandboxir::ResumeInst mirroring llvm::ResumeInst.
>From 1f2c60468da2b7a46373871a892bf88117cb11ad Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Fri, 16 Aug 2024 09:38:42 -0700
Subject: [PATCH] [SandboxIR] Implement ResumeInst
This patch implements sandboxir::ResumeInst mirroring llvm::ResumeInst.
---
llvm/include/llvm/SandboxIR/SandboxIR.h | 21 ++++++++++
.../llvm/SandboxIR/SandboxIRValues.def | 1 +
llvm/lib/SandboxIR/SandboxIR.cpp | 25 ++++++++++++
llvm/unittests/SandboxIR/SandboxIRTest.cpp | 39 +++++++++++++++++++
4 files changed, 86 insertions(+)
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index e4c48e39a40015..ebce95de4c2c5e 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -141,6 +141,7 @@ class PossiblyNonNegInst;
class PtrToIntInst;
class BitCastInst;
class AllocaInst;
+class ResumeInst;
class CatchSwitchInst;
class SwitchInst;
class UnaryOperator;
@@ -274,6 +275,7 @@ class Value {
friend class CleanupPadInst; // For getting `Val`.
friend class CatchReturnInst; // For getting `Val`.
friend class GetElementPtrInst; // For getting `Val`.
+ friend class ResumeInst; // For getting `Val`.
friend class CatchSwitchInst; // For getting `Val`.
friend class CleanupReturnInst; // For getting `Val`.
friend class SwitchInst; // For getting `Val`.
@@ -705,6 +707,7 @@ class Instruction : public sandboxir::User {
friend class CatchReturnInst; // For getTopmostLLVMInstruction().
friend class CleanupReturnInst; // For getTopmostLLVMInstruction().
friend class GetElementPtrInst; // For getTopmostLLVMInstruction().
+ friend class ResumeInst; // For getTopmostLLVMInstruction().
friend class CatchSwitchInst; // For getTopmostLLVMInstruction().
friend class SwitchInst; // For getTopmostLLVMInstruction().
friend class UnaryOperator; // For getTopmostLLVMInstruction().
@@ -2249,6 +2252,22 @@ class CatchSwitchInst
}
};
+class ResumeInst : public SingleLLVMInstructionImpl<llvm::ResumeInst> {
+public:
+ ResumeInst(llvm::ResumeInst *CSI, Context &Ctx)
+ : SingleLLVMInstructionImpl(ClassID::Resume, Opcode::Resume, CSI, Ctx) {}
+
+ static ResumeInst *create(Value *Exn, BBIterator WhereIt, BasicBlock *WhereBB,
+ Context &Ctx);
+ Value *getValue() const;
+ unsigned getNumSuccessors() const {
+ return cast<llvm::ResumeInst>(Val)->getNumSuccessors();
+ }
+ static bool classof(const Value *From) {
+ return From->getSubclassID() == ClassID::Resume;
+ }
+};
+
class SwitchInst : public SingleLLVMInstructionImpl<llvm::SwitchInst> {
public:
SwitchInst(llvm::SwitchInst *SI, Context &Ctx)
@@ -3027,6 +3046,8 @@ class Context {
friend GetElementPtrInst; // For createGetElementPtrInst()
CatchSwitchInst *createCatchSwitchInst(llvm::CatchSwitchInst *I);
friend CatchSwitchInst; // For createCatchSwitchInst()
+ ResumeInst *createResumeInst(llvm::ResumeInst *I);
+ friend ResumeInst; // For createResumeInst()
SwitchInst *createSwitchInst(llvm::SwitchInst *I);
friend SwitchInst; // For createSwitchInst()
UnaryOperator *createUnaryOperator(llvm::UnaryOperator *I);
diff --git a/llvm/include/llvm/SandboxIR/SandboxIRValues.def b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
index 8d79523253f233..4d74ef4ea036df 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIRValues.def
+++ b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
@@ -54,6 +54,7 @@ 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(Resume, OP(Resume), ResumeInst)
DEF_INSTR(CatchSwitch, OP(CatchSwitch), CatchSwitchInst)
DEF_INSTR(Switch, OP(Switch), SwitchInst)
DEF_INSTR(UnOp, OPCODES( \
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index 35b642ac7f3a22..741c3736ae6039 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -1496,6 +1496,21 @@ void CatchSwitchInst::addHandler(BasicBlock *Dest) {
cast<llvm::BasicBlock>(Dest->Val));
}
+ResumeInst *ResumeInst::create(Value *Exn, 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 *LLVMI = cast<llvm::ResumeInst>(Builder.CreateResume(Exn->Val));
+ return Ctx.createResumeInst(LLVMI);
+}
+
+Value *ResumeInst::getValue() const {
+ return Ctx.getValue(cast<llvm::ResumeInst>(Val)->getValue());
+}
+
SwitchInst *SwitchInst::create(Value *V, BasicBlock *Dest, unsigned NumCases,
BasicBlock::iterator WhereIt,
BasicBlock *WhereBB, Context &Ctx,
@@ -2346,6 +2361,12 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
new CatchSwitchInst(LLVMCatchSwitchInst, *this));
return It->second.get();
}
+ case llvm::Instruction::Resume: {
+ auto *LLVMResumeInst = cast<llvm::ResumeInst>(LLVMV);
+ It->second =
+ std::unique_ptr<ResumeInst>(new ResumeInst(LLVMResumeInst, *this));
+ return It->second.get();
+ }
case llvm::Instruction::Switch: {
auto *LLVMSwitchInst = cast<llvm::SwitchInst>(LLVMV);
It->second =
@@ -2552,6 +2573,10 @@ CatchSwitchInst *Context::createCatchSwitchInst(llvm::CatchSwitchInst *I) {
auto NewPtr = std::unique_ptr<CatchSwitchInst>(new CatchSwitchInst(I, *this));
return cast<CatchSwitchInst>(registerValue(std::move(NewPtr)));
}
+ResumeInst *Context::createResumeInst(llvm::ResumeInst *I) {
+ auto NewPtr = std::unique_ptr<ResumeInst>(new ResumeInst(I, *this));
+ return cast<ResumeInst>(registerValue(std::move(NewPtr)));
+}
SwitchInst *Context::createSwitchInst(llvm::SwitchInst *I) {
auto NewPtr = std::unique_ptr<SwitchInst>(new SwitchInst(I, *this));
return cast<SwitchInst>(registerValue(std::move(NewPtr)));
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 869e752b23913f..74abcdd293d03b 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -2523,6 +2523,45 @@ define void @foo(i32 %cond0, i32 %cond1) {
EXPECT_EQ(NewCSI->getParentPad(), CS0);
}
+TEST_F(SandboxIRTest, ResumeInst){
+ parseIR(C, R"IR(
+define void @foo() {
+entry:
+ invoke void @foo()
+ to label %bb unwind label %unwind
+bb:
+ ret void
+unwind:
+ %lpad = landingpad { ptr, i32 }
+ cleanup
+ resume { ptr, i32 } %lpad
+}
+)IR");
+ Function &LLVMF = *M->getFunction("foo");
+ auto *LLVMUnwindBB = getBasicBlockByName(LLVMF, "unwind");
+ auto LLVMIt = LLVMUnwindBB->begin();
+ [[maybe_unused]] auto *LLVMLPad = cast<llvm::LandingPadInst>(&*LLVMIt++);
+ auto *LLVMResume = cast<llvm::ResumeInst>(&*LLVMIt++);
+
+ sandboxir::Context Ctx(C);
+ [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
+ auto *UnwindBB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMUnwindBB));
+ auto It = UnwindBB->begin();
+ auto *LPad = cast<sandboxir::LandingPadInst>(&*It++);
+ auto *Resume = cast<sandboxir::ResumeInst>(&*It++);
+ // Check getValue().
+ EXPECT_EQ(Resume->getValue(), LPad);
+ EXPECT_EQ(Resume->getValue(), Ctx.getValue(LLVMResume->getValue()));
+ // Check getNumSuccessors().
+ EXPECT_EQ(Resume->getNumSuccessors(), LLVMResume->getNumSuccessors());
+ // Check create().
+ auto *NewResume =
+ sandboxir::ResumeInst::create(LPad, UnwindBB->end(), UnwindBB, Ctx);
+ EXPECT_EQ(NewResume->getValue(), LPad);
+ EXPECT_EQ(NewResume->getParent(), UnwindBB);
+ EXPECT_EQ(NewResume->getNextNode(), nullptr);
+}
+
TEST_F(SandboxIRTest, SwitchInst) {
parseIR(C, R"IR(
define void @foo(i32 %cond0, i32 %cond1) {
More information about the llvm-commits
mailing list