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

Chris Lattner lattner at cs.uiuc.edu
Thu Mar 30 18:07:07 PST 2006



Changes in directory llvm/lib/CodeGen/SelectionDAG:

LegalizeDAG.cpp updated: 1.343 -> 1.344
SelectionDAG.cpp updated: 1.292 -> 1.293
SelectionDAGISel.cpp updated: 1.212 -> 1.213
---
Log message:

Significantly improve handling of vectors that are live across basic blocks,
handling cases where the vector elements need promotion, expansion, and when
the vector type itself needs to be decimated.



---
Diffs of the changes:  (+101 -52)

 LegalizeDAG.cpp      |    5 -
 SelectionDAG.cpp     |    3 -
 SelectionDAGISel.cpp |  145 ++++++++++++++++++++++++++++++++++-----------------
 3 files changed, 101 insertions(+), 52 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.343 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.344
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.343	Thu Mar 30 19:27:51 2006
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	Thu Mar 30 20:06:55 2006
@@ -4497,9 +4497,6 @@
 /// type for the result.
 SDOperand SelectionDAGLegalize::PackVectorOp(SDOperand Op, 
                                              MVT::ValueType NewVT) {
-  // FIXME: THIS IS A TEMPORARY HACK
-  if (Op.getValueType() == NewVT) return Op;
-    
   assert(Op.getValueType() == MVT::Vector && "Bad PackVectorOp invocation!");
   SDNode *Node = Op.Val;
   
@@ -4536,7 +4533,7 @@
     break;
   }
   case ISD::VBUILD_VECTOR:
