[llvm] r249492 - [SEH] Add llvm.eh.exceptioncode intrinsic

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 6 17:27:33 PDT 2015


Author: rnk
Date: Tue Oct  6 19:27:33 2015
New Revision: 249492

URL: http://llvm.org/viewvc/llvm-project?rev=249492&view=rev
Log:
[SEH] Add llvm.eh.exceptioncode intrinsic

This will support the Clang __exception_code intrinsic.

Modified:
    llvm/trunk/include/llvm/CodeGen/FunctionLoweringInfo.h
    llvm/trunk/include/llvm/IR/Intrinsics.td
    llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
    llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/test/CodeGen/WinEH/seh-exception-code.ll
    llvm/trunk/test/CodeGen/WinEH/seh-exception-code2.ll
    llvm/trunk/test/CodeGen/WinEH/seh-resume-phi.ll

Modified: llvm/trunk/include/llvm/CodeGen/FunctionLoweringInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FunctionLoweringInfo.h?rev=249492&r1=249491&r2=249492&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/FunctionLoweringInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/FunctionLoweringInfo.h Tue Oct  6 19:27:33 2015
@@ -72,7 +72,10 @@ public:
   /// ValueMap - Since we emit code for the function a basic block at a time,
   /// we must remember which virtual registers hold the values for
   /// cross-basic-block values.
-  DenseMap<const Value*, unsigned> ValueMap;
+  DenseMap<const Value *, unsigned> ValueMap;
+
+  /// Track virtual registers created for exception pointers.
+  DenseMap<const Value *, unsigned> CatchPadExceptionPointers;
 
   // Keep track of frame indices allocated for statepoints as they could be used
   // across basic block boundaries.
@@ -234,6 +237,9 @@ public:
   /// getArgumentFrameIndex - Get frame index for the byval argument.
   int getArgumentFrameIndex(const Argument *A);
 
+  unsigned getCatchPadExceptionPointerVReg(const Value *CPI,
+                                           const TargetRegisterClass *RC);
+
 private:
   void addSEHHandlersForLPads(ArrayRef<const LandingPadInst *> LPads);
 

Modified: llvm/trunk/include/llvm/IR/Intrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=249492&r1=249491&r2=249492&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Intrinsics.td (original)
+++ llvm/trunk/include/llvm/IR/Intrinsics.td Tue Oct  6 19:27:33 2015
@@ -441,10 +441,14 @@ def int_eh_endcatch : Intrinsic<[], []>;
 def int_eh_exceptionpointer : Intrinsic<[llvm_anyptr_ty], [llvm_token_ty],
                                         [IntrNoMem]>;
 
+// Gets the exception code from a catchpad token. Only used on some platforms.
+def int_eh_exceptioncode : Intrinsic<[llvm_i32_ty], [llvm_token_ty], [IntrNoMem]>;
+
 // Represents the list of actions to take when an exception is thrown.
 def int_eh_actions : Intrinsic<[llvm_ptr_ty], [llvm_vararg_ty], []>;
 
-def int_eh_exceptioncode : Intrinsic<[llvm_i32_ty], [], [IntrReadMem]>;
+// FIXME: Remove this when landing pad EH can be removed.
+def int_eh_exceptioncode_old : Intrinsic<[llvm_i32_ty], [], [IntrReadMem]>;
 
 // __builtin_unwind_init is an undocumented GCC intrinsic that causes all
 // callee-saved registers to be saved and restored (regardless of whether they

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp?rev=249492&r1=249491&r2=249492&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp Tue Oct  6 19:27:33 2015
@@ -577,6 +577,17 @@ int FunctionLoweringInfo::getArgumentFra
   return 0;
 }
 
