[llvm] r317903 - Allow separation of declarations and definitions in <Target>ISelDAGToDAG.inc

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 10 10:36:04 PST 2017


Author: kparzysz
Date: Fri Nov 10 10:36:04 2017
New Revision: 317903

URL: http://llvm.org/viewvc/llvm-project?rev=317903&view=rev
Log:
Allow separation of declarations and definitions in <Target>ISelDAGToDAG.inc

This patch adds the ability to include the member function declarations
in the instruction selector class separately from the member bodies.

Defining GET_DAGISEL_DECL macro to any value will only include the member
declarations. To include bodies, define GET_DAGISEL_BODY macro to be the
selector class name. Example:

  class FooDAGToDAGISel : public SelectionDAGISel {
    // Pull in declarations only.
    #define GET_DAGISEL_DECL
    #include "FooISelDAGToDAG.inc"
  };

  // Include the function bodies (with names qualified with the provided
  // class name).
  #define GET_DAGISEL_BODY FooDAGToDAGISel
  #include "FooISelDAGToDAG.inc"

When neither of the two macros are defined, the function bodies are emitted
inline (in the same way as before this patch).

Differential Revision: https://reviews.llvm.org/D39596

Modified:
    llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
    llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp

Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=317903&r1=317902&r2=317903&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Fri Nov 10 10:36:04 2017
@@ -127,6 +127,16 @@ void DAGISelEmitter::run(raw_ostream &OS
      << "// *** instruction selector class.  These functions are really "
      << "methods.\n\n";
 
+  OS << "// If GET_DAGISEL_DECL is #defined with any value, only function\n"
+        "// declarations will be included when this file is included.\n"
+        "// If GET_DAGISEL_BODY is #defined, its value should be the name of\n"
+        "// the instruction selector class. Function bodies will be emitted\n"
+        "// and each function's name will be qualified with the name of the\n"
+        "// class.\n"
+        "//\n"
+        "// When neither of the GET_DAGISEL* macros is defined, the functions\n"
+        "// are emitted inline.\n\n";
+
   DEBUG(errs() << "\n\nALL PATTERNS TO MATCH:\n\n";
         for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(),
              E = CGP.ptm_end(); I != E; ++I) {

Modified: llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp?rev=317903&r1=317902&r2=317903&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp Fri Nov 10 10:36:04 2017
@@ -208,13 +208,37 @@ static std::string getIncludePath(const
   return str;
 }
 
+static void BeginEmitFunction(raw_ostream &OS, StringRef RetType,
+                              StringRef Decl, bool AddOverride) {
+  OS << "#ifdef GET_DAGISEL_DECL\n";
+  OS << RetType << ' ' << Decl;
+  if (AddOverride)
+    OS << " override";
+  OS << ";\n"
+        "#endif\n"
+        "#if defined(GET_DAGISEL_BODY) || DAGISEL_INLINE\n";
+  OS << RetType << " DAGISEL_CLASS_COLONCOLON " << Decl << "\n";
+  if (AddOverride) {
+    OS << "#if DAGISEL_INLINE\n"
+          "  override\n"
+          "#endif\n";
+  }
+}
+
+static void EndEmitFunction(raw_ostream &OS) {
+  OS << "#endif // GET_DAGISEL_BODY\n\n";
+}
+
 void MatcherTableEmitter::EmitPatternMatchTable(raw_ostream &OS) {
 
   assert(isUInt<16>(VecPatterns.size()) &&
          "Using only 16 bits to encode offset into Pattern Table");
   assert(VecPatterns.size() == VecIncludeStrings.size() &&
          "The sizes of Pattern and include vectors should be the same");
-  OS << "StringRef getPatternForIndex(unsigned Index) override {\n";
+
+  BeginEmitFunction(OS, "StringRef", "getPatternForIndex(unsigned Index)",
+                    true/*AddOverride*/);
+  OS << "{\n";
   OS << "static const char * PATTERN_MATCH_TABLE[] = {\n";
 
   for (const auto &It : VecPatterns) {
@@ -224,8 +248,11 @@ void MatcherTableEmitter::EmitPatternMat
   OS << "\n};";
   OS << "\nreturn StringRef(PATTERN_MATCH_TABLE[Index]);";
   OS << "\n}";
+  EndEmitFunction(OS);
 
-  OS << "\nStringRef getIncludePathForIndex(unsigned Index) override {\n";
+  BeginEmitFunction(OS, "StringRef", "getIncludePathForIndex(unsigned Index)",
+                    true/*AddOverride*/);
+  OS << "{\n";
   OS << "static const char * INCLUDE_PATH_TABLE[] = {\n";
 
   for (const auto &It : VecIncludeStrings) {
@@ -235,6 +262,7 @@ void MatcherTableEmitter::EmitPatternMat
   OS << "\n};";
   OS << "\nreturn StringRef(INCLUDE_PATH_TABLE[Index]);";
   OS << "\n}";
+  EndEmitFunction(OS);
 }
 
 /// EmitMatcher - Emit bytes for the specified matcher and return
@@ -755,19 +783,24 @@ EmitMatcherList(const Matcher *N, unsign
 void MatcherTableEmitter::EmitPredicateFunctions(raw_ostream &OS) {
   // Emit pattern predicates.
   if (!PatternPredicates.empty()) {
-    OS << "bool CheckPatternPredicate(unsigned PredNo) const override {\n";
+    BeginEmitFunction(OS, "bool",
+          "CheckPatternPredicate(unsigned PredNo) const", true/*AddOverride*/);
+    OS << "{\n";
     OS << "  switch (PredNo) {\n";
     OS << "  default: llvm_unreachable(\"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 << "}\n";
+    EndEmitFunction(OS);
   }
 
   // Emit Node predicates.
   if (!NodePredicates.empty()) {
-    OS << "bool CheckNodePredicate(SDNode *Node,\n";
-    OS << "                        unsigned PredNo) const override {\n";
+    BeginEmitFunction(OS, "bool",
+          "CheckNodePredicate(SDNode *Node, unsigned PredNo) const",
+          true/*AddOverride*/);
+    OS << "{\n";
     OS << "  switch (PredNo) {\n";
     OS << "  default: llvm_unreachable(\"Invalid predicate in table?\");\n";
     for (unsigned i = 0, e = NodePredicates.size(); i != e; ++i) {
@@ -783,15 +816,19 @@ void MatcherTableEmitter::EmitPredicateF
       OS << PredFn.getCodeToRunOnSDNode() << "\n  }\n";
     }
     OS << "  }\n";
-    OS << "}\n\n";
+    OS << "}\n";
+    EndEmitFunction(OS);
   }
 
   // Emit CompletePattern matchers.
   // FIXME: This should be const.
   if (!ComplexPatterns.empty()) {
-    OS << "bool CheckComplexPattern(SDNode *Root, SDNode *Parent,\n";
-    OS << "                         SDValue N, unsigned PatternNo,\n";
-    OS << "         SmallVectorImpl<std::pair<SDValue, SDNode*> > &Result) override {\n";
+    BeginEmitFunction(OS, "bool",
+          "CheckComplexPattern(SDNode *Root, SDNode *Parent,\n"
+          "      SDValue N, unsigned PatternNo,\n"
+          "      SmallVectorImpl<std::pair<SDValue, SDNode*>> &Result)",
+          true/*AddOverride*/);
+    OS << "{\n";
     OS << "  unsigned NextRes = Result.size();\n";
     OS << "  switch (PatternNo) {\n";
     OS << "  default: llvm_unreachable(\"Invalid pattern # in table?\");\n";
@@ -835,14 +872,17 @@ void MatcherTableEmitter::EmitPredicateF
       }
     }
     OS << "  }\n";
-    OS << "}\n\n";
+    OS << "}\n";
+    EndEmitFunction(OS);
   }
 
 
   // Emit SDNodeXForm handlers.
   // FIXME: This should be const.
   if (!NodeXForms.empty()) {
-    OS << "SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) override {\n";
+    BeginEmitFunction(OS, "SDValue",
+          "RunSDNodeXForm(SDValue V, unsigned XFormNo)", true/*AddOverride*/);
+    OS << "{\n";
     OS << "  switch (XFormNo) {\n";
     OS << "  default: llvm_unreachable(\"Invalid xform # in table?\");\n";
 
@@ -868,7 +908,8 @@ void MatcherTableEmitter::EmitPredicateF
       OS << Code << "\n  }\n";
     }
     OS << "  }\n";
-    OS << "}\n\n";
+    OS << "}\n";
+    EndEmitFunction(OS);
   }
 }
 
@@ -958,11 +999,39 @@ void MatcherTableEmitter::EmitHistogram(
 void llvm::EmitMatcherTable(const Matcher *TheMatcher,
                             const CodeGenDAGPatterns &CGP,
                             raw_ostream &OS) {
-  OS << "// The main instruction selector code.\n";
-  OS << "void SelectCode(SDNode *N) {\n";
+  OS << "#if defined(GET_DAGISEL_DECL) && defined(GET_DAGISEL_BODY)\n";
+  OS << "#error GET_DAGISEL_DECL and GET_DAGISEL_BODY cannot be both defined, ";
+  OS << "undef both for inline definitions\n";
+  OS << "#endif\n\n";
+
+  // Emit a check for omitted class name.
+  OS << "#ifdef GET_DAGISEL_BODY\n";
+  OS << "#define LOCAL_DAGISEL_STRINGIZE(X) LOCAL_DAGISEL_STRINGIZE_(X)\n";
+  OS << "#define LOCAL_DAGISEL_STRINGIZE_(X) #X\n";
+  OS << "static_assert(sizeof(LOCAL_DAGISEL_STRINGIZE(GET_DAGISEL_BODY)) > 1,"
+        "\n";
+  OS << "   \"GET_DAGISEL_BODY is empty: it should be defined with the class "
+        "name\");\n";
+  OS << "#undef LOCAL_DAGISEL_STRINGIZE_\n";
+  OS << "#undef LOCAL_DAGISEL_STRINGIZE\n";
+  OS << "#endif\n\n";
+
+  OS << "#if !defined(GET_DAGISEL_DECL) && !defined(GET_DAGISEL_BODY)\n";
+  OS << "#define DAGISEL_INLINE 1\n";
+  OS << "#else\n";
+  OS << "#define DAGISEL_INLINE 0\n";
+  OS << "#endif\n\n";
+
+  OS << "#if !DAGISEL_INLINE\n";
+  OS << "#define DAGISEL_CLASS_COLONCOLON GET_DAGISEL_BODY ::\n";
+  OS << "#else\n";
+  OS << "#define DAGISEL_CLASS_COLONCOLON\n";
+  OS << "#endif\n\n";
 
+  BeginEmitFunction(OS, "void", "SelectCode(SDNode *N)", false/*AddOverride*/);
   MatcherTableEmitter MatcherEmitter(CGP);
 
+  OS << "{\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";
@@ -974,11 +1043,27 @@ void llvm::EmitMatcherTable(const Matche
 
   OS << "  #undef TARGET_VAL\n";
   OS << "  SelectCodeCommon(N, MatcherTable,sizeof(MatcherTable));\n";
-  OS << "}\n\n";
+  OS << "}\n";
+  EndEmitFunction(OS);
 
   // Next up, emit the function for node and pattern predicates:
   MatcherEmitter.EmitPredicateFunctions(OS);
 
   if (InstrumentCoverage)
     MatcherEmitter.EmitPatternMatchTable(OS);
+
+  // Clean up the preprocessor macros.
+  OS << "\n";
+  OS << "#ifdef DAGISEL_INLINE\n";
+  OS << "#undef DAGISEL_INLINE\n";
+  OS << "#endif\n";
+  OS << "#ifdef DAGISEL_CLASS_COLONCOLON\n";
+  OS << "#undef DAGISEL_CLASS_COLONCOLON\n";
+  OS << "#endif\n";
+  OS << "#ifdef GET_DAGISEL_DECL\n";
+  OS << "#undef GET_DAGISEL_DECL\n";
+  OS << "#endif\n";
+  OS << "#ifdef GET_DAGISEL_BODY\n";
+  OS << "#undef GET_DAGISEL_BODY\n";
+  OS << "#endif\n";
 }




More information about the llvm-commits mailing list