Tablegen support for insert & extract element matching


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46901 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/TargetSelectionDAG.td b/lib/Target/TargetSelectionDAG.td
index cdc50fa..a38d863 100644
--- a/lib/Target/TargetSelectionDAG.td
+++ b/lib/Target/TargetSelectionDAG.td
@@ -60,6 +60,13 @@
   int OtherOpNum = OtherOp;
 }
 
+/// SDTCisEltOfVec - This indicates that ThisOp is a scalar type of the same
+/// type as the element type of OtherOp, which is a vector type.
+class  SDTCisEltOfVec<int ThisOp, int OtherOp>
+  : SDTypeConstraint<ThisOp> {
+  int OtherOpNum = OtherOp;
+}
+
 //===----------------------------------------------------------------------===//
 // Selection DAG Type Profile definitions.
 //
@@ -171,6 +178,12 @@
 def SDTVecShuffle : SDTypeProfile<1, 3, [
   SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisIntVectorOfSameSize<3, 0>
 ]>;
+def SDTVecExtract : SDTypeProfile<1, 2, [ // vector extract
+  SDTCisEltOfVec<0, 1>, SDTCisPtrTy<2>
+]>;
+def SDTVecInsert : SDTypeProfile<1, 2, [  // vector insert
+  SDTCisEltOfVec<1, 0>, SDTCisPtrTy<2>
+]>;
 
 class SDCallSeqStart<list<SDTypeConstraint> constraints> :
         SDTypeProfile<0, 1, constraints>;
@@ -283,6 +296,9 @@
 def anyext     : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>;
 def trunc      : SDNode<"ISD::TRUNCATE"   , SDTIntTruncOp>;
 def bitconvert : SDNode<"ISD::BIT_CONVERT", SDTUnaryOp>;
+def extractelt : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTVecExtract>;
+def insertelt  : SDNode<"ISD::INSERT_VECTOR_ELT", SDTVecInsert>;
+
                         
 def fadd       : SDNode<"ISD::FADD"       , SDTFPBinOp, [SDNPCommutative]>;
 def fsub       : SDNode<"ISD::FSUB"       , SDTFPBinOp>;
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 14b2b80..146488e 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -112,6 +112,10 @@
     ConstraintType = SDTCisIntVectorOfSameSize;
     x.SDTCisIntVectorOfSameSize_Info.OtherOperandNum =
       R->getValueAsInt("OtherOpNum");
+  } else if (R->isSubClassOf("SDTCisEltOfVec")) {
+    ConstraintType = SDTCisEltOfVec;
+    x.SDTCisEltOfVec_Info.OtherOperandNum =
+      R->getValueAsInt("OtherOpNum");
   } else {
     cerr << "Unrecognized SDTypeConstraint '" << R->getName() << "'!\n";
     exit(1);
@@ -288,6 +292,19 @@
     }
     return false;
   }
+  case SDTCisEltOfVec: {
+    TreePatternNode *OtherOperand =
+      getOperandNum(x.SDTCisIntVectorOfSameSize_Info.OtherOperandNum,
+                    N, NumResults);
+    if (OtherOperand->hasTypeSet()) {
+      if (!MVT::isVector(OtherOperand->getTypeNum(0)))
+        TP.error(N->getOperator()->getName() + " VT operand must be a vector!");
+      MVT::ValueType IVT = OtherOperand->getTypeNum(0);
+      IVT = MVT::getVectorElementType(IVT);
+      return NodeToApply->UpdateNodeType(IVT, TP);
+    }
+    return false;
+  }
   }  
   return false;
 }
diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h
index d62b279..44c154a 100644
--- a/utils/TableGen/CodeGenDAGPatterns.h
+++ b/utils/TableGen/CodeGenDAGPatterns.h
@@ -56,7 +56,8 @@
   unsigned OperandNo;   // The operand # this constraint applies to.
   enum { 
     SDTCisVT, SDTCisPtrTy, SDTCisInt, SDTCisFP, SDTCisSameAs, 
-    SDTCisVTSmallerThanOp, SDTCisOpSmallerThanOp, SDTCisIntVectorOfSameSize
+    SDTCisVTSmallerThanOp, SDTCisOpSmallerThanOp, SDTCisIntVectorOfSameSize,
+    SDTCisEltOfVec
   } ConstraintType;
   
   union {   // The discriminated union.
@@ -75,6 +76,9 @@
     struct {
       unsigned OtherOperandNum;
     } SDTCisIntVectorOfSameSize_Info;
+    struct {
+      unsigned OtherOperandNum;
+    } SDTCisEltOfVec_Info;
   } x;
 
   /// ApplyTypeConstraint - Given a node in a pattern, apply this type