[llvm] r247102 - [WinEH] Avoid creating MBBs for LLVM BBs that cannot contain code

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 8 16:28:39 PDT 2015


Author: rnk
Date: Tue Sep  8 18:28:38 2015
New Revision: 247102

URL: http://llvm.org/viewvc/llvm-project?rev=247102&view=rev
Log:
[WinEH] Avoid creating MBBs for LLVM BBs that cannot contain code

Typically these are catchpads, which hold data used to decide whether to
catch the exception or continue unwinding. We also shouldn't create MBBs
for catchendpads, cleanupendpads, or terminatepads, since no real code
can live in them.

This fixes a problem where MI passes (like the register allocator) would
try to put code into catchpad blocks, which are not executed by the
runtime. In the new world, blocks ending in invokes now have many
possible successors.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
    llvm/trunk/test/CodeGen/X86/win-catchpad.ll

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp?rev=247102&r1=247101&r2=247102&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp Tue Sep  8 18:28:38 2015
@@ -212,6 +212,22 @@ void FunctionLoweringInfo::set(const Fun
   // also creates the initial PHI MachineInstrs, though none of the input
   // operands are populated.
   for (BB = Fn->begin(); BB != EB; ++BB) {
+    // Don't create MachineBasicBlocks for imaginary EH pad blocks. These blocks
+    // are really data, and no instructions can live here.
+    if (BB->isEHPad()) {
+      const Instruction *I = BB->getFirstNonPHI();
+      if (!isa<LandingPadInst>(I))
+        MMI.setHasEHFunclets(true);
+      if (isa<CatchPadInst>(I) || isa<CatchEndPadInst>(I) ||
+          isa<CleanupEndPadInst>(I)) {
+        assert(&*BB->begin() == I &&
+               "WinEHPrepare failed to remove PHIs from imaginary BBs");
+        continue;
+      } else if (!isa<LandingPadInst>(I)) {
+        llvm_unreachable("unhandled EH pad in MBB graph");
+      }
+    }
+
     MachineBasicBlock *MBB = mf.CreateMachineBasicBlock(BB);
     MBBMap[BB] = MBB;
     MF->push_back(MBB);
@@ -252,9 +268,9 @@ void FunctionLoweringInfo::set(const Fun
   // Mark landing pad blocks.
   SmallVector<const LandingPadInst *, 4> LPads;
   for (BB = Fn->begin(); BB != EB; ++BB) {
-    if (BB->isEHPad())
-      MBBMap[BB]->setIsEHPad();
     const Instruction *FNP = BB->getFirstNonPHI();
+    if (BB->isEHPad() && !isa<CatchPadInst>(FNP) && !isa<CatchEndPadInst>(FNP))
+      MBBMap[BB]->setIsEHPad();
     if (const auto *LPI = dyn_cast<LandingPadInst>(FNP))
       LPads.push_back(LPI);
   }

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=247102&r1=247101&r2=247102&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Tue Sep  8 18:28:38 2015
@@ -1160,16 +1160,7 @@ SDValue SelectionDAGBuilder::getValueImp
 }
 
 void SelectionDAGBuilder::visitCatchPad(const CatchPadInst &I) {
-  // Update machine-CFG edges.
-  MachineBasicBlock *PadMBB = FuncInfo.MBB;
-  MachineBasicBlock *CatchingMBB = FuncInfo.MBBMap[I.getNormalDest()];
-  MachineBasicBlock *UnwindMBB = FuncInfo.MBBMap[I.getUnwindDest()];
-  PadMBB->addSuccessor(CatchingMBB);
-  PadMBB->addSuccessor(UnwindMBB);
-
-  CatchingMBB->setIsEHFuncletEntry();
-  MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
-  MMI.setHasEHFunclets(true);
+  llvm_unreachable("should never codegen catchpads");
 }
 
 void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) {
@@ -1185,19 +1176,10 @@ void SelectionDAGBuilder::visitCatchRet(
 }
 
 void SelectionDAGBuilder::visitCatchEndPad(const CatchEndPadInst &I) {
-  // If this unwinds to caller, we don't need a DAG node hanging around.
-  if (!I.hasUnwindDest())
-    return;
-
-  // Update machine-CFG edge.
-  MachineBasicBlock *PadMBB = FuncInfo.MBB;
-  MachineBasicBlock *UnwindMBB = FuncInfo.MBBMap[I.getUnwindDest()];
-  PadMBB->addSuccessor(UnwindMBB);
+  llvm_unreachable("should never codegen catchendpads");
 }
 
 void SelectionDAGBuilder::visitCleanupPad(const CleanupPadInst &CPI) {
-  MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
-  MMI.setHasEHFunclets(true);
   report_fatal_error("visitCleanupPad not yet implemented!");
 }
 
@@ -2003,9 +1985,11 @@ void SelectionDAGBuilder::visitBitTestCa
 void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) {
   MachineBasicBlock *InvokeMBB = FuncInfo.MBB;
 
-  // Retrieve successors.
+  // Retrieve successors. Look through artificial IR level blocks like catchpads
+  // and catchendpads for successors.
   MachineBasicBlock *Return = FuncInfo.MBBMap[I.getSuccessor(0)];
-  MachineBasicBlock *LandingPad = FuncInfo.MBBMap[I.getSuccessor(1)];
+  const BasicBlock *EHPadBB = I.getSuccessor(1);
+  bool IsLandingPad = EHPadBB->isLandingPad();
 
   const Value *Callee(I.getCalledValue());
   const Function *Fn = dyn_cast<Function>(Callee);
@@ -2020,14 +2004,14 @@ void SelectionDAGBuilder::visitInvoke(co
       break;
     case Intrinsic::experimental_patchpoint_void:
     case Intrinsic::experimental_patchpoint_i64:
-      visitPatchpoint(&I, LandingPad);
+      visitPatchpoint(&I, EHPadBB);
       break;
     case Intrinsic::experimental_gc_statepoint:
-      LowerStatepoint(ImmutableStatepoint(&I), LandingPad);
+      LowerStatepoint(ImmutableStatepoint(&I), EHPadBB);
       break;
     }
   } else
-    LowerCallTo(&I, getValue(Callee), false, LandingPad);
+    LowerCallTo(&I, getValue(Callee), false, EHPadBB);
 
   // If the value of the invoke is used outside of its defining block, make it
   // available as a virtual register.
@@ -2037,9 +2021,37 @@ void SelectionDAGBuilder::visitInvoke(co
     CopyToExportRegsIfNeeded(&I);
   }
 
+  // Stop when we hit a pad that generates real code or we unwind to caller.
+  // Catchpads are conditional branches that add real MBB destinations and
+  // continue the loop. EH "end" pads are not real BBs and simply continue.
+  SmallVector<MachineBasicBlock *, 1> UnwindDests;
+  while (EHPadBB) {
+    const Instruction *Pad = EHPadBB->getFirstNonPHI();
+    if (isa<CleanupPadInst>(Pad) || isa<LandingPadInst>(Pad)) {
+      assert(FuncInfo.MBBMap[EHPadBB]);
+      // Stop on cleanup pads and landingpads.
+      UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]);
+      break;
+    } else if (const auto *CPI = dyn_cast<CatchPadInst>(Pad)) {
+      // Add the catchpad handler to the possible destinations.
+      UnwindDests.push_back(FuncInfo.MBBMap[CPI->getNormalDest()]);
+      EHPadBB = CPI->getUnwindDest();
+    } else if (const auto *CEPI = dyn_cast<CatchEndPadInst>(Pad)) {
+      EHPadBB = CEPI->getUnwindDest();
+    } else if (const auto *CEPI = dyn_cast<CleanupEndPadInst>(Pad)) {
+      EHPadBB = CEPI->getUnwindDest();
+    }
+  }
+
   // Update successor info
