diff options
author | Duncan Sands <baldrick@free.fr> | 2008-12-01 11:39:25 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2008-12-01 11:39:25 +0000 |
commit | 1607f05cb7d77d01ce521a30232faa389dbed4e2 (patch) | |
tree | aa158f63740a3b308cc75229bd80c57c21e269f1 | |
parent | d54d86038d1486e29969385a2cbd4fce1cd97202 (diff) |
Change the interface to the type legalization method
ReplaceNodeResults: rather than returning a node which
must have the same number of results as the original
node (which means mucking around with MERGE_VALUES,
and which is also easy to get wrong since SelectionDAG
folding may mean you don't get the node you expect),
return the results in a vector.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60348 91177308-0d34-0410-b5e6-96231b3b80d8
20 files changed, 377 insertions, 378 deletions
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 4350484207..6b7d42ecc4 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1130,17 +1130,18 @@ public: /// implement this. The default implementation of this aborts. virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); - /// ReplaceNodeResults - This callback is invoked for operations that are - /// unsupported by the target, which are registered to use 'custom' lowering, - /// 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. + /// ReplaceNodeResults - This callback is invoked when a node result type is + /// illegal for the target, and the operation was registered to use 'custom' + /// lowering for that result type. The target places new result values for + /// the node in Results (their number and types must exactly match those of + /// the original return values of the node), or leaves Results empty, which + /// indicates that the node is not to be custom lowered after all. /// /// If the target has no operations that require custom lowering, it need not /// implement this. The default implementation aborts. - virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) { + virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, + SelectionDAG &DAG) { assert(0 && "ReplaceNodeResults not implemented for this target!"); - return 0; } /// IsEligibleForTailCallOptimization - Check whether the call is eligible for diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 3ff6645fb3..5b230fb655 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -6083,8 +6083,10 @@ SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDValue LegalOp, // 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 = SDValue(TLI.ReplaceNodeResults(Operation.getNode(), DAG), 0); - assert(Operation.getNode() && "Didn't return anything"); + SmallVector<SDValue, 2> Results; + TLI.ReplaceNodeResults(Operation.getNode(), Results, DAG); + assert(Results.size() == 1 && "Incorrect FP_TO_XINT lowering!"); + Operation = Results[0]; } // Truncate the result of the extended FP_TO_*INT operation to the desired diff --git a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index e803bbac51..9510987525 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -727,16 +727,8 @@ void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { Lo = Hi = SDValue(); // 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; - } - } + if (CustomLowerResults(N, ResNo)) + return; switch (N->getOpcode()) { default: diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 6e781076b8..0c17531aca 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -34,16 +34,8 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { SDValue Result = SDValue(); // 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; - } - } + if (CustomLowerResults(N, ResNo)) + return; switch (N->getOpcode()) { default: @@ -949,16 +941,8 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) { Lo = Hi = SDValue(); // 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; - } - } + if (CustomLowerResults(N, ResNo)) + return; switch (N->getOpcode()) { default: diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 9502b27be1..9a22f09ee6 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -376,45 +376,6 @@ void DAGTypeLegalizer::ReplaceValueWith(SDValue From, SDValue To) { ReplacedValues[From] = To; } -/// ReplaceNodeWith - Replace uses of the 'from' node's results with the 'to' -/// node's results. The from and to node must define identical result types. -void DAGTypeLegalizer::ReplaceNodeWith(SDNode *From, SDNode *To) { - if (From == To) return; - - // If expansion produced new nodes, make sure they are properly marked. - ExpungeNode(From); - - To = AnalyzeNewNode(To); // Expunges To. - // If To morphed into an already processed node, its values may need - // remapping. This is done below. - - assert(From->getNumValues() == To->getNumValues() && - "Node results don't match"); - - // Anything that used the old node should now use the new one. Note that this - // can potentially cause recursive merging. - NodeUpdateListener NUL(*this); - for (unsigned i = 0, e = From->getNumValues(); i != e; ++i) { - SDValue FromVal(From, i); - SDValue ToVal(To, i); - - // AnalyzeNewNode may have morphed a new node into a processed node. Remap - // values now. - if (To->getNodeId() == Processed) - RemapValue(ToVal); - - assert(FromVal.getValueType() == ToVal.getValueType() && - "Node results don't match!"); - - // Make anything that used the old value use the new value. - DAG.ReplaceAllUsesOfValueWith(FromVal, ToVal, &NUL); - - // The old node may still be present in a map like ExpandedIntegers or - // PromotedIntegers. Inform maps about the replacement. - ReplacedValues[FromVal] = ToVal; - } -} - /// RemapValue - If the specified value was already legalized to another value, /// replace it by that value. void DAGTypeLegalizer::RemapValue(SDValue &N) { @@ -621,6 +582,28 @@ SDValue DAGTypeLegalizer::CreateStackStoreLoad(SDValue Op, return DAG.getLoad(DestVT, Store, FIPtr, NULL, 0); } +/// CustomLowerResults - Replace the node's results with custom code provided +/// by the target and return "true", or do nothing and return "false". +bool DAGTypeLegalizer::CustomLowerResults(SDNode *N, unsigned ResNo) { + // See if the target wants to custom lower this node. + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) != + TargetLowering::Custom) + return false; + + SmallVector<SDValue, 8> Results; + TLI.ReplaceNodeResults(N, Results, DAG); + if (Results.empty()) + // The target didn't want to custom lower it after all. + return false; + + // Make everything that once used N's values now use those in Results instead. + assert(Results.size() == N->getNumValues() && + "Custom lowering returned the wrong number of results!"); + for (unsigned i = 0, e = Results.size(); i != e; ++i) + ReplaceValueWith(SDValue(N, i), Results[i]); + return true; +} + /// JoinIntegers - Build an integer with low bits Lo and high bits Hi. SDValue DAGTypeLegalizer::JoinIntegers(SDValue Lo, SDValue Hi) { MVT LVT = Lo.getValueType(); diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 6d41cc5110..6a003a00c6 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -185,12 +185,13 @@ private: void AnalyzeNewValue(SDValue &Val); void ReplaceValueWith(SDValue From, SDValue To); - void ReplaceNodeWith(SDNode *From, SDNode *To); void RemapValue(SDValue &N); void ExpungeNode(SDNode *N); // Common routines. + bool CustomLowerResults(SDNode *N, unsigned ResNo); + SDValue CreateStackStoreLoad(SDValue Op, MVT DestVT); SDValue MakeLibCall(RTLIB::Libcall LC, MVT RetVT, const SDValue *Ops, unsigned NumOps, bool isSigned); diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index c54ebdc0b0..1f6294f03c 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -1344,7 +1344,7 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, return DAG.getNode(ISD::TokenFactor, MVT::Other, &TFOps[0], i); } -static SDNode *ExpandBIT_CONVERT(SDNode *N, SelectionDAG &DAG) { +static SDValue ExpandBIT_CONVERT(SDNode *N, SelectionDAG &DAG) { SDValue Op = N->getOperand(0); if (N->getValueType(0) == MVT::f64) { // Turn i64->f64 into FMDRR. @@ -1352,7 +1352,7 @@ static SDNode *ExpandBIT_CONVERT(SDNode *N, SelectionDAG &DAG) { DAG.getConstant(0, MVT::i32)); SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, DAG.getConstant(1, MVT::i32)); - return DAG.getNode(ARMISD::FMDRR, MVT::f64, Lo, Hi).getNode(); + return DAG.getNode(ARMISD::FMDRR, MVT::f64, Lo, Hi); } // Turn f64->i64 into FMRRD. @@ -1360,21 +1360,21 @@ static SDNode *ExpandBIT_CONVERT(SDNode *N, SelectionDAG &DAG) { &Op, 1); // Merge the pieces into a single i64 value. - return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Cvt, Cvt.getValue(1)).getNode(); + return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Cvt, Cvt.getValue(1)); } -static SDNode *ExpandSRx(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST) { +static SDValue ExpandSRx(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST) { assert(N->getValueType(0) == MVT::i64 && (N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA) && "Unknown shift to lower!"); - + // We only lower SRA, SRL of 1 here, all others use generic lowering. if (!isa<ConstantSDNode>(N->getOperand(1)) || cast<ConstantSDNode>(N->getOperand(1))->getZExtValue() != 1) - return 0; + return SDValue(); // If we are in thumb mode, we don't have RRX. - if (ST->isThumb()) return 0; + if (ST->isThumb()) return SDValue(); // Okay, we have a 64-bit SRA or SRL of 1. Lower this to an RRX expr. SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, N->getOperand(0), @@ -1391,7 +1391,7 @@ static SDNode *ExpandSRx(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST) { Lo = DAG.getNode(ARMISD::RRX, MVT::i32, Lo, Hi.getValue(1)); // Merge the pieces into a single i64 value. - return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi).getNode(); + return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); } @@ -1419,22 +1419,34 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::FRAMEADDR: break; case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG); - case ISD::BIT_CONVERT: return SDValue(ExpandBIT_CONVERT(Op.getNode(), DAG), 0); + case ISD::BIT_CONVERT: return ExpandBIT_CONVERT(Op.getNode(), DAG); case ISD::SRL: - case ISD::SRA: return SDValue(ExpandSRx(Op.getNode(), DAG,Subtarget),0); + case ISD::SRA: return ExpandSRx(Op.getNode(), DAG,Subtarget); } return SDValue(); } -/// ReplaceNodeResults - Provide custom lowering hooks for nodes with illegal -/// result types. -SDNode *ARMTargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) { +/// ReplaceNodeResults - Replace the results of node with an illegal result +/// type with new values built out of custom code. +/// +void ARMTargetLowering::ReplaceNodeResults(SDNode *N, + SmallVectorImpl<SDValue>&Results, + 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); + default: + assert(0 && "Don't know how to custom expand this!"); + return; + case ISD::BIT_CONVERT: + Results.push_back(ExpandBIT_CONVERT(N, DAG)); + return; case ISD::SRL: - case ISD::SRA: return ExpandSRx(N, DAG, Subtarget); + case ISD::SRA: { + SDValue Res = ExpandSRx(N, DAG, Subtarget); + if (Res.getNode()) + Results.push_back(Res); + return; + } } } diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index 8408cc527a..3f664fcd12 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -76,8 +76,13 @@ namespace llvm { explicit ARMTargetLowering(TargetMachine &TM); virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); - virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); - + + /// ReplaceNodeResults - Replace the results of node with an illegal result + /// type with new values built out of custom code. + /// + virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results, + SelectionDAG &DAG); + virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; virtual const char *getTargetNodeName(unsigned Opcode) const; diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp index 360db5fcff..66d66d0d8a 100644 --- a/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/lib/Target/Alpha/AlphaISelLowering.cpp @@ -612,15 +612,18 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { return SDValue(); } -SDNode *AlphaTargetLowering::ReplaceNodeResults(SDNode *N, - SelectionDAG &DAG) { +void AlphaTargetLowering::ReplaceNodeResults(SDNode *N, + SmallVectorImpl<SDValue>&Results, + SelectionDAG &DAG) { assert(N->getValueType(0) == MVT::i32 && N->getOpcode() == ISD::VAARG && "Unknown node to custom promote!"); SDValue Chain, DataPtr; LowerVAARG(N, Chain, DataPtr, DAG); - return DAG.getLoad(N->getValueType(0), Chain, DataPtr, NULL, 0).getNode(); + SDValue Res = DAG.getLoad(N->getValueType(0), Chain, DataPtr, NULL, 0); + Results.push_back(Res); + Results.push_back(SDValue(Res.getNode(), 1)); } diff --git a/lib/Target/Alpha/AlphaISelLowering.h b/lib/Target/Alpha/AlphaISelLowering.h index 3e870aff88..a29a518a10 100644 --- a/lib/Target/Alpha/AlphaISelLowering.h +++ b/lib/Target/Alpha/AlphaISelLowering.h @@ -72,7 +72,12 @@ namespace llvm { /// LowerOperation - Provide custom lowering hooks for some operations. /// virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); - virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); + + /// ReplaceNodeResults - Replace the results of node with an illegal result + /// type with new values built out of custom code. + /// + virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results, + SelectionDAG &DAG); // Friendly names for dumps const char *getTargetNodeName(unsigned Opcode) const; diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp index 6e64caecb4..bca8a4104f 100644 --- a/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/lib/Target/CellSPU/SPUISelLowering.cpp @@ -2866,7 +2866,9 @@ SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) return SDValue(); } -SDNode *SPUTargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) +void SPUTargetLowering::ReplaceNodeResults(SDNode *N, + SmallVectorImpl<SDValue>&Results, + SelectionDAG &DAG) { #if 0 unsigned Opc = (unsigned) N->getOpcode(); @@ -2885,7 +2887,6 @@ SDNode *SPUTargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) #endif /* Otherwise, return unchanged */ - return 0; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/CellSPU/SPUISelLowering.h b/lib/Target/CellSPU/SPUISelLowering.h index a252ee37a5..fefaa683cb 100644 --- a/lib/Target/CellSPU/SPUISelLowering.h +++ b/lib/Target/CellSPU/SPUISelLowering.h @@ -113,9 +113,10 @@ namespace llvm { //! Custom lowering hooks virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); - //! Provide custom lowering hooks for nodes with illegal result types. - SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); - + //! Custom lowering hook for nodes with illegal result types. + virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results, + SelectionDAG &DAG); + virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; virtual void computeMaskedBitsForTargetNode(const SDValue Op, diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp index 8a5fdb23e8..880fcc9496 100644 --- a/lib/Target/PIC16/PIC16ISelLowering.cpp +++ b/lib/Target/PIC16/PIC16ISelLowering.cpp @@ -90,24 +90,35 @@ const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const { } } -SDNode *PIC16TargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) { +void PIC16TargetLowering::ReplaceNodeResults(SDNode *N, + SmallVectorImpl<SDValue>&Results, + SelectionDAG &DAG) { switch (N->getOpcode()) { case ISD::GlobalAddress: - return ExpandGlobalAddress(N, DAG); + Results.push_back(ExpandGlobalAddress(N, DAG)); + return; case ISD::STORE: - return ExpandStore(N, DAG); + Results.push_back(ExpandStore(N, DAG)); + return; case ISD::LOAD: - return ExpandLoad(N, DAG); + Results.push_back(ExpandLoad(N, DAG)); + return; case ISD::ADD: - return ExpandAdd(N, DAG); - case ISD::SHL: - return ExpandShift(N, DAG); +// return ExpandAdd(N, DAG); + return; + case ISD::SHL: { + SDValue Res = ExpandShift(N, DAG); + if (Res.getNode()) + Results.push_back(Res); + return; + } default: assert (0 && "not implemented"); + return; } } -SDNode *PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) { +SDValue PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) { StoreSDNode *St = cast<StoreSDNode>(N); SDValue Chain = St->getChain(); SDValue Src = St->getValue(); @@ -119,9 +130,8 @@ SDNode *PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) { LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, StoreOffset); if (ValueType == MVT::i8) { - SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other, Chain, Src, - PtrLo, PtrHi, DAG.getConstant (0, MVT::i8)); - return Store.getNode(); + return DAG.getNode (PIC16ISD::PIC16Store, MVT::Other, Chain, Src, + PtrLo, PtrHi, DAG.getConstant (0, MVT::i8)); } else if (ValueType == MVT::i16) { // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR. @@ -142,7 +152,7 @@ SDNode *PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) { DAG.getConstant (1 + StoreOffset, MVT::i8)); return DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1), - getChain(Store2)).getNode(); + getChain(Store2)); } else if (ValueType == MVT::i32) { // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR. @@ -190,16 +200,16 @@ SDNode *PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) { getChain(Store2)); SDValue RetHi = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store3), getChain(Store4)); - return DAG.getNode(ISD::TokenFactor, MVT::Other, RetLo, RetHi).getNode(); - + return DAG.getNode(ISD::TokenFactor, MVT::Other, RetLo, RetHi); } else { assert (0 && "value type not supported"); + return SDValue(); } } // ExpandGlobalAddress - -SDNode *PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) { +SDValue PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) { GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(SDValue(N, 0)); SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i8, @@ -209,7 +219,7 @@ SDNode *PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) { SDValue Hi = DAG.getNode(PIC16ISD::Hi, MVT::i8, TGA); SDValue BP = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, Lo, Hi); - return BP.getNode(); + return BP; } bool PIC16TargetLowering::isDirectAddress(const SDValue &Op) { @@ -351,20 +361,20 @@ void PIC16TargetLowering:: LegalizeAddress(SDValue Ptr, SelectionDAG &DAG, return; } -SDNode *PIC16TargetLowering::ExpandAdd(SDNode *N, SelectionDAG &DAG) { - SDValue OperLeft = N->getOperand(0); - SDValue OperRight = N->getOperand(1); - - if((OperLeft.getOpcode() == ISD::Constant) || - (OperRight.getOpcode() == ISD::Constant)) { - return NULL; - } - - // These case are yet to be handled - return NULL; -} +//SDNode *PIC16TargetLowering::ExpandAdd(SDNode *N, SelectionDAG &DAG) { +// SDValue OperLeft = N->getOperand(0); +// SDValue OperRight = N->getOperand(1); +// +// if((OperLeft.getOpcode() == ISD::Constant) || +// (OperRight.getOpcode() == ISD::Constant)) { +// return NULL; +// } +// +// // These case are yet to be handled +// return NULL; +//} -SDNode *PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) { +SDValue PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) { LoadSDNode *LD = dyn_cast<LoadSDNode>(SDValue(N, 0)); SDValue Chain = LD->getChain(); SDValue Ptr = LD->getBasePtr(); @@ -438,7 +448,7 @@ SDNode *PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) { if (VT == MVT::i8) { // Operand of Load is illegal -- Load itself is legal - return PICLoads[0].getNode(); + return PICLoads[0]; } else if (VT == MVT::i16) { BP = DAG.getNode(ISD::BUILD_PAIR, VT, PICLoads[0], PICLoads[1]); @@ -467,12 +477,10 @@ SDNode *PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) { } } Tys = DAG.getVTList(VT, MVT::Other); - SDValue MergeV = DAG.getNode(ISD::MERGE_VALUES, Tys, BP, Chain); - return MergeV.getNode(); - + return DAG.getNode(ISD::MERGE_VALUES, Tys, BP, Chain); } -SDNode *PIC16TargetLowering::ExpandShift(SDNode *N, SelectionDAG &DAG) { +SDValue PIC16TargetLowering::ExpandShift(SDNode *N, SelectionDAG &DAG) { SDValue Value = N->getOperand(0); SDValue Amt = N->getOperand(1); SDValue BCF, BCFInput; @@ -483,11 +491,11 @@ SDNode *PIC16TargetLowering::ExpandShift(SDNode *N, SelectionDAG &DAG) { // Currently handling Constant shift only if (Amt.getOpcode() != ISD::Constant) - return NULL; + return SDValue(); // Following code considers 16 bit left-shift only if (N->getValueType(0) != MVT::i16) - return NULL; + return SDValue(); if (N->getOpcode() == ISD::SHL) { ShfNode = PIC16ISD::LSLF; @@ -515,8 +523,7 @@ SDNode *PIC16TargetLowering::ExpandShift(SDNode *N, SelectionDAG &DAG) { BCFInput = RotCom.getValue(1); } - SDValue BP = DAG.getNode(ISD::BUILD_PAIR, N->getValueType(0), ShfCom, RotCom); - return BP.getNode(); + return DAG.getNode(ISD::BUILD_PAIR, N->getValueType(0), ShfCom, RotCom); } SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { @@ -532,11 +539,11 @@ SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::SUBC: return LowerSUBC(Op, DAG); case ISD::LOAD: - return SDValue(ExpandLoad(Op.getNode(), DAG), Op.getResNo()); + return ExpandLoad(Op.getNode(), DAG); case ISD::STORE: - return SDValue(ExpandStore(Op.getNode(), DAG), Op.getResNo()); + return ExpandStore(Op.getNode(), DAG); case ISD::SHL: - return SDValue(ExpandShift(Op.getNode(), DAG), Op.getResNo()); + return ExpandShift(Op.getNode(), DAG); case ISD::OR: case ISD::AND: case ISD::XOR: diff --git a/lib/Target/PIC16/PIC16ISelLowering.h b/lib/Target/PIC16/PIC16ISelLowering.h index a2af24c6d9..de8bd2b024 100644 --- a/lib/Target/PIC16/PIC16ISelLowering.h +++ b/lib/Target/PIC16/PIC16ISelLowering.h @@ -66,12 +66,17 @@ namespace llvm { SDValue LowerSUBC(SDValue Op, SelectionDAG &DAG); SDValue LowerBinOp(SDValue Op, SelectionDAG &DAG); - SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); - SDNode *ExpandStore(SDNode *N, SelectionDAG &DAG); - SDNode *ExpandLoad(SDNode *N, SelectionDAG &DAG); - SDNode *ExpandAdd(SDNode *N, SelectionDAG &DAG); - SDNode *ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG); - SDNode *ExpandShift(SDNode *N, SelectionDAG &DAG); + /// ReplaceNodeResults - Replace the results of node with an illegal result + /// type with new values built out of custom code. + /// + virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results, + SelectionDAG &DAG); + + SDValue ExpandStore(SDNode *N, SelectionDAG &DAG); + SDValue ExpandLoad(SDNode *N, SelectionDAG &DAG); +// SDNode *ExpandAdd(SDNode *N, SelectionDAG &DAG); + SDValue ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG); + SDValue ExpandShift(SDNode *N, SelectionDAG &DAG); SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; SDValue PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const; diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index b02acaf9b1..d72fdf6ee5 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -2874,66 +2874,6 @@ SDValue PPCTargetLowering::LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) { return DAG.getLoad(Op.getValueType(), Chain, FIPtr, NULL, 0); } -SDValue PPCTargetLowering::LowerFP_ROUND_INREG(SDValue Op, - SelectionDAG &DAG) { - assert(Op.getValueType() == MVT::ppcf128); - SDNode *Node = Op.getNode(); - assert(Node->getOperand(0).getValueType() == MVT::ppcf128); - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::f64, Node->getOperand(0), - DAG.getIntPtrConstant(0)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::f64, Node->getOperand(0), - DAG.getIntPtrConstant(1)); - - // This sequence changes FPSCR to do round-to-zero, adds the two halves - // of the long double, and puts FPSCR back the way it was. We do not - // actually model FPSCR. - std::vector<MVT> NodeTys; - SDValue Ops[4], Result, MFFSreg, InFlag, FPreg; - - NodeTys.push_back(MVT::f64); // Return register - NodeTys.push_back(MVT::Flag); // Returns a flag for later insns - Result = DAG.getNode(PPCISD::MFFS, NodeTys, &InFlag, 0); - MFFSreg = Result.getValue(0); - InFlag = Result.getValue(1); - - NodeTys.clear(); - NodeTys.push_back(MVT::Flag); // Returns a flag - Ops[0] = DAG.getConstant(31, MVT::i32); - Ops[1] = InFlag; - Result = DAG.getNode(PPCISD::MTFSB1, NodeTys, Ops, 2); - InFlag = Result.getValue(0); - - NodeTys.clear(); - NodeTys.push_back(MVT::Flag); // Returns a flag - Ops[0] = DAG.getConstant(30, MVT::i32); - Ops[1] = InFlag; - Result = DAG.getNode(PPCISD::MTFSB0, NodeTys, Ops, 2); - InFlag = Result.getValue(0); - - NodeTys.clear(); - NodeTys.push_back(MVT::f64); // result of add - NodeTys.push_back(MVT::Flag); // Returns a flag - Ops[0] = Lo; - Ops[1] = Hi; - Ops[2] = InFlag; - Result = DAG.getNode(PPCISD::FADDRTZ, NodeTys, Ops, 3); - FPreg = Result.getValue(0); - InFlag = Result.getValue(1); - - NodeTys.clear(); - NodeTys.push_back(MVT::f64); - Ops[0] = DAG.getConstant(1, MVT::i32); - Ops[1] = MFFSreg; - Ops[2] = FPreg; - Ops[3] = InFlag; - Result = DAG.getNode(PPCISD::MTFSF, NodeTys, Ops, 4); - FPreg = Result.getValue(0); - - // We know the low half is about to be thrown away, so just use something - // convenient. - return DAG.getNode(ISD::BUILD_PAIR, MVT::ppcf128, FPreg, FPreg); -} - SDValue PPCTargetLowering::LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) { // Don't handle ppc_fp128 here; let it be lowered to a libcall. if (Op.getValueType() != MVT::f32 && Op.getValueType() != MVT::f64) @@ -3874,7 +3814,6 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG); case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG); - case ISD::FP_ROUND_INREG: return LowerFP_ROUND_INREG(Op, DAG); case ISD::FLT_ROUNDS_: return LowerFLT_ROUNDS_(Op, DAG); // Lower 64-bit shifts. @@ -3896,17 +3835,74 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { return SDValue(); } -SDNode *PPCTargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) { +void PPCTargetLowering::ReplaceNodeResults(SDNode *N, + SmallVectorImpl<SDValue>&Results, |