add many new cases to SplitResult. SplitResult now handles all the cases that Legali...
authorChris Lattner <sabre@nondot.org>
Sat, 8 Dec 2007 23:58:27 +0000 (23:58 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 8 Dec 2007 23:58:27 +0000 (23:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44726 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/LegalizeTypes.h
lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp

index 3b7e26bab5cebfa34cf2b481d73cf96fe38d40be..0ecc70f4afff8317c88c1ce45704a91d84a6cdd2 100644 (file)
@@ -276,7 +276,17 @@ private:
 
   void SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi);
   void SplitRes_LOAD(LoadSDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void SplitRes_BUILD_PAIR(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void SplitRes_VECTOR_SHUFFLE(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+
+  void SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void SplitRes_CONCAT_VECTORS(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void SplitRes_BIT_CONVERT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void SplitRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi);
   void SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
   
   // Operand Vector Scalarization: <128 x ty> -> 2 x <64 x ty>.
   bool SplitOperand(SDNode *N, unsigned OpNo);
index c9bf70a3bca6eb75952b5207d1fbd7bf0823bca0..c16b05110dbd1189631088ab5d5a3df6659314bd 100644 (file)
@@ -71,8 +71,26 @@ void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) {
     assert(0 && "Do not know how to split the result of this operator!");
     abort();
     
-  case ISD::UNDEF:       SplitRes_UNDEF(N, Lo, Hi); break;
-  case ISD::LOAD:        SplitRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
+  case ISD::UNDEF:            SplitRes_UNDEF(N, Lo, Hi); break;
+  case ISD::LOAD:             SplitRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
+  case ISD::BUILD_PAIR:       SplitRes_BUILD_PAIR(N, Lo, Hi); break;
+  case ISD::INSERT_VECTOR_ELT:SplitRes_INSERT_VECTOR_ELT(N, Lo, Hi); break;
+  case ISD::VECTOR_SHUFFLE:   SplitRes_VECTOR_SHUFFLE(N, Lo, Hi); break;
+  case ISD::BUILD_VECTOR:     SplitRes_BUILD_VECTOR(N, Lo, Hi); break;
+  case ISD::CONCAT_VECTORS:   SplitRes_CONCAT_VECTORS(N, Lo, Hi); break;
+  case ISD::BIT_CONVERT:      SplitRes_BIT_CONVERT(N, Lo, Hi); break;
+  case ISD::CTTZ:
+  case ISD::CTLZ:
+  case ISD::CTPOP:
+  case ISD::FNEG:
+  case ISD::FABS:
+  case ISD::FSQRT:
+  case ISD::FSIN:
+  case ISD::FCOS:
+  case ISD::FP_TO_SINT:
+  case ISD::FP_TO_UINT:
+  case ISD::SINT_TO_FP:
+  case ISD::UINT_TO_FP:       SplitRes_UnOp(N, Lo, Hi); break;
   case ISD::ADD:
   case ISD::SUB:
   case ISD::MUL:
@@ -88,7 +106,9 @@ void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) {
   case ISD::XOR:
   case ISD::UREM:
   case ISD::SREM:
-  case ISD::FREM:        SplitRes_BinOp(N, Lo, Hi); break;
+  case ISD::FREM:             SplitRes_BinOp(N, Lo, Hi); break;
+  case ISD::FPOWI:            SplitRes_FPOWI(N, Lo, Hi); break;
+  case ISD::SELECT:           SplitRes_SELECT(N, Lo, Hi); break;
   }
   
   // If Lo/Hi is null, the sub-method took care of registering results etc.
@@ -134,6 +154,124 @@ void DAGTypeLegalizer::SplitRes_LOAD(LoadSDNode *LD,
   ReplaceValueWith(SDOperand(LD, 1), TF);
 }
 
+void DAGTypeLegalizer::SplitRes_BUILD_PAIR(SDNode *N, SDOperand &Lo,
+                                           SDOperand &Hi) {
+  Lo = N->getOperand(0);
+  Hi = N->getOperand(1);
+}
+
+void DAGTypeLegalizer::SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo,
+                                                  SDOperand &Hi) {
+  GetSplitOp(N->getOperand(0), Lo, Hi);
+  unsigned Index = cast<ConstantSDNode>(N->getOperand(2))->getValue();
+  SDOperand ScalarOp = N->getOperand(1);
+  unsigned LoNumElts = MVT::getVectorNumElements(Lo.getValueType());
+  if (Index < LoNumElts)
+    Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, Lo.getValueType(), Lo, ScalarOp,
+                     N->getOperand(2));
+  else
+    Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, Hi.getValueType(), Hi, ScalarOp,
+                     DAG.getConstant(Index - LoNumElts, TLI.getPointerTy()));
+  
+}
+
+void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N, 
+                                               SDOperand &Lo, SDOperand &Hi) {
+  // Build the low part.
+  SDOperand Mask = N->getOperand(2);
+  SmallVector<SDOperand, 16> Ops;
+  MVT::ValueType PtrVT = TLI.getPointerTy();
+  
+  MVT::ValueType LoVT, HiVT;
+  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+  MVT::ValueType EltVT = MVT::getVectorElementType(LoVT);
+  unsigned LoNumElts = MVT::getVectorNumElements(LoVT);
+  unsigned NumElements = Mask.getNumOperands();
+
+  // Insert all of the elements from the input that are needed.  We use 
+  // buildvector of extractelement here because the input vectors will have
+  // to be legalized, so this makes the code simpler.
+  for (unsigned i = 0; i != LoNumElts; ++i) {
+    unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
+    SDOperand InVec = N->getOperand(0);
+    if (Idx >= NumElements) {
+      InVec = N->getOperand(1);
+      Idx -= NumElements;
+    }
+    Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InVec,
+                              DAG.getConstant(Idx, PtrVT)));
+  }
+  Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &Ops[0], Ops.size());
+  Ops.clear();
+  
+  for (unsigned i = LoNumElts; i != NumElements; ++i) {
+    unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
+    SDOperand InVec = N->getOperand(0);
+    if (Idx >= NumElements) {
+      InVec = N->getOperand(1);
+      Idx -= NumElements;
+    }
+    Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InVec,
+                              DAG.getConstant(Idx, PtrVT)));
+  }
+  Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &Ops[0], Ops.size());
+}
+
+void DAGTypeLegalizer::SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo, 
+                                             SDOperand &Hi) {
+  MVT::ValueType LoVT, HiVT;
+  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+  unsigned LoNumElts = MVT::getVectorNumElements(LoVT);
+  SmallVector<SDOperand, 8> LoOps(N->op_begin(), N->op_begin()+LoNumElts);
+  Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &LoOps[0], LoOps.size());
+  
+  SmallVector<SDOperand, 8> HiOps(N->op_begin()+LoNumElts, N->op_end());
+  Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &HiOps[0], HiOps.size());
+}
+
+void DAGTypeLegalizer::SplitRes_CONCAT_VECTORS(SDNode *N, 
+                                               SDOperand &Lo, SDOperand &Hi) {
+  // FIXME: Handle non-power-of-two vectors?
+  unsigned NumSubvectors = N->getNumOperands() / 2;
+  if (NumSubvectors == 1) {
+    Lo = N->getOperand(0);
+    Hi = N->getOperand(1);
+    return;
+  }
+
+  MVT::ValueType LoVT, HiVT;
+  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+
+  SmallVector<SDOperand, 8> LoOps(N->op_begin(), N->op_begin()+NumSubvectors);
+  Lo = DAG.getNode(ISD::CONCAT_VECTORS, LoVT, &LoOps[0], LoOps.size());
+    
+  SmallVector<SDOperand, 8> HiOps(N->op_begin()+NumSubvectors, N->op_end());
+  Hi = DAG.getNode(ISD::CONCAT_VECTORS, HiVT, &HiOps[0], HiOps.size());
+}
+
+void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N, 
+                                            SDOperand &Lo, SDOperand &Hi) {
+  // We know the result is a vector.  The input may be either a vector or a
+  // scalar value.
+  SDOperand InOp = N->getOperand(0);
+  if (MVT::isVector(InOp.getValueType()) &&
+      MVT::getVectorNumElements(InOp.getValueType()) != 1) {
+    // If this is a vector, split the vector and convert each of the pieces now.
+    GetSplitOp(InOp, Lo, Hi);
+    
+    MVT::ValueType LoVT, HiVT;
+    GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+
+    Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
+    Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
+    return;
+  }
+  
+  // Lower the bit-convert to a store/load from the stack, then split the load.
+  SDOperand Op = CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
+  SplitRes_LOAD(cast<LoadSDNode>(Op.Val), Lo, Hi);
+}
+
 void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
   SDOperand LHSLo, LHSHi;
   GetSplitOp(N->getOperand(0), LHSLo, LHSHi);
