Add a default constructor to AsmWriterOperand to make VS2008sp1 happy. (AsmWriterOper...
[oota-llvm.git] / utils / TableGen / CodeGenDAGPatterns.cpp
index 2a7fd0bbfa2c26f3bae96f5519cdb618b39cc3e9..e987c2bc82e188d352027f01fcfdfaaa937fd455 100644 (file)
@@ -140,6 +140,33 @@ void DumpDepVars(MultipleUseVarSet &DepVars) {
 }
 }
 
+//===----------------------------------------------------------------------===//
+// PatternToMatch implementation
+//
+
+/// getPredicateCheck - Return a single string containing all of this
+/// pattern's predicates concatenated with "&&" operators.
+///
+std::string PatternToMatch::getPredicateCheck() const {
+  std::string PredicateCheck;
+  for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
+    if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) {
+      Record *Def = Pred->getDef();
+      if (!Def->isSubClassOf("Predicate")) {
+#ifndef NDEBUG
+        Def->dump();
+#endif
+        assert(0 && "Unknown predicate type!");
+      }
+      if (!PredicateCheck.empty())
+        PredicateCheck += " && ";
+      PredicateCheck += "(" + Def->getValueAsString("CondString") + ")";
+    }
+  }
+
+  return PredicateCheck;
+}
+
 //===----------------------------------------------------------------------===//
 // SDTypeConstraint implementation
 //
@@ -443,8 +470,8 @@ bool TreePatternNode::UpdateNodeType(const std::vector<unsigned char> &ExtVTs,
     return true;
   }
 