+unsigned FunctionLoweringInfo::getCatchPadExceptionPointerVReg(
+    const Value *CPI, const TargetRegisterClass *RC) {
+  MachineRegisterInfo &MRI = MF->getRegInfo();
+  auto I = CatchPadExceptionPointers.insert({CPI, 0});
+  unsigned &VReg = I.first->second;
+  if (I.second)
+    VReg = MRI.createVirtualRegister(RC);
+  assert(VReg && "null vreg in exception pointer table!");
+  return VReg;
+}
+
 /// ComputeUsesVAFloatArgument - Determine if any floating-point values are
 /// being passed to this variadic function, and set the MachineModuleInfo's
 /// usesVAFloatArgument flag if so. This flag is used to emit an undefined

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=249492&r1=249491&r2=249492&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Tue Oct  6 19:27:33 2015
@@ -5240,7 +5240,7 @@ SelectionDAGBuilder::visitIntrinsicCall(
   case Intrinsic::eh_begincatch:
   case Intrinsic::eh_endcatch:
     llvm_unreachable("begin/end catch intrinsics not lowered in codegen");
-  case Intrinsic::eh_exceptioncode: {
+  case Intrinsic::eh_exceptioncode_old: {
     unsigned Reg = TLI.getExceptionPointerRegister();
     assert(Reg && "cannot get exception code on this platform");
     MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
@@ -5250,6 +5250,20 @@ SelectionDAGBuilder::visitIntrinsicCall(
     SDValue N =
         DAG.getCopyFromReg(DAG.getEntryNode(), getCurSDLoc(), VReg, PtrVT);
     N = DAG.getZExtOrTrunc(N, getCurSDLoc(), MVT::i32);
+    setValue(&I, N);
+    return nullptr;
+  }
+
+  case Intrinsic::eh_exceptionpointer:
+  case Intrinsic::eh_exceptioncode: {
+    // Get the exception pointer vreg, copy from it, and resize it to fit.
+    const auto *CPI = cast<CatchPadInst>(I.getArgOperand(0));
+    MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
+    const TargetRegisterClass *PtrRC = TLI.getRegClassFor(PtrVT);
+    unsigned VReg = FuncInfo.getCatchPadExceptionPointerVReg(CPI, PtrRC);
+    SDValue N =
+        DAG.getCopyFromReg(DAG.getEntryNode(), getCurSDLoc(), VReg, PtrVT);
+    N = DAG.getZExtOrTrunc(N, getCurSDLoc(), MVT::i32);
     setValue(&I, N);
     return nullptr;
   }

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=249492&r1=249491&r2=249492&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Oct  6 19:27:33 2015
@@ -922,14 +922,46 @@ void SelectionDAGISel::DoInstructionSele
   PostprocessISelDAG();
 }
 
+static bool hasExceptionPointerOrCodeUser(const CatchPadInst *CPI) {
+  for (const User *U : CPI->users()) {
+    if (const IntrinsicInst *EHPtrCall = dyn_cast<IntrinsicInst>(U)) {
+      Intrinsic::ID IID = EHPtrCall->getIntrinsicID();
+      if (IID == Intrinsic::eh_exceptionpointer ||
+          IID == Intrinsic::eh_exceptioncode)
+        return true;
+    }
+  }
+  return false;
+}
+
 /// PrepareEHLandingPad - Emit an EH_LABEL, set up live-in registers, and
 /// do other setup for EH landing-pad blocks.
 bool SelectionDAGISel::PrepareEHLandingPad() {
   MachineBasicBlock *MBB = FuncInfo->MBB;
-
+  const BasicBlock *LLVMBB = MBB->getBasicBlock();
   const TargetRegisterClass *PtrRC =
       TLI->getRegClassFor(TLI->getPointerTy(CurDAG->getDataLayout()));
 
+  // Catchpads have one live-in register, which typically holds the exception
+  // pointer or code.
+  if (const auto *CPI = dyn_cast<CatchPadInst>(LLVMBB->getFirstNonPHI())) {
+    if (hasExceptionPointerOrCodeUser(CPI)) {
+      // Get or create the virtual register to hold the pointer or code.  Mark
+      // the live in physreg and copy into the vreg.
+      MCPhysReg EHPhysReg = TLI->getExceptionPointerRegister();
+      assert(EHPhysReg && "target lacks exception pointer register");
+      FuncInfo->ExceptionPointerVirtReg = MBB->addLiveIn(EHPhysReg, PtrRC);
+      unsigned VReg = FuncInfo->getCatchPadExceptionPointerVReg(CPI, PtrRC);
+      BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(),
+              TII->get(TargetOpcode::COPY), VReg)
+          .addReg(EHPhysReg, RegState::Kill);
+    }
+    return true;
+  }
+
+  if (!LLVMBB->isLandingPad())
+    return true;
+
   // Add a label to mark the beginning of the landing pad.  Deletion of the
   // landing pad can thus be detected via the MachineModuleInfo.
   MCSymbol *Label = MF->getMMI().addLandingPad(MBB);
@@ -943,7 +975,6 @@ bool SelectionDAGISel::PrepareEHLandingP
 
   // If this personality function uses funclets, we need to split the landing
   // pad into several BBs.
-  const BasicBlock *LLVMBB = MBB->getBasicBlock();
   const Constant *Personality = MF->getFunction()->getPersonalityFn();
   if (const auto *PF = dyn_cast<Function>(Personality->stripPointerCasts()))
     MF->getMMI().addPersonality(PF);
@@ -1159,10 +1190,8 @@ void SelectionDAGISel::SelectAllBasicBlo
     // Setup an EH landing-pad block.
     FuncInfo->ExceptionPointerVirtReg = 0;
     FuncInfo->ExceptionSelectorVirtReg = 0;
-    if (LLVMBB->isLandingPad())
-      if (!PrepareEHLandingPad())
-        continue;
-
+    if (!PrepareEHLandingPad())
+      continue;
 
     // Before doing SelectionDAG ISel, see if FastISel has been requested.
     if (FastIS) {

Modified: llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/WinEHPrepare.cpp?rev=249492&r1=249491&r2=249492&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/WinEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/WinEHPrepare.cpp Tue Oct  6 19:27:33 2015
@@ -1614,7 +1614,7 @@ void WinEHPrepare::processSEHCatchHandle
   }
   IRBuilder<> Builder(HandlerBB->getFirstInsertionPt());
   Function *EHCodeFn = Intrinsic::getDeclaration(
-      StartBB->getParent()->getParent(), Intrinsic::eh_exceptioncode);
+      StartBB->getParent()->getParent(), Intrinsic::eh_exceptioncode_old);
   Value *Code = Builder.CreateCall(EHCodeFn, {}, "sehcode");
   Code = Builder.CreateIntToPtr(Code, SEHExceptionCodeSlot->getAllocatedType());
   Builder.CreateStore(Code, SEHExceptionCodeSlot);
@@ -3019,12 +3019,11 @@ colorFunclets(Function &F, SmallVectorIm
       // Mark this as a funclet head as a member of itself.
       FuncletBlocks[Visiting].insert(Visiting);
       // Queue exits with the parent color.
-      for (User *Exit : VisitingHead->users()) {
-        for (BasicBlock *Succ :
-             successors(cast<Instruction>(Exit)->getParent())) {
-          if (BlockColors[Succ].insert(Color).second) {
-            Worklist.push_back({Succ, Color});
-          }
+      for (User *U : VisitingHead->users()) {
+        if (auto *Exit = dyn_cast<TerminatorInst>(U)) {
+          for (BasicBlock *Succ : successors(Exit->getParent()))
+            if (BlockColors[Succ].insert(Color).second)
+              Worklist.push_back({Succ, Color});
         }
       }
       // Handle CatchPad specially since its successors need different colors.
@@ -3124,7 +3123,9 @@ void llvm::calculateCatchReturnSuccessor
 
     // The users of a catchpad are always catchrets.
     for (User *Exit : CatchPad->users()) {
-      auto *CatchReturn = cast<CatchReturnInst>(Exit);
+      auto *CatchReturn = dyn_cast<CatchReturnInst>(Exit);
+      if (!CatchReturn)
+        continue;
       BasicBlock *CatchRetSuccessor = CatchReturn->getSuccessor();
       std::set<BasicBlock *> &SuccessorColors = BlockColors[CatchRetSuccessor];
       assert(SuccessorColors.size() == 1 && "Expected BB to be monochrome!");

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=249492&r1=249491&r2=249492&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Tue Oct  6 19:27:33 2015
@@ -3681,6 +3681,7 @@ void Verifier::visitIntrinsicCallSite(In
            "gc.relocate: relocating a pointer shouldn't change its address space", CS);
     break;
   }
+  case Intrinsic::eh_exceptioncode:
   case Intrinsic::eh_exceptionpointer: {
     Assert(isa<CatchPadInst>(CS.getArgOperand(0)),
            "eh.exceptionpointer argument must be a catchpad", CS);

Modified: llvm/trunk/test/CodeGen/WinEH/seh-exception-code.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/seh-exception-code.ll?rev=249492&r1=249491&r2=249492&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/seh-exception-code.ll (original)
+++ llvm/trunk/test/CodeGen/WinEH/seh-exception-code.ll Tue Oct  6 19:27:33 2015
@@ -52,13 +52,13 @@ __try.cont:
 ; CHECK: landingpad
 ; CHECK: indirectbr i8* %{{[^,]*}}, [label %[[except_split1:.*]]]
 ; CHECK: [[except_split1]]:
-; CHECK: call i32 @llvm.eh.exceptioncode()
+; CHECK: call i32 @llvm.eh.exceptioncode.old()
 ; CHECK: br label %__except
 ;
 ; CHECK: landingpad
 ; CHECK: indirectbr i8* %{{[^,]*}}, [label %[[except_split2:.*]]]
 ; CHECK: [[except_split2]]:
-; CHECK: call i32 @llvm.eh.exceptioncode()
+; CHECK: call i32 @llvm.eh.exceptioncode.old()
 ; CHECK: br label %__except
 ;
 ; CHECK: __except:

Modified: llvm/trunk/test/CodeGen/WinEH/seh-exception-code2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/seh-exception-code2.ll?rev=249492&r1=249491&r2=249492&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/seh-exception-code2.ll (original)
+++ llvm/trunk/test/CodeGen/WinEH/seh-exception-code2.ll Tue Oct  6 19:27:33 2015
@@ -87,5 +87,5 @@ entry:
 ; CHECK-NEXT: indirectbr i8* %{{[^,]*}}, [label %__except]
 ;
 ; CHECK: __except:
-; CHECK: call i32 @llvm.eh.exceptioncode()
+; CHECK: call i32 @llvm.eh.exceptioncode.old()
 ; CHECK: call i32 (i8*, ...) @printf

Modified: llvm/trunk/test/CodeGen/WinEH/seh-resume-phi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/seh-resume-phi.ll?rev=249492&r1=249491&r2=249492&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/seh-resume-phi.ll (original)
+++ llvm/trunk/test/CodeGen/WinEH/seh-resume-phi.ll Tue Oct  6 19:27:33 2015
@@ -55,7 +55,7 @@ eh.resume:
 ; CHECK-NEXT: indirectbr {{.*}} [label %__except]
 ;
 ; CHECK: __except:
-; CHECK: call i32 @llvm.eh.exceptioncode()
+; CHECK: call i32 @llvm.eh.exceptioncode.old()
 ; CHECK: invoke void @might_crash(i8* %{{.*}})
 ; CHECK: landingpad { i8*, i32 }
 ; CHECK-NEXT: cleanup




More information about the llvm-commits mailing list