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

Chris Lattner lattner at cs.uiuc.edu
Sat Mar 18 22:31:34 PST 2006



Changes in directory llvm/lib/CodeGen/SelectionDAG:

LegalizeDAG.cpp updated: 1.323 -> 1.324
SelectionDAG.cpp updated: 1.274 -> 1.275
---
Log message:

Add SCALAR_TO_VECTOR support


---
Diffs of the changes:  (+154 -90)

 LegalizeDAG.cpp  |  227 +++++++++++++++++++++++++++++++++----------------------
 SelectionDAG.cpp |   17 +++-
 2 files changed, 154 insertions(+), 90 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.323 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.324
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.323	Sat Mar 18 23:46:04 2006
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	Sun Mar 19 00:31:19 2006
@@ -160,12 +160,15 @@
 
   void LegalizeSetCCOperands(SDOperand &LHS, SDOperand &RHS, SDOperand &CC);
     
+  SDOperand CreateStackTemporary(MVT::ValueType VT);
+
   SDOperand ExpandLibCall(const char *Name, SDNode *Node,
                           SDOperand &Hi);
   SDOperand ExpandIntToFP(bool isSigned, MVT::ValueType DestTy,
                           SDOperand Source);
 
   SDOperand ExpandBIT_CONVERT(MVT::ValueType DestVT, SDOperand SrcOp);
+  SDOperand ExpandBUILD_VECTOR(SDNode *Node);
   SDOperand ExpandLegalINT_TO_FP(bool isSigned,
                                  SDOperand LegalOp,
                                  MVT::ValueType DestVT);
@@ -737,91 +740,10 @@
         break;
       }
       // FALLTHROUGH
-    case TargetLowering::Expand: {
-      // We assume that built vectors are not legal, and will be immediately
-      // spilled to memory.  If the values are all constants, turn this into a
-      // load from the constant pool.
-      bool isConstant = true;
-      for (SDNode::op_iterator I = Node->op_begin(), E = Node->op_end();
-           I != E; ++I) {
-        if (!isa<ConstantFPSDNode>(I) && !isa<ConstantSDNode>(I) &&
-            I->getOpcode() != ISD::UNDEF) {
-          isConstant = false;
-          break;
-        }
-      }
-      
-      // Create a ConstantPacked, and put it in the constant pool.
-      if (isConstant) {
-        MVT::ValueType VT = Node->getValueType(0);
-        const Type *OpNTy = 
-          MVT::getTypeForValueType(Node->getOperand(0).getValueType());
-        std::vector<Constant*> CV;
-        for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
-          if (ConstantFPSDNode *V = 
-                dyn_cast<ConstantFPSDNode>(Node->getOperand(i))) {
-            CV.push_back(ConstantFP::get(OpNTy, V->getValue()));
-          } else if (ConstantSDNode *V = 
-                         dyn_cast<ConstantSDNode>(Node->getOperand(i))) {
-            CV.push_back(ConstantUInt::get(OpNTy, V->getValue()));
-          } else {
-            assert(Node->getOperand(i).getOpcode() == ISD::UNDEF);
-            CV.push_back(UndefValue::get(OpNTy));
-          }
-        }
-        Constant *CP = ConstantPacked::get(CV);
-        SDOperand CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy());
-        Result = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
-                             DAG.getSrcValue(NULL));
-        break;
-      }
-      
-      // Otherwise, this isn't a constant entry.  Allocate a sufficiently
-      // aligned object on the stack, store each element into it, then load
-      // the result as a vector.
-      MVT::ValueType VT = Node->getValueType(0);
-      // Create the stack frame object.
-      MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();
-      unsigned ByteSize = MVT::getSizeInBits(VT)/8;
-      int FrameIdx = FrameInfo->CreateStackObject(ByteSize, ByteSize);
-      SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, TLI.getPointerTy());
-      
-      // Emit a store of each element to the stack slot.
-      std::vector<SDOperand> Stores;
-      bool isLittleEndian = TLI.isLittleEndian();
-      unsigned TypeByteSize = 
-        MVT::getSizeInBits(Node->getOperand(0).getValueType())/8;
-      unsigned VectorSize = MVT::getSizeInBits(VT)/8;
-      // Store (in the right endianness) the elements to memory.
-      for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
-        // Ignore undef elements.
-        if (Node->getOperand(i).getOpcode() == ISD::UNDEF) continue;
-        
-        unsigned Offset;
-        if (isLittleEndian) 
-          Offset = TypeByteSize*i;
-        else
-          Offset = TypeByteSize*(e-i-1);
-
-        SDOperand Idx = DAG.getConstant(Offset, FIPtr.getValueType());
-        Idx = DAG.getNode(ISD::ADD, FIPtr.getValueType(), FIPtr, Idx);
-
-        Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
-                                     Node->getOperand(i), Idx, 
-                                     DAG.getSrcValue(NULL)));
-      }
-      
-      SDOperand StoreChain;
-      if (!Stores.empty())    // Not all undef elements?
-        StoreChain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
-      else
-        StoreChain = DAG.getEntryNode();
-      
-      // Result is a load from the stack slot.
-      Result = DAG.getLoad(VT, StoreChain, FIPtr, DAG.getSrcValue(0));
+    case TargetLowering::Expand:
+      Result = ExpandBUILD_VECTOR(Result.Val);
       break;
     }
