diff options
author | Dan Gohman <gohman@apple.com> | 2007-06-25 16:23:39 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2007-06-25 16:23:39 +0000 |
commit | 7f32156bb9c017b71971c52fac892fa7b9b06dd2 (patch) | |
tree | 23e97cecd52949f8ec279c6abc8935b60a63f199 /lib/CodeGen/SelectionDAG/SelectionDAG.cpp | |
parent | 32791e06d8bdfaca5350e089056db2ac66bf3adf (diff) |
Generalize MVT::ValueType and associated functions to be able to represent
extended vector types. Remove the special SDNode opcodes used for pre-legalize
vector operations, and the special MVT::Vector type used with them. Adjust
lowering and legalize to work with the normal SDNode kinds instead, and to
use the normal MVT functions to work with vector types instead of using the
two special operands that the pre-legalize nodes held.
This allows pre-legalize and post-legalize DAGs, and the code that operates
on them, to be more consistent. Pre-legalize vector operators can be handled
more consistently with scalar operators. And, -view-dag-combine1-dags and
-view-legalize-dags now look prettier for vector code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37719 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 95 |
1 files changed, 52 insertions, 43 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index d70823379a..5780eff67a 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -673,7 +673,9 @@ SDOperand SelectionDAG::getConstant(uint64_t Val, MVT::ValueType VT, bool isT) { SDOperand SelectionDAG::getConstantFP(double Val, MVT::ValueType VT, bool isTarget) { assert(MVT::isFloatingPoint(VT) && "Cannot create integer FP constant!"); - if (VT == MVT::f32) + MVT::ValueType EltVT = + MVT::isVector(VT) ? MVT::getVectorElementType(VT) : VT; + if (EltVT == MVT::f32) Val = (float)Val; // Mask out extra precision. // Do the map lookup using the actual bit pattern for the floating point @@ -681,15 +683,21 @@ SDOperand SelectionDAG::getConstantFP(double Val, MVT::ValueType VT, // we don't have issues with SNANs. unsigned Opc = isTarget ? ISD::TargetConstantFP : ISD::ConstantFP; FoldingSetNodeID ID; - AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0); + AddNodeIDNode(ID, Opc, getVTList(EltVT), 0, 0); ID.AddDouble(Val); void *IP = 0; if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDOperand(E, 0); - SDNode *N = new ConstantFPSDNode(isTarget, Val, VT); + SDNode *N = new ConstantFPSDNode(isTarget, Val, EltVT); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); - return SDOperand(N, 0); + SDOperand Result(N, 0); + if (MVT::isVector(VT)) { + SmallVector<SDOperand, 8> Ops; + Ops.assign(MVT::getVectorNumElements(VT), Result); + Result = getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size()); + } + return Result; } SDOperand SelectionDAG::getGlobalAddress(const GlobalValue *GV, @@ -1952,6 +1960,23 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, if (EVT == VT) return N1; // Not actually extending break; } + case ISD::EXTRACT_VECTOR_ELT: + assert(N2C && "Bad EXTRACT_VECTOR_ELT!"); + + // EXTRACT_VECTOR_ELT of BUILD_PAIR is often formed while lowering is + // expanding copies of large vectors from registers. + if (N1.getOpcode() == ISD::BUILD_PAIR) { + unsigned NewNumElts = MVT::getVectorNumElements(N1.getValueType()) / 2; + bool Low = N2C->getValue() < NewNumElts; + return getNode(ISD::EXTRACT_VECTOR_ELT, VT, N1.getOperand(!Low), + Low ? N2 : getConstant(N2C->getValue() - NewNumElts, + N2.getValueType())); + } + // EXTRACT_VECTOR_ELT of BUILD_VECTOR is often formed while lowering is + // expanding large vector constants. + if (N1.getOpcode() == ISD::BUILD_VECTOR) + return N1.getOperand(N2C->getValue()); + break; case ISD::EXTRACT_ELEMENT: assert(N2C && (unsigned)N2C->getValue() < 2 && "Bad EXTRACT_ELEMENT!"); @@ -2045,14 +2070,10 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, MVT::getVectorNumElements(VT) == N3.getNumOperands() && "Illegal VECTOR_SHUFFLE node!"); break; - case ISD::VBIT_CONVERT: - // Fold vbit_convert nodes from a type to themselves. - if (N1.getValueType() == MVT::Vector) { - assert(isa<ConstantSDNode>(*(N1.Val->op_end()-2)) && - isa<VTSDNode>(*(N1.Val->op_end()-1)) && "Malformed vector input!"); - if (*(N1.Val->op_end()-2) == N2 && *(N1.Val->op_end()-1) == N3) - return N1; - } + case ISD::BIT_CONVERT: + // Fold bit_convert nodes from a type to themselves. + if (N1.getValueType() == VT) + return N1; break; } @@ -2095,7 +2116,7 @@ SDOperand SelectionDAG::getLoad(MVT::ValueType VT, bool isVolatile, unsigned Alignment) { if (Alignment == 0) { // Ensure that codegen never sees alignment 0 const Type *Ty = 0; - if (VT != MVT::Vector && VT != MVT::iPTR) { + if (VT != MVT::iPTR) { Ty = MVT::getTypeForValueType(VT); } else if (SV) { const PointerType *PT = dyn_cast<PointerType>(SV->getType()); @@ -2149,7 +2170,7 @@ SDOperand SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT, if (Alignment == 0) { // Ensure that codegen never sees alignment 0 const Type *Ty = 0; - if (VT != MVT::Vector && VT != MVT::iPTR) { + if (VT != MVT::iPTR) { Ty = MVT::getTypeForValueType(VT); } else if (SV) { const PointerType *PT = dyn_cast<PointerType>(SV->getType()); @@ -2211,14 +2232,6 @@ SelectionDAG::getIndexedLoad(SDOperand OrigLoad, SDOperand Base, return SDOperand(N, 0); } -SDOperand SelectionDAG::getVecLoad(unsigned Count, MVT::ValueType EVT, - SDOperand Chain, SDOperand Ptr, - SDOperand SV) { - SDOperand Ops[] = { Chain, Ptr, SV, getConstant(Count, MVT::i32), - getValueType(EVT) }; - return getNode(ISD::VLOAD, getVTList(MVT::Vector, MVT::Other), Ops, 5); -} - SDOperand SelectionDAG::getStore(SDOperand Chain, SDOperand Val, SDOperand Ptr, const Value *SV, int SVOffset, bool isVolatile, unsigned Alignment) { @@ -2226,7 +2239,7 @@ SDOperand SelectionDAG::getStore(SDOperand Chain, SDOperand Val, if (Alignment == 0) { // Ensure that codegen never sees alignment 0 const Type *Ty = 0; - if (VT != MVT::Vector && VT != MVT::iPTR) { + if (VT != MVT::iPTR) { Ty = MVT::getTypeForValueType(VT); } else if (SV) { const PointerType *PT = dyn_cast<PointerType>(SV->getType()); @@ -2271,7 +2284,7 @@ SDOperand SelectionDAG::getTruncStore(SDOperand Chain, SDOperand Val, if (Alignment == 0) { // Ensure that codegen never sees alignment 0 const Type *Ty = 0; - if (VT != MVT::Vector && VT != MVT::iPTR) { + if (VT != MVT::iPTR) { Ty = MVT::getTypeForValueType(VT); } else if (SV) { const PointerType *PT = dyn_cast<PointerType>(SV->getType()); @@ -2462,7 +2475,18 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, SDVTList VTList, } SDVTList SelectionDAG::getVTList(MVT::ValueType VT) { - return makeVTList(SDNode::getValueTypeList(VT), 1); + if (!MVT::isExtendedValueType(VT)) + return makeVTList(SDNode::getValueTypeList(VT), 1); + + for (std::list<std::vector<MVT::ValueType> >::iterator I = VTList.begin(), + E = VTList.end(); I != E; ++I) { + if (I->size() == 1 && (*I)[0] == VT) + return makeVTList(&(*I)[0], 1); + } + std::vector<MVT::ValueType> V; + V.push_back(VT); + VTList.push_front(V); + return makeVTList(&(*VTList.begin())[0], 1); } SDVTList SelectionDAG::getVTList(MVT::ValueType VT1, MVT::ValueType VT2) { @@ -2496,7 +2520,7 @@ SDVTList SelectionDAG::getVTList(MVT::ValueType VT1, MVT::ValueType VT2, SDVTList SelectionDAG::getVTList(const MVT::ValueType *VTs, unsigned NumVTs) { switch (NumVTs) { case 0: assert(0 && "Cannot have nodes without results!"); - case 1: return makeVTList(SDNode::getValueTypeList(VTs[0]), 1); + case 1: return getVTList(VTs[0]); case 2: return getVTList(VTs[0], VTs[1]); case 3: return getVTList(VTs[0], VTs[1], VTs[2]); default: break; @@ -3394,30 +3418,16 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const { case ISD::FDIV: return "fdiv"; case ISD::FREM: return "frem"; case ISD::FCOPYSIGN: return "fcopysign"; - case ISD::VADD: return "vadd"; - case ISD::VSUB: return "vsub"; - case ISD::VMUL: return "vmul"; - case ISD::VSDIV: return "vsdiv"; - case ISD::VUDIV: return "vudiv"; - case ISD::VAND: return "vand"; - case ISD::VOR: return "vor"; - case ISD::VXOR: return "vxor"; case ISD::SETCC: return "setcc"; case ISD::SELECT: return "select"; case ISD::SELECT_CC: return "select_cc"; - case ISD::VSELECT: return "vselect"; case ISD::INSERT_VECTOR_ELT: return "insert_vector_elt"; - case ISD::VINSERT_VECTOR_ELT: return "vinsert_vector_elt"; case ISD::EXTRACT_VECTOR_ELT: return "extract_vector_elt"; - case ISD::VEXTRACT_VECTOR_ELT: return "vextract_vector_elt"; - case ISD::VCONCAT_VECTORS: return "vconcat_vectors"; - case ISD::VEXTRACT_SUBVECTOR: return "vextract_subvector"; + case ISD::CONCAT_VECTORS: return "concat_vectors"; + case ISD::EXTRACT_SUBVECTOR: return "extract_subvector"; case ISD::SCALAR_TO_VECTOR: return "scalar_to_vector"; - case ISD::VBUILD_VECTOR: return "vbuild_vector"; case ISD::VECTOR_SHUFFLE: return "vector_shuffle"; - case ISD::VVECTOR_SHUFFLE: return "vvector_shuffle"; - case ISD::VBIT_CONVERT: return "vbit_convert"; case ISD::CARRY_FALSE: return "carry_false"; case ISD::ADDC: return "addc"; case ISD::ADDE: return "adde"; @@ -3456,7 +3466,6 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const { // Other operators case ISD::LOAD: return "load"; case ISD::STORE: return "store"; - case ISD::VLOAD: return "vload"; case ISD::VAARG: return "vaarg"; case ISD::VACOPY: return "vacopy"; case ISD::VAEND: return "vaend"; |