mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
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 llvm-svn: 317903
This commit is contained in:
parent
f8fa757956
commit
a38d7036dc
@ -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) {
|
||||
|
@ -208,13 +208,37 @@ static std::string getIncludePath(const Record *R) {
|
||||
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::EmitPatternMatchTable(raw_ostream &OS) {
|
||||
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::EmitPatternMatchTable(raw_ostream &OS) {
|
||||
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, unsigned Indent, unsigned CurrentIdx,
|
||||
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::EmitPredicateFunctions(raw_ostream &OS) {
|
||||
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::EmitPredicateFunctions(raw_ostream &OS) {
|
||||
}
|
||||
}
|
||||
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::EmitPredicateFunctions(raw_ostream &OS) {
|
||||
OS << Code << "\n }\n";
|
||||
}
|
||||
OS << " }\n";
|
||||
OS << "}\n\n";
|
||||
OS << "}\n";
|
||||
EndEmitFunction(OS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -958,11 +999,39 @@ void MatcherTableEmitter::EmitHistogram(const Matcher *M,
|
||||
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 Matcher *TheMatcher,
|
||||
|
||||
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";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user