[llvm-commits] [llvm] r57562 - in /llvm/trunk/utils/TableGen: CodeGenDAGPatterns.cpp CodeGenDAGPatterns.h DAGISelEmitter.cpp FastISelEmitter.cpp

Dan Gohman gohman at apple.com
Tue Oct 14 23:17:21 PDT 2008


Author: djg
Date: Wed Oct 15 01:17:21 2008
New Revision: 57562

URL: http://llvm.org/viewvc/llvm-project?rev=57562&view=rev
Log:
Add support for having multiple predicates on a TreePatternNode.
This will allow predicates to be composed, which will allow the
predicate definitions to become less redundant, and eventually
will allow DAGISelEmitter.cpp to emit less redundant code.

Modified:
    llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
    llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h
    llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
    llvm/trunk/utils/TableGen/FastISelEmitter.cpp

Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=57562&r1=57561&r2=57562&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Wed Oct 15 01:17:21 2008
@@ -579,8 +579,8 @@
     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())
@@ -602,7 +602,7 @@
                                      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;
 
@@ -640,7 +640,7 @@
   }
   New->setName(getName());
   New->setTypes(getExtTypes());
-  New->setPredicateFn(getPredicateFn());
+  New->setPredicateFns(getPredicateFns());
   New->setTransformFn(getTransformFn());
   return New;
 }
@@ -658,9 +658,12 @@
       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);
@@ -678,8 +681,16 @@
   
   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;
   }
 
@@ -694,6 +705,10 @@
 
   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.
@@ -706,7 +721,11 @@
   
   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!
   
@@ -1405,7 +1424,7 @@
     // 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.
@@ -1911,7 +1930,7 @@
       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()) {
@@ -2138,7 +2157,7 @@
     
     // Copy over properties.
     R->setName(Orig->getName());
-    R->setPredicateFn(Orig->getPredicateFn());
+    R->setPredicateFns(Orig->getPredicateFns());
     R->setTransformFn(Orig->getTransformFn());
     R->setTypes(Orig->getExtTypes());
     
@@ -2200,7 +2219,7 @@
   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;

Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h?rev=57562&r1=57561&r2=57562&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h Wed Oct 15 01:17:21 2008
@@ -16,6 +16,8 @@
 #define CODEGEN_DAGPATTERNS_H
 
 #include <set>
+#include <algorithm>
+#include <vector>
 
 #include "CodeGenTarget.h"
 #include "CodeGenIntrinsics.h"
@@ -158,9 +160,9 @@
   ///
   std::string Name;
   
-  /// PredicateFn - The predicate function to execute on this node to check
-  /// for a match.  If this string is empty, no predicate is involved.
-  std::string PredicateFn;
+  /// PredicateFns - The predicate functions to execute on this node to check
+  /// for a match.  If this list is empty, no predicate is involved.
+  std::vector<std::string> PredicateFns;
   
   /// TransformFn - The transformation function to execute on this node before
   /// it can be substituted into the resulting instruction on a pattern match.
@@ -213,8 +215,18 @@
     Children[i] = N;
   }
 
-  const std::string &getPredicateFn() const { return PredicateFn; }
-  void setPredicateFn(const std::string &Fn) { PredicateFn = Fn; }
+  const std::vector<std::string> &getPredicateFns() const { return PredicateFns; }
+  void clearPredicateFns() { PredicateFns.clear(); }
+  void setPredicateFns(const std::vector<std::string> &Fns) {
+    assert(PredicateFns.empty() && "Overwriting non-empty predicate list!");
+    PredicateFns = Fns;
+  }
+  void addPredicateFn(const std::string &Fn) { 
+    assert(!Fn.empty() && "Empty predicate string!");
+    if (std::find(PredicateFns.begin(), PredicateFns.end(), Fn) ==
+          PredicateFns.end())
+      PredicateFns.push_back(Fn);
+  }
 
   Record *getTransformFn() const { return TransformFn; }
   void setTransformFn(Record *Fn) { TransformFn = Fn; }

Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=57562&r1=57561&r2=57562&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Wed Oct 15 01:17:21 2008
@@ -76,7 +76,7 @@
 
   // If this node has some predicate function that must match, it adds to the
   // complexity of this node.
-  if (!P->getPredicateFn().empty())
+  if (!P->getPredicateFns().empty())
     ++Size;
   
   // Count children in the count if they are also nodes.
@@ -89,7 +89,7 @@
         Size += 5;  // Matches a ConstantSDNode (+3) and a specific value (+2).
       else if (NodeIsComplexPattern(Child))
         Size += getPatternSize(Child, CGP);