-    }
     break;
   case ISD::INSERT_VECTOR_ELT:
     Tmp1 = LegalizeOp(Node->getOperand(0));  // InVec
@@ -853,6 +775,29 @@
     }
     }
     break;
+  case ISD::SCALAR_TO_VECTOR:
+    Tmp1 = LegalizeOp(Node->getOperand(0));  // InVal
+    Result = DAG.UpdateNodeOperands(Result, Tmp1);
+    switch (TLI.getOperationAction(ISD::SCALAR_TO_VECTOR,
+                                   Node->getValueType(0))) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Legal:
+      break;
+    case TargetLowering::Expand: {
+      // If the target doesn't support this, store the value to a temporary
+      // stack slot, then EXTLOAD the vector back out.
+      SDOperand StackPtr = 
+        CreateStackTemporary(Node->getOperand(0).getValueType());
+      SDOperand Ch = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+                                 Node->getOperand(0), StackPtr,
+                                 DAG.getSrcValue(NULL));
+      Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0), Ch, StackPtr,
+                              DAG.getSrcValue(NULL),
+                              Node->getOperand(0).getValueType());
+      break;
+    }
+    }
+    break;
   case ISD::CALLSEQ_START: {
     SDNode *CallEnd = FindCallEndFromCallStart(Node);
     
@@ -3005,10 +2950,7 @@
 SDOperand SelectionDAGLegalize::ExpandBIT_CONVERT(MVT::ValueType DestVT, 
                                                   SDOperand SrcOp) {
   // Create the stack frame object.
-  MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();
-  unsigned ByteSize = MVT::getSizeInBits(DestVT)/8;
-  int FrameIdx = FrameInfo->CreateStackObject(ByteSize, ByteSize);
-  SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, TLI.getPointerTy());
+  SDOperand FIPtr = CreateStackTemporary(DestVT);
   
   // Emit a store to the stack slot.
   SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
@@ -3017,6 +2959,117 @@
   return DAG.getLoad(DestVT, Store, FIPtr, DAG.getSrcValue(0));
 }
 
