diff options
-rw-r--r-- | include/llvm/CodeGen/SelectionDAG.h | 8 | ||||
-rw-r--r-- | include/llvm/CodeGen/SelectionDAGNodes.h | 67 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 40 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 46 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp | 9 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp | 49 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 153 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp | 19 | ||||
-rw-r--r-- | lib/Target/CellSPU/SPUISelDAGToDAG.cpp | 6 | ||||
-rw-r--r-- | lib/Target/CellSPU/SPUISelLowering.cpp | 86 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 123 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 100 | ||||
-rw-r--r-- | test/CodeGen/X86/legalizedag_vec.ll | 4 |
14 files changed, 397 insertions, 318 deletions
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index f4b20fff6d..5f3196a8b8 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -403,6 +403,14 @@ public: (unsigned)Ops.size() - (InFlag.getNode() == 0 ? 1 : 0)); } + /// getBUILD_VECTOR - Return a new BUILD_VECTOR node + SDValue getBUILD_VECTOR(MVT vecVT, DebugLoc dl, SDValue E1); + SDValue getBUILD_VECTOR(MVT vecVT, DebugLoc dl, SDValue E1, SDValue E2); + SDValue getBUILD_VECTOR(MVT vecVT, DebugLoc dl, SDValue E1, SDValue E2, + SDValue E3, SDValue E4); + SDValue getBUILD_VECTOR(MVT vecVT, DebugLoc dl, const SDValue *Elts, + unsigned NumElts); + /// getUNDEF - Return an UNDEF node. UNDEF does not have a useful DebugLoc. SDValue getUNDEF(MVT VT) { return getNode(ISD::UNDEF, DebugLoc::getUnknownLoc(), VT); diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index e874ba7c06..4cb1a3d8e0 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -1929,6 +1929,73 @@ public: } }; +/// BuildVectorSDNode - A container for ISD::BUILD_VECTOR. This is used to +/// encapsulate common BUILD_VECTOR code and operations such as constant splat +/// testing. +class BuildVectorSDNode : public SDNode { + //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ + // Constant splat state: + //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ + //! We've computed the splat already? + bool computedSplat; + //! It is a splat? + bool isSplatVector; + //! Splat has undefined bits in it + bool hasUndefSplatBitsFlag; + //! The splat value + uint64_t SplatBits; + //! The undefined part of the splat + uint64_t SplatUndef; + //! The splat's size (1, 2, 4 or 8 bytes) + unsigned SplatSize; + +protected: + friend class SelectionDAG; + + //! Arbitrary element ISD::BUILD_VECTOR constructor + explicit BuildVectorSDNode(MVT vecVT, DebugLoc dl, const SDValue *Elts, + unsigned NumElts); + +public: + //! Constant splat predicate. + /*! + Determine if this ISD::BUILD_VECTOR is a constant splat. The results are + cached to prevent recomputation. + + @param MinSplatBits: minimum number of bits in the constant splat, defaults + to 0 for 'don't care', but normally one of [8, 16, 32, 64]. + @return true if the splat has the required minimum number of bits and the + splat really is a constant splat (accounting for undef bits). + */ + bool isConstantSplat(int MinSplatBits = 0); + + //! Get the splatbits + uint64_t getSplatBits() const { + assert(computedSplat && "BuildVectorSDNode: compute splat bits first!"); + return SplatBits; + } + + uint64_t getSplatUndef() const { + assert(computedSplat && "BuildVectorSDNode: compute splat bits first!"); + return SplatUndef; + } + + unsigned getSplatSize() const { + assert(computedSplat && "BuildVectorSDNode: compute splat bits first!"); + return SplatSize; + } + + bool hasAnyUndefBits() const { + assert(computedSplat && "BuildVectorSDNode: compute splat bits first!"); + return hasUndefSplatBitsFlag; + } + + static bool classof(const BuildVectorSDNode *) { return true; } + static bool classof(const SDNode *N) { + return N->getOpcode() == ISD::BUILD_VECTOR; + } +}; + /// SrcValueSDNode - An SDNode that holds an arbitrary LLVM IR Value. This is /// used when the SelectionDAG needs to make a simple reference to something /// in the LLVM IR representation. diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 4b3935c217..883f66afb1 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2386,8 +2386,7 @@ SDValue DAGCombiner::visitXOR(SDNode *N) { // Produce a vector of zeros. SDValue El = DAG.getConstant(0, VT.getVectorElementType()); std::vector<SDValue> Ops(VT.getVectorNumElements(), El); - return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT, - &Ops[0], Ops.size()); + return DAG.getBUILD_VECTOR(VT, N->getDebugLoc(), &Ops[0], Ops.size()); } } @@ -3858,8 +3857,7 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) { } MVT VT = MVT::getVectorVT(DstEltVT, BV->getValueType(0).getVectorNumElements()); - return DAG.getNode(ISD::BUILD_VECTOR, BV->getDebugLoc(), VT, - &Ops[0], Ops.size()); + return DAG.getBUILD_VECTOR(VT, BV->getDebugLoc(), &Ops[0], Ops.size()); } // Otherwise, we're growing or shrinking the elements. To avoid having to @@ -3915,8 +3913,7 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) { } MVT VT = MVT::getVectorVT(DstEltVT, Ops.size()); - return DAG.getNode(ISD::BUILD_VECTOR, BV->getDebugLoc(), VT, - &Ops[0], Ops.size()); + return DAG.getBUILD_VECTOR(VT, BV->getDebugLoc(), &Ops[0], Ops.size()); } // Finally, this must be the case where we are shrinking elements: each input @@ -3950,8 +3947,7 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) { std::reverse(Ops.end()-NumOutputsPerInput, Ops.end()); } - return DAG.getNode(ISD::BUILD_VECTOR, BV->getDebugLoc(), VT, - &Ops[0], Ops.size()); + return DAG.getBUILD_VECTOR(VT, BV->getDebugLoc(), &Ops[0], Ops.size()); } SDValue DAGCombiner::visitFADD(SDNode *N) { @@ -5084,8 +5080,8 @@ SDValue DAGCombiner::visitINSERT_VECTOR_ELT(SDNode *N) { InVec.getNode()->op_end()); if (Elt < Ops.size()) Ops[Elt] = InVal; - return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), - InVec.getValueType(), &Ops[0], Ops.size()); + return DAG.getBUILD_VECTOR(InVec.getValueType(), N->getDebugLoc(), + &Ops[0], Ops.size()); } return SDValue(); @@ -5270,13 +5266,13 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) { // Use an undef build_vector as input for the second operand. std::vector<SDValue> UnOps(NumInScalars, DAG.getUNDEF(EltType)); - Ops[1] = DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT, - &UnOps[0], UnOps.size()); + Ops[1] = DAG.getBUILD_VECTOR(VT, N->getDebugLoc(), + &UnOps[0], UnOps.size()); AddToWorkList(Ops[1].getNode()); } - Ops[2] = DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), BuildVecVT, - &BuildVecIndices[0], BuildVecIndices.size()); + Ops[2] = DAG.getBUILD_VECTOR(BuildVecVT, N->getDebugLoc(), + &BuildVecIndices[0], BuildVecIndices.size()); return DAG.getNode(ISD::VECTOR_SHUFFLE, N->getDebugLoc(), VT, Ops, 3); } @@ -5419,9 +5415,8 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) { } } - ShufMask = DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), - ShufMask.getValueType(), - &MappedOps[0], MappedOps.size()); + ShufMask = DAG.getBUILD_VECTOR(ShufMask.getValueType(), N->getDebugLoc(), + &MappedOps[0], MappedOps.size()); AddToWorkList(ShufMask.getNode()); return DAG.getNode(ISD::VECTOR_SHUFFLE, N->getDebugLoc(), N->getValueType(0), N0, @@ -5471,10 +5466,10 @@ SDValue DAGCombiner::XformToShuffleWithZero(SDNode *N) { Ops.push_back(LHS); AddToWorkList(LHS.getNode()); std::vector<SDValue> ZeroOps(NumElts, DAG.getConstant(0, EVT)); - Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), - VT, &ZeroOps[0], ZeroOps.size())); - Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), - MaskVT, &IdxOps[0], IdxOps.size())); + Ops.push_back(DAG.getBUILD_VECTOR(VT, N->getDebugLoc(), + &ZeroOps[0], ZeroOps.size())); + Ops.push_back(DAG.getBUILD_VECTOR(MaskVT, N->getDebugLoc(), + &IdxOps[0], IdxOps.size())); SDValue Result = DAG.getNode(ISD::VECTOR_SHUFFLE, N->getDebugLoc(), VT, &Ops[0], Ops.size()); @@ -5543,8 +5538,7 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) { if (Ops.size() == LHS.getNumOperands()) { MVT VT = LHS.getValueType(); - return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT, - &Ops[0], Ops.size()); + return DAG.getBUILD_VECTOR(VT, N->getDebugLoc(), &Ops[0], Ops.size()); } } diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 15af7dd98c..0ab749638a 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -353,8 +353,7 @@ SDNode *SelectionDAGLegalize::isShuffleLegal(MVT VT, SDValue Mask) const { } } } - Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getDebugLoc(), - NVT, &Ops[0], Ops.size()); + Mask = DAG.getBUILD_VECTOR(NVT, Mask.getDebugLoc(), &Ops[0], Ops.size()); } VT = NVT; break; @@ -931,7 +930,7 @@ SDValue SelectionDAGLegalize::UnrollVectorOp(SDValue Op) { } } - return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Scalars[0], Scalars.size()); + return DAG.getBUILD_VECTOR(VT, dl, &Scalars[0], Scalars.size()); } /// GetFPLibCall - Return the right libcall for the given floating point type. @@ -1290,7 +1289,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { unsigned Line = DSP->getLine(); unsigned Col = DSP->getColumn(); - const Function *F = DAG.getMachineFunction().getFunction(); if (!F->hasFnAttr(Attribute::OptimizeForSize)) { @@ -1676,8 +1674,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { else ShufOps.push_back(DAG.getConstant(NumElts, ShufMaskEltVT)); } - SDValue ShufMask = DAG.getNode(ISD::BUILD_VECTOR, dl, ShufMaskVT, - &ShufOps[0], ShufOps.size()); + SDValue ShufMask = DAG.getBUILD_VECTOR(ShufMaskVT, dl, + &ShufOps[0], ShufOps.size()); Result = DAG.getNode(ISD::VECTOR_SHUFFLE, dl, Tmp1.getValueType(), Tmp1, ScVec, ShufMask); @@ -1756,7 +1754,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { DAG.getConstant(Idx - NumElems, PtrVT))); } } - Result = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], Ops.size()); + Result = DAG.getBUILD_VECTOR(VT, dl, &Ops[0], Ops.size()); break; } case TargetLowering::Promote: { @@ -1808,8 +1806,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { DAG.getConstant(j, PtrVT))); } } - return LegalizeOp(DAG.getNode(ISD::BUILD_VECTOR, dl, Node->getValueType(0), - &Ops[0], Ops.size())); + return LegalizeOp(DAG.getBUILD_VECTOR(Node->getValueType(0), dl, + &Ops[0], Ops.size())); } case ISD::CALLSEQ_START: { @@ -3162,7 +3160,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { APInt::getAllOnesValue(EltVT.getSizeInBits()), EltVT), DAG.getConstant(0, EltVT)); } - Result = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElems); + Result = DAG.getBUILD_VECTOR(VT, dl, &Ops[0], NumElems); break; } } @@ -5557,8 +5555,8 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { MVT MaskVT = MVT::getIntVectorWithNumElements(NumElems); SDValue Zero = DAG.getConstant(0, MaskVT.getVectorElementType()); std::vector<SDValue> ZeroVec(NumElems, Zero); - SDValue SplatMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MaskVT, - &ZeroVec[0], ZeroVec.size()); + SDValue SplatMask = DAG.getBUILD_VECTOR(MaskVT, dl, + &ZeroVec[0], ZeroVec.size()); // If the target supports VECTOR_SHUFFLE and this shuffle mask, use it. if (isShuffleLegal(Node->getValueType(0), SplatMask)) { @@ -5610,8 +5608,8 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { else MaskVec[Val2Elts[i]] = DAG.getUNDEF(MaskEltVT); - SDValue ShuffleMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MaskVT, - &MaskVec[0], MaskVec.size()); + SDValue ShuffleMask = DAG.getBUILD_VECTOR(MaskVT, dl, + &MaskVec[0], MaskVec.size()); // If the target supports SCALAR_TO_VECTOR and this shuffle mask, use it. if (TLI.isOperationLegalOrCustom(ISD::SCALAR_TO_VECTOR, @@ -5957,7 +5955,7 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source, DebugLoc dl) { SDValue Scalar = ScalarizeVectorOp(Source); SDValue Result = LegalizeINT_TO_FP(SDValue(), isSigned, DestEltTy, Scalar, dl); - return DAG.getNode(ISD::BUILD_VECTOR, dl, DestTy, Result); + return DAG.getBUILD_VECTOR(DestTy, dl, Result); } SDValue Lo, Hi; SplitVectorOp(Source, Lo, Hi); @@ -7572,7 +7570,7 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, InVec, DAG.getConstant(Idx, PtrVT))); } - Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Lo, &Ops[0], Ops.size()); + Lo = DAG.getBUILD_VECTOR(NewVT_Lo, dl, &Ops[0], Ops.size()); Ops.clear(); for (unsigned i = NewNumElts_Lo; i != NumElements; ++i) { @@ -7590,17 +7588,17 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, InVec, DAG.getConstant(Idx, PtrVT))); } - Hi = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Hi, &Ops[0], Ops.size()); + Hi = DAG.getBUILD_VECTOR(NewVT_Hi, dl, &Ops[0], Ops.size()); break; } case ISD::BUILD_VECTOR: { SmallVector<SDValue, 8> LoOps(Node->op_begin(), Node->op_begin()+NewNumElts_Lo); - Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Lo, &LoOps[0], LoOps.size()); + Lo = DAG.getBUILD_VECTOR(NewVT_Lo, dl, &LoOps[0], LoOps.size()); SmallVector<SDValue, 8> HiOps(Node->op_begin()+NewNumElts_Lo, Node->op_end()); - Hi = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Hi, &HiOps[0], HiOps.size()); + Hi = DAG.getBUILD_VECTOR(NewVT_Hi, dl, &HiOps[0], HiOps.size()); break; } case ISD::CONCAT_VECTORS: { @@ -8066,8 +8064,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { for (unsigned i = NumElts; i < NewNumElts; ++i) { NewOps.push_back(DAG.getUNDEF(EVT)); } - Result = DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, - &NewOps[0], NewOps.size()); + Result = DAG.getBUILD_VECTOR(WidenVT, dl, &NewOps[0], NewOps.size()); break; } case ISD::INSERT_VECTOR_ELT: { @@ -8104,9 +8101,8 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { NewOps.push_back(DAG.getUNDEF(PVT)); } - SDValue Tmp3 = DAG.getNode(ISD::BUILD_VECTOR, dl, - MVT::getVectorVT(PVT, NewOps.size()), - &NewOps[0], NewOps.size()); + SDValue Tmp3 = DAG.getBUILD_VECTOR(MVT::getVectorVT(PVT, NewOps.size()), dl, + &NewOps[0], NewOps.size()); Result = DAG.getNode(ISD::VECTOR_SHUFFLE, dl, WidenVT, Tmp1, Tmp2, Tmp3); break; @@ -8152,7 +8148,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { Ops[i] = UndefVal; MVT NewInVT = MVT::getVectorVT(InVT, NewNumElts); - Result = DAG.getNode(ISD::BUILD_VECTOR, dl, NewInVT, &Ops[0], NewNumElts); + Result = DAG.getBUILD_VECTOR(NewInVT, dl, &Ops[0], NewNumElts); Result = DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, Result); } break; diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 661391be4d..b89d07ff40 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -810,9 +810,8 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) { NewElts.push_back(JoinIntegers(Lo, Hi)); } - SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl, - MVT::getVectorVT(NewVT, NewElts.size()), - &NewElts[0], NewElts.size()); + SDValue NewVec = DAG.getBUILD_VECTOR(MVT::getVectorVT(NewVT, NewElts.size()), + dl, &NewElts[0], NewElts.size()); // Convert the new vector to the old vector type. return DAG.getNode(ISD::BIT_CONVERT, dl, VecVT, NewVec); diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp index 65c00201b3..7a9210bb4e 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp @@ -246,7 +246,7 @@ SDValue DAGTypeLegalizer::ExpandOp_BIT_CONVERT(SDNode *N) { if (TLI.isBigEndian()) std::swap(Parts[0], Parts[1]); - SDValue Vec = DAG.getNode(ISD::BUILD_VECTOR, dl, NVT, Parts, 2); + SDValue Vec = DAG.getBUILD_VECTOR(NVT, dl, Parts, 2); return DAG.getNode(ISD::BIT_CONVERT, dl, N->getValueType(0), Vec); } } @@ -277,9 +277,8 @@ SDValue DAGTypeLegalizer::ExpandOp_BUILD_VECTOR(SDNode *N) { NewElts.push_back(Hi); } - SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl, - MVT::getVectorVT(NewVT, NewElts.size()), - &NewElts[0], NewElts.size()); + SDValue NewVec = DAG.getBUILD_VECTOR(MVT::getVectorVT(NewVT, NewElts.size()), + dl, &NewElts[0], NewElts.size()); // Convert the new vector to the old vector type. return DAG.getNode(ISD::BIT_CONVERT, dl, VecVT, NewVec); @@ -335,7 +334,7 @@ SDValue DAGTypeLegalizer::ExpandOp_SCALAR_TO_VECTOR(SDNode *N) { SDValue UndefVal = DAG.getUNDEF(Ops[0].getValueType()); for (unsigned i = 1; i < NumElts; ++i) Ops[i] = UndefVal; - return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElts); + return DAG.getBUILD_VECTOR(VT, dl, &Ops[0], NumElts); } SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) { diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index e679f01a35..e58f2d90b1 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -309,8 +309,8 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(SDNode *N) { SmallVector<SDValue, 8> Ops(N->getNumOperands()); for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i) Ops[i] = GetScalarizedVector(N->getOperand(i)); - return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), N->getValueType(0), - &Ops[0], Ops.size()); + return DAG.getBUILD_VECTOR(N->getValueType(0), N->getDebugLoc(), + &Ops[0], Ops.size()); } /// ScalarizeVecOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to @@ -501,10 +501,10 @@ void DAGTypeLegalizer::SplitVecRes_BUILD_VECTOR(SDNode *N, SDValue &Lo, GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); unsigned LoNumElts = LoVT.getVectorNumElements(); SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+LoNumElts); - Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, LoVT, &LoOps[0], LoOps.size()); + Lo = DAG.getBUILD_VECTOR(LoVT, dl, &LoOps[0], LoOps.size()); SmallVector<SDValue, 8> HiOps(N->op_begin()+LoNumElts, N->op_end()); - Hi = DAG.getNode(ISD::BUILD_VECTOR, dl, HiVT, &HiOps[0], HiOps.size()); + Hi = DAG.getBUILD_VECTOR(HiVT, dl, &HiOps[0], HiOps.size()); } void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo, @@ -805,15 +805,14 @@ void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo, } // Construct the Lo/Hi output using a BUILD_VECTOR. - Output = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT, &Ops[0], Ops.size()); + Output = DAG.getBUILD_VECTOR(NewVT, dl, &Ops[0], Ops.size()); } else if (InputUsed[0] == -1U) { // No input vectors were used! The result is undefined. Output = DAG.getUNDEF(NewVT); } else { // At least one input vector was used. Create a new shuffle vector. - SDValue NewMask = DAG.getNode(ISD::BUILD_VECTOR, dl, - MVT::getVectorVT(IdxVT, Ops.size()), - &Ops[0], Ops.size()); + SDValue NewMask = DAG.getBUILD_VECTOR(MVT::getVectorVT(IdxVT, Ops.size()), + dl, &Ops[0], Ops.size()); SDValue Op0 = Inputs[InputUsed[0]]; // If only one input was used, use an undefined vector for the other. SDValue Op1 = InputUsed[1] == -1U ? @@ -1080,8 +1079,8 @@ SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo) { } return DAG.UpdateNodeOperands(SDValue(N,0), N->getOperand(0), N->getOperand(1), - DAG.getNode(ISD::BUILD_VECTOR, dl, - VecVT, &Ops[0], Ops.size())); + DAG.getBUILD_VECTOR(VecVT, dl, + &Ops[0], Ops.size())); } // Continuing is pointless - failure is certain. @@ -1246,7 +1245,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) { for (; i < WidenNumElts; ++i) Ops[i] = UndefVal; - return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts); + return DAG.getBUILD_VECTOR(WidenVT, dl, &Ops[0], WidenNumElts); } SDValue DAGTypeLegalizer::WidenVecRes_Shift(SDNode *N) { @@ -1344,8 +1343,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) { NewVec = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewInVT, &Ops[0], NewNumElts); else - NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl, - NewInVT, &Ops[0], NewNumElts); + NewVec = DAG.getBUILD_VECTOR(NewInVT, dl, &Ops[0], NewNumElts); return DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, NewVec); } } @@ -1379,7 +1377,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_BUILD_VECTOR(SDNode *N) { for (unsigned i = NumElts; i < WidenNumElts; ++i) NewOps.push_back(DAG.getUNDEF(EltVT)); - return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &NewOps[0], NewOps.size()); + return DAG.getBUILD_VECTOR(WidenVT, dl, &NewOps[0], NewOps.size()); } SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) { @@ -1425,8 +1423,8 @@ SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) { MaskOps[i] = DAG.getConstant(i, PtrVT); MaskOps[i+WidenNumElts/2] = DAG.getConstant(i+WidenNumElts, PtrVT); } - SDValue Mask = DAG.getNode(ISD::BUILD_VECTOR, dl, - MVT::getVectorVT(PtrVT, WidenNumElts), + SDValue Mask = + DAG.getBUILD_VECTOR(MVT::getVectorVT(PtrVT, WidenNumElts), dl, &MaskOps[0], WidenNumElts); return DAG.getNode(ISD::VECTOR_SHUFFLE, dl, WidenVT, GetWidenedVector(N->getOperand(0)), @@ -1451,7 +1449,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) { SDValue UndefVal = DAG.getUNDEF(EltVT); for (; Idx < WidenNumElts; ++Idx) Ops[Idx] = UndefVal; - return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts); + return DAG.getBUILD_VECTOR(WidenVT, dl, &Ops[0], WidenNumElts); } SDValue DAGTypeLegalizer::WidenVecRes_CONVERT_RNDSAT(SDNode *N) { @@ -1529,7 +1527,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_CONVERT_RNDSAT(SDNode *N) { for (; i < WidenNumElts; ++i) Ops[i] = UndefVal; - return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts); + return DAG.getBUILD_VECTOR(WidenVT, dl, &Ops[0], WidenNumElts); } SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) { @@ -1582,7 +1580,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) { SDValue UndefVal = DAG.getUNDEF(EltVT); for (; i < WidenNumElts; ++i) Ops[i] = UndefVal; - return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts); + return DAG.getBUILD_VECTOR(WidenVT, dl, &Ops[0], WidenNumElts); } SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) { @@ -1639,7 +1637,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) { for (; i != WidenNumElts; ++i) Ops[i] = UndefVal; - Result = DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], Ops.size()); + Result = DAG.getBUILD_VECTOR(WidenVT, dl, &Ops[0], Ops.size()); } else { assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType()); unsigned int LdWidth = LdVT.getSizeInBits(); @@ -1735,9 +1733,8 @@ SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(SDNode *N) { } for (unsigned i = NumElts; i < WidenNumElts; ++i) MaskOps[i] = DAG.getUNDEF(IdxVT); - SDValue NewMask = DAG.getNode(ISD::BUILD_VECTOR, dl, - MVT::getVectorVT(IdxVT, WidenNumElts), - &MaskOps[0], WidenNumElts); + SDValue NewMask = DAG.getBUILD_VECTOR(MVT::getVectorVT(IdxVT, WidenNumElts), + dl, &MaskOps[0], WidenNumElts); return DAG.getNode(ISD::VECTOR_SHUFFLE, dl, WidenVT, InOp1, InOp2, NewMask); } @@ -1830,7 +1827,7 @@ SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) { DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp, DAG.getIntPtrConstant(i))); - return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElts); + return DAG.getBUILD_VECTOR(VT, dl, &Ops[0], NumElts); } SDValue DAGTypeLegalizer::WidenVecOp_BIT_CONVERT(SDNode *N) { @@ -1889,7 +1886,7 @@ SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) { Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, DAG.getIntPtrConstant(j)); } - return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElts); + return DAG.getBUILD_VECTOR(VT, dl, &Ops[0], NumElts); } SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { @@ -2179,5 +2176,5 @@ SDValue DAGTypeLegalizer::ModifyToType(SDValue InOp, MVT NVT) { SDValue UndefVal = DAG.getUNDEF(EltVT); for ( ; Idx < WidenNumElts; ++Idx) Ops[Idx] = UndefVal; - return DAG.getNode(ISD::BUILD_VECTOR, dl, NVT, &Ops[0], WidenNumElts); + return DAG.getBUILD_VECTOR(NVT, dl, &Ops[0], WidenNumElts); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 3f16344f59..66356f5f9a 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -847,7 +847,7 @@ SDValue SelectionDAG::getNOT(DebugLoc DL, SDValue Val, MVT VT) { SDValue NegOneElt = getConstant(APInt::getAllOnesValue(EltVT.getSizeInBits()), EltVT); std::vector<SDValue> NegOnes(VT.getVectorNumElements(), NegOneElt); - NegOne = getNode(ISD::BUILD_VECTOR, DL, VT, &NegOnes[0], NegOnes.size()); + NegOne = getBUILD_VECTOR(VT, DL, &NegOnes[0], NegOnes.size()); } else { NegOne = getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT); } @@ -893,8 +893,8 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, MVT VT, bool isT) { if (VT.isVector()) { SmallVector<SDValue, 8> Ops; Ops.assign(VT.getVectorNumElements(), Result); - Result = getNode(ISD::BUILD_VECTOR, DebugLoc::getUnknownLoc(), - VT, &Ops[0], Ops.size()); + Result = getBUILD_VECTOR(VT, DebugLoc::getUnknownLoc(), + &Ops[0], Ops.size()); } return Result; } @@ -937,9 +937,8 @@ SDValue SelectionDAG::getConstantFP(const ConstantFP& V, MVT VT, bool isTarget){ if (VT.isVector()) { SmallVector<SDValue, 8> Ops; Ops.assign(VT.getVectorNumElements(), Result); - // FIXME DebugLoc info might be appropriate here - Result = getNode(ISD::BUILD_VECTOR, DebugLoc::getUnknownLoc(), - VT, &Ops[0], Ops.size()); + Result = getBUILD_VECTOR(VT, DebugLoc::getUnknownLoc(), + &Ops[0], Ops.size()); } return Result; } @@ -1078,6 +1077,39 @@ SDValue SelectionDAG::getBasicBlock(MachineBasicBlock *MBB) { return SDValue(N, 0); } +SDValue SelectionDAG::getBUILD_VECTOR(MVT vecVT, DebugLoc dl, SDValue E1) { + return getBUILD_VECTOR(vecVT, dl, &E1, 1); +} + +SDValue SelectionDAG::getBUILD_VECTOR(MVT vecVT, DebugLoc dl, SDValue E1, + SDValue E2) { + SDValue Ops[2] = { E1, E2 }; + return getBUILD_VECTOR(vecVT, dl, &Ops[0], 2); +} + +SDValue SelectionDAG::getBUILD_VECTOR(MVT vecVT, DebugLoc dl, SDValue E1, + SDValue E2, SDValue E3, SDValue E4) { + SDValue Ops[4] = { E1, E2, E3, E4 }; + return getBUILD_VECTOR(vecVT, dl, &Ops[0], 4); +} + +SDValue SelectionDAG::getBUILD_VECTOR(MVT vecVT, DebugLoc dl, + const SDValue *Elts, unsigned NumElts) { + FoldingSetNodeID ID; + void *IP = 0; + SDNode *N = 0; + + AddNodeIDNode(ID, ISD::BUILD_VECTOR, getVTList(vecVT), Elts, NumElts); + if ((N = CSEMap.FindNodeOrInsertPos(ID, IP)) == 0) { + N = NodeAllocator.Allocate<BuildVectorSDNode>(); + new (N) BuildVectorSDNode(vecVT, dl, Elts, NumElts); + CSEMap.InsertNode(N, IP); + AllNodes.push_back(N); + } + + return SDValue(N, 0); +} + SDValue SelectionDAG::getArgFlags(ISD::ArgFlagsTy Flags) { FoldingSetNodeID ID; AddNodeIDNode(ID, ISD::ARG_FLAGS, getVTList(MVT::Other), 0, 0); @@ -2409,7 +2441,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT, N2.getOpcode() == ISD::BUILD_VECTOR) { SmallVector<SDValue, 16> Elts(N1.getNode()->op_begin(), N1.getNode()->op_end()); Elts.insert(Elts.end(), N2.getNode()->op_begin(), N2.getNode()->op_end()); - return getNode(ISD::BUILD_VECTOR, DL, VT, &Elts[0], Elts.size()); + return getBUILD_VECTOR(VT, DL, &Elts[0], Elts.size()); } break; case ISD::AND: @@ -2763,7 +2795,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT, SmallVector<SDValue, 16> Elts(N1.getNode()->op_begin(), N1.getNode()->op_end()); Elts.insert(Elts.end(), N2.getNode()->op_begin(), N2.getNode()->op_end()); Elts.insert(Elts.end(), N3.getNode()->op_begin(), N3.getNode()->op_end()); - return getNode(ISD::BUILD_VECTOR, DL, VT, &Elts[0], Elts.size()); + return getBUILD_VECTOR(VT, DL, &Elts[0], Elts.size()); } break; case ISD::SETCC: { @@ -4822,6 +4854,111 @@ MemSDNode::MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, assert(isVolatile() == vol && "Volatile representation error!"); } +BuildVectorSDNode::BuildVectorSDNode(MVT vecVT, DebugLoc dl, + const SDValue *Elts, unsigned NumElts) + : SDNode(ISD::BUILD_VECTOR, dl, getSDVTList(vecVT), Elts, NumElts), + computedSplat(false), isSplatVector(false), hasUndefSplatBitsFlag(false), + SplatBits(0LL), SplatUndef(0LL), SplatSize(0) +{ } + +bool BuildVectorSDNode::isConstantSplat(int MinSplatBits) { + unsigned int nOps = getNumOperands(); + assert(nOps > 0 && "isConstantSplat has 0-size build vector"); + + // Return early if we already know the answer: + if (computedSplat) + return isSplatVector; + + // The vector's used (non-undef) bits + uint64_t VectorBits[2] = { 0, 0 }; + // The vector's undefined bits + uint64_t UndefBits[2] = { 0, 0 }; + + // Assume that this isn't a constant splat. + isSplatVector = false; + + // Gather the constant and undefined bits + unsigned EltBitSize = getOperand(0).getValueType().getSizeInBits(); + for (unsigned i = 0; i < nOps; ++i) { + SDValue OpVal = getOperand(i); + unsigned PartNo = i >= nOps/2; // In the upper 128 bits? + unsigned SlotNo = nOps/2 - (i & (nOps/2-1))-1;// Which subpiece of the uint64_t. + uint64_t EltBits = 0; + + if (OpVal.getOpcode() == ISD::UNDEF) { + uint64_t EltUndefBits = ~0U >> (32-EltBitSize); + UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize); + continue; + } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) { + EltBits = CN->getZExtValue(); + if (EltBitSize <= 32) + EltBits &= (~0U >> (32-EltBitSize)); + } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) { + const APFloat &apf = CN->getValueAPF(); + if (OpVal.getValueType() == MVT::f32) + EltBits = FloatToBits(apf.convertToFloat()); + else + EltBits = DoubleToBits(apf.convertToDouble()); + } else { + // Nonconstant element -> not a splat. + computedSplat = true; + return isSplatVector; + } + + VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize); + } + + if ((VectorBits[0] & ~UndefBits[1]) != (VectorBits[1] & ~UndefBits[0])) { + // Can't be a splat if two pieces don't match. + computedSplat = true; + return isSplatVector; + } + + // Don't let undefs prevent splats from matching. See if the top 64-bits + // are the same as the lower 64-bits, ignoring undefs. + uint64_t Bits64 = VectorBits[0] | VectorBits[1]; + uint64_t Undef64 = UndefBits[0] & UndefBits[1]; + uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32); + uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32); + uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16); + uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16); + + bool splat64 = + (VectorBits[0] & ~UndefBits[1]) == (VectorBits[1] & ~UndefBits[0]); + bool splat32 = (Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64); + bool splat16 = (Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Und |