aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorJim Laskey <jlaskey@mac.com>2007-02-21 22:53:45 +0000
committerJim Laskey <jlaskey@mac.com>2007-02-21 22:53:45 +0000
commitb180aa17539e14a5430d020bbc7de83c79b7fc4b (patch)
treeb5a4c1f525b4b47f1dbb3448c12ac9772fede9a0 /lib/CodeGen
parentc518ccfeb540502176f5cea865f4eedb38d33b13 (diff)
Selection and lowering for exception handling.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34481 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/IntrinsicLowering.cpp5
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp139
4 files changed, 146 insertions, 2 deletions
diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp
index 35e20e3c69..03ca7afb50 100644
--- a/lib/CodeGen/IntrinsicLowering.cpp
+++ b/lib/CodeGen/IntrinsicLowering.cpp
@@ -357,6 +357,11 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
case Intrinsic::dbg_func_start:
case Intrinsic::dbg_declare:
break; // Simply strip out debugging intrinsics
+
+ case Intrinsic::eh_exception:
+ case Intrinsic::eh_handlers:
+ assert(0 && "Should not have leaked through");
+ break;
case Intrinsic::memcpy_i32:
case Intrinsic::memcpy_i64: {
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index eb44250cc0..0992e421b1 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -668,6 +668,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
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);
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 92c84d85e8..23a66f5562 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -2679,6 +2679,8 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const {
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: {
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 38d2300d70..10053acaab 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -496,8 +496,8 @@ public:
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 @@ void SelectionDAGLowering::visitJumpTable(SelectionDAGISel::JumpTable &JT) {
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 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
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,