-  if (getExtTypeNum(0) == MVT::iPTR) {
-    if (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == EMVT::isInt)
+  if (getExtTypeNum(0) == MVT::iPTR || getExtTypeNum(0) == MVT::iPTRAny) {
+    if (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny || ExtVTs[0] == EMVT::isInt)
       return false;
     if (EMVT::isExtIntegerInVTs(ExtVTs)) {
       std::vector<unsigned char> FVTs = FilterEVTs(ExtVTs, isInteger);
@@ -463,7 +490,8 @@ bool TreePatternNode::UpdateNodeType(const std::vector<unsigned char> &ExtVTs,
     setTypes(FVTs);
     return true;
   }
-  if (ExtVTs[0] == MVT::iPTR && EMVT::isExtIntegerInVTs(getExtTypes())) {
+  if ((ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny) &&
+      EMVT::isExtIntegerInVTs(getExtTypes())) {
     //assert(hasTypeSet() && "should be handled above!");
     std::vector<unsigned char> FVTs = FilterEVTs(getExtTypes(), isInteger);
     if (getExtTypes() == FVTs)
@@ -495,7 +523,8 @@ bool TreePatternNode::UpdateNodeType(const std::vector<unsigned char> &ExtVTs,
     setTypes(ExtVTs);
     return true;
   }
-  if (getExtTypeNum(0) == EMVT::isInt && ExtVTs[0] == MVT::iPTR) {
+  if (getExtTypeNum(0) == EMVT::isInt &&
+      (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny)) {
     setTypes(ExtVTs);
     return true;
   }
@@ -527,6 +556,7 @@ void TreePatternNode::print(std::ostream &OS) const {
   case EMVT::isFP : OS << ":isFP"; break;
   case EMVT::isUnknown: ; /*OS << ":?";*/ break;
   case MVT::iPTR:  OS << ":iPTR"; break;
+  case MVT::iPTRAny:  OS << ":iPTRAny"; break;
   default: {
     std::string VTName = llvm::getName(getTypeNum(0));
     // Strip off MVT:: prefix if present.
@@ -549,8 +579,8 @@ void TreePatternNode::print(std::ostream &OS) const {
     OS << ")";
   }
   
-  if (!PredicateFn.empty())
-    OS << "<<P:" << PredicateFn << ">>";
+  for (unsigned i = 0, e = PredicateFns.size(); i != e; ++i)
+    OS << "<<P:" << PredicateFns[i] << ">>";
   if (TransformFn)
     OS << "<<X:" << TransformFn->getName() << ">>";
   if (!getName().empty())
@@ -572,7 +602,7 @@ bool TreePatternNode::isIsomorphicTo(const TreePatternNode *N,
                                      const MultipleUseVarSet &DepVars) const {
   if (N == this) return true;
   if (N->isLeaf() != isLeaf() || getExtTypes() != N->getExtTypes() ||
-      getPredicateFn() != N->getPredicateFn() ||
+      getPredicateFns() != N->getPredicateFns() ||
       getTransformFn() != N->getTransformFn())
     return false;
 
@@ -610,7 +640,7 @@ TreePatternNode *TreePatternNode::clone() const {
   }
   New->setName(getName());
   New->setTypes(getExtTypes());
-  New->setPredicateFn(getPredicateFn());
+  New->setPredicateFns(getPredicateFns());
   New->setTransformFn(getTransformFn());
   return New;
 }
@@ -628,9 +658,12 @@ SubstituteFormalArguments(std::map<std::string, TreePatternNode*> &ArgMap) {
       if (dynamic_cast<DefInit*>(Val) &&
           static_cast<DefInit*>(Val)->getDef()->getName() == "node") {
         // We found a use of a formal argument, replace it with its value.
-        Child = ArgMap[Child->getName()];
-        assert(Child && "Couldn't find formal argument!");
-        setChild(i, Child);
+        TreePatternNode *NewChild = ArgMap[Child->getName()];
+        assert(NewChild && "Couldn't find formal argument!");
+        assert((Child->getPredicateFns().empty() ||
+                NewChild->getPredicateFns() == Child->getPredicateFns()) &&
+               "Non-empty child predicate clobbered!");
+        setChild(i, NewChild);
       }
     } else {
       getChild(i)->SubstituteFormalArguments(ArgMap);
@@ -648,8 +681,16 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) {
   
   if (!Op->isSubClassOf("PatFrag")) {
     // Just recursively inline children nodes.
-    for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
-      setChild(i, getChild(i)->InlinePatternFragments(TP));
+    for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
+      TreePatternNode *Child = getChild(i);
+      TreePatternNode *NewChild = Child->InlinePatternFragments(TP);
+
+      assert((Child->getPredicateFns().empty() ||
+              NewChild->getPredicateFns() == Child->getPredicateFns()) &&
+             "Non-empty child predicate clobbered!");
+
+      setChild(i, NewChild);
+    }
     return this;
   }
 
@@ -664,6 +705,10 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) {
 
   TreePatternNode *FragTree = Frag->getOnlyTree()->clone();
 
+  std::string Code = Op->getValueAsCode("Predicate");
+  if (!Code.empty())
+    FragTree->addPredicateFn("Predicate_"+Op->getName());
+
   // Resolve formal arguments to their actual value.
   if (Frag->getNumArgs()) {
     // Compute the map of formal to actual arguments.
@@ -676,10 +721,17 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) {
   
   FragTree->setName(getName());
   FragTree->UpdateNodeType(getExtTypes(), TP);
-  
+
+  // Transfer in the old predicates.
+  for (unsigned i = 0, e = getPredicateFns().size(); i != e; ++i)
+    FragTree->addPredicateFn(getPredicateFns()[i]);
+
   // Get a new copy of this fragment to stitch into here.
   //delete this;    // FIXME: implement refcounting!
-  return FragTree;
+  
+  // The fragment we inlined could have recursive inlining that is needed.  See
+  // if there are any pattern fragments in it and inline them as needed.
+  return FragTree->InlinePatternFragments(TP);
 }
 
 /// getImplicitType - Check to see if the specified record has an implicit
@@ -778,7 +830,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
           assert(getTypeNum(i) == VT && "TreePattern has too many types!");
         
         VT = getTypeNum(0);
-        if (VT != MVT::iPTR) {
+        if (VT != MVT::iPTR && VT != MVT::iPTRAny) {
           unsigned Size = MVT(VT).getSizeInBits();
           // Make sure that the value is representable for this type.
           if (Size < 32) {
@@ -1372,7 +1424,7 @@ void CodeGenDAGPatterns::ParsePatternFragments() {
     // this fragment uses it.
     std::string Code = Fragments[i]->getValueAsCode("Predicate");
     if (!Code.empty())
-      P->getOnlyTree()->setPredicateFn("Predicate_"+Fragments[i]->getName());
+      P->getOnlyTree()->addPredicateFn("Predicate_"+Fragments[i]->getName());
     
     // If there is a node transformation corresponding to this, keep track of
     // it.
@@ -1383,9 +1435,8 @@ void CodeGenDAGPatterns::ParsePatternFragments() {
   
   // Now that we've parsed all of the tree fragments, do a closure on them so
   // that there are not references to PatFrags left inside of them.
-  for (std::map<Record*, TreePattern*>::iterator I = PatternFragments.begin(),
-       E = PatternFragments.end(); I != E; ++I) {
-    TreePattern *ThePat = I->second;
+  for (unsigned i = 0, e = Fragments.size(); i != e; ++i) {
+    TreePattern *ThePat = PatternFragments[Fragments[i]];
     ThePat->InlinePatternFragments();
         
     // Infer as many types as possible.  Don't worry about it if we don't infer
@@ -1879,7 +1930,7 @@ void CodeGenDAGPatterns::ParseInstructions() {
       TreePatternNode *OpNode = InVal->clone();
       
       // No predicate is useful on the result.
-      OpNode->setPredicateFn("");
+      OpNode->clearPredicateFns();
       
       // Promote the xform function to be an explicit node if set.
       if (Record *Xform = OpNode->getTransformFn()) {
@@ -2106,7 +2157,7 @@ static void CombineChildVariants(TreePatternNode *Orig,
     
     // Copy over properties.
     R->setName(Orig->getName());
-    R->setPredicateFn(Orig->getPredicateFn());
+    R->setPredicateFns(Orig->getPredicateFns());
     R->setTransformFn(Orig->getTransformFn());
     R->setTypes(Orig->getExtTypes());
     
@@ -2168,7 +2219,7 @@ static void GatherChildrenOfAssociativeOpcode(TreePatternNode *N,
   Record *Operator = N->getOperator();
   
   // Only permit raw nodes.
-  if (!N->getName().empty() || !N->getPredicateFn().empty() ||
+  if (!N->getName().empty() || !N->getPredicateFns().empty() ||
       N->getTransformFn()) {
     Children.push_back(N);
     return;