diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/MachineModuleInfo.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/PrologEpilogInserter.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 16 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 47 |
5 files changed, 71 insertions, 2 deletions
diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp index 88d8507425..77fb643b65 100644 --- a/lib/CodeGen/MachineModuleInfo.cpp +++ b/lib/CodeGen/MachineModuleInfo.cpp @@ -1476,6 +1476,8 @@ MachineModuleInfo::MachineModuleInfo() , FrameMoves() , LandingPads() , Personalities() +, CallsEHReturn(0) +, CallsUnwindInit(0) { // Always emit "no personality" info Personalities.push_back(NULL); @@ -1523,6 +1525,8 @@ void MachineModuleInfo::EndFunction() { TypeInfos.clear(); FilterIds.clear(); FilterEnds.clear(); + CallsEHReturn = 0; + CallsUnwindInit = 0; } /// getDescFor - Convert a Value to a debug information descriptor. diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index 0658ad23c8..882c6a7440 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -121,7 +121,7 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { const TargetFrameInfo *TFI = Fn.getTarget().getFrameInfo(); // Get the callee saved register list... - const unsigned *CSRegs = RegInfo->getCalleeSavedRegs(); + const unsigned *CSRegs = RegInfo->getCalleeSavedRegs(&Fn); // Get the function call frame set-up and tear-down instruction opcode int FrameSetupOpcode = RegInfo->getCallFrameSetupOpcode(); @@ -170,7 +170,7 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { // function, thus needing to be saved and restored in the prolog/epilog. // const TargetRegisterClass* const *CSRegClasses = - RegInfo->getCalleeSavedRegClasses(); + RegInfo->getCalleeSavedRegClasses(&Fn); std::vector<CalleeSavedInfo> CSI; for (unsigned i = 0; CSRegs[i]; ++i) { unsigned Reg = CSRegs[i]; diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index a5146bd452..8b82b62b65 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -640,6 +640,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { break; case ISD::FRAMEADDR: case ISD::RETURNADDR: + case ISD::FRAME_TO_ARGS_OFFSET: // 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); @@ -695,6 +696,21 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { } } break; + case ISD::EH_RETURN: + MVT::ValueType VT = Node->getValueType(0); + // The only "good" option for this node is to custom lower it. + switch (TLI.getOperationAction(Node->getOpcode(), VT)) { + default: assert(0 && "This action is not supported at all!"); + case TargetLowering::Custom: + Result = TLI.LowerOperation(Op, DAG); + if (Result.Val) break; + // Fall Thru + case TargetLowering::Legal: + // Target does not know, how to lower this, lower to noop + Result = LegalizeOp(Node->getOperand(0)); + break; + } + break; case ISD::AssertSext: case ISD::AssertZext: Tmp1 = LegalizeOp(Node->getOperand(0)); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index dc23151bdd..9803ab87e2 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3369,8 +3369,10 @@ std::string 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::FRAME_TO_ARGS_OFFSET: return "FRAME_TO_ARGS_OFFSET"; case ISD::EXCEPTIONADDR: return "EXCEPTIONADDR"; case ISD::EHSELECTION: return "EHSELECTION"; + case ISD::EH_RETURN: return "EH_RETURN"; 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 87bf249764..8a2f7b1f5f 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2721,6 +2721,53 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { return 0; } + case Intrinsic::eh_return: { + MachineModuleInfo *MMI = DAG.getMachineModuleInfo(); + + if (MMI && ExceptionHandling) { + MMI->setCallsEHReturn(true); + DAG.setRoot(DAG.getNode(ISD::EH_RETURN, + MVT::Other, + getRoot(), + getValue(I.getOperand(1)), + getValue(I.getOperand(2)))); + } else { + setValue(&I, DAG.getConstant(0, TLI.getPointerTy())); + } + + return 0; + } + + case Intrinsic::eh_unwind_init: { + if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo()) { + MMI->setCallsUnwindInit(true); + } + + return 0; + } + + case Intrinsic::eh_dwarf_cfa: { + if (ExceptionHandling) { + MVT::ValueType VT = getValue(I.getOperand(1)).getValueType(); + SDOperand Offset = DAG.getNode(ISD::ADD, + TLI.getPointerTy(), + DAG.getNode(ISD::FRAME_TO_ARGS_OFFSET, + VT), + getValue(I.getOperand(1))); + setValue(&I, DAG.getNode(ISD::ADD, + TLI.getPointerTy(), + DAG.getNode(ISD::FRAMEADDR, + TLI.getPointerTy(), + DAG.getConstant(0, + TLI.getPointerTy())), + Offset)); + } else { + setValue(&I, DAG.getConstant(0, TLI.getPointerTy())); + } + + return 0; + } + case Intrinsic::sqrt_f32: case Intrinsic::sqrt_f64: setValue(&I, DAG.getNode(ISD::FSQRT, |