generate code for node and pattern predicates. Note that this won't
authorChris Lattner <sabre@nondot.org>
Tue, 16 Feb 2010 07:21:10 +0000 (07:21 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 16 Feb 2010 07:21:10 +0000 (07:21 +0000)
build if enabled, it will fail with constness issues. I'll resolve
these next.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96336 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/DAGISelHeader.h
include/llvm/CodeGen/SelectionDAGISel.h
utils/TableGen/DAGISelMatcher.h
utils/TableGen/DAGISelMatcherEmitter.cpp

index 831475d9a5aa3173a07b91a5a64730710cf5af31..7fda6f76e1cfe52c6e1d2ac62cdc16c3430c64c1 100644 (file)
@@ -164,23 +164,29 @@ bool CheckOrImmediate(SDValue V, int64_t Val) {
   return true;
 }
 
-static int8_t GetInt1(const unsigned char *MatcherTable, unsigned &Idx) {
+// These functions are marked always inline so that Idx doesn't get pinned to
+// the stack.
+ALWAYS_INLINE static int8_t
+GetInt1(const unsigned char *MatcherTable, unsigned &Idx) {
   return MatcherTable[Idx++];
 }
 
-static int16_t GetInt2(const unsigned char *MatcherTable, unsigned &Idx) {
+ALWAYS_INLINE static int16_t
+GetInt2(const unsigned char *MatcherTable, unsigned &Idx) {
   int16_t Val = GetInt1(MatcherTable, Idx);
   Val |= int16_t(GetInt1(MatcherTable, Idx)) << 8;
   return Val;
 }
 
-static int32_t GetInt4(const unsigned char *MatcherTable, unsigned &Idx) {
+ALWAYS_INLINE static int32_t
+GetInt4(const unsigned char *MatcherTable, unsigned &Idx) {
   int32_t Val = GetInt2(MatcherTable, Idx);
   Val |= int32_t(GetInt2(MatcherTable, Idx)) << 16;
   return Val;
 }
 
-static int64_t GetInt8(const unsigned char *MatcherTable, unsigned &Idx) {
+ALWAYS_INLINE static int64_t
+GetInt8(const unsigned char *MatcherTable, unsigned &Idx) {
   int64_t Val = GetInt4(MatcherTable, Idx);
   Val |= int64_t(GetInt4(MatcherTable, Idx)) << 32;
   return Val;
@@ -308,18 +314,12 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
       if (N != RecordedNodes[RecNo]) break;
       continue;
     }
-    case OPC_CheckPatternPredicate: {
-      unsigned PredNo = MatcherTable[MatcherIndex++];
-      (void)PredNo;
-      // FIXME: CHECK IT.
+    case OPC_CheckPatternPredicate:
+      if (!CheckPatternPredicate(MatcherTable[MatcherIndex++])) break;
       continue;
-    }
-    case OPC_CheckPredicate: {
-      unsigned PredNo = MatcherTable[MatcherIndex++];
-      (void)PredNo;
-      // FIXME: CHECK IT.
+    case OPC_CheckPredicate:
+      if (!CheckNodePredicate(N.getNode(), MatcherTable[MatcherIndex++])) break;
       continue;
-    }
     case OPC_CheckComplexPat: {
       unsigned PatNo = MatcherTable[MatcherIndex++];
       (void)PatNo;
index ae78c5577b6e7f06df1fda63ef7e41f34e729fc6..0be91b414d0b5791f9b43dada9c9c2190f02cf15 100644 (file)
@@ -112,6 +112,25 @@ protected:
   bool CheckOrMask(SDValue LHS, ConstantSDNode *RHS,
                     int64_t DesiredMaskS) const;
   
+  
+  /// CheckPatternPredicate - This function is generated by tblgen in the
+  /// target.  It runs the specified pattern predicate and returns true if it
+  /// succeeds or false if it fails.  The number is a private implementation
+  /// detail to the code tblgen produces.
+  virtual bool CheckPatternPredicate(unsigned PredNo) const {
+    assert(0 && "Tblgen should generate the implementation of this!");
+    return 0;
+  }
+
+  /// CheckNodePredicate - This function is generated by tblgen in the
+  /// target.  It runs node predicate #PredNo and returns true if it succeeds or
+  /// false if it fails.  The number is a private implementation
+  /// detail to the code tblgen produces.
+  virtual bool CheckNodePredicate(SDNode *N, unsigned PredNo) const {
+    assert(0 && "Tblgen should generate the implementation of this!");
+    return 0;
+  }
+  
   // Calls to these functions are generated by tblgen.
   SDNode *Select_INLINEASM(SDNode *N);
   SDNode *Select_UNDEF(SDNode *N);
index 8699d516ed8d8699b99e7b525995a4b2abee2357..b40fbf9cd0e16543eb4a0f82dc5a162b1f73af92 100644 (file)
 #ifndef TBLGEN_DAGISELMATCHER_H
 #define TBLGEN_DAGISELMATCHER_H
 
+#include "llvm/CodeGen/ValueTypes.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/Support/Casting.h"
 
 namespace llvm {
   class CodeGenDAGPatterns;
index 3d2791d22e5d11809a6b88cee6859897f51be4a7..c0ad16934e79a6b481cae2a8b07aba3f3798c896 100644 (file)
@@ -14,7 +14,7 @@
 #include "DAGISelMatcher.h"
 #include "CodeGenDAGPatterns.h"
 #include "llvm/ADT/SmallString.h"
-#include "llvm/Support/Casting.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/Support/FormattedStream.h"
 using namespace llvm;
 
@@ -66,12 +66,35 @@ static unsigned EmitInt(int64_t Val, formatted_raw_ostream &OS) {
 namespace {
 class MatcherTableEmitter {
   formatted_raw_ostream &OS;
+  
+  StringMap<unsigned> NodePredicateMap, PatternPredicateMap;
+  std::vector<std::string> NodePredicates, PatternPredicates;
+  
 public:
   MatcherTableEmitter(formatted_raw_ostream &os) : OS(os) {}
 
   unsigned EmitMatcherAndChildren(const MatcherNode *N, unsigned Indent);
+  
+  void EmitPredicateFunctions();
 private:
   unsigned EmitMatcher(const MatcherNode *N, unsigned Indent);
+  
+  unsigned getNodePredicate(StringRef PredName) {
+    unsigned &Entry = NodePredicateMap[PredName];
+    if (Entry == 0) {
+      NodePredicates.push_back(PredName.str());
+      Entry = NodePredicates.size();
+    }
+    return Entry-1;
+  }
+  unsigned getPatternPredicate(StringRef PredName) {
+    unsigned &Entry = PatternPredicateMap[PredName];
+    if (Entry == 0) {
+      PatternPredicates.push_back(PredName.str());
+      Entry = PatternPredicates.size();
+    }
+    return Entry-1;
+  }
 };
 } // end anonymous namespace.
 
@@ -107,18 +130,19 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) {
        << cast<CheckSameMatcherNode>(N)->getMatchNumber() << ",\n";
     return 2;
 
-  case MatcherNode::CheckPatternPredicate:
-    OS << "OPC_CheckPatternPredicate, /*XXX*/0,";
-    OS.PadToColumn(CommentIndent) << "// "
-      << cast<CheckPatternPredicateMatcherNode>(N)->getPredicate() << '\n';
+  case MatcherNode::CheckPatternPredicate: {
+    StringRef Pred = cast<CheckPatternPredicateMatcherNode>(N)->getPredicate();
+    OS << "OPC_CheckPatternPredicate, " << getPatternPredicate(Pred) << ',';
+    OS.PadToColumn(CommentIndent) << "// " << Pred << '\n';
     return 2;
-    
-  case MatcherNode::CheckPredicate:
-    OS << "OPC_CheckPredicate, /*XXX*/0,";
-    OS.PadToColumn(CommentIndent) << "// "
-      << cast<CheckPredicateMatcherNode>(N)->getPredicateName() << '\n';
+  }
+  case MatcherNode::CheckPredicate: {
+    StringRef Pred = cast<CheckPredicateMatcherNode>(N)->getPredicateName();
+    OS << "OPC_CheckPredicate, " << getNodePredicate(Pred) << ',';
+    OS.PadToColumn(CommentIndent) << "// " << Pred << '\n';
     return 2;
-      
+  }
+
   case MatcherNode::CheckOpcode:
     OS << "OPC_CheckOpcode, "
        << cast<CheckOpcodeMatcherNode>(N)->getOpcodeName() << ",\n";
@@ -216,6 +240,25 @@ EmitMatcherAndChildren(const MatcherNode *N, unsigned Indent) {
   }
 }
 
+void MatcherTableEmitter::EmitPredicateFunctions() {
+  OS << "bool CheckPatternPredicate(unsigned PredNo) const {\n";
+  OS << "  switch (PredNo) {\n";
+  OS << "  default: assert(0 && \"Invalid predicate in table?\");\n";
+  for (unsigned i = 0, e = PatternPredicates.size(); i != e; ++i)
+    OS << "  case " << i << ": return "  << PatternPredicates[i] << ";\n";
+  OS << "  }\n";
+  OS << "}\n\n";
+
+  OS << "bool CheckNodePredicate(SDNode *N, unsigned PredNo) const {\n";
+  OS << "  switch (PredNo) {\n";
+  OS << "  default: assert(0 && \"Invalid predicate in table?\");\n";
+  for (unsigned i = 0, e = NodePredicates.size(); i != e; ++i)
+    OS << "  case " << i << ": return "  << NodePredicates[i] << "(N);\n";
+  OS << "  }\n";
+  OS << "}\n\n";
+}
+
+
 void llvm::EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &O) {
   formatted_raw_ostream OS(O);
   
@@ -228,4 +271,8 @@ void llvm::EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &O) {
   unsigned TotalSize = MatcherEmitter.EmitMatcherAndChildren(Matcher, 2);
   OS << "    0\n  }; // Total Array size is " << (TotalSize+1) << " bytes\n\n";
   OS << "  return SelectCodeCommon(N, MatcherTable,sizeof(MatcherTable));\n}\n";
+  OS << "\n";
+  
+  // Next up, emit the function for node and pattern predicates:
+  MatcherEmitter.EmitPredicateFunctions();
 }