eliminate the CheckMultiOpcodeMatcher code and have each
authorChris Lattner <sabre@nondot.org>
Mon, 1 Mar 2010 07:17:40 +0000 (07:17 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 1 Mar 2010 07:17:40 +0000 (07:17 +0000)
ComplexPattern at the root be generated multiple times, once
for each opcode they are part of.  This encourages factoring
because the opcode checks get treated just like everything
else in the matcher.

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

include/llvm/CodeGen/SelectionDAGISel.h
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
utils/TableGen/DAGISelEmitter.cpp
utils/TableGen/DAGISelMatcher.cpp
utils/TableGen/DAGISelMatcher.h
utils/TableGen/DAGISelMatcherEmitter.cpp
utils/TableGen/DAGISelMatcherGen.cpp
utils/TableGen/DAGISelMatcherOpt.cpp

index 0e856a1c7bee47e9f9971bf93fa0b092a5f2bd80..fa3b08feec7ffeac9fc38cdfa311c74c86cf49d6 100644 (file)
@@ -113,7 +113,6 @@ public:
     OPC_CheckPredicate,
     OPC_CheckOpcode,
     OPC_SwitchOpcode,
-    OPC_CheckMultiOpcode,
     OPC_CheckType,
     OPC_CheckChild0Type, OPC_CheckChild1Type, OPC_CheckChild2Type,
     OPC_CheckChild3Type, OPC_CheckChild4Type, OPC_CheckChild5Type,
index 1e3550cb82016e0183aa211e256b82b71fa36851..f1e6b960ee097cc22116bb20dee76f1d8359ae8f 100644 (file)
@@ -1787,15 +1787,6 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
       continue;
     }
         
-    case OPC_CheckMultiOpcode: {
-      unsigned NumOps = MatcherTable[MatcherIndex++];
-      bool OpcodeEquals = false;
-      for (unsigned i = 0; i != NumOps; ++i)
-        OpcodeEquals |= N->getOpcode() == MatcherTable[MatcherIndex++];
-      if (!OpcodeEquals) break;
-      continue;
-    }
-        
     case OPC_CheckType: {
       MVT::SimpleValueType VT =
         (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
index 2854e4f221da09e01a398e9b38ba21ee20b549c7..533664669ac577bfb621c603c885bb68c48ee45b 100644 (file)
@@ -1959,10 +1959,17 @@ void DAGISelEmitter::run(raw_ostream &OS) {
                    PatternSortingPredicate2(CGP));
   
   
-  // Convert each pattern into Matcher's.
+  // Convert each variant of each pattern into a Matcher.
   std::vector<Matcher*> PatternMatchers;
-  for (unsigned i = 0, e = Patterns.size(); i != e; ++i)
-    PatternMatchers.push_back(ConvertPatternToMatcher(*Patterns[i], CGP));
+  for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
+    for (unsigned Variant = 0; ; ++Variant) {
+      if (Matcher *M = ConvertPatternToMatcher(*Patterns[i], Variant, CGP))
+        PatternMatchers.push_back(M);
+      else
+        break;
+    }
+  }
+          
   
   Matcher *TheMatcher = new ScopeMatcher(&PatternMatchers[0],
                                          PatternMatchers.size());
index c88f260c4e4d75fa06944123417428eeb68185af..860165f7f4fa6ffaefdfb4321e5cf14b7c13b6d0 100644 (file)
@@ -98,10 +98,6 @@ void SwitchOpcodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
 }
 
 
-void CheckMultiOpcodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const{
-  OS.indent(indent) << "CheckMultiOpcode <todo args>\n";
-}
-
 void CheckTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
   OS.indent(indent) << "CheckType " << getEnumName(Type) << '\n';
 }
@@ -221,13 +217,6 @@ unsigned CheckOpcodeMatcher::getHashImpl() const {
   return HashString(Opcode.getEnumName());
 }
 
-unsigned CheckMultiOpcodeMatcher::getHashImpl() const {
-  unsigned Result = 0;
-  for (unsigned i = 0, e = Opcodes.size(); i != e; ++i)
-    Result |= HashString(Opcodes[i]->getEnumName());
-  return Result;
-}
-
 unsigned CheckCondCodeMatcher::getHashImpl() const {
   return HashString(CondCodeName);
 }
@@ -311,8 +300,6 @@ bool CheckOpcodeMatcher::isContradictoryImpl(const Matcher *M) const {
     return COM->getOpcode().getEnumName() != getOpcode().getEnumName();
   }
   
