[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