+/// ExpandBUILD_VECTOR - Expand a BUILD_VECTOR node on targets that don't
+/// support the operation, but do support the resultant packed vector type.
+SDOperand SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
+  
+  // If the only non-undef value is the low element, turn this into a 
+  // SCALAR_TO_VECTOR node.
+  bool isOnlyLowElement = true;
+  for (SDNode::op_iterator I = Node->op_begin()+1, E = Node->op_end();
+       I != E; ++I) {
+    if (I->getOpcode() != ISD::UNDEF) {
+      isOnlyLowElement = false;
+      break;
+    }
+  }
+  
+  if (isOnlyLowElement) {
+    // If the low element is an undef too, then this whole things is an undef.
+    if (Node->getOperand(0).getOpcode() == ISD::UNDEF)
+      return DAG.getNode(ISD::UNDEF, Node->getValueType(0));
+    // Otherwise, turn this into a scalar_to_vector node.
+    return DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0),
+                       Node->getOperand(0));
+  }
+  
+  // If the elements are all constants, turn this into a load from the constant
+  // pool.
+  bool isConstant = true;
+  for (SDNode::op_iterator I = Node->op_begin(), E = Node->op_end();
+       I != E; ++I) {
+    if (!isa<ConstantFPSDNode>(I) && !isa<ConstantSDNode>(I) &&
+        I->getOpcode() != ISD::UNDEF) {
+      isConstant = false;
+      break;
+    }
+  }
+  
+  // Create a ConstantPacked, and put it in the constant pool.
+  if (isConstant) {
+    MVT::ValueType VT = Node->getValueType(0);
+    const Type *OpNTy = 
+      MVT::getTypeForValueType(Node->getOperand(0).getValueType());
+    std::vector<Constant*> CV;
+    for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
+      if (ConstantFPSDNode *V = 
+          dyn_cast<ConstantFPSDNode>(Node->getOperand(i))) {
+        CV.push_back(ConstantFP::get(OpNTy, V->getValue()));
+      } else if (ConstantSDNode *V = 
+                 dyn_cast<ConstantSDNode>(Node->getOperand(i))) {
+        CV.push_back(ConstantUInt::get(OpNTy, V->getValue()));
+      } else {
+        assert(Node->getOperand(i).getOpcode() == ISD::UNDEF);
+        CV.push_back(UndefValue::get(OpNTy));
+      }
+    }
+    Constant *CP = ConstantPacked::get(CV);
+    SDOperand CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy());
+    return DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
+                       DAG.getSrcValue(NULL));
+  }
+  
+  // Otherwise, we can't handle this case efficiently.  Allocate a sufficiently
+  // aligned object on the stack, store each element into it, then load
+  // the result as a vector.
+  MVT::ValueType VT = Node->getValueType(0);
+  // Create the stack frame object.
+  SDOperand FIPtr = CreateStackTemporary(VT);
+  
+  // Emit a store of each element to the stack slot.
+  std::vector<SDOperand> Stores;
+  bool isLittleEndian = TLI.isLittleEndian();
+  unsigned TypeByteSize = 
+    MVT::getSizeInBits(Node->getOperand(0).getValueType())/8;
+  unsigned VectorSize = MVT::getSizeInBits(VT)/8;
+  // Store (in the right endianness) the elements to memory.
+  for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
+    // Ignore undef elements.
+    if (Node->getOperand(i).getOpcode() == ISD::UNDEF) continue;
+    
+    unsigned Offset;
+    if (isLittleEndian) 
+      Offset = TypeByteSize*i;
+    else
+      Offset = TypeByteSize*(e-i-1);
+    
+    SDOperand Idx = DAG.getConstant(Offset, FIPtr.getValueType());
+    Idx = DAG.getNode(ISD::ADD, FIPtr.getValueType(), FIPtr, Idx);
+    
+    Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+                                 Node->getOperand(i), Idx, 
+                                 DAG.getSrcValue(NULL)));
+  }
+  
+  SDOperand StoreChain;
+  if (!Stores.empty())    // Not all undef elements?
+    StoreChain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
+  else
+    StoreChain = DAG.getEntryNode();
+  
+  // Result is a load from the stack slot.
+  return DAG.getLoad(VT, StoreChain, FIPtr, DAG.getSrcValue(0));
+}
+
+/// CreateStackTemporary - Create a stack temporary, suitable for holding the
+/// specified value type.
+SDOperand SelectionDAGLegalize::CreateStackTemporary(MVT::ValueType VT) {
+  MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();
+  unsigned ByteSize = MVT::getSizeInBits(VT)/8;
+  int FrameIdx = FrameInfo->CreateStackObject(ByteSize, ByteSize);
+  return DAG.getFrameIndex(FrameIdx, TLI.getPointerTy());
+}
+
 void SelectionDAGLegalize::ExpandShiftParts(unsigned NodeOp,
                                             SDOperand Op, SDOperand Amt,
                                             SDOperand &Lo, SDOperand &Hi) {


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.274 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.275
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.274	Sat Mar 18 18:52:58 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp	Sun Mar 19 00:31:19 2006
@@ -1092,6 +1092,11 @@
     if (OpOpcode == ISD::BIT_CONVERT)  // bitconv(bitconv(x)) -> bitconv(x)
       return getNode(ISD::BIT_CONVERT, VT, Operand.getOperand(0));
     break;
+  case ISD::SCALAR_TO_VECTOR:
+    assert(MVT::isVector(VT) && !MVT::isVector(Operand.getValueType()) &&
+           MVT::getVectorBaseType(VT) == Operand.getValueType() &&
+           "Illegal SCALAR_TO_VECTOR node!");
+    break;
   case ISD::FNEG:
     if (OpOpcode == ISD::FSUB)   // -(X-Y) -> (Y-X)
       return getNode(ISD::FSUB, VT, Operand.Val->getOperand(1),
@@ -1555,10 +1560,15 @@
     // normal load.
     if (ResultTys[0] == EVT)
       return getLoad(ResultTys[0], Ops[0], Ops[1], Ops[2]);
-    assert(EVT < ResultTys[0] &&
-           "Should only be an extending load, not truncating!");
+    if (MVT::isVector(ResultTys[0])) {
+      assert(EVT == MVT::getVectorBaseType(ResultTys[0]) &&
+             "Invalid vector extload!");
+    } else {
+      assert(EVT < ResultTys[0] &&
+             "Should only be an extending load, not truncating!");
+    }
     assert((Opcode == ISD::EXTLOAD || MVT::isInteger(ResultTys[0])) &&
-           "Cannot sign/zero extend a FP load!");
+           "Cannot sign/zero extend a FP/Vector load!");
     assert(MVT::isInteger(ResultTys[0]) == MVT::isInteger(EVT) &&
            "Cannot convert from FP to Int or Int -> FP!");
     break;
@@ -2654,6 +2664,7 @@
   case ISD::SELECT_CC:   return "select_cc";
   case ISD::INSERT_VECTOR_ELT: return "insert_vector_elt";
   case ISD::VINSERT_VECTOR_ELT: return "vinsert_vector_elt";
+  case ISD::SCALAR_TO_VECTOR:   return "scalar_to_vector";
   case ISD::ADDC:        return "addc";
   case ISD::ADDE:        return "adde";
   case ISD::SUBC:        return "subc";






More information about the llvm-commits mailing list