-    if (!MVT::isVector(NewVT)) {
+    if (Node->getOperand(0).getValueType() == NewVT) {
       // Returning a scalar?
       Result = Node->getOperand(0);
     } else {


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.292 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.293
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.292	Tue Mar 28 13:54:42 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp	Thu Mar 30 20:06:56 2006
@@ -1162,8 +1162,7 @@
     break;
   case ISD::BIT_CONVERT:
     // Basic sanity checking.
-    assert((Operand.getValueType() == MVT::Vector ||   // FIXME: This is a hack.
-           MVT::getSizeInBits(VT) == MVT::getSizeInBits(Operand.getValueType()))
+    assert(MVT::getSizeInBits(VT) == MVT::getSizeInBits(Operand.getValueType())
            && "Cannot BIT_CONVERT between two different types!");
     if (VT == Operand.getValueType()) return Operand;  // noop conversion.
     if (OpOpcode == ISD::BIT_CONVERT)  // bitconv(bitconv(x)) -> bitconv(x)


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.212 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.213
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.212	Tue Mar 28 18:11:43 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	Thu Mar 30 20:06:56 2006
@@ -264,8 +264,16 @@
     for (BasicBlock::iterator I = BB->begin();
          (PN = dyn_cast<PHINode>(I)); ++I)
       if (!PN->use_empty()) {
-        unsigned NumElements =
-          TLI.getNumElements(TLI.getValueType(PN->getType()));
+        MVT::ValueType VT = TLI.getValueType(PN->getType());
+        unsigned NumElements;
+        if (VT != MVT::Vector)
+          NumElements = TLI.getNumElements(VT);
+        else {
+          MVT::ValueType VT1,VT2;
+          NumElements = 
+            TLI.getPackedTypeBreakdown(cast<PackedType>(PN->getType()),
+                                       VT1, VT2);
+        }
         unsigned PHIReg = ValueMap[PN];
         assert(PHIReg &&"PHI node does not have an assigned virtual register!");
         for (unsigned i = 0; i != NumElements; ++i)
@@ -622,32 +630,61 @@
   unsigned InReg = VMI->second;
   
   // If this type is not legal, make it so now.
-  if (VT == MVT::Vector) {
-    // FIXME: We only handle legal vectors right now.  We need a VBUILD_VECTOR
-    const PackedType *PTy = cast<PackedType>(VTy);
-    unsigned NumElements = PTy->getNumElements();
-    MVT::ValueType PVT = TLI.getValueType(PTy->getElementType());
-    MVT::ValueType TVT = MVT::getVectorType(PVT, NumElements);
-    assert(TLI.isTypeLegal(TVT) &&
-           "FIXME: Cannot handle illegal vector types here yet!");
-    VT = TVT;
-  }
+  if (VT != MVT::Vector) {
+    MVT::ValueType DestVT = TLI.getTypeToTransformTo(VT);
   
-  MVT::ValueType DestVT = TLI.getTypeToTransformTo(VT);
-  
-  N = DAG.getCopyFromReg(DAG.getEntryNode(), InReg, DestVT);
-  if (DestVT < VT) {
-    // Source must be expanded.  This input value is actually coming from the
-    // register pair VMI->second and VMI->second+1.
-    N = DAG.getNode(ISD::BUILD_PAIR, VT, N,
-                    DAG.getCopyFromReg(DAG.getEntryNode(), InReg+1, DestVT));
-  } else {
-    if (DestVT > VT) { // Promotion case
+    N = DAG.getCopyFromReg(DAG.getEntryNode(), InReg, DestVT);
+    if (DestVT < VT) {
+      // Source must be expanded.  This input value is actually coming from the
+      // register pair VMI->second and VMI->second+1.
+      N = DAG.getNode(ISD::BUILD_PAIR, VT, N,
+                      DAG.getCopyFromReg(DAG.getEntryNode(), InReg+1, DestVT));
+    } else if (DestVT > VT) { // Promotion case
       if (MVT::isFloatingPoint(VT))
         N = DAG.getNode(ISD::FP_ROUND, VT, N);
       else
         N = DAG.getNode(ISD::TRUNCATE, VT, N);
     }
+  } else {
+    // Otherwise, if this is a vector, make it available as a generic vector
+    // here.
+    MVT::ValueType PTyElementVT, PTyLegalElementVT;
+    unsigned NE = TLI.getPackedTypeBreakdown(cast<PackedType>(VTy),PTyElementVT,
+                                             PTyLegalElementVT);
+
+    // Build a VBUILD_VECTOR with the input registers.
+    std::vector<SDOperand> Ops;
+    if (PTyElementVT == PTyLegalElementVT) {
+      // If the value types are legal, just VBUILD the CopyFromReg nodes.
+      for (unsigned i = 0; i != NE; ++i)
+        Ops.push_back(DAG.getCopyFromReg(DAG.getEntryNode(), InReg++, 
+                                         PTyElementVT));
+    } else if (PTyElementVT < PTyLegalElementVT) {
+      // If the register was promoted, use TRUNCATE of FP_ROUND as appropriate.
+      for (unsigned i = 0; i != NE; ++i) {
+        SDOperand Op = DAG.getCopyFromReg(DAG.getEntryNode(), InReg++, 
+                                          PTyElementVT);
+        if (MVT::isFloatingPoint(PTyElementVT))
+          Op = DAG.getNode(ISD::FP_ROUND, PTyElementVT, Op);
+        else
+          Op = DAG.getNode(ISD::TRUNCATE, PTyElementVT, Op);
+        Ops.push_back(Op);
+      }
+    } else {
+      // If the register was expanded, use BUILD_PAIR.
+      assert((NE & 1) == 0 && "Must expand into a multiple of 2 elements!");
+      for (unsigned i = 0; i != NE/2; ++i) {
+        SDOperand Op0 = DAG.getCopyFromReg(DAG.getEntryNode(), InReg++, 
+                                           PTyElementVT);
+        SDOperand Op1 = DAG.getCopyFromReg(DAG.getEntryNode(), InReg++, 
+                                           PTyElementVT);
+        Ops.push_back(DAG.getNode(ISD::BUILD_PAIR, VT, Op0, Op1));
+      }
+    }
+    
+    Ops.push_back(DAG.getConstant(NE, MVT::i32));
+    Ops.push_back(DAG.getValueType(PTyLegalElementVT));
+    N = DAG.getNode(ISD::VBUILD_VECTOR, MVT::Vector, Ops);
   }
   
   return N;
@@ -2589,31 +2626,47 @@
   if (SrcVT == DestVT) {
     return DAG.getCopyToReg(SDL.getRoot(), Reg, Op);
   } else if (SrcVT == MVT::Vector) {
-    // FIXME: THIS DOES NOT SUPPORT PROMOTED/EXPANDED ELEMENTS!
-
-    // Figure out the right, legal destination reg to copy into.
-    const PackedType *PTy = cast<PackedType>(V->getType());
-    unsigned NumElts = PTy->getNumElements();
-    MVT::ValueType EltTy = TLI.getValueType(PTy->getElementType());
-    
-    unsigned NumVectorRegs = 1;
-
-    // Divide the input until we get to a supported size.  This will always
-    // end with a scalar if the target doesn't support vectors.
-    while (NumElts > 1 && !TLI.isTypeLegal(getVectorType(EltTy, NumElts))) {
-      NumElts >>= 1;
-      NumVectorRegs <<= 1;
+    // Handle copies from generic vectors to registers.
+    MVT::ValueType PTyElementVT, PTyLegalElementVT;
+    unsigned NE = TLI.getPackedTypeBreakdown(cast<PackedType>(V->getType()),
+                                             PTyElementVT, PTyLegalElementVT);
+    
+    // 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.
+    std::vector<SDOperand> OutChains;
+    SDOperand Root = SDL.getRoot();
+    for (unsigned i = 0; i != NE; ++i) {
+      SDOperand Elt = DAG.getNode(ISD::VEXTRACT_VECTOR_ELT, PTyElementVT,
+                                  Op, DAG.getConstant(i, MVT::i32));
+      if (PTyElementVT == PTyLegalElementVT) {
+        // Elements are legal.
+        OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Elt));
+      } else if (PTyLegalElementVT > PTyElementVT) {
+        // Elements are promoted.
+        if (MVT::isFloatingPoint(PTyLegalElementVT))
+          Elt = DAG.getNode(ISD::FP_EXTEND, PTyLegalElementVT, Elt);
+        else
+          Elt = DAG.getNode(ISD::ANY_EXTEND, PTyLegalElementVT, Elt);
+        OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Elt));
+      } else {
+        // Elements are expanded.
+        // The src value is expanded into multiple registers.
+        SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, PTyLegalElementVT,
+                                   Elt, DAG.getConstant(0, MVT::i32));
+        SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, PTyLegalElementVT,
+                                   Elt, DAG.getConstant(1, MVT::i32));
+        OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Lo));
+        OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Hi));
+      }
     }
-    
-    MVT::ValueType VT;
-    if (NumElts == 1)
-      VT = EltTy;
-    else
-      VT = getVectorType(EltTy, NumElts);
-    
-    // FIXME: THIS ASSUMES THAT THE INPUT VECTOR WILL BE LEGAL!
-    Op = DAG.getNode(ISD::BIT_CONVERT, VT, Op);
-    return DAG.getCopyToReg(SDL.getRoot(), Reg, Op);
+    return DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains);
   } else if (SrcVT < DestVT) {
     // The src value is promoted to the register.
     if (MVT::isFloatingPoint(SrcVT))






More information about the llvm-commits mailing list