[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp SelectionDAGISel.cpp

Dan Gohman djg at cray.com
Wed Jun 13 08:12:34 PDT 2007



Changes in directory llvm/lib/CodeGen/SelectionDAG:

LegalizeDAG.cpp updated: 1.495 -> 1.496
SelectionDAG.cpp updated: 1.405 -> 1.406
SelectionDAGISel.cpp updated: 1.460 -> 1.461
---
Log message:

Introduce new SelectionDAG node opcodes VEXTRACT_SUBVECTOR and
VCONCAT_VECTORS. Use these for CopyToReg and CopyFromReg legalizing in
the case that the full register is to be split into subvectors instead
of scalars. This replaces uses of VBIT_CONVERT to present values as
vector-of-vector types in order to make whole subvectors accessible via
BUILD_VECTOR and EXTRACT_VECTOR_ELT.

This is in preparation for adding extended ValueType values, where
having vector-of-vector types is undesirable.


---
Diffs of the changes:  (+83 -21)

 LegalizeDAG.cpp      |   63 +++++++++++++++++++++++++++++++++++++++++++++++++++
 SelectionDAG.cpp     |    2 +
 SelectionDAGISel.cpp |   39 ++++++++++++++-----------------
 3 files changed, 83 insertions(+), 21 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.495 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.496
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.495	Mon Jun  4 11:17:33 2007
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	Wed Jun 13 10:12:02 2007
@@ -225,6 +225,7 @@
                         SDOperand &Lo, SDOperand &Hi);
 
   SDOperand LowerVEXTRACT_VECTOR_ELT(SDOperand Op);
+  SDOperand LowerVEXTRACT_SUBVECTOR(SDOperand Op);
   SDOperand ExpandEXTRACT_VECTOR_ELT(SDOperand Op);
   
   SDOperand getIntPtrConstant(uint64_t Val) {
@@ -1178,6 +1179,10 @@
     Result = LegalizeOp(LowerVEXTRACT_VECTOR_ELT(Op));
     break;
     
+  case ISD::VEXTRACT_SUBVECTOR: 
+    Result = LegalizeOp(LowerVEXTRACT_SUBVECTOR(Op));
+    break;
+    
   case ISD::CALLSEQ_START: {
     SDNode *CallEnd = FindCallEndFromCallStart(Node);
     
@@ -3561,6 +3566,9 @@
   case ISD::VEXTRACT_VECTOR_ELT:
     Result = PromoteOp(LowerVEXTRACT_VECTOR_ELT(Op));
     break;
+  case ISD::VEXTRACT_SUBVECTOR:
+    Result = PromoteOp(LowerVEXTRACT_SUBVECTOR(Op));
+    break;
   case ISD::EXTRACT_VECTOR_ELT:
     Result = PromoteOp(ExpandEXTRACT_VECTOR_ELT(Op));
     break;
@@ -3622,6 +3630,37 @@
   }
 }
 
+/// LowerVEXTRACT_SUBVECTOR - Lower a VEXTRACT_SUBVECTOR operation.  For now
+/// we assume the operation can be split if it is not already legal.
+SDOperand SelectionDAGLegalize::LowerVEXTRACT_SUBVECTOR(SDOperand Op) {
+  // We know that operand #0 is the Vec vector.  For now we assume the index
+  // is a constant and that the extracted result is a supported hardware type.
+  SDOperand Vec = Op.getOperand(0);
+  SDOperand Idx = LegalizeOp(Op.getOperand(1));
+  
+  SDNode *InVal = Vec.Val;
+  unsigned NumElems = cast<ConstantSDNode>(*(InVal->op_end()-2))->getValue();
+  
+  if (NumElems == MVT::getVectorNumElements(Op.getValueType())) {
+    // This must be an access of the desired vector length.  Return it.
+    return PackVectorOp(Vec, Op.getValueType());
+  }
+
+  ConstantSDNode *CIdx = cast<ConstantSDNode>(Idx);
+  SDOperand Lo, Hi;
+  SplitVectorOp(Vec, Lo, Hi);
+  if (CIdx->getValue() < NumElems/2) {
+    Vec = Lo;
+  } else {
+    Vec = Hi;
+    Idx = DAG.getConstant(CIdx->getValue() - NumElems/2, Idx.getValueType());
+  }
+  
+  // It's now an extract from the appropriate high or low part.  Recurse.
+  Op = DAG.UpdateNodeOperands(Op, Vec, Idx);
+  return LowerVEXTRACT_SUBVECTOR(Op);
+}
+
 /// ExpandEXTRACT_VECTOR_ELT - Expand an EXTRACT_VECTOR_ELT operation into
 /// memory traffic.
 SDOperand SelectionDAGLegalize::ExpandEXTRACT_VECTOR_ELT(SDOperand Op) {
@@ -5501,6 +5540,21 @@
     Hi = DAG.getNode(ISD::VBUILD_VECTOR, MVT::Vector, &HiOps[0], HiOps.size());
     break;
   }
+  case ISD::VCONCAT_VECTORS: {
+    unsigned NewNumSubvectors = (Node->getNumOperands() - 2) / 2;
+    SmallVector<SDOperand, 8> LoOps(Node->op_begin(), 
+                                    Node->op_begin()+NewNumSubvectors);
+    LoOps.push_back(NewNumEltsNode);
+    LoOps.push_back(TypeNode);
+    Lo = DAG.getNode(ISD::VCONCAT_VECTORS, MVT::Vector, &LoOps[0], LoOps.size());
+
+    SmallVector<SDOperand, 8> HiOps(Node->op_begin()+NewNumSubvectors, 
+                                    Node->op_end()-2);
+    HiOps.push_back(NewNumEltsNode);
+    HiOps.push_back(TypeNode);
+    Hi = DAG.getNode(ISD::VCONCAT_VECTORS, MVT::Vector, &HiOps[0], HiOps.size());
+    break;
+  }
   case ISD::VADD:
   case ISD::VSUB:
   case ISD::VMUL:
