aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp')
-rw-r--r--contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp150
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);
}