diff options
| author | Jim Laskey <jlaskey@mac.com> | 2007-02-21 22:53:45 +0000 | 
|---|---|---|
| committer | Jim Laskey <jlaskey@mac.com> | 2007-02-21 22:53:45 +0000 | 
| commit | 4b37a4c712b6c6e0df8083dce530aa06b77d2c66 (patch) | |
| tree | 10e2596c161437a268356f177095417e756ffac6 /llvm/lib/CodeGen/SelectionDAG | |
| parent | e4ccf22c34b5ab2ca8bc989fbaa03eb62325ebb5 (diff) | |
| download | bcm5719-llvm-4b37a4c712b6c6e0df8083dce530aa06b77d2c66.tar.gz bcm5719-llvm-4b37a4c712b6c6e0df8083dce530aa06b77d2c66.zip | |
Selection and lowering for exception handling.
llvm-svn: 34481
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 139 | 
3 files changed, 141 insertions, 2 deletions
| diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index eb44250cc05..0992e421b1b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/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/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 92c84d85e84..23a66f55629 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/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/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 38d2300d709..10053acaab9 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/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, | 

