[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp SelectionDAGISel.cpp
Jim Laskey
jlaskey at apple.com
Wed Feb 21 14:54:04 PST 2007
Changes in directory llvm/lib/CodeGen/SelectionDAG:
LegalizeDAG.cpp updated: 1.476 -> 1.477
SelectionDAG.cpp updated: 1.389 -> 1.390
SelectionDAGISel.cpp updated: 1.369 -> 1.370
---
Log message:
Selection and lowering for exception handling.
---
Diffs of the changes: (+141 -2)
LegalizeDAG.cpp | 2
SelectionDAG.cpp | 2
SelectionDAGISel.cpp | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 141 insertions(+), 2 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.476 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.477
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.476 Wed Feb 14 21:39:18 2007
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Feb 21 16:53:45 2007
@@ -668,6 +668,8 @@
break;
case ISD::FRAMEADDR:
case ISD::RETURNADDR:
+ case ISD::EXCEPTIONADDR:
+ case ISD::EHSELECTION:
// The only option for these nodes is to custom lower them. If the target
// does not custom lower them, then return zero.
Tmp1 = TLI.LowerOperation(Op, DAG);
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.389 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.390
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.389 Sun Feb 4 02:35:21 2007
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Feb 21 16:53:45 2007
@@ -2679,6 +2679,8 @@
case ISD::GLOBAL_OFFSET_TABLE: return "GLOBAL_OFFSET_TABLE";
case ISD::RETURNADDR: return "RETURNADDR";
case ISD::FRAMEADDR: return "FRAMEADDR";
+ case ISD::EXCEPTIONADDR: return "EXCEPTIONADDR";
+ case ISD::EHSELECTION: return "EHSELECTION";
case ISD::ConstantPool: return "ConstantPool";
case ISD::ExternalSymbol: return "ExternalSymbol";
case ISD::INTRINSIC_WO_CHAIN: {
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.369 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.370
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.369 Wed Feb 14 21:39:18 2007
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Feb 21 16:53:45 2007
@@ -496,8 +496,8 @@
void visitJumpTable(SelectionDAGISel::JumpTable &JT);
// These all get lowered before this pass.
- void visitInvoke(InvokeInst &I) { assert(0 && "TODO"); }
- void visitUnwind(UnwindInst &I) { assert(0 && "TODO"); }
+ void visitInvoke(InvokeInst &I);
+ void visitUnwind(UnwindInst &I);
void visitScalarBinary(User &I, unsigned OpCode);
void visitVectorBinary(User &I, unsigned OpCode);
@@ -1101,6 +1101,56 @@
return;
}
+void SelectionDAGLowering::visitInvoke(InvokeInst &I) {
+ // Retrieve successors.
+ MachineBasicBlock *Return = FuncInfo.MBBMap[I.getSuccessor(0)];
+ MachineBasicBlock *LandingPad = FuncInfo.MBBMap[I.getSuccessor(1)];
+
+ // Mark landing pad so that it doesn't get deleted in branch folding.
+ LandingPad->setIsLandingPad();
+
+ // 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.
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+ unsigned BeginLabel = MMI->NextLabelID();
+ DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
+ DAG.getConstant(BeginLabel, MVT::i32)));
+
+ // Insert a normal call instruction.
+ std::vector<Value*> Args;
+ for (InvokeInst::op_iterator OI = I.op_begin() + 3, E = I.op_end();
+ OI != E; ++OI) {
+ Args.push_back(*OI);
+ }
+ CallInst *NewCall = new CallInst(I.getCalledValue(), &Args[0], Args.size(),
+ I.getName(), &I);
+ NewCall->setCallingConv(I.getCallingConv());
+ I.replaceAllUsesWith(NewCall);
+ visitCall(*NewCall);
+
+ // 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.
+ unsigned EndLabel = MMI->NextLabelID();
+ DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
+ DAG.getConstant(EndLabel, MVT::i32)));
+
+ // Inform MachineModuleInfo of range.
+ MMI->addInvoke(LandingPad, BeginLabel, EndLabel);
+
+ // Drop into normal successor.
+ DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getRoot(),
+ DAG.getBasicBlock(Return)));
+
+ // Update successor info
+ CurMBB->addSuccessor(Return);
+ CurMBB->addSuccessor(LandingPad);
+}
+
+void SelectionDAGLowering::visitUnwind(UnwindInst &I) {
+}
+
void SelectionDAGLowering::visitSwitch(SwitchInst &I) {
// Figure out which block is immediately after the current one.
MachineBasicBlock *NextBlock = 0;
@@ -2033,6 +2083,91 @@
return 0;
}
+ case Intrinsic::eh_exception: {
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+
+ // 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(CurMBB);
+ DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, DAG.getEntryNode(),
+ DAG.getConstant(LabelID, MVT::i32)));
+
+ // Mark exception register as live in.
+ const MRegisterInfo *MRI = DAG.getTarget().getRegisterInfo();
+ unsigned Reg = MRI->getEHExceptionRegister();
+ if (Reg) CurMBB->addLiveIn(Reg);
+
+ // Insert the EXCEPTIONADDR instruction.
+ SDVTList VTs = DAG.getVTList(TLI.getPointerTy(), MVT::Other);
+ SDOperand Ops[1];
+ Ops[0] = DAG.getRoot();
+ SDOperand Op = DAG.getNode(ISD::EXCEPTIONADDR, VTs, Ops, 1);
+ setValue(&I, Op);
+ DAG.setRoot(Op.getValue(1));
+
+ return 0;
+ }
+
+ case Intrinsic::eh_handlers: {
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+
+ // Inform the MachineModuleInfo of the personality for this landing pad.
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(2))) {
+ if (CE->getOpcode() == Instruction::BitCast) {
+ 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) {
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(i))) {
+ if (CE->getOpcode() == Instruction::BitCast) {
+ TyInfo.push_back(cast<GlobalVariable>(CE->getOperand(0)));
+ continue;
+ }
+ }
+
+ TyInfo.push_back(NULL);
+ }
+ MMI->addCatchTypeInfo(CurMBB, TyInfo);
+
+ // Mark exception selector register as live in.
+ const MRegisterInfo *MRI = DAG.getTarget().getRegisterInfo();
+ unsigned Reg = MRI->getEHHandlerRegister();
+ if (Reg) CurMBB->addLiveIn(Reg);
+
+ // Insert the EHSELECTION instruction.
+ SDVTList VTs = DAG.getVTList(TLI.getPointerTy(), MVT::Other);
+ SDOperand Ops[2];
+ Ops[0] = getValue(I.getOperand(1));
+ Ops[1] = getRoot();
+ SDOperand Op = DAG.getNode(ISD::EHSELECTION, VTs, Ops, 2);
+ setValue(&I, Op);
+ DAG.setRoot(Op.getValue(1));
+
+ return 0;
+ }
+
+ case Intrinsic::eh_typeid_for: {
+ GlobalVariable *GV = NULL;
+
+ // Find the type id for the given typeinfo.
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(1))) {
+ if (CE->getOpcode() == Instruction::BitCast) {
+ GV = cast<GlobalVariable>(CE->getOperand(0));
+ }
+ }
+
+ unsigned TypeID = MMI->getTypeIDFor(GV);
+ setValue(&I, DAG.getConstant(TypeID, MVT::i32));
+
+ return 0;
+ }
+
case Intrinsic::sqrt_f32:
case Intrinsic::sqrt_f64:
setValue(&I, DAG.getNode(ISD::FSQRT,
More information about the llvm-commits
mailing list