llvm.org GIT mirror llvm / 3ca5641
[Tablegen] Instrumenting table gen DAGGenISelDAG To help assist in debugging ISEL or to prioritize GlobalISel backend work, this patch adds two more tables to <Target>GenISelDAGISel.inc - one which contains the patterns that are used during selection and the other containing include source location of the patterns Enabled through CMake varialbe LLVM_ENABLE_DAGISEL_COV git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@295081 91177308-0d34-0410-b5e6-96231b3b80d8 Aditya Nandakumar 3 years ago
5 changed file(s) with 166 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
172172 if(LLVM_BUILD_GLOBAL_ISEL)
173173 add_definitions(-DLLVM_BUILD_GLOBAL_ISEL)
174174 endif()
175
176 option(LLVM_ENABLE_DAGISEL_COV "Debug: Prints tablegen patterns that were used for selecting" OFF)
175177
176178 # Add path for custom modules
177179 set(CMAKE_MODULE_PATH
2222 set(LLVM_TARGET_DEFINITIONS_ABSOLUTE
2323 ${CMAKE_CURRENT_SOURCE_DIR}/${LLVM_TARGET_DEFINITIONS})
2424 endif()
25 if (LLVM_ENABLE_DAGISEL_COV)
26 list(FIND ARGN "-gen-dag-isel" idx)
27 if( NOT idx EQUAL -1 )
28 list(APPEND LLVM_TABLEGEN_FLAGS "-instrument-coverage")
29 endif()
30 endif()
31
2532 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.tmp
2633 # Generate tablegen output in a temporary file.
2734 COMMAND ${${project}_TABLEGEN_EXE} ${ARGN} -I ${CMAKE_CURRENT_SOURCE_DIR}
151151 OPC_MorphNodeTo,
152152 // Space-optimized forms that implicitly encode number of result VTs.
153153 OPC_MorphNodeTo0, OPC_MorphNodeTo1, OPC_MorphNodeTo2,
154 OPC_CompleteMatch
154 OPC_CompleteMatch,
155 // Contains offset in table for pattern being selected
156 OPC_Coverage
155157 };
156158
157159 enum {
213215 void SelectInlineAsmMemoryOperands(std::vector &Ops,
214216 const SDLoc &DL);
215217
218 /// getPatternForIndex - Patterns selected by tablegen during ISEL
219 virtual StringRef getPatternForIndex(unsigned index) {
220 llvm_unreachable("Tblgen should generate the implementation of this!");
221 }
222
223 /// getIncludePathForIndex - get the td source location of pattern instantiation
224 virtual StringRef getIncludePathForIndex(unsigned index) {
225 llvm_unreachable("Tblgen should generate the implementation of this!");
226 }
216227 public:
217228 // Calls to these predicates are generated by tblgen.
218229 bool CheckAndMask(SDValue LHS, ConstantSDNode *RHS,
35043504 RecordedNodes.push_back(std::pair(Res, nullptr));
35053505 continue;
35063506 }
3507 case OPC_Coverage: {
3508 // This is emitted right before MorphNode/EmitNode.
3509 // So it should be safe to assume that this node has been selected
3510 unsigned index = MatcherTable[MatcherIndex++];
3511 index |= (MatcherTable[MatcherIndex++] << 8);
3512 dbgs() << "COVERED: " << getPatternForIndex(index) << "\n";
3513 dbgs() << "INCLUDED: " << getIncludePathForIndex(index) << "\n";
3514 continue;
3515 }
35073516
35083517 case OPC_EmitNode: case OPC_MorphNodeTo:
35093518 case OPC_EmitNode0: case OPC_EmitNode1: case OPC_EmitNode2:
1010 //
1111 //===----------------------------------------------------------------------===//
1212
13 #include "CodeGenDAGPatterns.h"
1314 #include "DAGISelMatcher.h"
14 #include "CodeGenDAGPatterns.h"
1515 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/ADT/StringMap.h"
17 #include "llvm/ADT/MapVector.h"
1618 #include "llvm/ADT/SmallString.h"
1719 #include "llvm/ADT/StringMap.h"
1820 #include "llvm/ADT/TinyPtrVector.h"
1921 #include "llvm/Support/CommandLine.h"
2022 #include "llvm/Support/FormattedStream.h"
23 #include "llvm/Support/SourceMgr.h"
24 #include "llvm/TableGen/Error.h"
2125 #include "llvm/TableGen/Record.h"
2226 using namespace llvm;
2327
2933 static cl::opt
3034 OmitComments("omit-comments", cl::desc("Do not generate comments"),
3135 cl::init(false));
36
37 static cl::opt InstrumentCoverage(
38 "instrument-coverage",
39 cl::desc("Generates tables to help identify patterns matched"),
40 cl::init(false));
3241
3342 namespace {
3443 class MatcherTableEmitter {
5160 DenseMap NodeXFormMap;
5261 std::vector NodeXForms;
5362
63 std::vector VecIncludeStrings;
64 MapVector > VecPatterns;
65
66 unsigned getPatternIdxFromTable(std::string &&P, std::string &&include_loc) {
67 const auto It = VecPatterns.find(P);
68 if (It == VecPatterns.end()) {
69 VecPatterns.insert(make_pair(std::move(P), VecPatterns.size()));
70 VecIncludeStrings.push_back(std::move(include_loc));
71 return VecIncludeStrings.size() - 1;
72 }
73 return It->second;
74 }
75
5476 public:
5577 MatcherTableEmitter(const CodeGenDAGPatterns &cgp)
5678 : CGP(cgp) {}
6183 void EmitPredicateFunctions(formatted_raw_ostream &OS);
6284
6385 void EmitHistogram(const Matcher *N, formatted_raw_ostream &OS);
86
87 void EmitPatternMatchTable(raw_ostream &OS);
88
6489 private:
6590 unsigned EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
6691 formatted_raw_ostream &OS);
116141 };
117142 } // end anonymous namespace.
118143
144 static std::string GetPatFromTreePatternNode(const TreePatternNode *N) {
145 std::string str;
146 raw_string_ostream Stream(str);
147 Stream << *N;
148 Stream.str();
149 return str;
150 }
151
119152 static unsigned GetVBRSize(unsigned Val) {
120153 if (Val <= 127) return 1;
121154
147180 OS << "/*" << InVal << "*/";
148181 OS << ", ";
149182 return NumBytes+1;
183 }
184
185 // This is expensive and slow.
186 static std::string getIncludePath(const Record *R) {
187 std::string str;
188 raw_string_ostream Stream(str);
189 auto Locs = R->getLoc();
190 SMLoc L;
191 if (Locs.size() > 1) {
192 // Get where the pattern prototype was instantiated
193 L = Locs[1];
194 } else if (Locs.size() == 1) {
195 L = Locs[0];
196 }
197 unsigned CurBuf = SrcMgr.FindBufferContainingLoc(L);
198 assert(CurBuf && "Invalid or unspecified location!");
199
200 Stream << SrcMgr.getBufferInfo(CurBuf).Buffer->getBufferIdentifier() << ":"
201 << SrcMgr.FindLineNumber(L, CurBuf);
202 Stream.str();
203 return str;
204 }
205
206 void MatcherTableEmitter::EmitPatternMatchTable(raw_ostream &OS) {
207
208 assert(isUInt<16>(VecPatterns.size()) &&
209 "Using only 16 bits to encode offset into Pattern Table");
210 assert(VecPatterns.size() == VecIncludeStrings.size() &&
211 "The sizes of Pattern and include vectors should be the same");
212 OS << "StringRef getPatternForIndex(unsigned Index) override {\n";
213 OS << "static const char * PATTERN_MATCH_TABLE[] = {\n";
214
215 for (const auto &It : VecPatterns) {
216 OS << "\"" << It.first << "\",\n";
217 }
218
219 OS << "\n};";
220 OS << "\nreturn StringRef(PATTERN_MATCH_TABLE[Index]);";
221 OS << "\n}";
222
223 OS << "\nStringRef getIncludePathForIndex(unsigned Index) override {\n";
224 OS << "static const char * INCLUDE_PATH_TABLE[] = {\n";
225
226 for (const auto &It : VecIncludeStrings) {
227 OS << "\"" << It << "\",\n";
228 }
229
230 OS << "\n};";
231 OS << "\nreturn StringRef(INCLUDE_PATH_TABLE[Index]);";
232 OS << "\n}";
150233 }
151234
152235 /// EmitMatcher - Emit bytes for the specified matcher and return
536619
537620 case Matcher::EmitNode:
538621 case Matcher::MorphNodeTo: {
622 auto NumCoveredBytes = 0;
623 if (InstrumentCoverage) {
624 if (const MorphNodeToMatcher *SNT = dyn_cast(N)) {
625 NumCoveredBytes = 3;
626 OS << "OPC_Coverage, ";
627 std::string src =
628 GetPatFromTreePatternNode(SNT->getPattern().getSrcPattern());
629 std::string dst =
630 GetPatFromTreePatternNode(SNT->getPattern().getDstPattern());
631 Record *PatRecord = SNT->getPattern().getSrcRecord();
632 std::string include_src = getIncludePath(PatRecord);
633 unsigned Offset =
634 getPatternIdxFromTable(src + " -> " + dst, std::move(include_src));
635 OS << "TARGET_VAL(" << Offset << "),\n";
636 OS.PadToColumn(Indent * 2);
637 }
638 }
539639 const EmitNodeMatcherCommon *EN = cast(N);
540640 OS << (isa(EN) ? "OPC_EmitNode" : "OPC_MorphNodeTo");
541641 bool CompressVTs = EN->getNumVTs() < 3;
592692 } else
593693 OS << '\n';
594694
595 return 5 + !CompressVTs + EN->getNumVTs() + NumOperandBytes;
695 return 5 + !CompressVTs + EN->getNumVTs() + NumOperandBytes +
696 NumCoveredBytes;
596697 }
597698 case Matcher::CompleteMatch: {
598699 const CompleteMatchMatcher *CM = cast(N);
700 auto NumCoveredBytes = 0;
701 if (InstrumentCoverage) {
702 NumCoveredBytes = 3;
703 OS << "OPC_Coverage, ";
704 std::string src =
705 GetPatFromTreePatternNode(CM->getPattern().getSrcPattern());
706 std::string dst =
707 GetPatFromTreePatternNode(CM->getPattern().getDstPattern());
708 Record *PatRecord = CM->getPattern().getSrcRecord();
709 std::string include_src = getIncludePath(PatRecord);
710 unsigned Offset =
711 getPatternIdxFromTable(src + " -> " + dst, std::move(include_src));
712 OS << "TARGET_VAL(" << Offset << "),\n";
713 OS.PadToColumn(Indent * 2);
714 }
599715 OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";
600716 unsigned NumResultBytes = 0;
601717 for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
609725 << *CM->getPattern().getDstPattern();
610726 }
611727 OS << '\n';
612 return 2 + NumResultBytes;
728 return 2 + NumResultBytes + NumCoveredBytes;
613729 }
614730 }
615731 llvm_unreachable("Unreachable");
685801 ++NumOps; // Get the chained node too.
686802
687803 OS << " case " << i << ":\n";
804 if (InstrumentCoverage)
805 OS << " {\n";
688806 OS << " Result.resize(NextRes+" << NumOps << ");\n";
689 OS << " return " << P.getSelectFunc();
807 if (InstrumentCoverage)
808 OS << " bool Succeeded = " << P.getSelectFunc();
809 else
810 OS << " return " << P.getSelectFunc();
690811
691812 OS << "(";
692813 // If the complex pattern wants the root of the match, pass it in as the
703824 for (unsigned i = 0; i != NumOps; ++i)
704825 OS << ", Result[NextRes+" << i << "].first";
705826 OS << ");\n";
827 if (InstrumentCoverage) {
828 OS << " if (Succeeded)\n";
829 OS << " dbgs() << \"\\nCOMPLEX_PATTERN: " << P.getSelectFunc()
830 << "\\n\" ;\n";
831 OS << " return Succeeded;\n";
832 OS << " }\n";
833 }
706834 }
707835 OS << " }\n";
708836 OS << "}\n\n";
846974
847975 // Next up, emit the function for node and pattern predicates:
848976 MatcherEmitter.EmitPredicateFunctions(OS);
849 }
977
978 if (InstrumentCoverage)
979 MatcherEmitter.EmitPatternMatchTable(OS);
980 }