[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Duncan Sands baldrick at free.fr
Fri Jun 15 12:04:43 PDT 2007



Changes in directory llvm/lib/CodeGen/SelectionDAG:

SelectionDAGISel.cpp updated: 1.463 -> 1.464
---
Log message:

Workaround for PR1508: http://llvm.org/PR1508 .


---
Diffs of the changes:  (+96 -29)

 SelectionDAGISel.cpp |  125 +++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 96 insertions(+), 29 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.463 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.464
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.463	Thu Jun 14 17:58:02 2007
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	Fri Jun 15 14:04:19 2007
@@ -179,6 +179,11 @@
     /// anywhere in the function.
     std::map<const AllocaInst*, int> StaticAllocaMap;
 
+#ifndef NDEBUG
+    SmallSet<Instruction*, 8> CatchInfoLost;
+    SmallSet<Instruction*, 8> CatchInfoFound;
+#endif
+
     unsigned MakeReg(MVT::ValueType VT) {
       return RegMap->createVirtualRegister(TLI.getRegClassFor(VT));
     }
@@ -199,6 +204,15 @@
   };
 }
 
+/// isFilterOrSelector - Return true if this instruction is a call to the
+/// eh.filter or the eh.selector intrinsic.
+static bool isFilterOrSelector(Instruction *I) {
+  if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
+    return II->getIntrinsicID() == Intrinsic::eh_selector
+      || II->getIntrinsicID() == Intrinsic::eh_filter;
+  return false;
+}
+
 /// isUsedOutsideOfDefiningBlock - Return true if this instruction is used by
 /// PHI nodes or outside of the basic block that defines it, or used by a 
 /// switch instruction, which may expand to multiple basic blocks.
@@ -2463,6 +2477,33 @@
   return NULL;
 }
 
+/// addCatchInfo - Extract the personality and type infos from an eh.selector
+/// or eh.filter call, and add them to the specified machine basic block.
+static void addCatchInfo(CallInst &I, MachineModuleInfo *MMI,
+                         MachineBasicBlock *MBB) {
+  // Inform the MachineModuleInfo of the personality for this landing pad.
+  ConstantExpr *CE = cast<ConstantExpr>(I.getOperand(2));
+  assert(CE->getOpcode() == Instruction::BitCast &&
+         isa<Function>(CE->getOperand(0)) &&
+         "Personality should be a function");
+  MMI->addPersonality(MBB, cast<Function>(CE->getOperand(0)));
+
+  // Gather all the type infos for this landing pad and pass them along to
+  // MachineModuleInfo.
+  std::vector<GlobalVariable *> TyInfo;
+  for (unsigned i = 3, N = I.getNumOperands(); i < N; ++i) {
+    Constant *C = cast<Constant>(I.getOperand(i));
+    GlobalVariable *GV = ExtractGlobalVariable(C);
+    assert (GV || isa<ConstantPointerNull>(C) &&
+            "TypeInfo must be a global variable or NULL");
+    TyInfo.push_back(GV);
+  }
+  if (I.getCalledFunction()->getIntrinsicID() == Intrinsic::eh_filter)
+    MMI->addFilterTypeInfo(MBB, TyInfo);
+  else
+    MMI->addCatchTypeInfo(MBB, TyInfo);
+}
+
 /// visitIntrinsicCall - Lower the call to the specified intrinsic function.  If
 /// we want to emit this as a call to a named external function, return the name
 /// otherwise lower it and return null.
@@ -2595,29 +2636,14 @@
   case Intrinsic::eh_selector:
   case Intrinsic::eh_filter:{
     MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
-    
+
     if (ExceptionHandling && MMI) {
-      // Inform the MachineModuleInfo of the personality for this landing pad.
-      ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(2));
-      assert(CE && CE->getOpcode() == Instruction::BitCast &&
-             isa<Function>(CE->getOperand(0)) &&
-             "Personality should be a function");
-      MMI->addPersonality(CurMBB, cast<Function>(CE->getOperand(0)));
-
-      // Gather all the type infos for this landing pad and pass them along to
-      // MachineModuleInfo.
-      std::vector<GlobalVariable *> TyInfo;
-      for (unsigned i = 3, N = I.getNumOperands(); i < N; ++i) {
-        Constant *C = cast<Constant>(I.getOperand(i));
-        GlobalVariable *GV = ExtractGlobalVariable(C);
-        assert (GV || isa<ConstantPointerNull>(C) &&
-                "TypeInfo must be a global variable or NULL");
-        TyInfo.push_back(GV);
-      }
-      if (Intrinsic == Intrinsic::eh_filter)
-        MMI->addFilterTypeInfo(CurMBB, TyInfo);
+      if (CurMBB->isLandingPad())
+        addCatchInfo(I, MMI, CurMBB);
+#ifndef NDEBUG
       else
-        MMI->addCatchTypeInfo(CurMBB, TyInfo);
+        FuncInfo.CatchInfoLost.insert(&I);
+#endif
 
       // Mark exception selector register as live in.
       unsigned Reg = TLI.getExceptionSelectorRegister();
@@ -4403,6 +4429,11 @@
            E = MF.livein_end(); I != E; ++I)
       BB->addLiveIn(I->first);
 
