diff options
Diffstat (limited to 'contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp')
-rw-r--r-- | contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp | 150 |
1 files changed, 141 insertions, 9 deletions
diff --git a/contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp index d30fc5131cba..67e8f15b248e 100644 --- a/contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -11,14 +11,18 @@ // //===----------------------------------------------------------------------===// -#include "DAGISelMatcher.h" #include "CodeGenDAGPatterns.h" +#include "DAGISelMatcher.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" using namespace llvm; @@ -26,10 +30,17 @@ enum { CommentIndent = 30 }; +cl::OptionCategory DAGISelCat("Options for -gen-dag-isel"); + // To reduce generated source code size. -static cl::opt<bool> -OmitComments("omit-comments", cl::desc("Do not generate comments"), - cl::init(false)); +static cl::opt<bool> OmitComments("omit-comments", + cl::desc("Do not generate comments"), + cl::init(false), cl::cat(DAGISelCat)); + +static cl::opt<bool> InstrumentCoverage( + "instrument-coverage", + cl::desc("Generates tables to help identify patterns matched"), + cl::init(false), cl::cat(DAGISelCat)); namespace { class MatcherTableEmitter { @@ -52,6 +63,19 @@ class MatcherTableEmitter { DenseMap<Record*, unsigned> NodeXFormMap; std::vector<Record*> NodeXForms; + std::vector<std::string> VecIncludeStrings; + MapVector<std::string, unsigned, StringMap<unsigned> > VecPatterns; + + unsigned getPatternIdxFromTable(std::string &&P, std::string &&include_loc) { + const auto It = VecPatterns.find(P); + if (It == VecPatterns.end()) { + VecPatterns.insert(make_pair(std::move(P), VecPatterns.size())); + VecIncludeStrings.push_back(std::move(include_loc)); + return VecIncludeStrings.size() - 1; + } + return It->second; + } + public: MatcherTableEmitter(const CodeGenDAGPatterns &cgp) : CGP(cgp) {} @@ -62,6 +86,9 @@ public: void EmitPredicateFunctions(formatted_raw_ostream &OS); void EmitHistogram(const Matcher *N, formatted_raw_ostream &OS); + + void EmitPatternMatchTable(raw_ostream &OS); + private: unsigned EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, formatted_raw_ostream &OS); @@ -117,6 +144,14 @@ private: }; } // end anonymous namespace. +static std::string GetPatFromTreePatternNode(const TreePatternNode *N) { + std::string str; + raw_string_ostream Stream(str); + Stream << *N; + Stream.str(); + return str; +} + static unsigned GetVBRSize(unsigned Val) { if (Val <= 127) return 1; @@ -150,6 +185,56 @@ static uint64_t EmitVBRValue(uint64_t Val, raw_ostream &OS) { return NumBytes+1; } +// This is expensive and slow. +static std::string getIncludePath(const Record *R) { + std::string str; + raw_string_ostream Stream(str); + auto Locs = R->getLoc(); + SMLoc L; + if (Locs.size() > 1) { + // Get where the pattern prototype was instantiated + L = Locs[1]; + } else if (Locs.size() == 1) { + L = Locs[0]; + } + unsigned CurBuf = SrcMgr.FindBufferContainingLoc(L); + assert(CurBuf && "Invalid or unspecified location!"); + + Stream << SrcMgr.getBufferInfo(CurBuf).Buffer->getBufferIdentifier() << ":" + << SrcMgr.FindLineNumber(L, CurBuf); + Stream.str(); + return str; +} + +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"; + OS << "static const char * PATTERN_MATCH_TABLE[] = {\n"; + + for (const auto &It : VecPatterns) { + OS << "\"" << It.first << "\",\n"; + } + + OS << "\n};"; + OS << "\nreturn StringRef(PATTERN_MATCH_TABLE[Index]);"; + OS << "\n}"; + + OS << "\nStringRef getIncludePathForIndex(unsigned Index) override {\n"; + OS << "static const char * INCLUDE_PATH_TABLE[] = {\n"; + + for (const auto &It : VecIncludeStrings) { + OS << "\"" << It << "\",\n"; + } + + OS << "\n};"; + OS << "\nreturn StringRef(INCLUDE_PATH_TABLE[Index]);"; + OS << "\n}"; +} + /// EmitMatcher - Emit bytes for the specified matcher and return /// the number of bytes emitted. unsigned MatcherTableEmitter:: @@ -537,6 +622,23 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, case Matcher::EmitNode: case Matcher::MorphNodeTo: { + auto NumCoveredBytes = 0; + if (InstrumentCoverage) { + if (const MorphNodeToMatcher *SNT = dyn_cast<MorphNodeToMatcher>(N)) { + NumCoveredBytes = 3; + OS << "OPC_Coverage, "; + std::string src = + GetPatFromTreePatternNode(SNT->getPattern().getSrcPattern()); + std::string dst = + GetPatFromTreePatternNode(SNT->getPattern().getDstPattern()); + Record *PatRecord = SNT->getPattern().getSrcRecord(); + std::string include_src = getIncludePath(PatRecord); + unsigned Offset = + getPatternIdxFromTable(src + " -> " + dst, std::move(include_src)); + OS << "TARGET_VAL(" << Offset << "),\n"; + OS.PadToColumn(Indent * 2); + } + } const EmitNodeMatcherCommon *EN = cast<EmitNodeMatcherCommon>(N); OS << (isa<EmitNodeMatcher>(EN) ? "OPC_EmitNode" : "OPC_MorphNodeTo"); bool CompressVTs = EN->getNumVTs() < 3; @@ -593,10 +695,26 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, } else OS << '\n'; - return 5 + !CompressVTs + EN->getNumVTs() + NumOperandBytes; + return 5 + !CompressVTs + EN->getNumVTs() + NumOperandBytes + + NumCoveredBytes; } case Matcher::CompleteMatch: { const CompleteMatchMatcher *CM = cast<CompleteMatchMatcher>(N); + auto NumCoveredBytes = 0; + if (InstrumentCoverage) { + NumCoveredBytes = 3; + OS << "OPC_Coverage, "; + std::string src = + GetPatFromTreePatternNode(CM->getPattern().getSrcPattern()); + std::string dst = + GetPatFromTreePatternNode(CM->getPattern().getDstPattern()); + Record *PatRecord = CM->getPattern().getSrcRecord(); + std::string include_src = getIncludePath(PatRecord); + unsigned Offset = + getPatternIdxFromTable(src + " -> " + dst, std::move(include_src)); + OS << "TARGET_VAL(" << Offset << "),\n"; + OS.PadToColumn(Indent * 2); + } OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", "; unsigned NumResultBytes = 0; for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i) @@ -610,7 +728,7 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, << *CM->getPattern().getDstPattern(); } OS << '\n'; - return 2 + NumResultBytes; + return 2 + NumResultBytes + NumCoveredBytes; } } llvm_unreachable("Unreachable"); @@ -686,8 +804,13 @@ void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) { ++NumOps; // Get the chained node too. OS << " case " << i << ":\n"; + if (InstrumentCoverage) + OS << " {\n"; OS << " Result.resize(NextRes+" << NumOps << ");\n"; - OS << " return " << P.getSelectFunc(); + if (InstrumentCoverage) + OS << " bool Succeeded = " << P.getSelectFunc(); + else + OS << " return " << P.getSelectFunc(); OS << "("; // If the complex pattern wants the root of the match, pass it in as the @@ -704,6 +827,13 @@ void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) { for (unsigned i = 0; i != NumOps; ++i) OS << ", Result[NextRes+" << i << "].first"; OS << ");\n"; + if (InstrumentCoverage) { + OS << " if (Succeeded)\n"; + OS << " dbgs() << \"\\nCOMPLEX_PATTERN: " << P.getSelectFunc() + << "\\n\" ;\n"; + OS << " return Succeeded;\n"; + OS << " }\n"; + } } OS << " }\n"; OS << "}\n\n"; @@ -827,7 +957,7 @@ void llvm::EmitMatcherTable(const Matcher *TheMatcher, formatted_raw_ostream OS(O); OS << "// The main instruction selector code.\n"; - OS << "SDNode *SelectCode(SDNode *N) {\n"; + OS << "void SelectCode(SDNode *N) {\n"; MatcherTableEmitter MatcherEmitter(CGP); @@ -842,9 +972,11 @@ void llvm::EmitMatcherTable(const Matcher *TheMatcher, OS << " #undef TARGET_VAL\n"; OS << " SelectCodeCommon(N, MatcherTable,sizeof(MatcherTable));\n"; - OS << " return nullptr;\n"; OS << "}\n"; // Next up, emit the function for node and pattern predicates: MatcherEmitter.EmitPredicateFunctions(OS); + + if (InstrumentCoverage) + MatcherEmitter.EmitPatternMatchTable(OS); } |