[SEH] Reimplement x64 SEH using WinEHPrepare
[oota-llvm.git] / lib / CodeGen / SelectionDAG / SelectionDAGISel.cpp
index 1e116dddafaaef73853c16530569f0158f682289..0478c7382f2259af88374e9fc7058591148176d1 100644 (file)
@@ -911,7 +911,7 @@ void SelectionDAGISel::DoInstructionSelection() {
 
 /// PrepareEHLandingPad - Emit an EH_LABEL, set up live-in registers, and
 /// do other setup for EH landing-pad blocks.
 
 /// PrepareEHLandingPad - Emit an EH_LABEL, set up live-in registers, and
 /// do other setup for EH landing-pad blocks.
-void SelectionDAGISel::PrepareEHLandingPad() {
+bool SelectionDAGISel::PrepareEHLandingPad() {
   MachineBasicBlock *MBB = FuncInfo->MBB;
 
   const TargetRegisterClass *PtrRC = TLI->getRegClassFor(TLI->getPointerTy());
   MachineBasicBlock *MBB = FuncInfo->MBB;
 
   const TargetRegisterClass *PtrRC = TLI->getRegClassFor(TLI->getPointerTy());
@@ -937,70 +937,28 @@ void SelectionDAGISel::PrepareEHLandingPad() {
 
   if (isMSVCEHPersonality(Personality)) {
     SmallVector<MachineBasicBlock *, 4> ClauseBBs;
 
   if (isMSVCEHPersonality(Personality)) {
     SmallVector<MachineBasicBlock *, 4> ClauseBBs;
-    const IntrinsicInst *Actions =
+    const IntrinsicInst *ActionsCall =
         dyn_cast<IntrinsicInst>(LLVMBB->getFirstInsertionPt());
     // Get all invoke BBs that unwind to this landingpad.
     SmallVector<MachineBasicBlock *, 4> InvokeBBs(MBB->pred_begin(),
                                                   MBB->pred_end());
         dyn_cast<IntrinsicInst>(LLVMBB->getFirstInsertionPt());
     // Get all invoke BBs that unwind to this landingpad.
     SmallVector<MachineBasicBlock *, 4> InvokeBBs(MBB->pred_begin(),
                                                   MBB->pred_end());
-    if (Actions && Actions->getIntrinsicID() == Intrinsic::eh_actions) {
-      // If this is a call to llvm.eh.actions followed by indirectbr, then we've
-      // run WinEHPrepare, and we should remove this block from the machine CFG.
-      // Mark the targets of the indirectbr as landingpads instead.
-      for (const BasicBlock *LLVMSucc : successors(LLVMBB)) {
-        MachineBasicBlock *ClauseBB = FuncInfo->MBBMap[LLVMSucc];
-        // Add the edge from the invoke to the clause.
-        for (MachineBasicBlock *InvokeBB : InvokeBBs)
-          InvokeBB->addSuccessor(ClauseBB);
-      }
-    } else {
-      // Otherwise, we haven't done the preparation, and we need to invent some
-      // clause basic blocks that branch into the landingpad.
-      // FIXME: Remove this code once SEH preparation works.
-
-      // Make virtual registers and a series of labels that fill in values for
-      // the clauses.
-      auto &RI = MF->getRegInfo();
-      FuncInfo->ExceptionSelectorVirtReg = RI.createVirtualRegister(PtrRC);
-
-      // Emit separate machine basic blocks with separate labels for each clause
-      // before the main landing pad block.
-      MachineInstrBuilder SelectorPHI = BuildMI(
-          *MBB, MBB->begin(), SDB->getCurDebugLoc(),
-          TII->get(TargetOpcode::PHI), FuncInfo->ExceptionSelectorVirtReg);
-      for (unsigned I = 0, E = LPadInst->getNumClauses(); I != E; ++I) {
-        // Skip filter clauses, we can't implement them.
-        if (LPadInst->isFilter(I))
-          continue;
-
-        MachineBasicBlock *ClauseBB = MF->CreateMachineBasicBlock(LLVMBB);
-        MF->insert(MBB, ClauseBB);
-
-        // Add the edge from the invoke to the clause.
-        for (MachineBasicBlock *InvokeBB : InvokeBBs)
-          InvokeBB->addSuccessor(ClauseBB);
-
-        // Mark the clause as a landing pad or MI passes will delete it.
-        ClauseBB->setIsLandingPad();
-
-        GlobalValue *ClauseGV = ExtractTypeInfo(LPadInst->getClause(I));
-
-        // Start the BB with a label.
-        MCSymbol *ClauseLabel = MF->getMMI().addClauseForLandingPad(MBB);
-        BuildMI(*ClauseBB, ClauseBB->begin(), SDB->getCurDebugLoc(), II)
-            .addSym(ClauseLabel);
-
-        // Construct a simple BB that defines a register with the typeid
-        // constant.
-        FuncInfo->MBB = ClauseBB;
-        FuncInfo->InsertPt = ClauseBB->end();
-        unsigned VReg = SDB->visitLandingPadClauseBB(ClauseGV, MBB);
-        CurDAG->setRoot(SDB->getRoot());
-        SDB->clear();
-        CodeGenAndEmitDAG();
+    if (!ActionsCall || ActionsCall->getIntrinsicID() != Intrinsic::eh_actions) {
+      assert(isa<UnreachableInst>(LLVMBB->getFirstInsertionPt()) &&
+             "found landingpad without unreachable or llvm.eh.actions");
+      return false;
+    }
 
 
-        // Add the typeid virtual register to the phi in the main landing pad.
-        SelectorPHI.addReg(VReg).addMBB(ClauseBB);
-      }
+    // If this is a call to llvm.eh.actions followed by indirectbr, then we've
+    // run WinEHPrepare, and we should remove this block from the machine CFG.
+    // Mark the targets of the indirectbr as landingpads instead.
+    for (const BasicBlock *LLVMSucc : successors(LLVMBB)) {
+      MachineBasicBlock *ClauseBB = FuncInfo->MBBMap[LLVMSucc];
+      // Add the edge from the invoke to the clause.
+      for (MachineBasicBlock *InvokeBB : InvokeBBs)
+        InvokeBB->addSuccessor(ClauseBB);
+
+      // Mark the clause as a landing pad or MI passes will delete it.
+      ClauseBB->setIsLandingPad();
     }
 
     // Remove the edge from the invoke to the lpad.
     }
 
     // Remove the edge from the invoke to the lpad.
@@ -1017,7 +975,9 @@ void SelectionDAGISel::PrepareEHLandingPad() {
       WinEHFuncInfo &FI = MF->getMMI().getWinEHFuncInfo(MF->getFunction());
       MF->getMMI().addWinEHState(MBB, FI.LandingPadStateMap[LPadInst]);
     }
       WinEHFuncInfo &FI = MF->getMMI().getWinEHFuncInfo(MF->getFunction());
       MF->getMMI().addWinEHState(MBB, FI.LandingPadStateMap[LPadInst]);
     }
-    return;
+
+    // Don't select instructions for landing pads using llvm.eh.actions.
+    return false;
   }
 
   // Mark exception register as live in.
   }
 
   // Mark exception register as live in.
@@ -1027,6 +987,8 @@ void SelectionDAGISel::PrepareEHLandingPad() {
   // Mark exception selector register as live in.
   if (unsigned Reg = TLI->getExceptionSelectorRegister())
     FuncInfo->ExceptionSelectorVirtReg = MBB->addLiveIn(Reg, PtrRC);
   // Mark exception selector register as live in.
   if (unsigned Reg = TLI->getExceptionSelectorRegister())
     FuncInfo->ExceptionSelectorVirtReg = MBB->addLiveIn(Reg, PtrRC);
+
+  return true;
 }
 
 /// isFoldedOrDeadInstruction - Return true if the specified instruction is
 }
 
 /// isFoldedOrDeadInstruction - Return true if the specified instruction is
@@ -1197,7 +1159,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
     FuncInfo->ExceptionPointerVirtReg = 0;
     FuncInfo->ExceptionSelectorVirtReg = 0;
     if (LLVMBB->isLandingPad())
     FuncInfo->ExceptionPointerVirtReg = 0;
     FuncInfo->ExceptionSelectorVirtReg = 0;
     if (LLVMBB->isLandingPad())
-      PrepareEHLandingPad();
+      if (!PrepareEHLandingPad())
+        continue;
 
     // Before doing SelectionDAG ISel, see if FastISel has been requested.
     if (FastIS) {
 
     // Before doing SelectionDAG ISel, see if FastISel has been requested.
     if (FastIS) {