[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