File: | llvm/utils/TableGen/DAGISelMatcherEmitter.cpp |
Warning: | line 1124, column 12 Value stored to 'TotalSize' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- DAGISelMatcherEmitter.cpp - Matcher Emitter ------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file contains code to generate C++ code for a matcher. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "CodeGenDAGPatterns.h" |
14 | #include "DAGISelMatcher.h" |
15 | #include "llvm/ADT/DenseMap.h" |
16 | #include "llvm/ADT/StringMap.h" |
17 | #include "llvm/ADT/MapVector.h" |
18 | #include "llvm/ADT/SmallString.h" |
19 | #include "llvm/ADT/StringMap.h" |
20 | #include "llvm/ADT/TinyPtrVector.h" |
21 | #include "llvm/Support/CommandLine.h" |
22 | #include "llvm/Support/Format.h" |
23 | #include "llvm/Support/SourceMgr.h" |
24 | #include "llvm/TableGen/Error.h" |
25 | #include "llvm/TableGen/Record.h" |
26 | |
27 | using namespace llvm; |
28 | |
29 | enum { |
30 | IndexWidth = 6, |
31 | FullIndexWidth = IndexWidth + 4, |
32 | HistOpcWidth = 40, |
33 | }; |
34 | |
35 | cl::OptionCategory DAGISelCat("Options for -gen-dag-isel"); |
36 | |
37 | // To reduce generated source code size. |
38 | static cl::opt<bool> OmitComments("omit-comments", |
39 | cl::desc("Do not generate comments"), |
40 | cl::init(false), cl::cat(DAGISelCat)); |
41 | |
42 | static cl::opt<bool> InstrumentCoverage( |
43 | "instrument-coverage", |
44 | cl::desc("Generates tables to help identify patterns matched"), |
45 | cl::init(false), cl::cat(DAGISelCat)); |
46 | |
47 | namespace { |
48 | class MatcherTableEmitter { |
49 | const CodeGenDAGPatterns &CGP; |
50 | |
51 | SmallVector<unsigned, Matcher::HighestKind+1> OpcodeCounts; |
52 | |
53 | DenseMap<TreePattern *, unsigned> NodePredicateMap; |
54 | std::vector<TreePredicateFn> NodePredicates; |
55 | std::vector<TreePredicateFn> NodePredicatesWithOperands; |
56 | |
57 | // We de-duplicate the predicates by code string, and use this map to track |
58 | // all the patterns with "identical" predicates. |
59 | StringMap<TinyPtrVector<TreePattern *>> NodePredicatesByCodeToRun; |
60 | |
61 | StringMap<unsigned> PatternPredicateMap; |
62 | std::vector<std::string> PatternPredicates; |
63 | |
64 | DenseMap<const ComplexPattern*, unsigned> ComplexPatternMap; |
65 | std::vector<const ComplexPattern*> ComplexPatterns; |
66 | |
67 | |
68 | DenseMap<Record*, unsigned> NodeXFormMap; |
69 | std::vector<Record*> NodeXForms; |
70 | |
71 | std::vector<std::string> VecIncludeStrings; |
72 | MapVector<std::string, unsigned, StringMap<unsigned> > VecPatterns; |
73 | |
74 | unsigned getPatternIdxFromTable(std::string &&P, std::string &&include_loc) { |
75 | const auto It = VecPatterns.find(P); |
76 | if (It == VecPatterns.end()) { |
77 | VecPatterns.insert(make_pair(std::move(P), VecPatterns.size())); |
78 | VecIncludeStrings.push_back(std::move(include_loc)); |
79 | return VecIncludeStrings.size() - 1; |
80 | } |
81 | return It->second; |
82 | } |
83 | |
84 | public: |
85 | MatcherTableEmitter(const CodeGenDAGPatterns &cgp) : CGP(cgp) { |
86 | OpcodeCounts.assign(Matcher::HighestKind+1, 0); |
87 | } |
88 | |
89 | unsigned EmitMatcherList(const Matcher *N, const unsigned Indent, |
90 | unsigned StartIdx, raw_ostream &OS); |
91 | |
92 | unsigned SizeMatcherList(Matcher *N, raw_ostream &OS); |
93 | |
94 | void EmitPredicateFunctions(raw_ostream &OS); |
95 | |
96 | void EmitHistogram(const Matcher *N, raw_ostream &OS); |
97 | |
98 | void EmitPatternMatchTable(raw_ostream &OS); |
99 | |
100 | private: |
101 | void EmitNodePredicatesFunction(const std::vector<TreePredicateFn> &Preds, |
102 | StringRef Decl, raw_ostream &OS); |
103 | |
104 | unsigned SizeMatcher(Matcher *N, raw_ostream &OS); |
105 | |
106 | unsigned EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx, |
107 | raw_ostream &OS); |
108 | |
109 | unsigned getNodePredicate(TreePredicateFn Pred) { |
110 | TreePattern *TP = Pred.getOrigPatFragRecord(); |
111 | unsigned &Entry = NodePredicateMap[TP]; |
112 | if (Entry == 0) { |
113 | TinyPtrVector<TreePattern *> &SameCodePreds = |
114 | NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode()]; |
115 | if (SameCodePreds.empty()) { |
116 | // We've never seen a predicate with the same code: allocate an entry. |
117 | if (Pred.usesOperands()) { |
118 | NodePredicatesWithOperands.push_back(Pred); |
119 | Entry = NodePredicatesWithOperands.size(); |
120 | } else { |
121 | NodePredicates.push_back(Pred); |
122 | Entry = NodePredicates.size(); |
123 | } |
124 | } else { |
125 | // We did see an identical predicate: re-use it. |
126 | Entry = NodePredicateMap[SameCodePreds.front()]; |
127 | assert(Entry != 0)((Entry != 0) ? static_cast<void> (0) : __assert_fail ( "Entry != 0", "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 127, __PRETTY_FUNCTION__)); |
128 | assert(TreePredicateFn(SameCodePreds.front()).usesOperands() ==((TreePredicateFn(SameCodePreds.front()).usesOperands() == Pred .usesOperands() && "PatFrags with some code must have same usesOperands setting" ) ? static_cast<void> (0) : __assert_fail ("TreePredicateFn(SameCodePreds.front()).usesOperands() == Pred.usesOperands() && \"PatFrags with some code must have same usesOperands setting\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 130, __PRETTY_FUNCTION__)) |
129 | Pred.usesOperands() &&((TreePredicateFn(SameCodePreds.front()).usesOperands() == Pred .usesOperands() && "PatFrags with some code must have same usesOperands setting" ) ? static_cast<void> (0) : __assert_fail ("TreePredicateFn(SameCodePreds.front()).usesOperands() == Pred.usesOperands() && \"PatFrags with some code must have same usesOperands setting\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 130, __PRETTY_FUNCTION__)) |
130 | "PatFrags with some code must have same usesOperands setting")((TreePredicateFn(SameCodePreds.front()).usesOperands() == Pred .usesOperands() && "PatFrags with some code must have same usesOperands setting" ) ? static_cast<void> (0) : __assert_fail ("TreePredicateFn(SameCodePreds.front()).usesOperands() == Pred.usesOperands() && \"PatFrags with some code must have same usesOperands setting\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 130, __PRETTY_FUNCTION__)); |
131 | } |
132 | // In both cases, we've never seen this particular predicate before, so |
133 | // mark it in the list of predicates sharing the same code. |
134 | SameCodePreds.push_back(TP); |
135 | } |
136 | return Entry-1; |
137 | } |
138 | |
139 | unsigned getPatternPredicate(StringRef PredName) { |
140 | unsigned &Entry = PatternPredicateMap[PredName]; |
141 | if (Entry == 0) { |
142 | PatternPredicates.push_back(PredName.str()); |
143 | Entry = PatternPredicates.size(); |
144 | } |
145 | return Entry-1; |
146 | } |
147 | unsigned getComplexPat(const ComplexPattern &P) { |
148 | unsigned &Entry = ComplexPatternMap[&P]; |
149 | if (Entry == 0) { |
150 | ComplexPatterns.push_back(&P); |
151 | Entry = ComplexPatterns.size(); |
152 | } |
153 | return Entry-1; |
154 | } |
155 | |
156 | unsigned getNodeXFormID(Record *Rec) { |
157 | unsigned &Entry = NodeXFormMap[Rec]; |
158 | if (Entry == 0) { |
159 | NodeXForms.push_back(Rec); |
160 | Entry = NodeXForms.size(); |
161 | } |
162 | return Entry-1; |
163 | } |
164 | |
165 | }; |
166 | } // end anonymous namespace. |
167 | |
168 | static std::string GetPatFromTreePatternNode(const TreePatternNode *N) { |
169 | std::string str; |
170 | raw_string_ostream Stream(str); |
171 | Stream << *N; |
172 | Stream.str(); |
173 | return str; |
174 | } |
175 | |
176 | static size_t GetVBRSize(unsigned Val) { |
177 | if (Val <= 127) return 1; |
178 | |
179 | unsigned NumBytes = 0; |
180 | while (Val >= 128) { |
181 | Val >>= 7; |
182 | ++NumBytes; |
183 | } |
184 | return NumBytes+1; |
185 | } |
186 | |
187 | /// EmitVBRValue - Emit the specified value as a VBR, returning the number of |
188 | /// bytes emitted. |
189 | static uint64_t EmitVBRValue(uint64_t Val, raw_ostream &OS) { |
190 | if (Val <= 127) { |
191 | OS << Val << ", "; |
192 | return 1; |
193 | } |
194 | |
195 | uint64_t InVal = Val; |
196 | unsigned NumBytes = 0; |
197 | while (Val >= 128) { |
198 | OS << (Val&127) << "|128,"; |
199 | Val >>= 7; |
200 | ++NumBytes; |
201 | } |
202 | OS << Val; |
203 | if (!OmitComments) |
204 | OS << "/*" << InVal << "*/"; |
205 | OS << ", "; |
206 | return NumBytes+1; |
207 | } |
208 | |
209 | // This is expensive and slow. |
210 | static std::string getIncludePath(const Record *R) { |
211 | std::string str; |
212 | raw_string_ostream Stream(str); |
213 | auto Locs = R->getLoc(); |
214 | SMLoc L; |
215 | if (Locs.size() > 1) { |
216 | // Get where the pattern prototype was instantiated |
217 | L = Locs[1]; |
218 | } else if (Locs.size() == 1) { |
219 | L = Locs[0]; |
220 | } |
221 | unsigned CurBuf = SrcMgr.FindBufferContainingLoc(L); |
222 | assert(CurBuf && "Invalid or unspecified location!")((CurBuf && "Invalid or unspecified location!") ? static_cast <void> (0) : __assert_fail ("CurBuf && \"Invalid or unspecified location!\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 222, __PRETTY_FUNCTION__)); |
223 | |
224 | Stream << SrcMgr.getBufferInfo(CurBuf).Buffer->getBufferIdentifier() << ":" |
225 | << SrcMgr.FindLineNumber(L, CurBuf); |
226 | Stream.str(); |
227 | return str; |
228 | } |
229 | |
230 | /// This function traverses the matcher tree and sizes all the nodes |
231 | /// that are children of the three kinds of nodes that have them. |
232 | unsigned MatcherTableEmitter:: |
233 | SizeMatcherList(Matcher *N, raw_ostream &OS) { |
234 | unsigned Size = 0; |
235 | while (N) { |
236 | Size += SizeMatcher(N, OS); |
237 | N = N->getNext(); |
238 | } |
239 | return Size; |
240 | } |
241 | |
242 | /// This function sizes the children of the three kinds of nodes that |
243 | /// have them. It does so by using special cases for those three |
244 | /// nodes, but sharing the code in EmitMatcher() for the other kinds. |
245 | unsigned MatcherTableEmitter:: |
246 | SizeMatcher(Matcher *N, raw_ostream &OS) { |
247 | unsigned Idx = 0; |
248 | |
249 | ++OpcodeCounts[N->getKind()]; |
250 | switch (N->getKind()) { |
251 | // The Scope matcher has its kind, a series of child size + child, |
252 | // and a trailing zero. |
253 | case Matcher::Scope: { |
254 | ScopeMatcher *SM = cast<ScopeMatcher>(N); |
255 | assert(SM->getNext() == nullptr && "Scope matcher should not have next")((SM->getNext() == nullptr && "Scope matcher should not have next" ) ? static_cast<void> (0) : __assert_fail ("SM->getNext() == nullptr && \"Scope matcher should not have next\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 255, __PRETTY_FUNCTION__)); |
256 | unsigned Size = 1; // Count the kind. |
257 | for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) { |
258 | const size_t ChildSize = SizeMatcherList(SM->getChild(i), OS); |
259 | assert(ChildSize != 0 && "Matcher cannot have child of size 0")((ChildSize != 0 && "Matcher cannot have child of size 0" ) ? static_cast<void> (0) : __assert_fail ("ChildSize != 0 && \"Matcher cannot have child of size 0\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 259, __PRETTY_FUNCTION__)); |
260 | SM->getChild(i)->setSize(ChildSize); |
261 | Size += GetVBRSize(ChildSize) + ChildSize; // Count VBR and child size. |
262 | } |
263 | ++Size; // Count the zero sentinel. |
264 | return Size; |
265 | } |
266 | |
267 | // SwitchOpcode and SwitchType have their kind, a series of child size + |
268 | // opcode/type + child, and a trailing zero. |
269 | case Matcher::SwitchOpcode: |
270 | case Matcher::SwitchType: { |
271 | unsigned Size = 1; // Count the kind. |
272 | unsigned NumCases; |
273 | if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) |
274 | NumCases = SOM->getNumCases(); |
275 | else |
276 | NumCases = cast<SwitchTypeMatcher>(N)->getNumCases(); |
277 | for (unsigned i = 0, e = NumCases; i != e; ++i) { |
278 | Matcher *Child; |
279 | if (SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) { |
280 | Child = SOM->getCaseMatcher(i); |
281 | Size += 2; // Count the child's opcode. |
282 | } else { |
283 | Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i); |
284 | ++Size; // Count the child's type. |
285 | } |
286 | const size_t ChildSize = SizeMatcherList(Child, OS); |
287 | assert(ChildSize != 0 && "Matcher cannot have child of size 0")((ChildSize != 0 && "Matcher cannot have child of size 0" ) ? static_cast<void> (0) : __assert_fail ("ChildSize != 0 && \"Matcher cannot have child of size 0\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 287, __PRETTY_FUNCTION__)); |
288 | Child->setSize(ChildSize); |
289 | Size += GetVBRSize(ChildSize) + ChildSize; // Count VBR and child size. |
290 | } |
291 | ++Size; // Count the zero sentinel. |
292 | return Size; |
293 | } |
294 | |
295 | default: |
296 | // Employ the matcher emitter to size other matchers. |
297 | return EmitMatcher(N, 0, Idx, OS); |
298 | } |
299 | llvm_unreachable("Unreachable")::llvm::llvm_unreachable_internal("Unreachable", "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 299); |
300 | } |
301 | |
302 | static void BeginEmitFunction(raw_ostream &OS, StringRef RetType, |
303 | StringRef Decl, bool AddOverride) { |
304 | OS << "#ifdef GET_DAGISEL_DECL\n"; |
305 | OS << RetType << ' ' << Decl; |
306 | if (AddOverride) |
307 | OS << " override"; |
308 | OS << ";\n" |
309 | "#endif\n" |
310 | "#if defined(GET_DAGISEL_BODY) || DAGISEL_INLINE\n"; |
311 | OS << RetType << " DAGISEL_CLASS_COLONCOLON " << Decl << "\n"; |
312 | if (AddOverride) { |
313 | OS << "#if DAGISEL_INLINE\n" |
314 | " override\n" |
315 | "#endif\n"; |
316 | } |
317 | } |
318 | |
319 | static void EndEmitFunction(raw_ostream &OS) { |
320 | OS << "#endif // GET_DAGISEL_BODY\n\n"; |
321 | } |
322 | |
323 | void MatcherTableEmitter::EmitPatternMatchTable(raw_ostream &OS) { |
324 | |
325 | assert(isUInt<16>(VecPatterns.size()) &&((isUInt<16>(VecPatterns.size()) && "Using only 16 bits to encode offset into Pattern Table" ) ? static_cast<void> (0) : __assert_fail ("isUInt<16>(VecPatterns.size()) && \"Using only 16 bits to encode offset into Pattern Table\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 326, __PRETTY_FUNCTION__)) |
326 | "Using only 16 bits to encode offset into Pattern Table")((isUInt<16>(VecPatterns.size()) && "Using only 16 bits to encode offset into Pattern Table" ) ? static_cast<void> (0) : __assert_fail ("isUInt<16>(VecPatterns.size()) && \"Using only 16 bits to encode offset into Pattern Table\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 326, __PRETTY_FUNCTION__)); |
327 | assert(VecPatterns.size() == VecIncludeStrings.size() &&((VecPatterns.size() == VecIncludeStrings.size() && "The sizes of Pattern and include vectors should be the same" ) ? static_cast<void> (0) : __assert_fail ("VecPatterns.size() == VecIncludeStrings.size() && \"The sizes of Pattern and include vectors should be the same\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 328, __PRETTY_FUNCTION__)) |
328 | "The sizes of Pattern and include vectors should be the same")((VecPatterns.size() == VecIncludeStrings.size() && "The sizes of Pattern and include vectors should be the same" ) ? static_cast<void> (0) : __assert_fail ("VecPatterns.size() == VecIncludeStrings.size() && \"The sizes of Pattern and include vectors should be the same\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 328, __PRETTY_FUNCTION__)); |
329 | |
330 | BeginEmitFunction(OS, "StringRef", "getPatternForIndex(unsigned Index)", |
331 | true/*AddOverride*/); |
332 | OS << "{\n"; |
333 | OS << "static const char *PATTERN_MATCH_TABLE[] = {\n"; |
334 | |
335 | for (const auto &It : VecPatterns) { |
336 | OS << "\"" << It.first << "\",\n"; |
337 | } |
338 | |
339 | OS << "\n};"; |
340 | OS << "\nreturn StringRef(PATTERN_MATCH_TABLE[Index]);"; |
341 | OS << "\n}\n"; |
342 | EndEmitFunction(OS); |
343 | |
344 | BeginEmitFunction(OS, "StringRef", "getIncludePathForIndex(unsigned Index)", |
345 | true/*AddOverride*/); |
346 | OS << "{\n"; |
347 | OS << "static const char *INCLUDE_PATH_TABLE[] = {\n"; |
348 | |
349 | for (const auto &It : VecIncludeStrings) { |
350 | OS << "\"" << It << "\",\n"; |
351 | } |
352 | |
353 | OS << "\n};"; |
354 | OS << "\nreturn StringRef(INCLUDE_PATH_TABLE[Index]);"; |
355 | OS << "\n}\n"; |
356 | EndEmitFunction(OS); |
357 | } |
358 | |
359 | /// EmitMatcher - Emit bytes for the specified matcher and return |
360 | /// the number of bytes emitted. |
361 | unsigned MatcherTableEmitter:: |
362 | EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx, |
363 | raw_ostream &OS) { |
364 | OS.indent(Indent); |
365 | |
366 | switch (N->getKind()) { |
367 | case Matcher::Scope: { |
368 | const ScopeMatcher *SM = cast<ScopeMatcher>(N); |
369 | unsigned StartIdx = CurrentIdx; |
370 | |
371 | // Emit all of the children. |
372 | for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) { |
373 | if (i == 0) { |
374 | OS << "OPC_Scope, "; |
375 | ++CurrentIdx; |
376 | } else { |
377 | if (!OmitComments) { |
378 | OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/"; |
379 | OS.indent(Indent) << "/*Scope*/ "; |
380 | } else |
381 | OS.indent(Indent); |
382 | } |
383 | |
384 | size_t ChildSize = SM->getChild(i)->getSize(); |
385 | size_t VBRSize = GetVBRSize(ChildSize); |
386 | EmitVBRValue(ChildSize, OS); |
387 | if (!OmitComments) { |
388 | OS << "/*->" << CurrentIdx + VBRSize + ChildSize << "*/"; |
389 | if (i == 0) |
390 | OS << " // " << SM->getNumChildren() << " children in Scope"; |
391 | } |
392 | OS << '\n'; |
393 | |
394 | ChildSize = EmitMatcherList(SM->getChild(i), Indent+1, |
395 | CurrentIdx + VBRSize, OS); |
396 | assert(ChildSize == SM->getChild(i)->getSize() &&((ChildSize == SM->getChild(i)->getSize() && "Emitted child size does not match calculated size" ) ? static_cast<void> (0) : __assert_fail ("ChildSize == SM->getChild(i)->getSize() && \"Emitted child size does not match calculated size\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 397, __PRETTY_FUNCTION__)) |
397 | "Emitted child size does not match calculated size")((ChildSize == SM->getChild(i)->getSize() && "Emitted child size does not match calculated size" ) ? static_cast<void> (0) : __assert_fail ("ChildSize == SM->getChild(i)->getSize() && \"Emitted child size does not match calculated size\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 397, __PRETTY_FUNCTION__)); |
398 | CurrentIdx += VBRSize + ChildSize; |
399 | } |
400 | |
401 | // Emit a zero as a sentinel indicating end of 'Scope'. |
402 | if (!OmitComments) |
403 | OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/"; |
404 | OS.indent(Indent) << "0, "; |
405 | if (!OmitComments) |
406 | OS << "/*End of Scope*/"; |
407 | OS << '\n'; |
408 | return CurrentIdx - StartIdx + 1; |
409 | } |
410 | |
411 | case Matcher::RecordNode: |
412 | OS << "OPC_RecordNode,"; |
413 | if (!OmitComments) |
414 | OS << " // #" |
415 | << cast<RecordMatcher>(N)->getResultNo() << " = " |
416 | << cast<RecordMatcher>(N)->getWhatFor(); |
417 | OS << '\n'; |
418 | return 1; |
419 | |
420 | case Matcher::RecordChild: |
421 | OS << "OPC_RecordChild" << cast<RecordChildMatcher>(N)->getChildNo() |
422 | << ','; |
423 | if (!OmitComments) |
424 | OS << " // #" |
425 | << cast<RecordChildMatcher>(N)->getResultNo() << " = " |
426 | << cast<RecordChildMatcher>(N)->getWhatFor(); |
427 | OS << '\n'; |
428 | return 1; |
429 | |
430 | case Matcher::RecordMemRef: |
431 | OS << "OPC_RecordMemRef,\n"; |
432 | return 1; |
433 | |
434 | case Matcher::CaptureGlueInput: |
435 | OS << "OPC_CaptureGlueInput,\n"; |
436 | return 1; |
437 | |
438 | case Matcher::MoveChild: { |
439 | const auto *MCM = cast<MoveChildMatcher>(N); |
440 | |
441 | OS << "OPC_MoveChild"; |
442 | // Handle the specialized forms. |
443 | if (MCM->getChildNo() >= 8) |
444 | OS << ", "; |
445 | OS << MCM->getChildNo() << ",\n"; |
446 | return (MCM->getChildNo() >= 8) ? 2 : 1; |
447 | } |
448 | |
449 | case Matcher::MoveParent: |
450 | OS << "OPC_MoveParent,\n"; |
451 | return 1; |
452 | |
453 | case Matcher::CheckSame: |
454 | OS << "OPC_CheckSame, " |
455 | << cast<CheckSameMatcher>(N)->getMatchNumber() << ",\n"; |
456 | return 2; |
457 | |
458 | case Matcher::CheckChildSame: |
459 | OS << "OPC_CheckChild" |
460 | << cast<CheckChildSameMatcher>(N)->getChildNo() << "Same, " |
461 | << cast<CheckChildSameMatcher>(N)->getMatchNumber() << ",\n"; |
462 | return 2; |
463 | |
464 | case Matcher::CheckPatternPredicate: { |
465 | StringRef Pred =cast<CheckPatternPredicateMatcher>(N)->getPredicate(); |
466 | OS << "OPC_CheckPatternPredicate, " << getPatternPredicate(Pred) << ','; |
467 | if (!OmitComments) |
468 | OS << " // " << Pred; |
469 | OS << '\n'; |
470 | return 2; |
471 | } |
472 | case Matcher::CheckPredicate: { |
473 | TreePredicateFn Pred = cast<CheckPredicateMatcher>(N)->getPredicate(); |
474 | unsigned OperandBytes = 0; |
475 | |
476 | if (Pred.usesOperands()) { |
477 | unsigned NumOps = cast<CheckPredicateMatcher>(N)->getNumOperands(); |
478 | OS << "OPC_CheckPredicateWithOperands, " << NumOps << "/*#Ops*/, "; |
479 | for (unsigned i = 0; i < NumOps; ++i) |
480 | OS << cast<CheckPredicateMatcher>(N)->getOperandNo(i) << ", "; |
481 | OperandBytes = 1 + NumOps; |
482 | } else { |
483 | OS << "OPC_CheckPredicate, "; |
484 | } |
485 | |
486 | OS << getNodePredicate(Pred) << ','; |
487 | if (!OmitComments) |
488 | OS << " // " << Pred.getFnName(); |
489 | OS << '\n'; |
490 | return 2 + OperandBytes; |
491 | } |
492 | |
493 | case Matcher::CheckOpcode: |
494 | OS << "OPC_CheckOpcode, TARGET_VAL(" |
495 | << cast<CheckOpcodeMatcher>(N)->getOpcode().getEnumName() << "),\n"; |
496 | return 3; |
497 | |
498 | case Matcher::SwitchOpcode: |
499 | case Matcher::SwitchType: { |
500 | unsigned StartIdx = CurrentIdx; |
501 | |
502 | unsigned NumCases; |
503 | if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) { |
504 | OS << "OPC_SwitchOpcode "; |
505 | NumCases = SOM->getNumCases(); |
506 | } else { |
507 | OS << "OPC_SwitchType "; |
508 | NumCases = cast<SwitchTypeMatcher>(N)->getNumCases(); |
509 | } |
510 | |
511 | if (!OmitComments) |
512 | OS << "/*" << NumCases << " cases */"; |
513 | OS << ", "; |
514 | ++CurrentIdx; |
515 | |
516 | // For each case we emit the size, then the opcode, then the matcher. |
517 | for (unsigned i = 0, e = NumCases; i != e; ++i) { |
518 | const Matcher *Child; |
519 | unsigned IdxSize; |
520 | if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) { |
521 | Child = SOM->getCaseMatcher(i); |
522 | IdxSize = 2; // size of opcode in table is 2 bytes. |
523 | } else { |
524 | Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i); |
525 | IdxSize = 1; // size of type in table is 1 byte. |
526 | } |
527 | |
528 | if (i != 0) { |
529 | if (!OmitComments) |
530 | OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/"; |
531 | OS.indent(Indent); |
532 | if (!OmitComments) |
533 | OS << (isa<SwitchOpcodeMatcher>(N) ? |
534 | "/*SwitchOpcode*/ " : "/*SwitchType*/ "); |
535 | } |
536 | |
537 | size_t ChildSize = Child->getSize(); |
538 | CurrentIdx += EmitVBRValue(ChildSize, OS) + IdxSize; |
539 | if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) |
540 | OS << "TARGET_VAL(" << SOM->getCaseOpcode(i).getEnumName() << "),"; |
541 | else |
542 | OS << getEnumName(cast<SwitchTypeMatcher>(N)->getCaseType(i)) << ','; |
543 | if (!OmitComments) |
544 | OS << "// ->" << CurrentIdx + ChildSize; |
545 | OS << '\n'; |
546 | |
547 | ChildSize = EmitMatcherList(Child, Indent+1, CurrentIdx, OS); |
548 | assert(ChildSize == Child->getSize() &&((ChildSize == Child->getSize() && "Emitted child size does not match calculated size" ) ? static_cast<void> (0) : __assert_fail ("ChildSize == Child->getSize() && \"Emitted child size does not match calculated size\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 549, __PRETTY_FUNCTION__)) |
549 | "Emitted child size does not match calculated size")((ChildSize == Child->getSize() && "Emitted child size does not match calculated size" ) ? static_cast<void> (0) : __assert_fail ("ChildSize == Child->getSize() && \"Emitted child size does not match calculated size\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 549, __PRETTY_FUNCTION__)); |
550 | CurrentIdx += ChildSize; |
551 | } |
552 | |
553 | // Emit the final zero to terminate the switch. |
554 | if (!OmitComments) |
555 | OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/"; |
556 | OS.indent(Indent) << "0,"; |
557 | if (!OmitComments) |
558 | OS << (isa<SwitchOpcodeMatcher>(N) ? |
559 | " // EndSwitchOpcode" : " // EndSwitchType"); |
560 | |
561 | OS << '\n'; |
562 | return CurrentIdx - StartIdx + 1; |
563 | } |
564 | |
565 | case Matcher::CheckType: |
566 | if (cast<CheckTypeMatcher>(N)->getResNo() == 0) { |
567 | OS << "OPC_CheckType, " |
568 | << getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n"; |
569 | return 2; |
570 | } |
571 | OS << "OPC_CheckTypeRes, " << cast<CheckTypeMatcher>(N)->getResNo() |
572 | << ", " << getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n"; |
573 | return 3; |
574 | |
575 | case Matcher::CheckChildType: |
576 | OS << "OPC_CheckChild" |
577 | << cast<CheckChildTypeMatcher>(N)->getChildNo() << "Type, " |
578 | << getEnumName(cast<CheckChildTypeMatcher>(N)->getType()) << ",\n"; |
579 | return 2; |
580 | |
581 | case Matcher::CheckInteger: { |
582 | OS << "OPC_CheckInteger, "; |
583 | unsigned Bytes=1+EmitVBRValue(cast<CheckIntegerMatcher>(N)->getValue(), OS); |
584 | OS << '\n'; |
585 | return Bytes; |
586 | } |
587 | case Matcher::CheckChildInteger: { |
588 | OS << "OPC_CheckChild" << cast<CheckChildIntegerMatcher>(N)->getChildNo() |
589 | << "Integer, "; |
590 | unsigned Bytes=1+EmitVBRValue(cast<CheckChildIntegerMatcher>(N)->getValue(), |
591 | OS); |
592 | OS << '\n'; |
593 | return Bytes; |
594 | } |
595 | case Matcher::CheckCondCode: |
596 | OS << "OPC_CheckCondCode, ISD::" |
597 | << cast<CheckCondCodeMatcher>(N)->getCondCodeName() << ",\n"; |
598 | return 2; |
599 | |
600 | case Matcher::CheckChild2CondCode: |
601 | OS << "OPC_CheckChild2CondCode, ISD::" |
602 | << cast<CheckChild2CondCodeMatcher>(N)->getCondCodeName() << ",\n"; |
603 | return 2; |
604 | |
605 | case Matcher::CheckValueType: |
606 | OS << "OPC_CheckValueType, MVT::" |
607 | << cast<CheckValueTypeMatcher>(N)->getTypeName() << ",\n"; |
608 | return 2; |
609 | |
610 | case Matcher::CheckComplexPat: { |
611 | const CheckComplexPatMatcher *CCPM = cast<CheckComplexPatMatcher>(N); |
612 | const ComplexPattern &Pattern = CCPM->getPattern(); |
613 | OS << "OPC_CheckComplexPat, /*CP*/" << getComplexPat(Pattern) << ", /*#*/" |
614 | << CCPM->getMatchNumber() << ','; |
615 | |
616 | if (!OmitComments) { |
617 | OS << " // " << Pattern.getSelectFunc(); |
618 | OS << ":$" << CCPM->getName(); |
619 | for (unsigned i = 0, e = Pattern.getNumOperands(); i != e; ++i) |
620 | OS << " #" << CCPM->getFirstResult()+i; |
621 | |
622 | if (Pattern.hasProperty(SDNPHasChain)) |
623 | OS << " + chain result"; |
624 | } |
625 | OS << '\n'; |
626 | return 3; |
627 | } |
628 | |
629 | case Matcher::CheckAndImm: { |
630 | OS << "OPC_CheckAndImm, "; |
631 | unsigned Bytes=1+EmitVBRValue(cast<CheckAndImmMatcher>(N)->getValue(), OS); |
632 | OS << '\n'; |
633 | return Bytes; |
634 | } |
635 | |
636 | case Matcher::CheckOrImm: { |
637 | OS << "OPC_CheckOrImm, "; |
638 | unsigned Bytes = 1+EmitVBRValue(cast<CheckOrImmMatcher>(N)->getValue(), OS); |
639 | OS << '\n'; |
640 | return Bytes; |
641 | } |
642 | |
643 | case Matcher::CheckFoldableChainNode: |
644 | OS << "OPC_CheckFoldableChainNode,\n"; |
645 | return 1; |
646 | |
647 | case Matcher::CheckImmAllOnesV: |
648 | OS << "OPC_CheckImmAllOnesV,\n"; |
649 | return 1; |
650 | |
651 | case Matcher::CheckImmAllZerosV: |
652 | OS << "OPC_CheckImmAllZerosV,\n"; |
653 | return 1; |
654 | |
655 | case Matcher::EmitInteger: { |
656 | int64_t Val = cast<EmitIntegerMatcher>(N)->getValue(); |
657 | OS << "OPC_EmitInteger, " |
658 | << getEnumName(cast<EmitIntegerMatcher>(N)->getVT()) << ", "; |
659 | unsigned Bytes = 2+EmitVBRValue(Val, OS); |
660 | OS << '\n'; |
661 | return Bytes; |
662 | } |
663 | case Matcher::EmitStringInteger: { |
664 | const std::string &Val = cast<EmitStringIntegerMatcher>(N)->getValue(); |
665 | // These should always fit into 7 bits. |
666 | OS << "OPC_EmitInteger, " |
667 | << getEnumName(cast<EmitStringIntegerMatcher>(N)->getVT()) << ", " |
668 | << Val << ",\n"; |
669 | return 3; |
670 | } |
671 | |
672 | case Matcher::EmitRegister: { |
673 | const EmitRegisterMatcher *Matcher = cast<EmitRegisterMatcher>(N); |
674 | const CodeGenRegister *Reg = Matcher->getReg(); |
675 | // If the enum value of the register is larger than one byte can handle, |
676 | // use EmitRegister2. |
677 | if (Reg && Reg->EnumValue > 255) { |
678 | OS << "OPC_EmitRegister2, " << getEnumName(Matcher->getVT()) << ", "; |
679 | OS << "TARGET_VAL(" << getQualifiedName(Reg->TheDef) << "),\n"; |
680 | return 4; |
681 | } else { |
682 | OS << "OPC_EmitRegister, " << getEnumName(Matcher->getVT()) << ", "; |
683 | if (Reg) { |
684 | OS << getQualifiedName(Reg->TheDef) << ",\n"; |
685 | } else { |
686 | OS << "0 "; |
687 | if (!OmitComments) |
688 | OS << "/*zero_reg*/"; |
689 | OS << ",\n"; |
690 | } |
691 | return 3; |
692 | } |
693 | } |
694 | |
695 | case Matcher::EmitConvertToTarget: |
696 | OS << "OPC_EmitConvertToTarget, " |
697 | << cast<EmitConvertToTargetMatcher>(N)->getSlot() << ",\n"; |
698 | return 2; |
699 | |
700 | case Matcher::EmitMergeInputChains: { |
701 | const EmitMergeInputChainsMatcher *MN = |
702 | cast<EmitMergeInputChainsMatcher>(N); |
703 | |
704 | // Handle the specialized forms OPC_EmitMergeInputChains1_0, 1_1, and 1_2. |
705 | if (MN->getNumNodes() == 1 && MN->getNode(0) < 3) { |
706 | OS << "OPC_EmitMergeInputChains1_" << MN->getNode(0) << ",\n"; |
707 | return 1; |
708 | } |
709 | |
710 | OS << "OPC_EmitMergeInputChains, " << MN->getNumNodes() << ", "; |
711 | for (unsigned i = 0, e = MN->getNumNodes(); i != e; ++i) |
712 | OS << MN->getNode(i) << ", "; |
713 | OS << '\n'; |
714 | return 2+MN->getNumNodes(); |
715 | } |
716 | case Matcher::EmitCopyToReg: { |
717 | const auto *C2RMatcher = cast<EmitCopyToRegMatcher>(N); |
718 | int Bytes = 3; |
719 | const CodeGenRegister *Reg = C2RMatcher->getDestPhysReg(); |
720 | if (Reg->EnumValue > 255) { |
721 | assert(isUInt<16>(Reg->EnumValue) && "not handled")((isUInt<16>(Reg->EnumValue) && "not handled" ) ? static_cast<void> (0) : __assert_fail ("isUInt<16>(Reg->EnumValue) && \"not handled\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 721, __PRETTY_FUNCTION__)); |
722 | OS << "OPC_EmitCopyToReg2, " << C2RMatcher->getSrcSlot() << ", " |
723 | << "TARGET_VAL(" << getQualifiedName(Reg->TheDef) << "),\n"; |
724 | ++Bytes; |
725 | } else { |
726 | OS << "OPC_EmitCopyToReg, " << C2RMatcher->getSrcSlot() << ", " |
727 | << getQualifiedName(Reg->TheDef) << ",\n"; |
728 | } |
729 | |
730 | return Bytes; |
731 | } |
732 | case Matcher::EmitNodeXForm: { |
733 | const EmitNodeXFormMatcher *XF = cast<EmitNodeXFormMatcher>(N); |
734 | OS << "OPC_EmitNodeXForm, " << getNodeXFormID(XF->getNodeXForm()) << ", " |
735 | << XF->getSlot() << ','; |
736 | if (!OmitComments) |
737 | OS << " // "<<XF->getNodeXForm()->getName(); |
738 | OS <<'\n'; |
739 | return 3; |
740 | } |
741 | |
742 | case Matcher::EmitNode: |
743 | case Matcher::MorphNodeTo: { |
744 | auto NumCoveredBytes = 0; |
745 | if (InstrumentCoverage) { |
746 | if (const MorphNodeToMatcher *SNT = dyn_cast<MorphNodeToMatcher>(N)) { |
747 | NumCoveredBytes = 3; |
748 | OS << "OPC_Coverage, "; |
749 | std::string src = |
750 | GetPatFromTreePatternNode(SNT->getPattern().getSrcPattern()); |
751 | std::string dst = |
752 | GetPatFromTreePatternNode(SNT->getPattern().getDstPattern()); |
753 | Record *PatRecord = SNT->getPattern().getSrcRecord(); |
754 | std::string include_src = getIncludePath(PatRecord); |
755 | unsigned Offset = |
756 | getPatternIdxFromTable(src + " -> " + dst, std::move(include_src)); |
757 | OS << "TARGET_VAL(" << Offset << "),\n"; |
758 | OS.indent(FullIndexWidth + Indent); |
759 | } |
760 | } |
761 | const EmitNodeMatcherCommon *EN = cast<EmitNodeMatcherCommon>(N); |
762 | OS << (isa<EmitNodeMatcher>(EN) ? "OPC_EmitNode" : "OPC_MorphNodeTo"); |
763 | bool CompressVTs = EN->getNumVTs() < 3; |
764 | if (CompressVTs) |
765 | OS << EN->getNumVTs(); |
766 | |
767 | OS << ", TARGET_VAL(" << EN->getOpcodeName() << "), 0"; |
768 | |
769 | if (EN->hasChain()) OS << "|OPFL_Chain"; |
770 | if (EN->hasInFlag()) OS << "|OPFL_GlueInput"; |
771 | if (EN->hasOutFlag()) OS << "|OPFL_GlueOutput"; |
772 | if (EN->hasMemRefs()) OS << "|OPFL_MemRefs"; |
773 | if (EN->getNumFixedArityOperands() != -1) |
774 | OS << "|OPFL_Variadic" << EN->getNumFixedArityOperands(); |
775 | OS << ",\n"; |
776 | |
777 | OS.indent(FullIndexWidth + Indent+4); |
778 | if (!CompressVTs) { |
779 | OS << EN->getNumVTs(); |
780 | if (!OmitComments) |
781 | OS << "/*#VTs*/"; |
782 | OS << ", "; |
783 | } |
784 | for (unsigned i = 0, e = EN->getNumVTs(); i != e; ++i) |
785 | OS << getEnumName(EN->getVT(i)) << ", "; |
786 | |
787 | OS << EN->getNumOperands(); |
788 | if (!OmitComments) |
789 | OS << "/*#Ops*/"; |
790 | OS << ", "; |
791 | unsigned NumOperandBytes = 0; |
792 | for (unsigned i = 0, e = EN->getNumOperands(); i != e; ++i) |
793 | NumOperandBytes += EmitVBRValue(EN->getOperand(i), OS); |
794 | |
795 | if (!OmitComments) { |
796 | // Print the result #'s for EmitNode. |
797 | if (const EmitNodeMatcher *E = dyn_cast<EmitNodeMatcher>(EN)) { |
798 | if (unsigned NumResults = EN->getNumVTs()) { |
799 | OS << " // Results ="; |
800 | unsigned First = E->getFirstResultSlot(); |
801 | for (unsigned i = 0; i != NumResults; ++i) |
802 | OS << " #" << First+i; |
803 | } |
804 | } |
805 | OS << '\n'; |
806 | |
807 | if (const MorphNodeToMatcher *SNT = dyn_cast<MorphNodeToMatcher>(N)) { |
808 | OS.indent(FullIndexWidth + Indent) << "// Src: " |
809 | << *SNT->getPattern().getSrcPattern() << " - Complexity = " |
810 | << SNT->getPattern().getPatternComplexity(CGP) << '\n'; |
811 | OS.indent(FullIndexWidth + Indent) << "// Dst: " |
812 | << *SNT->getPattern().getDstPattern() << '\n'; |
813 | } |
814 | } else |
815 | OS << '\n'; |
816 | |
817 | return 5 + !CompressVTs + EN->getNumVTs() + NumOperandBytes + |
818 | NumCoveredBytes; |
819 | } |
820 | case Matcher::CompleteMatch: { |
821 | const CompleteMatchMatcher *CM = cast<CompleteMatchMatcher>(N); |
822 | auto NumCoveredBytes = 0; |
823 | if (InstrumentCoverage) { |
824 | NumCoveredBytes = 3; |
825 | OS << "OPC_Coverage, "; |
826 | std::string src = |
827 | GetPatFromTreePatternNode(CM->getPattern().getSrcPattern()); |
828 | std::string dst = |
829 | GetPatFromTreePatternNode(CM->getPattern().getDstPattern()); |
830 | Record *PatRecord = CM->getPattern().getSrcRecord(); |
831 | std::string include_src = getIncludePath(PatRecord); |
832 | unsigned Offset = |
833 | getPatternIdxFromTable(src + " -> " + dst, std::move(include_src)); |
834 | OS << "TARGET_VAL(" << Offset << "),\n"; |
835 | OS.indent(FullIndexWidth + Indent); |
836 | } |
837 | OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", "; |
838 | unsigned NumResultBytes = 0; |
839 | for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i) |
840 | NumResultBytes += EmitVBRValue(CM->getResult(i), OS); |
841 | OS << '\n'; |
842 | if (!OmitComments) { |
843 | OS.indent(FullIndexWidth + Indent) << " // Src: " |
844 | << *CM->getPattern().getSrcPattern() << " - Complexity = " |
845 | << CM->getPattern().getPatternComplexity(CGP) << '\n'; |
846 | OS.indent(FullIndexWidth + Indent) << " // Dst: " |
847 | << *CM->getPattern().getDstPattern(); |
848 | } |
849 | OS << '\n'; |
850 | return 2 + NumResultBytes + NumCoveredBytes; |
851 | } |
852 | } |
853 | llvm_unreachable("Unreachable")::llvm::llvm_unreachable_internal("Unreachable", "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 853); |
854 | } |
855 | |
856 | /// This function traverses the matcher tree and emits all the nodes. |
857 | /// The nodes have already been sized. |
858 | unsigned MatcherTableEmitter:: |
859 | EmitMatcherList(const Matcher *N, const unsigned Indent, unsigned CurrentIdx, |
860 | raw_ostream &OS) { |
861 | unsigned Size = 0; |
862 | while (N) { |
863 | if (!OmitComments) |
864 | OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/"; |
865 | unsigned MatcherSize = EmitMatcher(N, Indent, CurrentIdx, OS); |
866 | Size += MatcherSize; |
867 | CurrentIdx += MatcherSize; |
868 | |
869 | // If there are other nodes in this list, iterate to them, otherwise we're |
870 | // done. |
871 | N = N->getNext(); |
872 | } |
873 | return Size; |
874 | } |
875 | |
876 | void MatcherTableEmitter::EmitNodePredicatesFunction( |
877 | const std::vector<TreePredicateFn> &Preds, StringRef Decl, |
878 | raw_ostream &OS) { |
879 | if (Preds.empty()) |
880 | return; |
881 | |
882 | BeginEmitFunction(OS, "bool", Decl, true/*AddOverride*/); |
883 | OS << "{\n"; |
884 | OS << " switch (PredNo) {\n"; |
885 | OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n"; |
886 | for (unsigned i = 0, e = Preds.size(); i != e; ++i) { |
887 | // Emit the predicate code corresponding to this pattern. |
888 | const TreePredicateFn PredFn = Preds[i]; |
889 | |
890 | assert(!PredFn.isAlwaysTrue() && "No code in this predicate")((!PredFn.isAlwaysTrue() && "No code in this predicate" ) ? static_cast<void> (0) : __assert_fail ("!PredFn.isAlwaysTrue() && \"No code in this predicate\"" , "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 890, __PRETTY_FUNCTION__)); |
891 | OS << " case " << i << ": {\n"; |
892 | for (auto *SimilarPred : |
893 | NodePredicatesByCodeToRun[PredFn.getCodeToRunOnSDNode()]) |
894 | OS << " // " << TreePredicateFn(SimilarPred).getFnName() <<'\n'; |
895 | |
896 | OS << PredFn.getCodeToRunOnSDNode() << "\n }\n"; |
897 | } |
898 | OS << " }\n"; |
899 | OS << "}\n"; |
900 | EndEmitFunction(OS); |
901 | } |
902 | |
903 | void MatcherTableEmitter::EmitPredicateFunctions(raw_ostream &OS) { |
904 | // Emit pattern predicates. |
905 | if (!PatternPredicates.empty()) { |
906 | BeginEmitFunction(OS, "bool", |
907 | "CheckPatternPredicate(unsigned PredNo) const", true/*AddOverride*/); |
908 | OS << "{\n"; |
909 | OS << " switch (PredNo) {\n"; |
910 | OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n"; |
911 | for (unsigned i = 0, e = PatternPredicates.size(); i != e; ++i) |
912 | OS << " case " << i << ": return " << PatternPredicates[i] << ";\n"; |
913 | OS << " }\n"; |
914 | OS << "}\n"; |
915 | EndEmitFunction(OS); |
916 | } |
917 | |
918 | // Emit Node predicates. |
919 | EmitNodePredicatesFunction( |
920 | NodePredicates, "CheckNodePredicate(SDNode *Node, unsigned PredNo) const", |
921 | OS); |
922 | EmitNodePredicatesFunction( |
923 | NodePredicatesWithOperands, |
924 | "CheckNodePredicateWithOperands(SDNode *Node, unsigned PredNo, " |
925 | "const SmallVectorImpl<SDValue> &Operands) const", |
926 | OS); |
927 | |
928 | // Emit CompletePattern matchers. |
929 | // FIXME: This should be const. |
930 | if (!ComplexPatterns.empty()) { |
931 | BeginEmitFunction(OS, "bool", |
932 | "CheckComplexPattern(SDNode *Root, SDNode *Parent,\n" |
933 | " SDValue N, unsigned PatternNo,\n" |
934 | " SmallVectorImpl<std::pair<SDValue, SDNode *>> &Result)", |
935 | true/*AddOverride*/); |
936 | OS << "{\n"; |
937 | OS << " unsigned NextRes = Result.size();\n"; |
938 | OS << " switch (PatternNo) {\n"; |
939 | OS << " default: llvm_unreachable(\"Invalid pattern # in table?\");\n"; |
940 | for (unsigned i = 0, e = ComplexPatterns.size(); i != e; ++i) { |
941 | const ComplexPattern &P = *ComplexPatterns[i]; |
942 | unsigned NumOps = P.getNumOperands(); |
943 | |
944 | if (P.hasProperty(SDNPHasChain)) |
945 | ++NumOps; // Get the chained node too. |
946 | |
947 | OS << " case " << i << ":\n"; |
948 | if (InstrumentCoverage) |
949 | OS << " {\n"; |
950 | OS << " Result.resize(NextRes+" << NumOps << ");\n"; |
951 | if (InstrumentCoverage) |
952 | OS << " bool Succeeded = " << P.getSelectFunc(); |
953 | else |
954 | OS << " return " << P.getSelectFunc(); |
955 | |
956 | OS << "("; |
957 | // If the complex pattern wants the root of the match, pass it in as the |
958 | // first argument. |
959 | if (P.hasProperty(SDNPWantRoot)) |
960 | OS << "Root, "; |
961 | |
962 | // If the complex pattern wants the parent of the operand being matched, |
963 | // pass it in as the next argument. |
964 | if (P.hasProperty(SDNPWantParent)) |
965 | OS << "Parent, "; |
966 | |
967 | OS << "N"; |
968 | for (unsigned i = 0; i != NumOps; ++i) |
969 | OS << ", Result[NextRes+" << i << "].first"; |
970 | OS << ");\n"; |
971 | if (InstrumentCoverage) { |
972 | OS << " if (Succeeded)\n"; |
973 | OS << " dbgs() << \"\\nCOMPLEX_PATTERN: " << P.getSelectFunc() |
974 | << "\\n\" ;\n"; |
975 | OS << " return Succeeded;\n"; |
976 | OS << " }\n"; |
977 | } |
978 | } |
979 | OS << " }\n"; |
980 | OS << "}\n"; |
981 | EndEmitFunction(OS); |
982 | } |
983 | |
984 | |
985 | // Emit SDNodeXForm handlers. |
986 | // FIXME: This should be const. |
987 | if (!NodeXForms.empty()) { |
988 | BeginEmitFunction(OS, "SDValue", |
989 | "RunSDNodeXForm(SDValue V, unsigned XFormNo)", true/*AddOverride*/); |
990 | OS << "{\n"; |
991 | OS << " switch (XFormNo) {\n"; |
992 | OS << " default: llvm_unreachable(\"Invalid xform # in table?\");\n"; |
993 | |
994 | // FIXME: The node xform could take SDValue's instead of SDNode*'s. |
995 | for (unsigned i = 0, e = NodeXForms.size(); i != e; ++i) { |
996 | const CodeGenDAGPatterns::NodeXForm &Entry = |
997 | CGP.getSDNodeTransform(NodeXForms[i]); |
998 | |
999 | Record *SDNode = Entry.first; |
1000 | const std::string &Code = Entry.second; |
1001 | |
1002 | OS << " case " << i << ": { "; |
1003 | if (!OmitComments) |
1004 | OS << "// " << NodeXForms[i]->getName(); |
1005 | OS << '\n'; |
1006 | |
1007 | std::string ClassName = |
1008 | std::string(CGP.getSDNodeInfo(SDNode).getSDClassName()); |
1009 | if (ClassName == "SDNode") |
1010 | OS << " SDNode *N = V.getNode();\n"; |
1011 | else |
1012 | OS << " " << ClassName << " *N = cast<" << ClassName |
1013 | << ">(V.getNode());\n"; |
1014 | OS << Code << "\n }\n"; |
1015 | } |
1016 | OS << " }\n"; |
1017 | OS << "}\n"; |
1018 | EndEmitFunction(OS); |
1019 | } |
1020 | } |
1021 | |
1022 | static StringRef getOpcodeString(Matcher::KindTy Kind) { |
1023 | switch (Kind) { |
1024 | case Matcher::Scope: return "OPC_Scope"; break; |
1025 | case Matcher::RecordNode: return "OPC_RecordNode"; break; |
1026 | case Matcher::RecordChild: return "OPC_RecordChild"; break; |
1027 | case Matcher::RecordMemRef: return "OPC_RecordMemRef"; break; |
1028 | case Matcher::CaptureGlueInput: return "OPC_CaptureGlueInput"; break; |
1029 | case Matcher::MoveChild: return "OPC_MoveChild"; break; |
1030 | case Matcher::MoveParent: return "OPC_MoveParent"; break; |
1031 | case Matcher::CheckSame: return "OPC_CheckSame"; break; |
1032 | case Matcher::CheckChildSame: return "OPC_CheckChildSame"; break; |
1033 | case Matcher::CheckPatternPredicate: |
1034 | return "OPC_CheckPatternPredicate"; break; |
1035 | case Matcher::CheckPredicate: return "OPC_CheckPredicate"; break; |
1036 | case Matcher::CheckOpcode: return "OPC_CheckOpcode"; break; |
1037 | case Matcher::SwitchOpcode: return "OPC_SwitchOpcode"; break; |
1038 | case Matcher::CheckType: return "OPC_CheckType"; break; |
1039 | case Matcher::SwitchType: return "OPC_SwitchType"; break; |
1040 | case Matcher::CheckChildType: return "OPC_CheckChildType"; break; |
1041 | case Matcher::CheckInteger: return "OPC_CheckInteger"; break; |
1042 | case Matcher::CheckChildInteger: return "OPC_CheckChildInteger"; break; |
1043 | case Matcher::CheckCondCode: return "OPC_CheckCondCode"; break; |
1044 | case Matcher::CheckChild2CondCode: return "OPC_CheckChild2CondCode"; break; |
1045 | case Matcher::CheckValueType: return "OPC_CheckValueType"; break; |
1046 | case Matcher::CheckComplexPat: return "OPC_CheckComplexPat"; break; |
1047 | case Matcher::CheckAndImm: return "OPC_CheckAndImm"; break; |
1048 | case Matcher::CheckOrImm: return "OPC_CheckOrImm"; break; |
1049 | case Matcher::CheckFoldableChainNode: |
1050 | return "OPC_CheckFoldableChainNode"; break; |
1051 | case Matcher::CheckImmAllOnesV: return "OPC_CheckImmAllOnesV"; break; |
1052 | case Matcher::CheckImmAllZerosV: return "OPC_CheckImmAllZerosV"; break; |
1053 | case Matcher::EmitInteger: return "OPC_EmitInteger"; break; |
1054 | case Matcher::EmitStringInteger: return "OPC_EmitStringInteger"; break; |
1055 | case Matcher::EmitRegister: return "OPC_EmitRegister"; break; |
1056 | case Matcher::EmitConvertToTarget: return "OPC_EmitConvertToTarget"; break; |
1057 | case Matcher::EmitMergeInputChains: return "OPC_EmitMergeInputChains"; break; |
1058 | case Matcher::EmitCopyToReg: return "OPC_EmitCopyToReg"; break; |
1059 | case Matcher::EmitNode: return "OPC_EmitNode"; break; |
1060 | case Matcher::MorphNodeTo: return "OPC_MorphNodeTo"; break; |
1061 | case Matcher::EmitNodeXForm: return "OPC_EmitNodeXForm"; break; |
1062 | case Matcher::CompleteMatch: return "OPC_CompleteMatch"; break; |
1063 | } |
1064 | |
1065 | llvm_unreachable("Unhandled opcode?")::llvm::llvm_unreachable_internal("Unhandled opcode?", "/build/llvm-toolchain-snapshot-12~++20210125100614+2cdb34efdac5/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp" , 1065); |
1066 | } |
1067 | |
1068 | void MatcherTableEmitter::EmitHistogram(const Matcher *M, |
1069 | raw_ostream &OS) { |
1070 | if (OmitComments) |
1071 | return; |
1072 | |
1073 | OS << " // Opcode Histogram:\n"; |
1074 | for (unsigned i = 0, e = OpcodeCounts.size(); i != e; ++i) { |
1075 | OS << " // #" |
1076 | << left_justify(getOpcodeString((Matcher::KindTy)i), HistOpcWidth) |
1077 | << " = " << OpcodeCounts[i] << '\n'; |
1078 | } |
1079 | OS << '\n'; |
1080 | } |
1081 | |
1082 | |
1083 | void llvm::EmitMatcherTable(Matcher *TheMatcher, |
1084 | const CodeGenDAGPatterns &CGP, |
1085 | raw_ostream &OS) { |
1086 | OS << "#if defined(GET_DAGISEL_DECL) && defined(GET_DAGISEL_BODY)\n"; |
1087 | OS << "#error GET_DAGISEL_DECL and GET_DAGISEL_BODY cannot be both defined, "; |
1088 | OS << "undef both for inline definitions\n"; |
1089 | OS << "#endif\n\n"; |
1090 | |
1091 | // Emit a check for omitted class name. |
1092 | OS << "#ifdef GET_DAGISEL_BODY\n"; |
1093 | OS << "#define LOCAL_DAGISEL_STRINGIZE(X) LOCAL_DAGISEL_STRINGIZE_(X)\n"; |
1094 | OS << "#define LOCAL_DAGISEL_STRINGIZE_(X) #X\n"; |
1095 | OS << "static_assert(sizeof(LOCAL_DAGISEL_STRINGIZE(GET_DAGISEL_BODY)) > 1," |
1096 | "\n"; |
1097 | OS << " \"GET_DAGISEL_BODY is empty: it should be defined with the class " |
1098 | "name\");\n"; |
1099 | OS << "#undef LOCAL_DAGISEL_STRINGIZE_\n"; |
1100 | OS << "#undef LOCAL_DAGISEL_STRINGIZE\n"; |
1101 | OS << "#endif\n\n"; |
1102 | |
1103 | OS << "#if !defined(GET_DAGISEL_DECL) && !defined(GET_DAGISEL_BODY)\n"; |
1104 | OS << "#define DAGISEL_INLINE 1\n"; |
1105 | OS << "#else\n"; |
1106 | OS << "#define DAGISEL_INLINE 0\n"; |
1107 | OS << "#endif\n\n"; |
1108 | |
1109 | OS << "#if !DAGISEL_INLINE\n"; |
1110 | OS << "#define DAGISEL_CLASS_COLONCOLON GET_DAGISEL_BODY ::\n"; |
1111 | OS << "#else\n"; |
1112 | OS << "#define DAGISEL_CLASS_COLONCOLON\n"; |
1113 | OS << "#endif\n\n"; |
1114 | |
1115 | BeginEmitFunction(OS, "void", "SelectCode(SDNode *N)", false/*AddOverride*/); |
1116 | MatcherTableEmitter MatcherEmitter(CGP); |
1117 | |
1118 | // First we size all the children of the three kinds of matchers that have |
1119 | // them. This is done by sharing the code in EmitMatcher(). but we don't |
1120 | // want to emit anything, so we turn off comments and use a null stream. |
1121 | bool SaveOmitComments = OmitComments; |
1122 | OmitComments = true; |
1123 | raw_null_ostream NullOS; |
1124 | unsigned TotalSize = MatcherEmitter.SizeMatcherList(TheMatcher, NullOS); |
Value stored to 'TotalSize' during its initialization is never read | |
1125 | OmitComments = SaveOmitComments; |
1126 | |
1127 | // Now that the matchers are sized, we can emit the code for them to the |
1128 | // final stream. |
1129 | OS << "{\n"; |
1130 | OS << " // Some target values are emitted as 2 bytes, TARGET_VAL handles\n"; |
1131 | OS << " // this.\n"; |
1132 | OS << " #define TARGET_VAL(X) X & 255, unsigned(X) >> 8\n"; |
1133 | OS << " static const unsigned char MatcherTable[] = {\n"; |
1134 | TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 1, 0, OS); |
1135 | OS << " 0\n }; // Total Array size is " << (TotalSize+1) << " bytes\n\n"; |
1136 | |
1137 | MatcherEmitter.EmitHistogram(TheMatcher, OS); |
1138 | |
1139 | OS << " #undef TARGET_VAL\n"; |
1140 | OS << " SelectCodeCommon(N, MatcherTable,sizeof(MatcherTable));\n"; |
1141 | OS << "}\n"; |
1142 | EndEmitFunction(OS); |
1143 | |
1144 | // Next up, emit the function for node and pattern predicates: |
1145 | MatcherEmitter.EmitPredicateFunctions(OS); |
1146 | |
1147 | if (InstrumentCoverage) |
1148 | MatcherEmitter.EmitPatternMatchTable(OS); |
1149 | |
1150 | // Clean up the preprocessor macros. |
1151 | OS << "\n"; |
1152 | OS << "#ifdef DAGISEL_INLINE\n"; |
1153 | OS << "#undef DAGISEL_INLINE\n"; |
1154 | OS << "#endif\n"; |
1155 | OS << "#ifdef DAGISEL_CLASS_COLONCOLON\n"; |
1156 | OS << "#undef DAGISEL_CLASS_COLONCOLON\n"; |
1157 | OS << "#endif\n"; |
1158 | OS << "#ifdef GET_DAGISEL_DECL\n"; |
1159 | OS << "#undef GET_DAGISEL_DECL\n"; |
1160 | OS << "#endif\n"; |
1161 | OS << "#ifdef GET_DAGISEL_BODY\n"; |
1162 | OS << "#undef GET_DAGISEL_BODY\n"; |
1163 | OS << "#endif\n"; |
1164 | } |