Tablegen support for insert & extract element matching
[oota-llvm.git] / utils / TableGen / CodeGenDAGPatterns.cpp
index 0d61003569d99c9351921d240995fbb960668740..146488e507baaff058a8ef8f01e21e94d22c52c4 100644 (file)
@@ -1,4 +1,4 @@
-//===- CodegenDAGPatterns.cpp - Read DAG patterns from .td file -----------===//
+//===- CodeGenDAGPatterns.cpp - Read DAG patterns from .td file -----------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,19 +7,18 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements the CodegenDAGPatterns class, which is used to read and
+// This file implements the CodeGenDAGPatterns class, which is used to read and
 // represent the patterns present in a .td file for instructions.
 //
 //===----------------------------------------------------------------------===//
 
-#include "CodegenDAGPatterns.h"
+#include "CodeGenDAGPatterns.h"
 #include "Record.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Debug.h"
-//#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Streams.h"
-//#include <algorithm>
 #include <set>
+#include <algorithm>
 using namespace llvm;
 
 //===----------------------------------------------------------------------===//
@@ -113,6 +112,10 @@ SDTypeConstraint::SDTypeConstraint(Record *R) {
     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);
@@ -289,6 +292,19 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N,
     }
     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;
 }
@@ -319,6 +335,12 @@ SDNodeInfo::SDNodeInfo(Record *R) : Def(R) {
       Properties |= 1 << SDNPInFlag;
     } else if (PropList[i]->getName() == "SDNPOptInFlag") {
       Properties |= 1 << SDNPOptInFlag;
+    } else if (PropList[i]->getName() == "SDNPMayStore") {
+      Properties |= 1 << SDNPMayStore;
+    } else if (PropList[i]->getName() == "SDNPMayLoad") {
+      Properties |= 1 << SDNPMayLoad;
+    } else if (PropList[i]->getName() == "SDNPSideEffect") {
+      Properties |= 1 << SDNPSideEffect;
     } else {
       cerr << "Unknown SD Node property '" << PropList[i]->getName()
            << "' on node '" << R->getName() << "'!\n";
@@ -635,12 +657,28 @@ static std::vector<unsigned char> getImplicitType(Record *R, bool NotRegisters,
   return Other;
 }
 
+
+/// getIntrinsicInfo - If this node corresponds to an intrinsic, return the
+/// CodeGenIntrinsic information for it, otherwise return a null pointer.
+const CodeGenIntrinsic *TreePatternNode::
+getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const {
+  if (getOperator() != CDP.get_intrinsic_void_sdnode() &&
+      getOperator() != CDP.get_intrinsic_w_chain_sdnode() &&
+      getOperator() != CDP.get_intrinsic_wo_chain_sdnode())
+    return 0;
+    
+  unsigned IID = 
+    dynamic_cast<IntInit*>(getChild(0)->getLeafValue())->getValue();
+  return &CDP.getIntrinsicInfo(IID);
+}
+
+
 /// ApplyTypeConstraints - Apply all of the type constraints relevent to
 /// this node and its children in the tree.  This returns true if it makes a
 /// change, false otherwise.  If a type contradiction is found, throw an
 /// exception.
 bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
-  CodegenDAGPatterns &CDP = TP.getDAGPatterns();
+  CodeGenDAGPatterns &CDP = TP.getDAGPatterns();
   if (isLeaf()) {
     if (DefInit *DI = dynamic_cast<DefInit*>(getLeafValue())) {
       // If it's a regclass or something else known, include the type.
@@ -701,27 +739,22 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
       MadeChange = getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
     MadeChange |= UpdateNodeType(MVT::isVoid, TP);
     return MadeChange;
-  } else if (getOperator() == CDP.get_intrinsic_void_sdnode() ||
-             getOperator() == CDP.get_intrinsic_w_chain_sdnode() ||
-             getOperator() == CDP.get_intrinsic_wo_chain_sdnode()) {
-    unsigned IID = 
-    dynamic_cast<IntInit*>(getChild(0)->getLeafValue())->getValue();
-    const CodeGenIntrinsic &Int = CDP.getIntrinsicInfo(IID);
+  } else if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) {
     bool MadeChange = false;
     
     // Apply the result type to the node.
-    MadeChange = UpdateNodeType(Int.ArgVTs[0], TP);
+    MadeChange = UpdateNodeType(Int->ArgVTs[0], TP);
     
-    if (getNumChildren() != Int.ArgVTs.size())
-      TP.error("Intrinsic '" + Int.Name + "' expects " +
-               utostr(Int.ArgVTs.size()-1) + " operands, not " +
+    if (getNumChildren() != Int->ArgVTs.size())
+      TP.error("Intrinsic '" + Int->Name + "' expects " +
+               utostr(Int->ArgVTs.size()-1) + " operands, not " +
                utostr(getNumChildren()-1) + " operands!");
 
     // Apply type info to the intrinsic ID.
     MadeChange |= getChild(0)->UpdateNodeType(MVT::iPTR, TP);
     
     for (unsigned i = 1, e = getNumChildren(); i != e; ++i) {
-      MVT::ValueType OpVT = Int.ArgVTs[i];
+      MVT::ValueType OpVT = Int->ArgVTs[i];
       MadeChange |= getChild(i)->UpdateNodeType(OpVT, TP);
       MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
     }
@@ -864,7 +897,7 @@ static bool OnlyOnRHSOfCommutative(TreePatternNode *N) {
 /// that can never possibly work), and to prevent the pattern permuter from
 /// generating stuff that is useless.
 bool TreePatternNode::canPatternMatch(std::string &Reason, 
-                                      CodegenDAGPatterns &CDP){
+                                      CodeGenDAGPatterns &CDP){
   if (isLeaf()) return true;
 
   for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
@@ -901,20 +934,20 @@ bool TreePatternNode::canPatternMatch(std::string &Reason,
 //
 
 TreePattern::TreePattern(Record *TheRec, ListInit *RawPat, bool isInput,
-                         CodegenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
+                         CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
    isInputPattern = isInput;
    for (unsigned i = 0, e = RawPat->getSize(); i != e; ++i)
      Trees.push_back(ParseTreePattern((DagInit*)RawPat->getElement(i)));
 }
 
 TreePattern::TreePattern(Record *TheRec, DagInit *Pat, bool isInput,
-                         CodegenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
+                         CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
   isInputPattern = isInput;
   Trees.push_back(ParseTreePattern(Pat));
 }
 
 TreePattern::TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput,
-                         CodegenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
+                         CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
   isInputPattern = isInput;
   Trees.push_back(Pat);
 }
@@ -1108,11 +1141,11 @@ void TreePattern::print(std::ostream &OS) const {
 void TreePattern::dump() const { print(*cerr.stream()); }
 
 //===----------------------------------------------------------------------===//
-// CodegenDAGPatterns implementation
+// CodeGenDAGPatterns implementation
 //
 
 // FIXME: REMOVE OSTREAM ARGUMENT
-CodegenDAGPatterns::CodegenDAGPatterns(RecordKeeper &R) : Records(R) {
+CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : Records(R) {
   Intrinsics = LoadIntrinsics(Records);
   ParseNodeInfo();
   ParseNodeTransforms();
@@ -1127,14 +1160,14 @@ CodegenDAGPatterns::CodegenDAGPatterns(RecordKeeper &R) : Records(R) {
   GenerateVariants();
 }
 
-CodegenDAGPatterns::~CodegenDAGPatterns() {
+CodeGenDAGPatterns::~CodeGenDAGPatterns() {
   for (std::map<Record*, TreePattern*>::iterator I = PatternFragments.begin(),
        E = PatternFragments.end(); I != E; ++I)
     delete I->second;
 }
 
 
-Record *CodegenDAGPatterns::getSDNodeNamed(const std::string &Name) const {
+Record *CodeGenDAGPatterns::getSDNodeNamed(const std::string &Name) const {
   Record *N = Records.getDef(Name);
   if (!N || !N->isSubClassOf("SDNode")) {
     cerr << "Error getting SDNode '" << Name << "'!\n";
@@ -1144,7 +1177,7 @@ Record *CodegenDAGPatterns::getSDNodeNamed(const std::string &Name) const {
 }
 
 // Parse all of the SDNode definitions for the target, populating SDNodes.
-void CodegenDAGPatterns::ParseNodeInfo() {
+void CodeGenDAGPatterns::ParseNodeInfo() {
   std::vector<Record*> Nodes = Records.getAllDerivedDefinitions("SDNode");
   while (!Nodes.empty()) {
     SDNodes.insert(std::make_pair(Nodes.back(), Nodes.back()));
@@ -1159,7 +1192,7 @@ void CodegenDAGPatterns::ParseNodeInfo() {
 
 /// ParseNodeTransforms - Parse all SDNodeXForm instances into the SDNodeXForms
 /// map, and emit them to the file as functions.
-void CodegenDAGPatterns::ParseNodeTransforms() {
+void CodeGenDAGPatterns::ParseNodeTransforms() {
   std::vector<Record*> Xforms = Records.getAllDerivedDefinitions("SDNodeXForm");
   while (!Xforms.empty()) {
     Record *XFormNode = Xforms.back();
@@ -1171,7 +1204,7 @@ void CodegenDAGPatterns::ParseNodeTransforms() {
   }
 }
 
-void CodegenDAGPatterns::ParseComplexPatterns() {
+void CodeGenDAGPatterns::ParseComplexPatterns() {
   std::vector<Record*> AMs = Records.getAllDerivedDefinitions("ComplexPattern");
   while (!AMs.empty()) {
     ComplexPatterns.insert(std::make_pair(AMs.back(), AMs.back()));
@@ -1185,7 +1218,7 @@ void CodegenDAGPatterns::ParseComplexPatterns() {
 /// inline fragments together as necessary, so that there are no references left
 /// inside a pattern fragment to a pattern fragment.
 ///
-void CodegenDAGPatterns::ParsePatternFragments() {
+void CodeGenDAGPatterns::ParsePatternFragments() {
   std::vector<Record*> Fragments = Records.getAllDerivedDefinitions("PatFrag");
   
   // First step, parse all of the fragments.
@@ -1268,7 +1301,7 @@ void CodegenDAGPatterns::ParsePatternFragments() {
   }
 }
 
-void CodegenDAGPatterns::ParseDefaultOperands() {
+void CodeGenDAGPatterns::ParseDefaultOperands() {
   std::vector<Record*> DefaultOps[2];
   DefaultOps[0] = Records.getAllDerivedDefinitions("PredicateOperand");
   DefaultOps[1] = Records.getAllDerivedDefinitions("OptionalDefOperand");
@@ -1375,7 +1408,7 @@ static bool HandleUse(TreePattern *I, TreePatternNode *Pat,
 /// FindPatternInputsAndOutputs - Scan the specified TreePatternNode (which is
 /// part of "I", the instruction), computing the set of inputs and outputs of
 /// the pattern.  Report errors if we see anything naughty.
-void CodegenDAGPatterns::
+void CodeGenDAGPatterns::
 FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
                             std::map<std::string, TreePatternNode*> &InstInputs,
                             std::map<std::string, TreePatternNode*>&InstResults,
@@ -1460,7 +1493,7 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
 /// ParseInstructions - Parse all of the instructions, inlining and resolving
 /// any fragments involved.  This populates the Instructions list with fully
 /// resolved instructions.
-void CodegenDAGPatterns::ParseInstructions() {
+void CodeGenDAGPatterns::ParseInstructions() {
   std::vector<Record*> Instrs = Records.getAllDerivedDefinitions("Instruction");
   
   for (unsigned i = 0, e = Instrs.size(); i != e; ++i) {
@@ -1663,7 +1696,7 @@ void CodegenDAGPatterns::ParseInstructions() {
   for (std::map<Record*, DAGInstruction>::iterator II = Instructions.begin(),
        E = Instructions.end(); II != E; ++II) {
     DAGInstruction &TheInst = II->second;
-    TreePattern *I = TheInst.getPattern();
+    const TreePattern *I = TheInst.getPattern();
     if (I == 0) continue;  // No pattern.
 
     // FIXME: Assume only the first tree is the pattern. The others are clobber
@@ -1690,7 +1723,7 @@ void CodegenDAGPatterns::ParseInstructions() {
   }
 }
 
-void CodegenDAGPatterns::ParsePatterns() {
+void CodeGenDAGPatterns::ParsePatterns() {
   std::vector<Record*> Patterns = Records.getAllDerivedDefinitions("Pattern");
 
   for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
@@ -1800,7 +1833,7 @@ void CodegenDAGPatterns::ParsePatterns() {
 static void CombineChildVariants(TreePatternNode *Orig, 
                const std::vector<std::vector<TreePatternNode*> > &ChildVariants,
                                  std::vector<TreePatternNode*> &OutVariants,
-                                 CodegenDAGPatterns &CDP) {
+                                 CodeGenDAGPatterns &CDP) {
   // Make sure that each operand has at least one variant to choose from.
   for (unsigned i = 0, e = ChildVariants.size(); i != e; ++i)
     if (ChildVariants[i].empty())
@@ -1865,7 +1898,7 @@ static void CombineChildVariants(TreePatternNode *Orig,
                                  const std::vector<TreePatternNode*> &LHS,
                                  const std::vector<TreePatternNode*> &RHS,
                                  std::vector<TreePatternNode*> &OutVariants,
-                                 CodegenDAGPatterns &CDP) {
+                                 CodeGenDAGPatterns &CDP) {
   std::vector<std::vector<TreePatternNode*> > ChildVariants;
   ChildVariants.push_back(LHS);
   ChildVariants.push_back(RHS);
@@ -1901,7 +1934,7 @@ static void GatherChildrenOfAssociativeOpcode(TreePatternNode *N,
 ///
 static void GenerateVariantsOf(TreePatternNode *N,
                                std::vector<TreePatternNode*> &OutVariants,
-                               CodegenDAGPatterns &CDP) {
+                               CodeGenDAGPatterns &CDP) {
   // We cannot permute leaves.
   if (N->isLeaf()) {
     OutVariants.push_back(N);
@@ -1997,7 +2030,7 @@ static void GenerateVariantsOf(TreePatternNode *N,
 
 // GenerateVariants - Generate variants.  For example, commutative patterns can
 // match multiple ways.  Add them to PatternsToMatch as well.
-void CodegenDAGPatterns::GenerateVariants() {
+void CodeGenDAGPatterns::GenerateVariants() {
   DOUT << "Generating instruction variants.\n";
   
   // Loop over all of the patterns we've collected, checking to see if we can