-      else if (!Child->getPredicateFn().empty())
+      else if (!Child->getPredicateFns().empty())
         ++Size;
     }
   }
@@ -140,8 +140,15 @@
   PatternSortingPredicate(CodeGenDAGPatterns &cgp) : CGP(cgp) {}
   CodeGenDAGPatterns &CGP;
 
-  bool operator()(const PatternToMatch *LHS,
-                  const PatternToMatch *RHS) {
+  typedef std::pair<unsigned, std::string> CodeLine;
+  typedef std::vector<CodeLine> CodeList;
+  typedef std::vector<std::pair<const PatternToMatch*, CodeList> > PatternList;
+
+  bool operator()(const std::pair<const PatternToMatch*, CodeList> &LHSPair,
+                  const std::pair<const PatternToMatch*, CodeList> &RHSPair) {
+    const PatternToMatch *LHS = LHSPair.first;
+    const PatternToMatch *RHS = RHSPair.first;
+
     unsigned LHSSize = getPatternSize(LHS->getSrcPattern(), CGP);
     unsigned RHSSize = getPatternSize(RHS->getSrcPattern(), CGP);
     LHSSize += LHS->getAddedComplexity();
@@ -541,11 +548,10 @@
       }
     }
 
-    // If there is a node predicate for this, emit the call.
-    if (!N->getPredicateFn().empty())
-      emitCheck(N->getPredicateFn() + "(" + RootName + ".getNode())");
+    // If there are node predicates for this, emit the calls.
+    for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i)
+      emitCheck(N->getPredicateFns()[i] + "(" + RootName + ".getNode())");
 
-    
     // If this is an 'and R, 1234' where the operation is AND/OR and the RHS is
     // a constant without a predicate fn that has more that one bit set, handle
     // this as a special case.  This is usually for targets that have special
@@ -560,7 +566,7 @@
         (N->getOperator()->getName() == "and" || 
          N->getOperator()->getName() == "or") &&
         N->getChild(1)->isLeaf() &&