@@ -5655,6 +5709,11 @@
       }
     }
     break;
+  case ISD::VCONCAT_VECTORS:
+    assert(Node->getOperand(0).getValueType() == NewVT &&
+           "Concat of non-legal vectors not yet supported!");
+    Result = Node->getOperand(0);
+    break;
   case ISD::VINSERT_VECTOR_ELT:
     if (!MVT::isVector(NewVT)) {
       // Returning a scalar?  Must be the inserted element.
@@ -5665,6 +5724,10 @@
                            Node->getOperand(1), Node->getOperand(2));
     }
     break;
+  case ISD::VEXTRACT_SUBVECTOR:
+    Result = PackVectorOp(Node->getOperand(0), NewVT);
+    assert(Result.getValueType() == NewVT);
+    break;
   case ISD::VVECTOR_SHUFFLE:
     if (!MVT::isVector(NewVT)) {
       // Returning a scalar?  Figure out if it is the LHS or RHS and return it.


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.405 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.406
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.405	Mon Jun  4 10:49:41 2007
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp	Wed Jun 13 10:12:02 2007
@@ -2865,6 +2865,8 @@
   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::SCALAR_TO_VECTOR:    return "scalar_to_vector";
   case ISD::VBUILD_VECTOR:       return "vbuild_vector";
   case ISD::VECTOR_SHUFFLE:      return "vector_shuffle";


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.460 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.461
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.460	Wed Jun 13 09:55:16 2007
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	Wed Jun 13 10:12:02 2007
@@ -761,7 +761,7 @@
     unsigned NE = TLI.getVectorTypeBreakdown(PTy, PTyElementVT,
                                              PTyLegalElementVT);
 
-    // Build a VBUILD_VECTOR with the input registers.
+    // Build a VBUILD_VECTOR or VCONCAT_VECTORS with the input registers.
     SmallVector<SDOperand, 8> Ops;
     if (PTyElementVT == PTyLegalElementVT) {
       // If the value types are legal, just VBUILD the CopyFromReg nodes.
@@ -791,16 +791,15 @@
       }
     }
     
-    Ops.push_back(DAG.getConstant(NE, MVT::i32));
-    Ops.push_back(DAG.getValueType(PTyElementVT));
-    N = DAG.getNode(ISD::VBUILD_VECTOR, MVT::Vector, &Ops[0], Ops.size());
-    
-    // Finally, use a VBIT_CONVERT to make this available as the appropriate
-    // vector type.
-    N = DAG.getNode(ISD::VBIT_CONVERT, MVT::Vector, N, 
-                    DAG.getConstant(PTy->getNumElements(),
-                                    MVT::i32),
-                    DAG.getValueType(TLI.getValueType(PTy->getElementType())));
+    if (MVT::isVector(PTyElementVT)) {
+      Ops.push_back(DAG.getConstant(NE * MVT::getVectorNumElements(PTyElementVT), MVT::i32));
+      Ops.push_back(DAG.getValueType(MVT::getVectorBaseType(PTyElementVT)));
+      N = DAG.getNode(ISD::VCONCAT_VECTORS, MVT::Vector, &Ops[0], Ops.size());
+    } else {
+      Ops.push_back(DAG.getConstant(NE, MVT::i32));
+      Ops.push_back(DAG.getValueType(PTyElementVT));
+      N = DAG.getNode(ISD::VBUILD_VECTOR, MVT::Vector, &Ops[0], Ops.size());
+    }
   }
   
   return N;
@@ -4426,21 +4425,19 @@
     MVT::ValueType PTyElementVT, PTyLegalElementVT;
     unsigned NE = TLI.getVectorTypeBreakdown(cast<VectorType>(V->getType()),
                                              PTyElementVT, PTyLegalElementVT);
+    uint64_t SrcVL = cast<ConstantSDNode>(*(Op.Val->op_end()-2))->getValue();
     
-    // Insert a VBIT_CONVERT of the input vector to a "N x PTyElementVT" 
-    // MVT::Vector type.
-    Op = DAG.getNode(ISD::VBIT_CONVERT, MVT::Vector, Op,
-                     DAG.getConstant(NE, MVT::i32), 
-                     DAG.getValueType(PTyElementVT));
-
     // Loop over all of the elements of the resultant vector,
-    // VEXTRACT_VECTOR_ELT'ing them, converting them to PTyLegalElementVT, then
-    // copying them into output registers.
+    // VEXTRACT_VECTOR_ELT'ing or VEXTRACT_SUBVECTOR'ing them, converting them
+    // to PTyLegalElementVT, then copying them into output registers.
     SmallVector<SDOperand, 8> OutChains;
     SDOperand Root = getRoot();
     for (unsigned i = 0; i != NE; ++i) {
-      SDOperand Elt = DAG.getNode(ISD::VEXTRACT_VECTOR_ELT, PTyElementVT,
-                                  Op, DAG.getConstant(i, TLI.getPointerTy()));
+      SDOperand Elt = MVT::isVector(PTyElementVT) ?
+        DAG.getNode(ISD::VEXTRACT_SUBVECTOR, PTyElementVT,
+                    Op, DAG.getConstant(i * (SrcVL / NE), TLI.getPointerTy())) :
+        DAG.getNode(ISD::VEXTRACT_VECTOR_ELT, PTyElementVT,
+                    Op, DAG.getConstant(i, TLI.getPointerTy()));
       if (PTyElementVT == PTyLegalElementVT) {
         // Elements are legal.
         OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Elt));






More information about the llvm-commits mailing list