+#ifndef NDEBUG
+  assert(FuncInfo.CatchInfoFound.size() == FuncInfo.CatchInfoLost.size() &&
+         "Not all catch info was assigned to a landing pad!");
+#endif
+
   return true;
 }
 
@@ -4513,6 +4544,20 @@
   EmitFunctionEntryCode(F, SDL.DAG.getMachineFunction());
 }
 
+static void copyCatchInfo(BasicBlock *SrcBB, BasicBlock *DestBB,
+                          MachineModuleInfo *MMI, FunctionLoweringInfo &FLI) {
+  assert(!FLI.MBBMap[SrcBB]->isLandingPad() &&
+         "Copying catch info out of a landing pad!");
+  for (BasicBlock::iterator I = SrcBB->begin(), E = --SrcBB->end(); I != E; ++I)
+    if (isFilterOrSelector(I)) {
+      // Apply the catch info to DestBB.
+      addCatchInfo(cast<CallInst>(*I), MMI, FLI.MBBMap[DestBB]);
+#ifndef NDEBUG
+      FLI.CatchInfoFound.insert(I);
+#endif
+    }
+}
+
 void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
        std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate,
                                          FunctionLoweringInfo &FuncInfo) {
@@ -4527,15 +4572,37 @@
   BB = FuncInfo.MBBMap[LLVMBB];
   SDL.setCurrentBasicBlock(BB);
 
-  if (ExceptionHandling && BB->isLandingPad()) {
-    MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+  MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
 
-    if (MMI) {
-      // Add a label to mark the beginning of the landing pad.  Deletion of the
-      // landing pad can thus be detected via the MachineModuleInfo.
-      unsigned LabelID = MMI->addLandingPad(BB);
-      DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, DAG.getEntryNode(),
-                              DAG.getConstant(LabelID, MVT::i32)));
+  if (ExceptionHandling && MMI && BB->isLandingPad()) {
+    // Add a label to mark the beginning of the landing pad.  Deletion of the
+    // landing pad can thus be detected via the MachineModuleInfo.
+    unsigned LabelID = MMI->addLandingPad(BB);
+    DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, DAG.getEntryNode(),
+                            DAG.getConstant(LabelID, MVT::i32)));
+
+    // FIXME: Hack around an exception handling flaw (PR1508): the personality
+    // function and list of typeids logically belong to the invoke (or, if you
+    // like, the basic block containing the invoke), and need to be associated
+    // with it in the dwarf exception handling tables.  Currently however the
+    // information is provided by intrinsics (eh.filter and eh.selector) that
+    // can be moved to unexpected places by the optimizers: if the unwind edge
+    // is critical, then breaking it can result in the intrinsics being in the
+    // successor of the landing pad, not the landing pad itself.  This results
+    // in exceptions not being caught because no typeids are associated with
+    // the invoke.  This may not be the only way things can go wrong, but it
+    // is the only way we try to work around for the moment.
+    BranchInst *Br = dyn_cast<BranchInst>(LLVMBB->getTerminator());
+
+    if (Br && Br->isUnconditional()) { // Critical edge?
+      BasicBlock::iterator I, E;
+      for (I = LLVMBB->begin(), E = --LLVMBB->end(); I != E; ++I)
+        if (isFilterOrSelector(I))
+          break;
+
+      if (I == E)
+        // No catch info found - try to extract some from the successor.
+        copyCatchInfo(Br->getSuccessor(0), LLVMBB, MMI, FuncInfo);
     }
   }
 






More information about the llvm-commits mailing list