Generalize the register matching code in DAGISel a bit.
authorJim Grosbach <grosbach@apple.com>
Tue, 1 Mar 2011 01:37:19 +0000 (01:37 +0000)
committerJim Grosbach <grosbach@apple.com>
Tue, 1 Mar 2011 01:37:19 +0000 (01:37 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126731 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 62358e7639eea601c9a4f78cddfa8fc07091f266..54576794ded08e964d63a06fdc0166508df4bec5 100644 (file)
@@ -127,6 +127,7 @@ public:
 
     OPC_EmitInteger,
     OPC_EmitRegister,
+    OPC_EmitRegister2,
     OPC_EmitConvertToTarget,
     OPC_EmitMergeInputChains,
     OPC_EmitMergeInputChains1_0,
index 68ba966d268a5600e5422236c4b5a074bb6f8867..5b0790f241d175a23931200d04fd1bf9bfa5385c 100644 (file)
@@ -2392,6 +2392,18 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
                               CurDAG->getRegister(RegNo, VT), (SDNode*)0));
       continue;
     }
+    case OPC_EmitRegister2: {
+      // For targets w/ more than 256 register names, the register enum
+      // values are stored in two bytes in the matcher table (just like
+      // opcodes).
+      MVT::SimpleValueType VT =
+        (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+      unsigned RegNo = MatcherTable[MatcherIndex++];
+      RegNo |= MatcherTable[MatcherIndex++] << 8;
+      RecordedNodes.push_back(std::pair<SDValue, SDNode*>(
+                              CurDAG->getRegister(RegNo, VT), (SDNode*)0));
+      continue;
+    }
 
     case OPC_EmitConvertToTarget:  {
       // Convert from IMM/FPIMM to target version.
index 8a73404dad95ca9a0fedd3be422aedff35aeed41..f3e8db361228ca2da76b9ed53c5e0eba2de329be 100644 (file)
@@ -148,8 +148,12 @@ void DAGISelEmitter::run(raw_ostream &OS) {
   Matcher *TheMatcher = new ScopeMatcher(&PatternMatchers[0],
                                          PatternMatchers.size());
 
+  CodeGenTarget Target(Records);
+  const std::vector<CodeGenRegister> &Registers = Target.getRegisters();
+  bool useEmitRegister2 = Registers.size() > 255;
+
   TheMatcher = OptimizeMatcher(TheMatcher, CGP);
   //Matcher->dump();
-  EmitMatcherTable(TheMatcher, CGP, OS);
+  EmitMatcherTable(TheMatcher, CGP, useEmitRegister2, OS);
   delete TheMatcher;
 }
index 8e6e44647ea1f8d97cd28585831cd1daeeee8e0a..d17051c0b67ab287b1bd2d398287cd100e64ce83 100644 (file)
@@ -29,7 +29,7 @@ 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,
-                      raw_ostream &OS);
+                      bool useEmitRegister2, raw_ostream &OS);
 
 
 /// Matcher - Base class for all the the DAG ISel Matcher representation
index 0b7fbf7c85184d3ab71159b01bcf88435b904daf..9d0e34dba97662c9da31efcd1b34b9db7613c786 100644 (file)
@@ -43,8 +43,11 @@ class MatcherTableEmitter {
   DenseMap<Record*, unsigned> NodeXFormMap;
   std::vector<Record*> NodeXForms;
 
+  bool useEmitRegister2;
+
 public:
-  MatcherTableEmitter(const CodeGenDAGPatterns &cgp) : CGP(cgp) {}
+  MatcherTableEmitter(const CodeGenDAGPatterns &cgp, bool _useEmitRegister2)
+    : CGP(cgp), useEmitRegister2(_useEmitRegister2) {}
 
   unsigned EmitMatcherList(const Matcher *N, unsigned Indent,
                            unsigned StartIdx, formatted_raw_ostream &OS);
@@ -255,7 +258,7 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
   }
 
   case Matcher::CheckOpcode:
-    OS << "OPC_CheckOpcode, TARGET_OPCODE("
+    OS << "OPC_CheckOpcode, TARGET_VAL("
        << cast<CheckOpcodeMatcher>(N)->getOpcode().getEnumName() << "),\n";
     return 3;
       
@@ -321,7 +324,7 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
       
       OS << ' ';
       if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