+  // FIXME: The weights for catchpads will be wrong.
   addSuccessorWithWeight(InvokeMBB, Return);
-  addSuccessorWithWeight(InvokeMBB, LandingPad);
+  for (auto *UnwindDest : UnwindDests) {
+    UnwindDest->setIsEHPad();
+    if (!IsLandingPad)
+      UnwindDest->setIsEHFuncletEntry();
+    addSuccessorWithWeight(InvokeMBB, UnwindDest);
+  }
 
   // Drop into normal successor.
   DAG.setRoot(DAG.getNode(ISD::BR, getCurSDLoc(),
@@ -5145,11 +5157,11 @@ SelectionDAGBuilder::visitIntrinsicCall(
 
 std::pair<SDValue, SDValue>
 SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
-                                    MachineBasicBlock *LandingPad) {
+                                    const BasicBlock *EHPadBB) {
   MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
   MCSymbol *BeginLabel = nullptr;
 
-  if (LandingPad) {
+  if (EHPadBB) {
     // Insert a label before the invoke call to mark the try range.  This can be
     // used to detect deletion of the invoke via the MachineModuleInfo.
     BeginLabel = MMI.getContext().createTempSymbol();
@@ -5159,7 +5171,7 @@ SelectionDAGBuilder::lowerInvokable(Targ
     unsigned CallSiteIndex = MMI.getCurrentCallSite();
     if (CallSiteIndex) {
       MMI.setCallSiteBeginLabel(BeginLabel, CallSiteIndex);
-      LPadToCallSiteMap[LandingPad].push_back(CallSiteIndex);
+      LPadToCallSiteMap[FuncInfo.MBBMap[EHPadBB]].push_back(CallSiteIndex);
 
       // Now that the call site is handled, stop tracking it.
       MMI.setCurrentCallSite(0);
@@ -5192,14 +5204,14 @@ SelectionDAGBuilder::lowerInvokable(Targ
     DAG.setRoot(Result.second);
   }
 
-  if (LandingPad) {
+  if (EHPadBB) {
     // Insert a label at the end of the invoke call to mark the try range.  This
     // can be used to detect deletion of the invoke via the MachineModuleInfo.
     MCSymbol *EndLabel = MMI.getContext().createTempSymbol();
     DAG.setRoot(DAG.getEHLabel(getCurSDLoc(), getRoot(), EndLabel));
 
     // Inform MachineModuleInfo of range.
-    MMI.addInvoke(LandingPad, BeginLabel, EndLabel);
+    MMI.addInvoke(FuncInfo.MBBMap[EHPadBB], BeginLabel, EndLabel);
   }
 
   return Result;
@@ -5207,7 +5219,7 @@ SelectionDAGBuilder::lowerInvokable(Targ
 
 void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee,
                                       bool isTailCall,
-                                      MachineBasicBlock *LandingPad) {
+                                      const BasicBlock *EHPadBB) {
   PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
   FunctionType *FTy = cast<FunctionType>(PT->getElementType());
   Type *RetTy = FTy->getReturnType();
@@ -5246,7 +5258,7 @@ void SelectionDAGBuilder::LowerCallTo(Im
   CLI.setDebugLoc(getCurSDLoc()).setChain(getRoot())
     .setCallee(RetTy, FTy, Callee, std::move(Args), CS)
     .setTailCall(isTailCall);
-  std::pair<SDValue,SDValue> Result = lowerInvokable(CLI, LandingPad);
+  std::pair<SDValue, SDValue> Result = lowerInvokable(CLI, EHPadBB);
 
   if (Result.first.getNode())
     setValue(CS.getInstruction(), Result.first);
@@ -6552,12 +6564,9 @@ void SelectionDAGBuilder::visitVACopy(co
 /// This is a helper for lowering intrinsics that follow a target calling
 /// convention or require stack pointer adjustment. Only a subset of the
 /// intrinsic's operands need to participate in the calling convention.
-std::pair<SDValue, SDValue>
-SelectionDAGBuilder::lowerCallOperands(ImmutableCallSite CS, unsigned ArgIdx,
-                                       unsigned NumArgs, SDValue Callee,
-                                       Type *ReturnTy,
-                                       MachineBasicBlock *LandingPad,
-                                       bool IsPatchPoint) {
+std::pair<SDValue, SDValue> SelectionDAGBuilder::lowerCallOperands(
+    ImmutableCallSite CS, unsigned ArgIdx, unsigned NumArgs, SDValue Callee,
+    Type *ReturnTy, const BasicBlock *EHPadBB, bool IsPatchPoint) {
   TargetLowering::ArgListTy Args;
   Args.reserve(NumArgs);
 
@@ -6581,7 +6590,7 @@ SelectionDAGBuilder::lowerCallOperands(I
     .setCallee(CS.getCallingConv(), ReturnTy, Callee, std::move(Args), NumArgs)
     .setDiscardResult(CS->use_empty()).setIsPatchPoint(IsPatchPoint);
 
-  return lowerInvokable(CLI, LandingPad);
+  return lowerInvokable(CLI, EHPadBB);
 }
 
 /// \brief Add a stack map intrinsic call's live variable operands to a stackmap
@@ -6685,7 +6694,7 @@ void SelectionDAGBuilder::visitStackmap(
 
 /// \brief Lower llvm.experimental.patchpoint directly to its target opcode.
 void SelectionDAGBuilder::visitPatchpoint(ImmutableCallSite CS,
-                                          MachineBasicBlock *LandingPad) {
+                                          const BasicBlock *EHPadBB) {
   // void|i64 @llvm.experimental.patchpoint.void|i64(i64 <id>,
   //                                                 i32 <numBytes>,
   //                                                 i8* <target>,
@@ -6722,9 +6731,8 @@ void SelectionDAGBuilder::visitPatchpoin
   unsigned NumCallArgs = IsAnyRegCC ? 0 : NumArgs;
   Type *ReturnTy =
     IsAnyRegCC ? Type::getVoidTy(*DAG.getContext()) : CS->getType();
-  std::pair<SDValue, SDValue> Result =
-    lowerCallOperands(CS, NumMetaOpers, NumCallArgs, Callee, ReturnTy,
-                      LandingPad, true);
+  std::pair<SDValue, SDValue> Result = lowerCallOperands(
+      CS, NumMetaOpers, NumCallArgs, Callee, ReturnTy, EHPadBB, true);
 
   SDNode *CallEnd = Result.second.getNode();
   if (HasDef && (CallEnd->getOpcode() == ISD::CopyFromReg))

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h?rev=247102&r1=247101&r2=247102&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h Tue Sep  8 18:28:38 2015
@@ -710,7 +710,7 @@ public:
   void CopyToExportRegsIfNeeded(const Value *V);
   void ExportFromCurrentBlock(const Value *V);
   void LowerCallTo(ImmutableCallSite CS, SDValue Callee, bool IsTailCall,
-                   MachineBasicBlock *LandingPad = nullptr);
+                   const BasicBlock *EHPadBB = nullptr);
 
   std::pair<SDValue, SDValue> lowerCallOperands(
           ImmutableCallSite CS,
@@ -718,7 +718,7 @@ public:
           unsigned NumArgs,
           SDValue Callee,
           Type *ReturnTy,
-          MachineBasicBlock *LandingPad = nullptr,
+          const BasicBlock *EHPadBB = nullptr,
           bool IsPatchPoint = false);
 
   /// UpdateSplitBlock - When an MBB was split during scheduling, update the
@@ -728,11 +728,11 @@ public:
   // This function is responsible for the whole statepoint lowering process.
   // It uniformly handles invoke and call statepoints.
   void LowerStatepoint(ImmutableStatepoint Statepoint,
-                       MachineBasicBlock *LandingPad = nullptr);
+                       const BasicBlock *EHPadBB = nullptr);
 private:
-  std::pair<SDValue, SDValue> lowerInvokable(
-          TargetLowering::CallLoweringInfo &CLI,
-          MachineBasicBlock *LandingPad);
+  std::pair<SDValue, SDValue>
+  lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
+                 const BasicBlock *EHPadBB = nullptr);
 
   // Terminator instructions.
   void visitRet(const ReturnInst &I);
@@ -855,7 +855,7 @@ private:
   void visitVACopy(const CallInst &I);
   void visitStackmap(const CallInst &I);
   void visitPatchpoint(ImmutableCallSite CS,
-                       MachineBasicBlock *LandingPad = nullptr);
+                       const BasicBlock *EHPadBB = nullptr);
 
   // These three are implemented in StatepointLowering.cpp
   void visitStatepoint(const CallInst &I);

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=247102&r1=247101&r2=247102&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Sep  8 18:28:38 2015
@@ -1153,6 +1153,8 @@ void SelectionDAGISel::SelectAllBasicBlo
     BasicBlock::const_iterator BI = End;
 
     FuncInfo->MBB = FuncInfo->MBBMap[LLVMBB];
+    if (!FuncInfo->MBB)
+      continue; // Some blocks like catchpads have no code or MBB.
     FuncInfo->InsertPt = FuncInfo->MBB->getFirstNonPHI();
 
     // Setup an EH landing-pad block.

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/StatepointLowering.cpp?rev=247102&r1=247101&r2=247102&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/StatepointLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/StatepointLowering.cpp Tue Sep  8 18:28:38 2015
@@ -283,7 +283,7 @@ static void removeDuplicatesGCPtrs(Small
 /// call node. Also update NodeMap so that getValue(statepoint) will
 /// reference lowered call result
 static SDNode *
-lowerCallFromStatepoint(ImmutableStatepoint ISP, MachineBasicBlock *LandingPad,
+lowerCallFromStatepoint(ImmutableStatepoint ISP, const BasicBlock *EHPadBB,
                         SelectionDAGBuilder &Builder,
                         SmallVectorImpl<SDValue> &PendingExports) {
 
@@ -316,7 +316,7 @@ lowerCallFromStatepoint(ImmutableStatepo
   SDValue ReturnValue, CallEndVal;
   std::tie(ReturnValue, CallEndVal) = Builder.lowerCallOperands(
       ISP.getCallSite(), ImmutableStatepoint::CallArgsBeginPos,
-      ISP.getNumCallArgs(), ActualCallee, DefTy, LandingPad,
+      ISP.getNumCallArgs(), ActualCallee, DefTy, EHPadBB,
       false /* IsPatchPoint */);
 
   SDNode *CallEnd = CallEndVal.getNode();
@@ -626,7 +626,7 @@ void SelectionDAGBuilder::visitStatepoin
 }
 
 void SelectionDAGBuilder::LowerStatepoint(
-    ImmutableStatepoint ISP, MachineBasicBlock *LandingPad /*=nullptr*/) {
+    ImmutableStatepoint ISP, const BasicBlock *EHPadBB /*= nullptr*/) {
   // The basic scheme here is that information about both the original call and
   // the safepoint is encoded in the CallInst.  We create a temporary call and
   // lower it, then reverse engineer the calling sequence.
@@ -666,7 +666,7 @@ void SelectionDAGBuilder::LowerStatepoin
 
   // Get call node, we will replace it later with statepoint
   SDNode *CallNode =
-      lowerCallFromStatepoint(ISP, LandingPad, *this, PendingExports);
+      lowerCallFromStatepoint(ISP, EHPadBB, *this, PendingExports);
 
   // Construct the actual GC_TRANSITION_START, STATEPOINT, and GC_TRANSITION_END
   // nodes with all the appropriate arguments and return values.

Modified: llvm/trunk/test/CodeGen/X86/win-catchpad.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win-catchpad.ll?rev=247102&r1=247101&r2=247102&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win-catchpad.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win-catchpad.ll Tue Sep  8 18:28:38 2015
@@ -29,7 +29,6 @@ $"\01??_R0H at 8" = comdat any
 
 declare void @f(i32 %p, i32* %l)
 declare i32 @__CxxFrameHandler3(...)
-declare void @barrier()
 
 define i32 @try_catch_catch() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
 entry:
@@ -42,10 +41,6 @@ catch.dispatch:
           to label %catch unwind label %catch.dispatch.2
 
 catch:                                            ; preds = %catch.dispatch
-  ; FIXME: Remove this barrier once we add more real register allocation barriers.
-  invoke void @barrier()
-          to label %barrier.split unwind label %catchendblock
-barrier.split:
   invoke void @f(i32 2, i32* %local)
           to label %invoke.cont.2 unwind label %catchendblock
 
@@ -83,7 +78,6 @@ catchendblock:
 ; X86: [[catch1bb:LBB0_[0-9]+]]: # %catch{{$}}
 ; X86: addl $12, %ebp
 ; X86: subl $8, %esp
-; X86: calll _barrier
 ; X86: movl $1, -{{[0-9]+}}(%ebp)
 ; X86: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]]
 ; X86-DAG: movl %[[addr_reg]], 4(%esp)




More information about the llvm-commits mailing list