-  // TODO: CheckMultiOpcodeMatcher?
-  
   // If the node has a known type, and if the type we're checking for is
   // different, then we know they contradict.  For example, a check for
   // ISD::STORE will never be true at the same time a check for Type i32 is.
index 9992c79a3296cc0dd7b5f46601cf1af13365b285..8b6b32291429899381441e6a70b6b0929ca18b15 100644 (file)
@@ -25,7 +25,7 @@ namespace llvm {
   class Record;
   class SDNodeInfo;
 
-Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern,
+Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern,unsigned Variant,
                                  const CodeGenDAGPatterns &CGP);
 Matcher *OptimizeMatcher(Matcher *Matcher, const CodeGenDAGPatterns &CGP);
 void EmitMatcherTable(const Matcher *Matcher, const CodeGenDAGPatterns &CGP,
@@ -449,33 +449,6 @@ private:
   virtual unsigned getHashImpl() const { return 4123; }
 };
   
-/// CheckMultiOpcodeMatcher - This checks to see if the current node has one
-/// of the specified opcode, if not it fails to match.
-class CheckMultiOpcodeMatcher : public Matcher {
-  SmallVector<const SDNodeInfo*, 4> Opcodes;
-public:
-  CheckMultiOpcodeMatcher(const SDNodeInfo * const *opcodes, unsigned numops)
-    : Matcher(CheckMultiOpcode), Opcodes(opcodes, opcodes+numops) {}
-  
-  unsigned getNumOpcodes() const { return Opcodes.size(); }
-  const SDNodeInfo &getOpcode(unsigned i) const { return *Opcodes[i]; }
-  
-  static inline bool classof(const Matcher *N) {
-    return N->getKind() == CheckMultiOpcode;
-  }
-  
-  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
-
-private:
-  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
-  virtual bool isEqualImpl(const Matcher *M) const {
-    return cast<CheckMultiOpcodeMatcher>(M)->Opcodes == Opcodes;
-  }
-  virtual unsigned getHashImpl() const;
-};
-  
-  
-  
 /// CheckTypeMatcher - This checks to see if the current node has the
 /// specified type, if not it fails to match.
 class CheckTypeMatcher : public Matcher {
index a828db30053b25f2cd1d5cb0ae6fe6468d688e5c..279f036b364324137bcdc466ad88f9ff0a6de2e8 100644 (file)
@@ -282,16 +282,7 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
     return CurrentIdx-StartIdx;
   }
 
-  case Matcher::CheckMultiOpcode: {
-    const CheckMultiOpcodeMatcher *CMO = cast<CheckMultiOpcodeMatcher>(N);
-    OS << "OPC_CheckMultiOpcode, " << CMO->getNumOpcodes() << ", ";
-    for (unsigned i = 0, e = CMO->getNumOpcodes(); i != e; ++i)
-      OS << CMO->getOpcode(i).getEnumName() << ", ";
-    OS << '\n';
-    return 2 + CMO->getNumOpcodes();
-  }
-      
-  case Matcher::CheckType:
+ case Matcher::CheckType:
     OS << "OPC_CheckType, "
        << getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
     return 2;
