From 126d90770bdb17e6925b2fe26de99aa079b7b9b3 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 4 Jul 2008 11:47:58 +0000 Subject: [PATCH] Rather than having a different custom legalization hook for each way in which a result type can be legalized (promotion, expansion, softening etc), just use one: ReplaceNodeResults, which returns a node with exactly the same result types as the node passed to it, but presumably with a bunch of custom code behind the scenes. No change if the new LegalizeTypes infrastructure is not turned on. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53137 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetLowering.h | 21 ++--- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 16 ++-- .../SelectionDAG/LegalizeFloatTypes.cpp | 22 ++--- .../SelectionDAG/LegalizeIntegerTypes.cpp | 87 +++++++++++-------- .../SelectionDAG/LegalizeVectorTypes.cpp | 42 --------- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 6 -- lib/Target/ARM/ARMISelLowering.cpp | 6 +- lib/Target/ARM/ARMISelLowering.h | 2 +- lib/Target/Alpha/AlphaISelLowering.cpp | 73 +++++++++------- lib/Target/Alpha/AlphaISelLowering.h | 10 ++- lib/Target/PowerPC/PPCISelLowering.cpp | 2 +- lib/Target/PowerPC/PPCISelLowering.h | 2 +- lib/Target/X86/X86ISelLowering.cpp | 5 +- lib/Target/X86/X86ISelLowering.h | 6 +- 14 files changed, 137 insertions(+), 163 deletions(-) diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index c66e0fa00e1..559004a6bd3 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1055,19 +1055,19 @@ public: /// implement this. The default implementation of this aborts. virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); - /// ExpandOperationResult - This callback is invoked for operations that are + /// ReplaceNodeResults - This callback is invoked for operations that are /// unsupported by the target, which are registered to use 'custom' lowering, - /// and whose result type needs to be expanded. This must return a node whose - /// results precisely match the results of the input node. This typically - /// involves a MERGE_VALUES node and/or BUILD_PAIR. + /// and whose result type is illegal. This must return a node whose results + /// precisely match the results of the input node. This typically involves a + /// MERGE_VALUES node and/or BUILD_PAIR. /// /// If the target has no operations that require custom lowering, it need not - /// implement this. The default implementation of this aborts. - virtual SDNode *ExpandOperationResult(SDNode *N, SelectionDAG &DAG) { - assert(0 && "ExpandOperationResult not implemented for this target!"); + /// implement this. The default implementation aborts. + virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) { + assert(0 && "ReplaceNodeResults not implemented for this target!"); return 0; } - + /// IsEligibleForTailCallOptimization - Check whether the call is eligible for /// tail call optimization. Targets which want to do tail call optimization /// should override this function. @@ -1107,11 +1107,6 @@ public: return Chain; } - /// CustomPromoteOperation - This callback is invoked for operations that are - /// unsupported by the target, are registered to use 'custom' lowering, and - /// whose type needs to be promoted. - virtual SDOperand CustomPromoteOperation(SDOperand Op, SelectionDAG &DAG); - /// getTargetNodeName() - This method returns the name of a target specific /// DAG node. virtual const char *getTargetNodeName(unsigned Opcode) const; diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index c6de8625144..d929ec01c31 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1236,7 +1236,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0)); AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); return Result.getValue(Op.ResNo); - } + } case ISD::ATOMIC_LOAD_ADD: case ISD::ATOMIC_LOAD_SUB: case ISD::ATOMIC_LOAD_AND: @@ -1254,14 +1254,14 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { for (unsigned int x = 0; x < num_operands; ++x) Ops[x] = LegalizeOp(Node->getOperand(x)); Result = DAG.UpdateNodeOperands(Result, &Ops[0], num_operands); - + switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { default: assert(0 && "This action is not supported yet!"); case TargetLowering::Custom: Result = TLI.LowerOperation(Result, DAG); break; case TargetLowering::Expand: - Result = SDOperand(TLI.ExpandOperationResult(Op.Val, DAG),0); + Result = SDOperand(TLI.ReplaceNodeResults(Op.Val, DAG),0); break; case TargetLowering::Legal: break; @@ -1269,7 +1269,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0)); AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); return Result.getValue(Op.ResNo); - } + } case ISD::Constant: { ConstantSDNode *CN = cast(Node); unsigned opAction = @@ -4399,7 +4399,7 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) { Tmp2 = Node->getOperand(1); // Get the pointer. if (TLI.getOperationAction(ISD::VAARG, VT) == TargetLowering::Custom) { Tmp3 = DAG.getVAArg(VT, Tmp1, Tmp2, Node->getOperand(2)); - Result = TLI.CustomPromoteOperation(Tmp3, DAG); + Result = TLI.LowerOperation(Tmp3, DAG); } else { const Value *V = cast(Node->getOperand(2))->getValue(); SDOperand VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2, V, 0); @@ -5640,15 +5640,15 @@ SDOperand SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDOperand LegalOp, // Okay, we found the operation and type to use. SDOperand Operation = DAG.getNode(OpToUse, NewOutTy, LegalOp); - + // If the operation produces an invalid type, it must be custom lowered. Use // the target lowering hooks to expand it. Just keep the low part of the // expanded operation, we know that we're truncating anyway. if (getTypeAction(NewOutTy) == Expand) { - Operation = SDOperand(TLI.ExpandOperationResult(Operation.Val, DAG), 0); + Operation = SDOperand(TLI.ReplaceNodeResults(Operation.Val, DAG), 0); assert(Operation.Val && "Didn't return anything"); } - + // Truncate the result of the extended FP_TO_*INT operation to the desired // size. return DAG.getNode(ISD::TRUNCATE, DestVT, Operation); diff --git a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index b2580f5fa70..bfe2ce6d883 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -48,20 +48,17 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) { cerr << "\n"); SDOperand R = SDOperand(); - // FIXME: Custom lowering for float-to-int? -#if 0 - // See if the target wants to custom convert this node to an integer. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == + // See if the target wants to custom expand this node. + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) == TargetLowering::Custom) { // If the target wants to, allow it to lower this itself. - if (SDNode *P = TLI.FloatToIntOperationResult(N, DAG)) { + if (SDNode *P = TLI.ReplaceNodeResults(N, DAG)) { // Everything that once used N now uses P. We are guaranteed that the // result value types of N and the result value types of P match. ReplaceNodeWith(N, P); return; } } -#endif switch (N->getOpcode()) { default: @@ -315,12 +312,9 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) { cerr << "\n"); SDOperand Res(0, 0); - // FIXME: Custom lowering for float-to-int? -#if 0 if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) == TargetLowering::Custom) - Res = TLI.LowerOperation(SDOperand(N, 0), DAG); -#endif + Res = TLI.LowerOperation(SDOperand(N, OpNo), DAG); if (Res.Val == 0) { switch (N->getOpcode()) { @@ -517,10 +511,10 @@ void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { Lo = Hi = SDOperand(); // See if the target wants to custom expand this node. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) { + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) == + TargetLowering::Custom) { // If the target wants to, allow it to lower this itself. - if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { + if (SDNode *P = TLI.ReplaceNodeResults(N, DAG)) { // Everything that once used N now uses P. We are guaranteed that the // result value types of N and the result value types of P match. ReplaceNodeWith(N, P); @@ -742,7 +736,7 @@ bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) { if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) == TargetLowering::Custom) - Res = TLI.LowerOperation(SDOperand(N, 0), DAG); + Res = TLI.LowerOperation(SDOperand(N, OpNo), DAG); if (Res.Val == 0) { switch (N->getOpcode()) { diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 1a97dcaf586..d877b0a093c 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -34,6 +34,18 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { DEBUG(cerr << "Promote integer result: "; N->dump(&DAG); cerr << "\n"); SDOperand Result = SDOperand(); + // See if the target wants to custom expand this node. + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) == + TargetLowering::Custom) { + // If the target wants to, allow it to lower this itself. + if (SDNode *P = TLI.ReplaceNodeResults(N, DAG)) { + // Everything that once used N now uses P. We are guaranteed that the + // result value types of N and the result value types of P match. + ReplaceNodeWith(N, P); + return; + } + } + switch (N->getOpcode()) { default: #ifndef NDEBUG @@ -453,41 +465,48 @@ SDOperand DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) { /// node may need promotion or expansion as well as the specified one. bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) { DEBUG(cerr << "Promote integer operand: "; N->dump(&DAG); cerr << "\n"); - SDOperand Res; - switch (N->getOpcode()) { - default: -#ifndef NDEBUG - cerr << "PromoteIntegerOperand Op #" << OpNo << ": "; - N->dump(&DAG); cerr << "\n"; -#endif - assert(0 && "Do not know how to promote this operator's operand!"); - abort(); + SDOperand Res(0, 0); - case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break; - case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break; - case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break; - case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break; - case ISD::FP_EXTEND: Res = PromoteIntOp_FP_EXTEND(N); break; - case ISD::FP_ROUND: Res = PromoteIntOp_FP_ROUND(N); break; - case ISD::SINT_TO_FP: - case ISD::UINT_TO_FP: Res = PromoteIntOp_INT_TO_FP(N); break; - case ISD::BUILD_PAIR: Res = PromoteIntOp_BUILD_PAIR(N); break; + if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) + == TargetLowering::Custom) + Res = TLI.LowerOperation(SDOperand(N, OpNo), DAG); - case ISD::BRCOND: Res = PromoteIntOp_BRCOND(N, OpNo); break; - case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break; - case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break; - case ISD::SELECT_CC: Res = PromoteIntOp_SELECT_CC(N, OpNo); break; - case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break; + if (Res.Val == 0) { + switch (N->getOpcode()) { + default: + #ifndef NDEBUG + cerr << "PromoteIntegerOperand Op #" << OpNo << ": "; + N->dump(&DAG); cerr << "\n"; + #endif + assert(0 && "Do not know how to promote this operator's operand!"); + abort(); - case ISD::STORE: Res = PromoteIntOp_STORE(cast(N), - OpNo); break; + case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break; + case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break; + case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break; + case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break; + case ISD::FP_EXTEND: Res = PromoteIntOp_FP_EXTEND(N); break; + case ISD::FP_ROUND: Res = PromoteIntOp_FP_ROUND(N); break; + case ISD::SINT_TO_FP: + case ISD::UINT_TO_FP: Res = PromoteIntOp_INT_TO_FP(N); break; + case ISD::BUILD_PAIR: Res = PromoteIntOp_BUILD_PAIR(N); break; - case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break; - case ISD::INSERT_VECTOR_ELT: - Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo); - break; + case ISD::BRCOND: Res = PromoteIntOp_BRCOND(N, OpNo); break; + case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break; + case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break; + case ISD::SELECT_CC: Res = PromoteIntOp_SELECT_CC(N, OpNo); break; + case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break; - case ISD::MEMBARRIER: Res = PromoteIntOp_MEMBARRIER(N); break; + case ISD::STORE: Res = PromoteIntOp_STORE(cast(N), + OpNo); break; + + case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break; + case ISD::INSERT_VECTOR_ELT: + Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo); + break; + + case ISD::MEMBARRIER: Res = PromoteIntOp_MEMBARRIER(N); break; + } } // If the result is null, the sub-method took care of registering results etc. @@ -777,10 +796,10 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) { Lo = Hi = SDOperand(); // See if the target wants to custom expand this node. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) { + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) == + TargetLowering::Custom) { // If the target wants to, allow it to lower this itself. - if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { + if (SDNode *P = TLI.ReplaceNodeResults(N, DAG)) { // Everything that once used N now uses P. We are guaranteed that the // result value types of N and the result value types of P match. ReplaceNodeWith(N, P); @@ -1626,7 +1645,7 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) { if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) == TargetLowering::Custom) - Res = TLI.LowerOperation(SDOperand(N, 0), DAG); + Res = TLI.LowerOperation(SDOperand(N, OpNo), DAG); if (Res.Val == 0) { switch (N->getOpcode()) { diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index 5306f82048b..44ee8ad706d 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -32,21 +32,6 @@ void DAGTypeLegalizer::ScalarizeResult(SDNode *N, unsigned ResNo) { cerr << "\n"); SDOperand R = SDOperand(); - // FIXME: Custom lowering for scalarization? -#if 0 - // See if the target wants to custom expand this node. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) { - // If the target wants to, allow it to lower this itself. - if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { - // Everything that once used N now uses P. We are guaranteed that the - // result value types of N and the result value types of P match. - ReplaceNodeWith(N, P); - return; - } - } -#endif - switch (N->getOpcode()) { default: #ifndef NDEBUG @@ -167,13 +152,6 @@ bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) { cerr << "\n"); SDOperand Res(0, 0); - // FIXME: Should we support custom lowering for scalarization? -#if 0 - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) - Res = TLI.LowerOperation(SDOperand(N, 0), DAG); -#endif - if (Res.Val == 0) { switch (N->getOpcode()) { default: @@ -253,20 +231,6 @@ void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) { DEBUG(cerr << "Split node result: "; N->dump(&DAG); cerr << "\n"); SDOperand Lo, Hi; -#if 0 - // See if the target wants to custom expand this node. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) { - // If the target wants to, allow it to lower this itself. - if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { - // Everything that once used N now uses P. We are guaranteed that the - // result value types of N and the result value types of P match. - ReplaceNodeWith(N, P); - return; - } - } -#endif - switch (N->getOpcode()) { default: #ifndef NDEBUG @@ -573,12 +537,6 @@ bool DAGTypeLegalizer::SplitOperand(SDNode *N, unsigned OpNo) { DEBUG(cerr << "Split node operand: "; N->dump(&DAG); cerr << "\n"); SDOperand Res(0, 0); -#if 0 - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) - Res = TLI.LowerOperation(SDOperand(N, 0), DAG); -#endif - if (Res.Val == 0) { switch (N->getOpcode()) { default: diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 0565e16eee0..9e7e9d8e424 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -4843,12 +4843,6 @@ SDOperand TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return SDOperand(); } -SDOperand TargetLowering::CustomPromoteOperation(SDOperand Op, - SelectionDAG &DAG) { - assert(0 && "CustomPromoteOperation not implemented for this target!"); - abort(); - return SDOperand(); -} //===----------------------------------------------------------------------===// // SelectionDAGISel code diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index b19c1d7c7d3..57044e567d1 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -1418,9 +1418,9 @@ SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { } -/// ExpandOperationResult - Provide custom lowering hooks for expanding -/// operations. -SDNode *ARMTargetLowering::ExpandOperationResult(SDNode *N, SelectionDAG &DAG) { +/// ReplaceNodeResults - Provide custom lowering hooks for nodes with illegal +/// result types. +SDNode *ARMTargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) { switch (N->getOpcode()) { default: assert(0 && "Don't know how to custom expand this!"); abort(); case ISD::BIT_CONVERT: return ExpandBIT_CONVERT(N, DAG); diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index 8e5a8b36d5f..969d42b736f 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -76,7 +76,7 @@ namespace llvm { explicit ARMTargetLowering(TargetMachine &TM); virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); - virtual SDNode *ExpandOperationResult(SDNode *N, SelectionDAG &DAG); + virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp index 83c3a483bc2..bf3a31dab17 100644 --- a/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/lib/Target/Alpha/AlphaISelLowering.cpp @@ -392,6 +392,34 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, return std::make_pair(RetVal, Chain); } +void AlphaTargetLowering::LowerVAARG(SDNode *N, SDOperand &Chain, + SDOperand &DataPtr, SelectionDAG &DAG) { + Chain = N->getOperand(0); + SDOperand VAListP = N->getOperand(1); + const Value *VAListS = cast(N->getOperand(2))->getValue(); + + SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP, VAListS, 0); + SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP, + DAG.getConstant(8, MVT::i64)); + SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1), + Tmp, NULL, 0, MVT::i32); + DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset); + if (N->getValueType(0).isFloatingPoint()) + { + //if fp && Offset < 6*8, then subtract 6*8 from DataPtr + SDOperand FPDataPtr = DAG.getNode(ISD::SUB, MVT::i64, DataPtr, + DAG.getConstant(8*6, MVT::i64)); + SDOperand CC = DAG.getSetCC(MVT::i64, Offset, + DAG.getConstant(8*6, MVT::i64), ISD::SETLT); + DataPtr = DAG.getNode(ISD::SELECT, MVT::i64, CC, FPDataPtr, DataPtr); + } + + SDOperand NewOffset = DAG.getNode(ISD::ADD, MVT::i64, Offset, + DAG.getConstant(8, MVT::i64)); + Chain = DAG.getTruncStore(Offset.getValue(1), NewOffset, Tmp, NULL, 0, + MVT::i32); +} + /// LowerOperation - Provide custom lowering hooks for some operations. /// SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { @@ -493,37 +521,15 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { break; case ISD::VAARG: { - SDOperand Chain = Op.getOperand(0); - SDOperand VAListP = Op.getOperand(1); - const Value *VAListS = cast(Op.getOperand(2))->getValue(); - - SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP, VAListS, 0); - SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP, - DAG.getConstant(8, MVT::i64)); - SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1), - Tmp, NULL, 0, MVT::i32); - SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset); - if (Op.getValueType().isFloatingPoint()) - { - //if fp && Offset < 6*8, then subtract 6*8 from DataPtr - SDOperand FPDataPtr = DAG.getNode(ISD::SUB, MVT::i64, DataPtr, - DAG.getConstant(8*6, MVT::i64)); - SDOperand CC = DAG.getSetCC(MVT::i64, Offset, - DAG.getConstant(8*6, MVT::i64), ISD::SETLT); - DataPtr = DAG.getNode(ISD::SELECT, MVT::i64, CC, FPDataPtr, DataPtr); - } + SDOperand Chain, DataPtr; + LowerVAARG(Op.Val, Chain, DataPtr, DAG); - SDOperand NewOffset = DAG.getNode(ISD::ADD, MVT::i64, Offset, - DAG.getConstant(8, MVT::i64)); - SDOperand Update = DAG.getTruncStore(Offset.getValue(1), NewOffset, - Tmp, NULL, 0, MVT::i32); - SDOperand Result; if (Op.getValueType() == MVT::i32) - Result = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Update, DataPtr, + Result = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Chain, DataPtr, NULL, 0, MVT::i32); else - Result = DAG.getLoad(Op.getValueType(), Update, DataPtr, NULL, 0); + Result = DAG.getLoad(Op.getValueType(), Chain, DataPtr, NULL, 0); return Result; } case ISD::VACOPY: { @@ -564,14 +570,15 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return SDOperand(); } -SDOperand AlphaTargetLowering::CustomPromoteOperation(SDOperand Op, - SelectionDAG &DAG) { - assert(Op.getValueType() == MVT::i32 && - Op.getOpcode() == ISD::VAARG && +SDNode *AlphaTargetLowering::ReplaceNodeResults(SDNode *N, + SelectionDAG &DAG) { + assert(N->getValueType(0) == MVT::i32 && + N->getOpcode() == ISD::VAARG && "Unknown node to custom promote!"); - - // The code in LowerOperation already handles i32 vaarg - return LowerOperation(Op, DAG); + + SDOperand Chain, DataPtr; + LowerVAARG(N, Chain, DataPtr, DAG); + return DAG.getLoad(N->getValueType(0), Chain, DataPtr, NULL, 0).Val; } diff --git a/lib/Target/Alpha/AlphaISelLowering.h b/lib/Target/Alpha/AlphaISelLowering.h index f88437e92e3..1440908c4f9 100644 --- a/lib/Target/Alpha/AlphaISelLowering.h +++ b/lib/Target/Alpha/AlphaISelLowering.h @@ -72,9 +72,9 @@ namespace llvm { /// LowerOperation - Provide custom lowering hooks for some operations. /// virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); - virtual SDOperand CustomPromoteOperation(SDOperand Op, SelectionDAG &DAG); + virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); - //Friendly names for dumps + // Friendly names for dumps const char *getTargetNodeName(unsigned Opcode) const; /// LowerCallTo - This hook lowers an abstract call to a function into an @@ -94,6 +94,12 @@ namespace llvm { MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB); + + private: + // Helpers for custom lowering. + void LowerVAARG(SDNode *N, SDOperand &Chain, SDOperand &DataPtr, + SelectionDAG &DAG); + }; } diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 4b2267d8122..d44dc5dcd4f 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -3964,7 +3964,7 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return SDOperand(); } -SDNode *PPCTargetLowering::ExpandOperationResult(SDNode *N, SelectionDAG &DAG) { +SDNode *PPCTargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) { switch (N->getOpcode()) { default: assert(0 && "Wasn't expecting to be able to lower this!"); case ISD::FP_TO_SINT: return LowerFP_TO_SINT(SDOperand(N, 0), DAG).Val; diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index e3ec7b0e3be..a620f414f23 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -273,7 +273,7 @@ namespace llvm { /// virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); - virtual SDNode *ExpandOperationResult(SDNode *N, SelectionDAG &DAG); + virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 9b57f3ac43a..c80c5476700 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -5762,8 +5762,9 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { } } -/// ExpandOperation - Provide custom lowering hooks for expanding operations. -SDNode *X86TargetLowering::ExpandOperationResult(SDNode *N, SelectionDAG &DAG) { +/// ReplaceNodeResults - Replace a node with an illegal result type +/// with a new node built out of custom code. +SDNode *X86TargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) { switch (N->getOpcode()) { default: assert(0 && "Should not custom lower this!"); case ISD::FP_TO_SINT: return ExpandFP_TO_SINT(N, DAG); diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index dff4beadbf7..648fe3bb1d2 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -352,10 +352,10 @@ namespace llvm { /// virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); - /// ExpandOperation - Custom lower the specified operation, splitting the - /// value into two pieces. + /// ReplaceNodeResults - Replace a node with an illegal result type + /// with a new node built out of custom code. /// - virtual SDNode *ExpandOperationResult(SDNode *N, SelectionDAG &DAG); + virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;