diff options
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 139 | 
1 files changed, 137 insertions, 2 deletions
| 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, | 