@@ -144,6 +282,33 @@ void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
   Hi = DAG.getNode(N->getOpcode(), LHSHi.getValueType(), LHSHi, RHSHi);
 }
 
+void DAGTypeLegalizer::SplitRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+  // Get the dest types.  This doesn't always match input types, e.g. int_to_fp.
+  MVT::ValueType LoVT, HiVT;
+  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+
+  GetSplitOp(N->getOperand(0), Lo, Hi);
+  Lo = DAG.getNode(N->getOpcode(), LoVT, Lo);
+  Hi = DAG.getNode(N->getOpcode(), HiVT, Hi);
+}
+
+void DAGTypeLegalizer::SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+  GetSplitOp(N->getOperand(0), Lo, Hi);
+  Lo = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Lo, N->getOperand(1));
+  Hi = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Hi, N->getOperand(1));
+}
+
+
+void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi){
+  SDOperand LL, LH, RL, RH;
+  GetSplitOp(N->getOperand(1), LL, LH);
+  GetSplitOp(N->getOperand(2), RL, RH);
+  
+  SDOperand Cond = N->getOperand(0);
+  Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), Cond, LL, RL);
+  Hi = DAG.getNode(ISD::SELECT, LH.getValueType(), Cond, LH, RH);
+}
+
 
 //===----------------------------------------------------------------------===//
 //  Operand Vector Splitting