-        OS << "TARGET_OPCODE(" << SOM->getCaseOpcode(i).getEnumName() << "),";
+        OS << "TARGET_VAL(" << SOM->getCaseOpcode(i).getEnumName() << "),";
       else
         OS << getEnumName(cast<SwitchTypeMatcher>(N)->getCaseType(i)) << ',';
 
@@ -429,17 +432,31 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
   }
       
   case Matcher::EmitRegister:
-    OS << "OPC_EmitRegister, "
-       << getEnumName(cast<EmitRegisterMatcher>(N)->getVT()) << ", ";
-    if (Record *R = cast<EmitRegisterMatcher>(N)->getReg())
-      OS << getQualifiedName(R) << ",\n";
-    else {
-      OS << "0 ";
-      if (!OmitComments)
-        OS << "/*zero_reg*/";
-      OS << ",\n";
+    if (useEmitRegister2) {
+      OS << "OPC_EmitRegister2, "
+        << getEnumName(cast<EmitRegisterMatcher>(N)->getVT()) << ", ";
+      if (Record *R = cast<EmitRegisterMatcher>(N)->getReg())
+        OS << "TARGET_VAL(" << getQualifiedName(R) << "),\n";
+      else {
+        OS << "TARGET_VAL(0) ";
+        if (!OmitComments)
+          OS << "/*zero_reg*/";
+        OS << ",\n";
+      }
+      return 4;
+    } else {
+      OS << "OPC_EmitRegister, "
+        << getEnumName(cast<EmitRegisterMatcher>(N)->getVT()) << ", ";
+      if (Record *R = cast<EmitRegisterMatcher>(N)->getReg())
+        OS << getQualifiedName(R) << ",\n";
+      else {
+        OS << "0 ";
+        if (!OmitComments)
+          OS << "/*zero_reg*/";
+        OS << ",\n";
+      }
+      return 3;
     }
-    return 3;
       
   case Matcher::EmitConvertToTarget:
     OS << "OPC_EmitConvertToTarget, "
@@ -482,7 +499,7 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
   case Matcher::MorphNodeTo: {
     const EmitNodeMatcherCommon *EN = cast<EmitNodeMatcherCommon>(N);
     OS << (isa<EmitNodeMatcher>(EN) ? "OPC_EmitNode" : "OPC_MorphNodeTo");
-    OS << ", TARGET_OPCODE(" << EN->getOpcodeName() << "), 0";
+    OS << ", TARGET_VAL(" << EN->getOpcodeName() << "), 0";
     
     if (EN->hasChain())   OS << "|OPFL_Chain";
     if (EN->hasInFlag())  OS << "|OPFL_GlueInput";
@@ -782,23 +799,26 @@ void MatcherTableEmitter::EmitHistogram(const Matcher *M,
 
 
 void llvm::EmitMatcherTable(const Matcher *TheMatcher,
-                            const CodeGenDAGPatterns &CGP, raw_ostream &O) {
+                            const CodeGenDAGPatterns &CGP,
+                            bool useEmitRegister2,
+                            raw_ostream &O) {
   formatted_raw_ostream OS(O);
   
   OS << "// The main instruction selector code.\n";
   OS << "SDNode *SelectCode(SDNode *N) {\n";
 
-  MatcherTableEmitter MatcherEmitter(CGP);
+  MatcherTableEmitter MatcherEmitter(CGP, useEmitRegister2);
 
-  OS << "  // Opcodes are emitted as 2 bytes, TARGET_OPCODE handles this.\n";
-  OS << "  #define TARGET_OPCODE(X) X & 255, unsigned(X) >> 8\n";
+  OS << "  // Some target values are emitted as 2 bytes, TARGET_VAL handles\n";
+  OS << "  // this.\n";
+  OS << "  #define TARGET_VAL(X) X & 255, unsigned(X) >> 8\n";
   OS << "  static const unsigned char MatcherTable[] = {\n";
   unsigned TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 5, 0, OS);
   OS << "    0\n  }; // Total Array size is " << (TotalSize+1) << " bytes\n\n";
   
   MatcherEmitter.EmitHistogram(TheMatcher, OS);
   
-  OS << "  #undef TARGET_OPCODE\n";
+  OS << "  #undef TARGET_VAL\n";
   OS << "  return SelectCodeCommon(N, MatcherTable,sizeof(MatcherTable));\n}\n";
   OS << '\n';