Changes in directory llvm/utils/TableGen:
DAGISelEmitter.cpp updated: 1.152 -> 1.153 DAGISelEmitter.h updated: 1.53 -> 1.54 --- Log message: Factor matching code that is common between patterns. This works around GCC not jump-threading across this common code, and produces far nicer output. --- Diffs of the changes: (+112 -35) DAGISelEmitter.cpp | 142 ++++++++++++++++++++++++++++++++++++++++------------- DAGISelEmitter.h | 5 + 2 files changed, 112 insertions(+), 35 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.152 llvm/utils/TableGen/DAGISelEmitter.cpp:1.153 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.152 Sat Jan 28 20:57:39 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Sat Jan 28 22:25:26 2006 @@ -2032,9 +2032,12 @@ } } else if (IntInit *II = dynamic_cast<IntInit*>(Child->getLeafValue())) { - emitCheck("isa<ConstantSDNode>(" + RootName + utostr(OpNo) + - ") && cast<ConstantSDNode>(" + RootName + utostr(OpNo) + - ")->getSignExtended() == " + itostr(II->getValue())); + emitCheck("isa<ConstantSDNode>(" + RootName + utostr(OpNo) + ")"); + unsigned CTmp = TmpNo++; + emitCode("int CN"+utostr(CTmp)+" = cast<ConstantSDNode>("+ + RootName + utostr(OpNo) + ")->getSignExtended();"); + + emitCheck("CN" + utostr(CTmp) + " == " +itostr(II->getValue())); } else { Child->dump(); assert(0 && "Unknown leaf type!"); @@ -2530,7 +2533,7 @@ /// EmitCodeForPattern - Given a pattern to match, emit code to the specified /// stream to match the pattern, and generate the code for the match if it /// succeeds. Returns true if the pattern is not guaranteed to match. -void DAGISelEmitter::EmitCodeForPattern(PatternToMatch &Pattern, +void DAGISelEmitter::GenerateCodeForPattern(PatternToMatch &Pattern, std::vector<std::pair<bool, std::string> > &GeneratedCode) { PatternCodeEmitter Emitter(*this, Pattern.getPredicates(), Pattern.getSrcPattern(), Pattern.getDstPattern(), @@ -2581,6 +2584,95 @@ delete Pat; } +/// EmitPatterns - Emit code for at least one pattern, but try to group common +/// code together between the patterns. +void DAGISelEmitter::EmitPatterns(std::vector<std::pair<PatternToMatch*, + std::vector<std::pair<bool, std::string> > > > + &Patterns, unsigned Indent, + std::ostream &OS) { + typedef std::pair<bool, std::string> CodeLine; + typedef std::vector<CodeLine> CodeList; + typedef std::vector<std::pair<PatternToMatch*, CodeList> > PatternList; + + if (Patterns.empty()) return; + + // Figure out how many patterns share the next code line: + const CodeLine &FirstCodeLine = Patterns.back().second.back(); + unsigned LastMatch = Patterns.size()-1; + while (LastMatch != 0 && Patterns[LastMatch-1].second.back() == FirstCodeLine) + --LastMatch; + + // If not all patterns share this line, split the list into two pieces. The + // first chunk will use this line, the second chunk won't. + if (LastMatch != 0) { + PatternList Shared(Patterns.begin()+LastMatch, Patterns.end()); + PatternList Other(Patterns.begin(), Patterns.begin()+LastMatch); + + // FIXME: Emit braces? + if (Shared.size() == 1) { + PatternToMatch &Pattern = *Shared.back().first; + OS << "\n" << std::string(Indent, ' ') << "// Pattern: "; + Pattern.getSrcPattern()->print(OS); + OS << "\n" << std::string(Indent, ' ') << "// Emits: "; + Pattern.getDstPattern()->print(OS); + OS << "\n"; + OS << std::string(Indent, ' ') << "// Pattern complexity = " + << getPatternSize(Pattern.getSrcPattern(), *this) << " cost = " + << getResultPatternCost(Pattern.getDstPattern()) << "\n"; + } + if (!FirstCodeLine.first) { + OS << std::string(Indent, ' ') << "{\n"; + Indent += 2; + } + EmitPatterns(Shared, Indent, OS); + if (!FirstCodeLine.first) { + Indent -= 2; + OS << std::string(Indent, ' ') << "}\n"; + } + + if (Other.size() == 1) { + PatternToMatch &Pattern = *Other.back().first; + OS << "\n" << std::string(Indent, ' ') << "// Pattern: "; + Pattern.getSrcPattern()->print(OS); + OS << "\n" << std::string(Indent, ' ') << "// Emits: "; + Pattern.getDstPattern()->print(OS); + OS << "\n"; + OS << std::string(Indent, ' ') << "// Pattern complexity = " + << getPatternSize(Pattern.getSrcPattern(), *this) << " cost = " + << getResultPatternCost(Pattern.getDstPattern()) << "\n"; + } + EmitPatterns(Other, Indent, OS); + return; + } + + bool isPredicate = FirstCodeLine.first; + + // Otherwise, every pattern in the list has this line. Emit it. + if (!isPredicate) { + // Normal code. + OS << std::string(Indent, ' ') << FirstCodeLine.second << "\n"; + } else { + OS << std::string(Indent, ' ') + << "if (" << FirstCodeLine.second << ") {\n"; + Indent += 2; + } + + // Remove this code from all of the patterns that share it. + for (unsigned i = 0, e = Patterns.size(); i != e; ++i) { + Patterns[i].second.pop_back(); + if (Patterns[i].second.empty()) { + Patterns.erase(Patterns.begin()+i); + --i; --e; + } + } + + EmitPatterns(Patterns, Indent, OS); + + if (isPredicate) + OS << std::string(Indent-2, ' ') << "}\n"; +} + + namespace { /// CompareByRecordName - An ordering predicate that implements less-than by @@ -2652,7 +2744,7 @@ std::vector<std::pair<PatternToMatch*, CodeList> > CodeForPatterns; for (unsigned i = 0, e = Patterns.size(); i != e; ++i) { CodeList GeneratedCode; - EmitCodeForPattern(*Patterns[i], GeneratedCode); + GenerateCodeForPattern(*Patterns[i], GeneratedCode); CodeForPatterns.push_back(std::make_pair(Patterns[i], GeneratedCode)); } @@ -2679,39 +2771,21 @@ exit(1); } } - + + // Loop through and reverse all of the CodeList vectors, as we will be + // accessing them from their logical front, but accessing the end of a + // vector is more efficient. for (unsigned i = 0, e = CodeForPatterns.size(); i != e; ++i) { CodeList &GeneratedCode = CodeForPatterns[i].second; - PatternToMatch &Pattern = *CodeForPatterns[i].first; - OS << " { // Pattern: "; - Pattern.getSrcPattern()->print(OS); - OS << "\n // Emits: "; - Pattern.getDstPattern()->print(OS); - OS << "\n"; - OS << " // Pattern complexity = " - << getPatternSize(Pattern.getSrcPattern(), *this) << " cost = " - << getResultPatternCost(Pattern.getDstPattern()) << "\n"; - - // Actually output the generated code now. - mightNotMatch = false; - unsigned Indent = 4; - for (unsigned j = 0, e = GeneratedCode.size(); j != e; ++j) { - if (!GeneratedCode[j].first) { - // Normal code. - OS << std::string(Indent, ' ') << GeneratedCode[j].second << "\n"; - } else { - mightNotMatch = true; - OS << std::string(Indent, ' ') - << "if (" << GeneratedCode[j].second << ") {\n"; - Indent += 2; - } - } - for (; Indent != 4; Indent -= 2) - OS << std::string(Indent-2, ' ') << "}\n"; - - OS << " }\n"; + std::reverse(GeneratedCode.begin(), GeneratedCode.end()); } + // Next, reverse the list of patterns itself for the same reason. + std::reverse(CodeForPatterns.begin(), CodeForPatterns.end()); + + // Emit all of the patterns now, grouped together to share code. + EmitPatterns(CodeForPatterns, 2, OS); + // If the last pattern has predicates (which could fail) emit code to catch // the case where nothing handles a pattern. if (mightNotMatch) Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.53 llvm/utils/TableGen/DAGISelEmitter.h:1.54 --- llvm/utils/TableGen/DAGISelEmitter.h:1.53 Sat Jan 28 20:43:35 2006 +++ llvm/utils/TableGen/DAGISelEmitter.h Sat Jan 28 22:25:26 2006 @@ -470,8 +470,11 @@ std::map<std::string, Record*> &InstResults, std::vector<Record*> &InstImpInputs, std::vector<Record*> &InstImpResults); - void EmitCodeForPattern(PatternToMatch &Pattern, + void GenerateCodeForPattern(PatternToMatch &Pattern, std::vector<std::pair<bool, std::string> > &GeneratedCode); + void EmitPatterns(std::vector<std::pair<PatternToMatch*, + std::vector<std::pair<bool, std::string> > > > &Patterns, + unsigned Indent, std::ostream &OS); void EmitInstructionSelector(std::ostream &OS); }; _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits