Added support to specify predicates.
authorEvan Cheng <evan.cheng@apple.com>
Wed, 14 Dec 2005 22:02:59 +0000 (22:02 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Wed, 14 Dec 2005 22:02:59 +0000 (22:02 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24715 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Target.td
lib/Target/TargetSelectionDAG.td
utils/TableGen/DAGISelEmitter.cpp
utils/TableGen/DAGISelEmitter.h

index d4b83f40202aa665bac11c76e024c6e543bd835d..69b6baf28e9051b2f53682f746cecfb9abb910dc 100644 (file)
@@ -127,6 +127,7 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
 //
 include "../TargetSchedule.td"
 
+class Predicate; // Forward def
 
 //===----------------------------------------------------------------------===//
 // Instruction set description - These classes correspond to the C++ classes in
@@ -149,6 +150,10 @@ class Instruction {
   list<Register> Uses = []; // Default to using no non-operand registers
   list<Register> Defs = []; // Default to modifying no non-operand registers
 
+  // Predicates - List of predicates which will be turned into isel matching
+  // code.
+  list<Predicate> Predicates = [];
+
   // These bits capture information about the high-level semantics of the
   // instruction.
   bit isReturn     = 0;     // Is this instruction a return instruction?
@@ -168,6 +173,15 @@ class Instruction {
   InstrItinClass Itinerary; // Execution steps used for scheduling. 
 }
 
+/// Predicates - These are extra conditionals which are turned into instruction
+/// selector matching code. Currently each predicate is just a string.
+class Predicate<string cond> {
+  string CondString = cond;
+}
+
+class Requires<list<Predicate> preds> {
+  list<Predicate> Predicates = preds;
+}
 
 /// ops definition - This is just a simple marker used to identify the operands
 /// list for an instruction.  This should be used like this:
index 0a810789157e9ad7c4c868c1216519265e51dc73..46fbd9f58a683384f9e4f0328b529bd02b1b268c 100644 (file)
@@ -382,8 +382,9 @@ def setne  : PatFrag<(ops node:$lhs, node:$rhs),
 //
 
 class Pattern<dag patternToMatch, list<dag> resultInstrs> {
-  dag       PatternToMatch = patternToMatch;
-  list<dag> ResultInstrs   = resultInstrs;
+  dag             PatternToMatch = patternToMatch;
+  list<dag>       ResultInstrs   = resultInstrs;
+  list<Predicate> Predicates     = [];  // See class Instruction in Target.td.
 }
 
 // Pat - A simple (but common) form of a pattern, which produces a simple result
index eca9ad11cef96f0bd397acf910f29137fd3bac8a..07d35d4b7d3042121f1b1a88c13bcc93e3493b43 100644 (file)
@@ -1300,11 +1300,13 @@ void DAGISelEmitter::ParseInstructions() {
     if (!SrcPattern->canPatternMatch(Reason, *this))
       I->error("Instruction can never match: " + Reason);
     
+    Record *Instr = II->first;
     TreePatternNode *DstPattern = TheInst.getResultPattern();
-    PatternsToMatch.push_back(std::make_pair(SrcPattern, DstPattern));
+    PatternsToMatch.
+      push_back(PatternToMatch(Instr->getValueAsListInit("Predicates"),
+                               SrcPattern, DstPattern));
 
     if (PatternHasCtrlDep(Pattern, *this)) {
-      Record *Instr = II->first;
       CodeGenInstruction &InstInfo = Target.getInstruction(Instr->getName());
       InstInfo.hasCtrlDep = true;
     }
@@ -1356,8 +1358,10 @@ void DAGISelEmitter::ParsePatterns() {
     if (!Pattern->getOnlyTree()->canPatternMatch(Reason, *this))
       Pattern->error("Pattern can never match: " + Reason);
     
-    PatternsToMatch.push_back(std::make_pair(Pattern->getOnlyTree(),
-                                             Result->getOnlyTree()));
+    PatternsToMatch.
+      push_back(PatternToMatch(Patterns[i]->getValueAsListInit("Predicates"),
+                               Pattern->getOnlyTree(),
+                               Result->getOnlyTree()));
   }
 }
 
@@ -1565,7 +1569,7 @@ void DAGISelEmitter::GenerateVariants() {
   //
   for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) {
     std::vector<TreePatternNode*> Variants;
-    GenerateVariantsOf(PatternsToMatch[i].first, Variants, *this);
+    GenerateVariantsOf(PatternsToMatch[i].getSrcPattern(), Variants, *this);
 
     assert(!Variants.empty() && "Must create at least original variant!");
     Variants.erase(Variants.begin());  // Remove the original pattern.
@@ -1574,7 +1578,7 @@ void DAGISelEmitter::GenerateVariants() {
       continue;
 
     DEBUG(std::cerr << "FOUND VARIANTS OF: ";
-          PatternsToMatch[i].first->dump();
+          PatternsToMatch[i].getSrcPattern()->dump();
           std::cerr << "\n");
 
     for (unsigned v = 0, e = Variants.size(); v != e; ++v) {
@@ -1588,7 +1592,7 @@ void DAGISelEmitter::GenerateVariants() {
       bool AlreadyExists = false;
       for (unsigned p = 0, e = PatternsToMatch.size(); p != e; ++p) {
         // Check to see if this variant already exists.
-        if (Variant->isIsomorphicTo(PatternsToMatch[p].first)) {
+        if (Variant->isIsomorphicTo(PatternsToMatch[p].getSrcPattern())) {
           DEBUG(std::cerr << "  *** ALREADY EXISTS, ignoring variant.\n");
           AlreadyExists = true;
           break;
@@ -1598,8 +1602,9 @@ void DAGISelEmitter::GenerateVariants() {
       if (AlreadyExists) continue;
 
       // Otherwise, add it to the list of patterns we have.
-      PatternsToMatch.push_back(std::make_pair(Variant, 
-                                               PatternsToMatch[i].second));
+      PatternsToMatch.
+        push_back(PatternToMatch(PatternsToMatch[i].getPredicates(),
+                                 Variant, PatternsToMatch[i].getDstPattern()));
     }
 
     DEBUG(std::cerr << "\n");
@@ -1685,15 +1690,16 @@ struct PatternSortingPredicate {
   PatternSortingPredicate(DAGISelEmitter &ise) : ISE(ise) {};
   DAGISelEmitter &ISE;
 
-  bool operator()(DAGISelEmitter::PatternToMatch *LHS,
-                  DAGISelEmitter::PatternToMatch *RHS) {
-    unsigned LHSSize = getPatternSize(LHS->first, ISE);
-    unsigned RHSSize = getPatternSize(RHS->first, ISE);
+  bool operator()(PatternToMatch *LHS,
+                  PatternToMatch *RHS) {
+    unsigned LHSSize = getPatternSize(LHS->getSrcPattern(), ISE);
+    unsigned RHSSize = getPatternSize(RHS->getSrcPattern(), ISE);
     if (LHSSize > RHSSize) return true;   // LHS -> bigger -> less cost
     if (LHSSize < RHSSize) return false;
     
     // If the patterns have equal complexity, compare generated instruction cost
-    return getResultPatternCost(LHS->second) <getResultPatternCost(RHS->second);
+    return getResultPatternCost(LHS->getDstPattern()) <
+      getResultPatternCost(RHS->getDstPattern());
   }
 };
 
@@ -1725,8 +1731,12 @@ class PatternCodeEmitter {
 private:
   DAGISelEmitter &ISE;
 
-  // LHS of the pattern being matched
-  TreePatternNode *LHS;
+  // Predicates.
+  ListInit *Predicates;
+  // Instruction selector pattern.
+  TreePatternNode *Pattern;
+  // Matched instruction.
+  TreePatternNode *Instruction;
   unsigned PatternNo;
   std::ostream &OS;
   // Node to name mapping
@@ -1738,16 +1748,39 @@ private:
   unsigned TmpNo;
 
 public:
-  PatternCodeEmitter(DAGISelEmitter &ise, TreePatternNode *lhs,
+  PatternCodeEmitter(DAGISelEmitter &ise, ListInit *preds,
+                     TreePatternNode *pattern, TreePatternNode *instr,
                      unsigned PatNum, std::ostream &os) :
-    ISE(ise), LHS(lhs), PatternNo(PatNum), OS(os),
-    FoundChain(false), InFlag(false), TmpNo(0) {};
+    ISE(ise), Predicates(preds), Pattern(pattern), Instruction(instr),
+    PatternNo(PatNum), OS(os), FoundChain(false), InFlag(false), TmpNo(0) {};
 
   /// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo
   /// if the match fails. At this point, we already know that the opcode for N
   /// matches, and the SDNode for the result has the RootName specified name.
   void EmitMatchCode(TreePatternNode *N, const std::string &RootName,
                      bool isRoot = false) {
+
+    // Emit instruction predicates. Each predicate is just a string for now.
+    if (isRoot) {
+      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")) {
+            if (i == 0)
+              OS << "      if (";
+            else
+              OS << " && ";
+            OS << "(" << Def->getValueAsString("CondString") << ")";
+            if (i == e-1)
+              OS << ") goto P" << PatternNo << "Fail;\n";
+          } else {
+            Def->dump();
+            assert(0 && "Unknown predicate type!");
+          }
+        }
+      }
+    }
+
     if (N->isLeaf()) {
       if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
         OS << "      if (cast<ConstantSDNode>(" << RootName
@@ -1998,7 +2031,7 @@ public:
       // Emit all the chain and CopyToReg stuff.
       if (II.hasCtrlDep)
         OS << "      Chain = Select(Chain);\n";
-      EmitCopyToRegs(LHS, "N", II.hasCtrlDep);
+      EmitCopyToRegs(Pattern, "N", II.hasCtrlDep);
 
       const DAGInstruction &Inst = ISE.getInstruction(Op);
       unsigned NumResults = Inst.getNumResults();    
@@ -2035,7 +2068,7 @@ public:
           OS << "      CodeGenMap[N.getValue(0)] = Result;\n";
         }
         OS << "      Chain ";
-        if (NodeHasChain(LHS, ISE))
+        if (NodeHasChain(Pattern, ISE))
           OS << "= CodeGenMap[N.getValue(" << NumResults << ")] ";
         for (unsigned j = 0, e = FoldedChains.size(); j < e; j++)
           OS << "= CodeGenMap[" << FoldedChains[j] << ".getValue("
@@ -2071,9 +2104,7 @@ public:
       return std::make_pair(1, ResNo);
     } else if (Op->isSubClassOf("SDNodeXForm")) {
       assert(N->getNumChildren() == 1 && "node xform should have one child!");
-      unsigned OpVal = EmitResultCode(N->getChild(0))
-        .second;
-    
+      unsigned OpVal = EmitResultCode(N->getChild(0)).second;
       unsigned ResNo = TmpNo++;
       OS << "      SDOperand Tmp" << ResNo << " = Transform_" << Op->getName()
          << "(Tmp" << OpVal << ".Val);\n";
@@ -2161,17 +2192,21 @@ void DAGISelEmitter::EmitCodeForPattern(PatternToMatch &Pattern,
   static unsigned PatternCount = 0;
   unsigned PatternNo = PatternCount++;
   OS << "    { // Pattern #" << PatternNo << ": ";
-  Pattern.first->print(OS);
+  Pattern.getSrcPattern()->print(OS);
   OS << "\n      // Emits: ";
-  Pattern.second->print(OS);
+  Pattern.getDstPattern()->print(OS);
   OS << "\n";
-  OS << "      // Pattern complexity = " << getPatternSize(Pattern.first, *this)
-     << "  cost = " << getResultPatternCost(Pattern.second) << "\n";
+  OS << "      // Pattern complexity = "
+     << getPatternSize(Pattern.getSrcPattern(), *this)
+     << "  cost = "
+     << getResultPatternCost(Pattern.getDstPattern()) << "\n";
 
-  PatternCodeEmitter Emitter(*this, Pattern.first, PatternNo, OS);
+  PatternCodeEmitter Emitter(*this, Pattern.getPredicates(),
+                             Pattern.getSrcPattern(), Pattern.getDstPattern(),
+                             PatternNo, OS);
 
   // Emit the matcher, capturing named arguments in VariableMap.
-  Emitter.EmitMatchCode(Pattern.first, "N", true /*the root*/);
+  Emitter.EmitMatchCode(Pattern.getSrcPattern(), "N", true /*the root*/);
 
   // TP - Get *SOME* tree pattern, we don't care which.
   TreePattern &TP = *PatternFragments.begin()->second;
@@ -2188,7 +2223,7 @@ void DAGISelEmitter::EmitCodeForPattern(PatternToMatch &Pattern,
   // apply the type to the tree, then rerun type inference.  Iterate until all
   // types are resolved.
   //
-  TreePatternNode *Pat = Pattern.first->clone();
+  TreePatternNode *Pat = Pattern.getSrcPattern()->clone();
   RemoveAllTypes(Pat);
   
   do {
@@ -2206,9 +2241,9 @@ void DAGISelEmitter::EmitCodeForPattern(PatternToMatch &Pattern,
     // Insert a check for an unresolved type and add it to the tree.  If we find
     // an unresolved type to add a check for, this returns true and we iterate,
     // otherwise we are done.
-  } while (Emitter.InsertOneTypeCheck(Pat, Pattern.first, "N"));
+  } while (Emitter.InsertOneTypeCheck(Pat, Pattern.getSrcPattern(), "N"));
 
-  Emitter.EmitResultCode(Pattern.second, true /*the root*/);
+  Emitter.EmitResultCode(Pattern.getDstPattern(), true /*the root*/);
 
   delete Pat;
   
@@ -2286,7 +2321,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
   std::map<Record*, std::vector<PatternToMatch*>,
            CompareByRecordName> PatternsByOpcode;
   for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) {
-    TreePatternNode *Node = PatternsToMatch[i].first;
+    TreePatternNode *Node = PatternsToMatch[i].getSrcPattern();
     if (!Node->isLeaf()) {
       PatternsByOpcode[Node->getOperator()].push_back(&PatternsToMatch[i]);
     } else {
@@ -2304,7 +2339,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
         std::cerr << "Unrecognized opcode '";
         Node->dump();
         std::cerr << "' on tree pattern '";
-        std::cerr << PatternsToMatch[i].second->getOperator()->getName();
+        std::cerr << PatternsToMatch[i].getDstPattern()->getOperator()->getName();
         std::cerr << "'!\n";
         exit(1);
       }
@@ -2366,8 +2401,8 @@ void DAGISelEmitter::run(std::ostream &OS) {
   
   DEBUG(std::cerr << "\n\nALL PATTERNS TO MATCH:\n\n";
         for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) {
-          std::cerr << "PATTERN: ";  PatternsToMatch[i].first->dump();
-          std::cerr << "\nRESULT:  ";PatternsToMatch[i].second->dump();
+          std::cerr << "PATTERN: ";  PatternsToMatch[i].getSrcPattern()->dump();
+          std::cerr << "\nRESULT:  ";PatternsToMatch[i].getDstPattern()->dump();
           std::cerr << "\n";
         });
   
index 7a050c53e1251ce06e74ec94629c7b83b65e9d35..1fbb32655234f0faaf7a20ba0727d421a0ee5a0e 100644 (file)
@@ -353,13 +353,27 @@ namespace llvm {
     TreePatternNode *getResultPattern() const { return ResultPattern; }
   };
   
-  
+/// PatternToMatch - Used by DAGISelEmitter to keep tab of patterns processed
+/// to produce isel.
+struct PatternToMatch {
+  PatternToMatch(ListInit *preds, TreePatternNode *src, TreePatternNode *dst):
+    Predicates(preds), SrcPattern(src), DstPattern(dst) {};
+
+  ListInit        *Predicates;  // Top level predicate conditions to match.
+  TreePatternNode *SrcPattern;  // Source pattern to match.
+  TreePatternNode *DstPattern;  // Resulting pattern.
+
+  ListInit        *getPredicates() const { return Predicates; }
+  TreePatternNode *getSrcPattern() const { return SrcPattern; }
+  TreePatternNode *getDstPattern() const { return DstPattern; }
+};
+
 /// InstrSelectorEmitter - The top-level class which coordinates construction
 /// and emission of the instruction selector.
 ///
 class DAGISelEmitter : public TableGenBackend {
 public:
-  typedef std::pair<TreePatternNode*, TreePatternNode*> PatternToMatch;
+  //typedef std::pair<TreePatternNode*, TreePatternNode*> PatternToMatch;
 private:
   RecordKeeper &Records;
   CodeGenTarget Target;