@@ -623,7 +614,6 @@ void MatcherTableEmitter::EmitHistogram(formatted_raw_ostream &OS) {
     case Matcher::CheckPredicate: OS << "OPC_CheckPredicate"; break;
     case Matcher::CheckOpcode: OS << "OPC_CheckOpcode"; break;
     case Matcher::SwitchOpcode: OS << "OPC_SwitchOpcode"; break;
-    case Matcher::CheckMultiOpcode: OS << "OPC_CheckMultiOpcode"; break;
     case Matcher::CheckType: OS << "OPC_CheckType"; break;
     case Matcher::CheckChildType: OS << "OPC_CheckChildType"; break;
     case Matcher::CheckInteger: OS << "OPC_CheckInteger"; break;
index 5a253e8d202b27e1e2199be20d10c240f03db9b7..95cfa5b251cee4ecd081be3340db604fbbb4dd8e 100644 (file)
@@ -97,7 +97,7 @@ namespace {
       delete PatWithNoTypes;
     }
     
-    void EmitMatcherCode();
+    bool EmitMatcherCode(unsigned Variant);
     void EmitResultCode();
     
     Matcher *GetMatcher() const { return TheMatcher; }
@@ -247,20 +247,6 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
 
     // Handle complex pattern.
     const ComplexPattern &CP = CGP.getComplexPattern(LeafRec);
-
-    // If we're at the root of the pattern, we have to check that the opcode
-    // is a one of the ones requested to be matched.
-    if (N == Pattern.getSrcPattern()) {
-      const std::vector<Record*> &OpNodes = CP.getRootNodes();
-      if (OpNodes.size() == 1) {
-        AddMatcher(new CheckOpcodeMatcher(CGP.getSDNodeInfo(OpNodes[0])));
-      } else if (!OpNodes.empty()) {
-        SmallVector<const SDNodeInfo*, 4> OpNames;
-        for (unsigned i = 0, e = OpNodes.size(); i != e; i++)
-          OpNames.push_back(&CGP.getSDNodeInfo(OpNodes[i]));
-        AddMatcher(new CheckMultiOpcodeMatcher(OpNames.data(), OpNames.size()));
-      }
-    }
     
     // Emit a CheckComplexPat operation, which does the match (aborting if it
     // fails) and pushes the matched operands onto the recorded nodes list.
@@ -495,7 +481,30 @@ void MatcherGen::EmitMatchCode(const TreePatternNode *N,
     EmitOperatorMatchCode(N, NodeNoTypes);
 }
 
-void MatcherGen::EmitMatcherCode() {
+/// EmitMatcherCode - Generate the code that matches the predicate of this
+/// pattern for the specified Variant.  If the variant is invalid this returns
+/// true and does not generate code, if it is valid, it returns false.
+bool MatcherGen::EmitMatcherCode(unsigned Variant) {
+  // If the root of the pattern is a ComplexPattern and if it is specified to
+  // match some number of root opcodes, these are considered to be our variants.
+  // Depending on which variant we're generating code for, emit the root opcode
+  // check.
+  if (const ComplexPattern *CP =
+                   Pattern.getSrcPattern()->getComplexPatternInfo(CGP)) {
+    
+    const std::vector<Record*> &OpNodes = CP->getRootNodes();
+    if (OpNodes.empty()) {
+      // FIXME: Empty OpNodes runs on everything, is this even valid?
+      if (Variant != 0) return true;
+    } else {
+      if (Variant >= OpNodes.size()) return true;
+      
+      AddMatcher(new CheckOpcodeMatcher(CGP.getSDNodeInfo(OpNodes[Variant])));
+    }
+  } else {
+    if (Variant != 0) return true;
+  }
+    
   // If the pattern has a predicate on it (e.g. only enabled when a subtarget
   // feature is around, do the check).
   // FIXME: This should get emitted after the match code below to encourage
@@ -503,11 +512,11 @@ void MatcherGen::EmitMatcherCode() {
   // dag combine, eliminating the horrible side-effect-full stuff from 
   // X86's MatchAddress.
   if (!Pattern.getPredicateCheck().empty())
-    AddMatcher(new 
-                 CheckPatternPredicateMatcher(Pattern.getPredicateCheck()));
-  
+    AddMatcher(new CheckPatternPredicateMatcher(Pattern.getPredicateCheck()));
+
   // Emit the matcher for the pattern structure and types.
   EmitMatchCode(Pattern.getSrcPattern(), PatWithNoTypes);
+  return false;
 }
 
 
@@ -849,13 +858,16 @@ void MatcherGen::EmitResultCode() {
 }
 
 
+/// ConvertPatternToMatcher - Create the matcher for the specified pattern with
+/// the specified variant.  If the variant number is invalid, this returns null.
 Matcher *llvm::ConvertPatternToMatcher(const PatternToMatch &Pattern,
+                                       unsigned Variant,
                                        const CodeGenDAGPatterns &CGP) {
   MatcherGen Gen(Pattern, CGP);
 
   // Generate the code for the matcher.
-  Gen.EmitMatcherCode();
-  
+  if (Gen.EmitMatcherCode(Variant))
+    return 0;
   
   // FIXME2: Kill extra MoveParent commands at the end of the matcher sequence.
   // FIXME2: Split result code out to another table, and make the matcher end
index 41ce6ae69133c680a8b33cbd1dccdc4c16f28d31..0e89fa028f595c245ad8116e08e03fc8585590c8 100644 (file)
@@ -153,8 +153,7 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
   // like X86 where many operations are valid on multiple types.
   if ((isa<CheckTypeMatcher>(N) || isa<CheckChildTypeMatcher>(N) ||
        isa<RecordMatcher>(N)) &&
-      (isa<CheckOpcodeMatcher>(N->getNext()) ||
-       isa<CheckMultiOpcodeMatcher>(N->getNext()))) {
+      isa<CheckOpcodeMatcher>(N->getNext())) {
     // Unlink the two nodes from the list.
     Matcher *CheckType = MatcherPtr.take();
     Matcher *CheckOpcode = CheckType->takeNext();