-        N->getChild(1)->getPredicateFn().empty()) {
+        N->getChild(1)->getPredicateFns().empty()) {
       if (IntInit *II = dynamic_cast<IntInit*>(N->getChild(1)->getLeafValue())) {
         if (!isPowerOf2_32(II->getValue())) {  // Don't bother with single bits.
           emitInit("SDValue " + RootName + "0" + " = " +
@@ -717,9 +723,9 @@
           assert(0 && "Unknown leaf type!");
         }
         
-        // If there is a node predicate for this, emit the call.
-        if (!Child->getPredicateFn().empty())
-          emitCheck(Child->getPredicateFn() + "(" + RootName +
+        // If there are node predicates for this, emit the calls.
+        for (unsigned i = 0, e = Child->getPredicateFns().size(); i != e; ++i)
+          emitCheck(Child->getPredicateFns()[i] + "(" + RootName +
                     ".getNode())");
       } else if (IntInit *II =
                  dynamic_cast<IntInit*>(Child->getLeafValue())) {
@@ -1265,7 +1271,8 @@
         emitCode(After[i]);
 
       return NodeOps;
-    } else if (Op->isSubClassOf("SDNodeXForm")) {
+    }
+    if (Op->isSubClassOf("SDNodeXForm")) {
       assert(N->getNumChildren() == 1 && "node xform should have one child!");
       // PatLeaf node - the operand may or may not be a leaf node. But it should
       // behave like one.
@@ -1279,11 +1286,11 @@
       if (isRoot)
         emitCode("return Tmp" + utostr(ResNo) + ".getNode();");
       return NodeOps;
-    } else {
-      N->dump();
-      cerr << "\n";
-      throw std::string("Unknown node in result pattern!");
     }
+
+    N->dump();
+    cerr << "\n";
+    throw std::string("Unknown node in result pattern!");
   }
 
   /// InsertOneTypeCheck - Insert a type-check for an unresolved type in 'Pat'
@@ -1641,12 +1648,6 @@
     std::vector<const PatternToMatch*> &PatternsOfOp = PBOI->second;
     assert(!PatternsOfOp.empty() && "No patterns but map has entry?");
 
-    // We want to emit all of the matching code now.  However, we want to emit
-    // the matches in order of minimal cost.  Sort the patterns so the least
-    // cost one is at the start.
-    std::stable_sort(PatternsOfOp.begin(), PatternsOfOp.end(),
-                     PatternSortingPredicate(CGP));
-
     // Split them into groups by type.
     std::map<MVT::SimpleValueType,
              std::vector<const PatternToMatch*> > PatternsByType;
@@ -1662,8 +1663,9 @@
          ++II) {
       MVT::SimpleValueType OpVT = II->first;
       std::vector<const PatternToMatch*> &Patterns = II->second;
-      typedef std::vector<std::pair<unsigned,std::string> > CodeList;
-      typedef std::vector<std::pair<unsigned,std::string> >::iterator CodeListI;
+      typedef std::pair<unsigned, std::string> CodeLine;
+      typedef std::vector<CodeLine> CodeList;
+      typedef CodeList::iterator CodeListI;
     
       std::vector<std::pair<const PatternToMatch*, CodeList> > CodeForPatterns;
       std::vector<std::vector<std::string> > PatternOpcodes;
@@ -1689,30 +1691,6 @@
         NumInputRootOpsCounts.push_back(NumInputRootOps);
       }
     
-      // Scan the code to see if all of the patterns are reachable and if it is
-      // possible that the last one might not match.
-      bool mightNotMatch = true;
-      for (unsigned i = 0, e = CodeForPatterns.size(); i != e; ++i) {
-        CodeList &GeneratedCode = CodeForPatterns[i].second;
-        mightNotMatch = false;
-
-        for (unsigned j = 0, e = GeneratedCode.size(); j != e; ++j) {
-          if (GeneratedCode[j].first == 1) { // predicate.
-            mightNotMatch = true;
-            break;
-          }
-        }
-      
-        // If this pattern definitely matches, and if it isn't the last one, the
-        // patterns after it CANNOT ever match.  Error out.
-        if (mightNotMatch == false && i != CodeForPatterns.size()-1) {
-          cerr << "Pattern '";
-          CodeForPatterns[i].first->getSrcPattern()->print(*cerr.stream());
-          cerr << "' is impossible to select!\n";
-          exit(1);
-        }
-      }
-
       // Factor target node emission code (emitted by EmitResultCode) into
       // separate functions. Uniquing and share them among all instruction
       // selection routines.
@@ -1815,6 +1793,36 @@
       OS << "SDNode *Select_" << getLegalCName(OpName)
          << OpVTStr << "(const SDValue &N) {\n";    
 
+      // We want to emit all of the matching code now.  However, we want to emit
+      // the matches in order of minimal cost.  Sort the patterns so the least
+      // cost one is at the start.
+      std::stable_sort(CodeForPatterns.begin(), CodeForPatterns.end(),
+                       PatternSortingPredicate(CGP));
+
+      // Scan the code to see if all of the patterns are reachable and if it is
+      // possible that the last one might not match.
+      bool mightNotMatch = true;
+      for (unsigned i = 0, e = CodeForPatterns.size(); i != e; ++i) {
+        CodeList &GeneratedCode = CodeForPatterns[i].second;
+        mightNotMatch = false;
+
+        for (unsigned j = 0, e = GeneratedCode.size(); j != e; ++j) {
+          if (GeneratedCode[j].first == 1) { // predicate.
+            mightNotMatch = true;
+            break;
+          }
+        }
+      
+        // If this pattern definitely matches, and if it isn't the last one, the
+        // patterns after it CANNOT ever match.  Error out.
+        if (mightNotMatch == false && i != CodeForPatterns.size()-1) {
+          cerr << "Pattern '";
+          CodeForPatterns[i].first->getSrcPattern()->print(*cerr.stream());
+          cerr << "' is impossible to select!\n";
+          exit(1);
+        }
+      }
+
       // Loop through and reverse all of the CodeList vectors, as we will be
       // accessing them from their logical front, but accessing the end of a
       // vector is more efficient.

Modified: llvm/trunk/utils/TableGen/FastISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FastISelEmitter.cpp?rev=57562&r1=57561&r2=57562&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/FastISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/FastISelEmitter.cpp Wed Oct 15 01:17:21 2008
@@ -71,7 +71,7 @@
     for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) {
       TreePatternNode *Op = InstPatNode->getChild(i);
       // For now, filter out any operand with a predicate.
-      if (!Op->getPredicateFn().empty())
+      if (!Op->getPredicateFns().empty())
         return false;
       // For now, filter out any operand with multiple values.
       if (Op->getExtTypes().size() != 1)
@@ -309,7 +309,7 @@
       continue;
 
     // For now, filter out any instructions with predicates.
-    if (!InstPatNode->getPredicateFn().empty())
+    if (!InstPatNode->getPredicateFns().empty())
       continue;
 
     // Check all the operands.





More information about the llvm-commits mailing list