[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