aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/MachineModuleInfo.cpp4
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp4
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp16
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp47
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,