xref: /freebsd-src/contrib/llvm-project/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- DAGISelMatcherEmitter.cpp - Matcher Emitter ------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file contains code to generate C++ code for a matcher.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
13*0fca6ea1SDimitry Andric #include "Basic/SDNodeProperties.h"
14*0fca6ea1SDimitry Andric #include "Common/CodeGenDAGPatterns.h"
15*0fca6ea1SDimitry Andric #include "Common/CodeGenInstruction.h"
16*0fca6ea1SDimitry Andric #include "Common/CodeGenRegisters.h"
17*0fca6ea1SDimitry Andric #include "Common/CodeGenTarget.h"
18*0fca6ea1SDimitry Andric #include "Common/DAGISelMatcher.h"
190b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
200b57cec5SDimitry Andric #include "llvm/ADT/MapVector.h"
210b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h"
220b57cec5SDimitry Andric #include "llvm/ADT/TinyPtrVector.h"
230b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
240b57cec5SDimitry Andric #include "llvm/Support/Format.h"
250b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h"
260b57cec5SDimitry Andric #include "llvm/TableGen/Error.h"
270b57cec5SDimitry Andric #include "llvm/TableGen/Record.h"
28e8d8bef9SDimitry Andric 
290b57cec5SDimitry Andric using namespace llvm;
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric enum {
320b57cec5SDimitry Andric   IndexWidth = 6,
330b57cec5SDimitry Andric   FullIndexWidth = IndexWidth + 4,
340b57cec5SDimitry Andric   HistOpcWidth = 40,
350b57cec5SDimitry Andric };
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric cl::OptionCategory DAGISelCat("Options for -gen-dag-isel");
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric // To reduce generated source code size.
400b57cec5SDimitry Andric static cl::opt<bool> OmitComments("omit-comments",
410b57cec5SDimitry Andric                                   cl::desc("Do not generate comments"),
420b57cec5SDimitry Andric                                   cl::init(false), cl::cat(DAGISelCat));
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric static cl::opt<bool> InstrumentCoverage(
450b57cec5SDimitry Andric     "instrument-coverage",
460b57cec5SDimitry Andric     cl::desc("Generates tables to help identify patterns matched"),
470b57cec5SDimitry Andric     cl::init(false), cl::cat(DAGISelCat));
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric namespace {
500b57cec5SDimitry Andric class MatcherTableEmitter {
510b57cec5SDimitry Andric   const CodeGenDAGPatterns &CGP;
520b57cec5SDimitry Andric 
53e8d8bef9SDimitry Andric   SmallVector<unsigned, Matcher::HighestKind + 1> OpcodeCounts;
54e8d8bef9SDimitry Andric 
557a6dacacSDimitry Andric   std::vector<TreePattern *> NodePredicates;
567a6dacacSDimitry Andric   std::vector<TreePattern *> NodePredicatesWithOperands;
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric   // We de-duplicate the predicates by code string, and use this map to track
590b57cec5SDimitry Andric   // all the patterns with "identical" predicates.
60b3edf446SDimitry Andric   MapVector<std::string, TinyPtrVector<TreePattern *>, StringMap<unsigned>>
61b3edf446SDimitry Andric       NodePredicatesByCodeToRun;
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric   std::vector<std::string> PatternPredicates;
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   std::vector<const ComplexPattern *> ComplexPatterns;
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric   DenseMap<Record *, unsigned> NodeXFormMap;
680b57cec5SDimitry Andric   std::vector<Record *> NodeXForms;
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   std::vector<std::string> VecIncludeStrings;
710b57cec5SDimitry Andric   MapVector<std::string, unsigned, StringMap<unsigned>> VecPatterns;
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   unsigned getPatternIdxFromTable(std::string &&P, std::string &&include_loc) {
740b57cec5SDimitry Andric     const auto It = VecPatterns.find(P);
750b57cec5SDimitry Andric     if (It == VecPatterns.end()) {
76*0fca6ea1SDimitry Andric       VecPatterns.insert(std::pair(std::move(P), VecPatterns.size()));
770b57cec5SDimitry Andric       VecIncludeStrings.push_back(std::move(include_loc));
780b57cec5SDimitry Andric       return VecIncludeStrings.size() - 1;
790b57cec5SDimitry Andric     }
800b57cec5SDimitry Andric     return It->second;
810b57cec5SDimitry Andric   }
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric public:
84297eecfbSDimitry Andric   MatcherTableEmitter(const Matcher *TheMatcher, const CodeGenDAGPatterns &cgp)
85297eecfbSDimitry Andric       : CGP(cgp), OpcodeCounts(Matcher::HighestKind + 1, 0) {
86297eecfbSDimitry Andric     // Record the usage of ComplexPattern.
877a6dacacSDimitry Andric     MapVector<const ComplexPattern *, unsigned> ComplexPatternUsage;
88297eecfbSDimitry Andric     // Record the usage of PatternPredicate.
897a6dacacSDimitry Andric     MapVector<StringRef, unsigned> PatternPredicateUsage;
907a6dacacSDimitry Andric     // Record the usage of Predicate.
917a6dacacSDimitry Andric     MapVector<TreePattern *, unsigned> PredicateUsage;
92297eecfbSDimitry Andric 
93297eecfbSDimitry Andric     // Iterate the whole MatcherTable once and do some statistics.
94297eecfbSDimitry Andric     std::function<void(const Matcher *)> Statistic = [&](const Matcher *N) {
95297eecfbSDimitry Andric       while (N) {
96297eecfbSDimitry Andric         if (auto *SM = dyn_cast<ScopeMatcher>(N))
97297eecfbSDimitry Andric           for (unsigned I = 0; I < SM->getNumChildren(); I++)
98297eecfbSDimitry Andric             Statistic(SM->getChild(I));
99297eecfbSDimitry Andric         else if (auto *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
100297eecfbSDimitry Andric           for (unsigned I = 0; I < SOM->getNumCases(); I++)
101297eecfbSDimitry Andric             Statistic(SOM->getCaseMatcher(I));
102297eecfbSDimitry Andric         else if (auto *STM = dyn_cast<SwitchTypeMatcher>(N))
103297eecfbSDimitry Andric           for (unsigned I = 0; I < STM->getNumCases(); I++)
104297eecfbSDimitry Andric             Statistic(STM->getCaseMatcher(I));
105297eecfbSDimitry Andric         else if (auto *CPM = dyn_cast<CheckComplexPatMatcher>(N))
106297eecfbSDimitry Andric           ++ComplexPatternUsage[&CPM->getPattern()];
107297eecfbSDimitry Andric         else if (auto *CPPM = dyn_cast<CheckPatternPredicateMatcher>(N))
108297eecfbSDimitry Andric           ++PatternPredicateUsage[CPPM->getPredicate()];
1097a6dacacSDimitry Andric         else if (auto *PM = dyn_cast<CheckPredicateMatcher>(N))
1107a6dacacSDimitry Andric           ++PredicateUsage[PM->getPredicate().getOrigPatFragRecord()];
111297eecfbSDimitry Andric         N = N->getNext();
112297eecfbSDimitry Andric       }
113297eecfbSDimitry Andric     };
114297eecfbSDimitry Andric     Statistic(TheMatcher);
115297eecfbSDimitry Andric 
116297eecfbSDimitry Andric     // Sort ComplexPatterns by usage.
117297eecfbSDimitry Andric     std::vector<std::pair<const ComplexPattern *, unsigned>> ComplexPatternList(
118297eecfbSDimitry Andric         ComplexPatternUsage.begin(), ComplexPatternUsage.end());
1197a6dacacSDimitry Andric     stable_sort(ComplexPatternList, [](const auto &A, const auto &B) {
1207a6dacacSDimitry Andric       return A.second > B.second;
1217a6dacacSDimitry Andric     });
122297eecfbSDimitry Andric     for (const auto &ComplexPattern : ComplexPatternList)
123297eecfbSDimitry Andric       ComplexPatterns.push_back(ComplexPattern.first);
124297eecfbSDimitry Andric 
125297eecfbSDimitry Andric     // Sort PatternPredicates by usage.
126297eecfbSDimitry Andric     std::vector<std::pair<std::string, unsigned>> PatternPredicateList(
127297eecfbSDimitry Andric         PatternPredicateUsage.begin(), PatternPredicateUsage.end());
1287a6dacacSDimitry Andric     stable_sort(PatternPredicateList, [](const auto &A, const auto &B) {
1297a6dacacSDimitry Andric       return A.second > B.second;
1307a6dacacSDimitry Andric     });
131297eecfbSDimitry Andric     for (const auto &PatternPredicate : PatternPredicateList)
132297eecfbSDimitry Andric       PatternPredicates.push_back(PatternPredicate.first);
1337a6dacacSDimitry Andric 
1347a6dacacSDimitry Andric     // Sort Predicates by usage.
1357a6dacacSDimitry Andric     // Merge predicates with same code.
1367a6dacacSDimitry Andric     for (const auto &Usage : PredicateUsage) {
1377a6dacacSDimitry Andric       TreePattern *TP = Usage.first;
1387a6dacacSDimitry Andric       TreePredicateFn Pred(TP);
1397a6dacacSDimitry Andric       NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode()].push_back(TP);
1407a6dacacSDimitry Andric     }
1417a6dacacSDimitry Andric 
1427a6dacacSDimitry Andric     std::vector<std::pair<TreePattern *, unsigned>> PredicateList;
1437a6dacacSDimitry Andric     // Sum the usage.
1447a6dacacSDimitry Andric     for (auto &Predicate : NodePredicatesByCodeToRun) {
1457a6dacacSDimitry Andric       TinyPtrVector<TreePattern *> &TPs = Predicate.second;
1467a6dacacSDimitry Andric       stable_sort(TPs, [](const auto *A, const auto *B) {
1477a6dacacSDimitry Andric         return A->getRecord()->getName() < B->getRecord()->getName();
1487a6dacacSDimitry Andric       });
1497a6dacacSDimitry Andric       unsigned Uses = 0;
1507a6dacacSDimitry Andric       for (TreePattern *TP : TPs)
1517a6dacacSDimitry Andric         Uses += PredicateUsage[TP];
1527a6dacacSDimitry Andric 
1537a6dacacSDimitry Andric       // We only add the first predicate here since they are with the same code.
1547a6dacacSDimitry Andric       PredicateList.push_back({TPs[0], Uses});
1557a6dacacSDimitry Andric     }
1567a6dacacSDimitry Andric 
1577a6dacacSDimitry Andric     stable_sort(PredicateList, [](const auto &A, const auto &B) {
1587a6dacacSDimitry Andric       return A.second > B.second;
1597a6dacacSDimitry Andric     });
1607a6dacacSDimitry Andric     for (const auto &Predicate : PredicateList) {
1617a6dacacSDimitry Andric       TreePattern *TP = Predicate.first;
1627a6dacacSDimitry Andric       if (TreePredicateFn(TP).usesOperands())
1637a6dacacSDimitry Andric         NodePredicatesWithOperands.push_back(TP);
1647a6dacacSDimitry Andric       else
1657a6dacacSDimitry Andric         NodePredicates.push_back(TP);
1667a6dacacSDimitry Andric     }
167297eecfbSDimitry Andric   }
1680b57cec5SDimitry Andric 
169e8d8bef9SDimitry Andric   unsigned EmitMatcherList(const Matcher *N, const unsigned Indent,
1700b57cec5SDimitry Andric                            unsigned StartIdx, raw_ostream &OS);
1710b57cec5SDimitry Andric 
172e8d8bef9SDimitry Andric   unsigned SizeMatcherList(Matcher *N, raw_ostream &OS);
173e8d8bef9SDimitry Andric 
1740b57cec5SDimitry Andric   void EmitPredicateFunctions(raw_ostream &OS);
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric   void EmitHistogram(const Matcher *N, raw_ostream &OS);
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric   void EmitPatternMatchTable(raw_ostream &OS);
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric private:
1817a6dacacSDimitry Andric   void EmitNodePredicatesFunction(const std::vector<TreePattern *> &Preds,
1820b57cec5SDimitry Andric                                   StringRef Decl, raw_ostream &OS);
1830b57cec5SDimitry Andric 
184e8d8bef9SDimitry Andric   unsigned SizeMatcher(Matcher *N, raw_ostream &OS);
185e8d8bef9SDimitry Andric 
186*0fca6ea1SDimitry Andric   unsigned EmitMatcher(const Matcher *N, const unsigned Indent,
187*0fca6ea1SDimitry Andric                        unsigned CurrentIdx, raw_ostream &OS);
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric   unsigned getNodePredicate(TreePredicateFn Pred) {
1907a6dacacSDimitry Andric     // We use the first predicate.
1917a6dacacSDimitry Andric     TreePattern *PredPat =
1927a6dacacSDimitry Andric         NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode()][0];
1937a6dacacSDimitry Andric     return Pred.usesOperands()
1947a6dacacSDimitry Andric                ? llvm::find(NodePredicatesWithOperands, PredPat) -
1957a6dacacSDimitry Andric                      NodePredicatesWithOperands.begin()
1967a6dacacSDimitry Andric                : llvm::find(NodePredicates, PredPat) - NodePredicates.begin();
1970b57cec5SDimitry Andric   }
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric   unsigned getPatternPredicate(StringRef PredName) {
200297eecfbSDimitry Andric     return llvm::find(PatternPredicates, PredName) - PatternPredicates.begin();
2010b57cec5SDimitry Andric   }
2020b57cec5SDimitry Andric   unsigned getComplexPat(const ComplexPattern &P) {
203297eecfbSDimitry Andric     return llvm::find(ComplexPatterns, &P) - ComplexPatterns.begin();
2040b57cec5SDimitry Andric   }
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric   unsigned getNodeXFormID(Record *Rec) {
2070b57cec5SDimitry Andric     unsigned &Entry = NodeXFormMap[Rec];
2080b57cec5SDimitry Andric     if (Entry == 0) {
2090b57cec5SDimitry Andric       NodeXForms.push_back(Rec);
2100b57cec5SDimitry Andric       Entry = NodeXForms.size();
2110b57cec5SDimitry Andric     }
2120b57cec5SDimitry Andric     return Entry - 1;
2130b57cec5SDimitry Andric   }
2140b57cec5SDimitry Andric };
2150b57cec5SDimitry Andric } // end anonymous namespace.
2160b57cec5SDimitry Andric 
217*0fca6ea1SDimitry Andric static std::string GetPatFromTreePatternNode(const TreePatternNode &N) {
2180b57cec5SDimitry Andric   std::string str;
2190b57cec5SDimitry Andric   raw_string_ostream Stream(str);
220*0fca6ea1SDimitry Andric   Stream << N;
2210b57cec5SDimitry Andric   return str;
2220b57cec5SDimitry Andric }
2230b57cec5SDimitry Andric 
224fe6060f1SDimitry Andric static unsigned GetVBRSize(unsigned Val) {
225*0fca6ea1SDimitry Andric   if (Val <= 127)
226*0fca6ea1SDimitry Andric     return 1;
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric   unsigned NumBytes = 0;
2290b57cec5SDimitry Andric   while (Val >= 128) {
2300b57cec5SDimitry Andric     Val >>= 7;
2310b57cec5SDimitry Andric     ++NumBytes;
2320b57cec5SDimitry Andric   }
2330b57cec5SDimitry Andric   return NumBytes + 1;
2340b57cec5SDimitry Andric }
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric /// EmitVBRValue - Emit the specified value as a VBR, returning the number of
2370b57cec5SDimitry Andric /// bytes emitted.
238fe6060f1SDimitry Andric static unsigned EmitVBRValue(uint64_t Val, raw_ostream &OS) {
2390b57cec5SDimitry Andric   if (Val <= 127) {
2400b57cec5SDimitry Andric     OS << Val << ", ";
2410b57cec5SDimitry Andric     return 1;
2420b57cec5SDimitry Andric   }
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric   uint64_t InVal = Val;
2450b57cec5SDimitry Andric   unsigned NumBytes = 0;
2460b57cec5SDimitry Andric   while (Val >= 128) {
2470b57cec5SDimitry Andric     OS << (Val & 127) << "|128,";
2480b57cec5SDimitry Andric     Val >>= 7;
2490b57cec5SDimitry Andric     ++NumBytes;
2500b57cec5SDimitry Andric   }
2510b57cec5SDimitry Andric   OS << Val;
2520b57cec5SDimitry Andric   if (!OmitComments)
2530b57cec5SDimitry Andric     OS << "/*" << InVal << "*/";
2540b57cec5SDimitry Andric   OS << ", ";
2550b57cec5SDimitry Andric   return NumBytes + 1;
2560b57cec5SDimitry Andric }
2570b57cec5SDimitry Andric 
258fe6060f1SDimitry Andric /// Emit the specified signed value as a VBR. To improve compression we encode
259fe6060f1SDimitry Andric /// positive numbers shifted left by 1 and negative numbers negated and shifted
260fe6060f1SDimitry Andric /// left by 1 with bit 0 set.
261fe6060f1SDimitry Andric static unsigned EmitSignedVBRValue(uint64_t Val, raw_ostream &OS) {
262fe6060f1SDimitry Andric   if ((int64_t)Val >= 0)
263fe6060f1SDimitry Andric     Val = Val << 1;
264fe6060f1SDimitry Andric   else
265fe6060f1SDimitry Andric     Val = (-Val << 1) | 1;
266fe6060f1SDimitry Andric 
267fe6060f1SDimitry Andric   return EmitVBRValue(Val, OS);
268fe6060f1SDimitry Andric }
269fe6060f1SDimitry Andric 
2700b57cec5SDimitry Andric // This is expensive and slow.
2710b57cec5SDimitry Andric static std::string getIncludePath(const Record *R) {
2720b57cec5SDimitry Andric   std::string str;
2730b57cec5SDimitry Andric   raw_string_ostream Stream(str);
2740b57cec5SDimitry Andric   auto Locs = R->getLoc();
2750b57cec5SDimitry Andric   SMLoc L;
2760b57cec5SDimitry Andric   if (Locs.size() > 1) {
2770b57cec5SDimitry Andric     // Get where the pattern prototype was instantiated
2780b57cec5SDimitry Andric     L = Locs[1];
2790b57cec5SDimitry Andric   } else if (Locs.size() == 1) {
2800b57cec5SDimitry Andric     L = Locs[0];
2810b57cec5SDimitry Andric   }
2820b57cec5SDimitry Andric   unsigned CurBuf = SrcMgr.FindBufferContainingLoc(L);
2830b57cec5SDimitry Andric   assert(CurBuf && "Invalid or unspecified location!");
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   Stream << SrcMgr.getBufferInfo(CurBuf).Buffer->getBufferIdentifier() << ":"
2860b57cec5SDimitry Andric          << SrcMgr.FindLineNumber(L, CurBuf);
2870b57cec5SDimitry Andric   return str;
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric 
290e8d8bef9SDimitry Andric /// This function traverses the matcher tree and sizes all the nodes
291e8d8bef9SDimitry Andric /// that are children of the three kinds of nodes that have them.
292*0fca6ea1SDimitry Andric unsigned MatcherTableEmitter::SizeMatcherList(Matcher *N, raw_ostream &OS) {
293e8d8bef9SDimitry Andric   unsigned Size = 0;
294e8d8bef9SDimitry Andric   while (N) {
295e8d8bef9SDimitry Andric     Size += SizeMatcher(N, OS);
296e8d8bef9SDimitry Andric     N = N->getNext();
297e8d8bef9SDimitry Andric   }
298e8d8bef9SDimitry Andric   return Size;
299e8d8bef9SDimitry Andric }
300e8d8bef9SDimitry Andric 
301e8d8bef9SDimitry Andric /// This function sizes the children of the three kinds of nodes that
302e8d8bef9SDimitry Andric /// have them. It does so by using special cases for those three
303e8d8bef9SDimitry Andric /// nodes, but sharing the code in EmitMatcher() for the other kinds.
304*0fca6ea1SDimitry Andric unsigned MatcherTableEmitter::SizeMatcher(Matcher *N, raw_ostream &OS) {
305e8d8bef9SDimitry Andric   unsigned Idx = 0;
306e8d8bef9SDimitry Andric 
307e8d8bef9SDimitry Andric   ++OpcodeCounts[N->getKind()];
308e8d8bef9SDimitry Andric   switch (N->getKind()) {
309e8d8bef9SDimitry Andric   // The Scope matcher has its kind, a series of child size + child,
310e8d8bef9SDimitry Andric   // and a trailing zero.
311e8d8bef9SDimitry Andric   case Matcher::Scope: {
312e8d8bef9SDimitry Andric     ScopeMatcher *SM = cast<ScopeMatcher>(N);
313e8d8bef9SDimitry Andric     assert(SM->getNext() == nullptr && "Scope matcher should not have next");
314e8d8bef9SDimitry Andric     unsigned Size = 1; // Count the kind.
315e8d8bef9SDimitry Andric     for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) {
316fe6060f1SDimitry Andric       const unsigned ChildSize = SizeMatcherList(SM->getChild(i), OS);
317e8d8bef9SDimitry Andric       assert(ChildSize != 0 && "Matcher cannot have child of size 0");
318e8d8bef9SDimitry Andric       SM->getChild(i)->setSize(ChildSize);
319e8d8bef9SDimitry Andric       Size += GetVBRSize(ChildSize) + ChildSize; // Count VBR and child size.
320e8d8bef9SDimitry Andric     }
321e8d8bef9SDimitry Andric     ++Size; // Count the zero sentinel.
322e8d8bef9SDimitry Andric     return Size;
323e8d8bef9SDimitry Andric   }
324e8d8bef9SDimitry Andric 
325e8d8bef9SDimitry Andric   // SwitchOpcode and SwitchType have their kind, a series of child size +
326e8d8bef9SDimitry Andric   // opcode/type + child, and a trailing zero.
327e8d8bef9SDimitry Andric   case Matcher::SwitchOpcode:
328e8d8bef9SDimitry Andric   case Matcher::SwitchType: {
329e8d8bef9SDimitry Andric     unsigned Size = 1; // Count the kind.
330e8d8bef9SDimitry Andric     unsigned NumCases;
331e8d8bef9SDimitry Andric     if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
332e8d8bef9SDimitry Andric       NumCases = SOM->getNumCases();
333e8d8bef9SDimitry Andric     else
334e8d8bef9SDimitry Andric       NumCases = cast<SwitchTypeMatcher>(N)->getNumCases();
335e8d8bef9SDimitry Andric     for (unsigned i = 0, e = NumCases; i != e; ++i) {
336e8d8bef9SDimitry Andric       Matcher *Child;
337e8d8bef9SDimitry Andric       if (SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {
338e8d8bef9SDimitry Andric         Child = SOM->getCaseMatcher(i);
339e8d8bef9SDimitry Andric         Size += 2; // Count the child's opcode.
340e8d8bef9SDimitry Andric       } else {
341e8d8bef9SDimitry Andric         Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i);
342e8d8bef9SDimitry Andric         ++Size; // Count the child's type.
343e8d8bef9SDimitry Andric       }
344fe6060f1SDimitry Andric       const unsigned ChildSize = SizeMatcherList(Child, OS);
345e8d8bef9SDimitry Andric       assert(ChildSize != 0 && "Matcher cannot have child of size 0");
346e8d8bef9SDimitry Andric       Child->setSize(ChildSize);
347e8d8bef9SDimitry Andric       Size += GetVBRSize(ChildSize) + ChildSize; // Count VBR and child size.
348e8d8bef9SDimitry Andric     }
349e8d8bef9SDimitry Andric     ++Size; // Count the zero sentinel.
350e8d8bef9SDimitry Andric     return Size;
351e8d8bef9SDimitry Andric   }
352e8d8bef9SDimitry Andric 
353e8d8bef9SDimitry Andric   default:
354e8d8bef9SDimitry Andric     // Employ the matcher emitter to size other matchers.
355e8d8bef9SDimitry Andric     return EmitMatcher(N, 0, Idx, OS);
356e8d8bef9SDimitry Andric   }
357e8d8bef9SDimitry Andric   llvm_unreachable("Unreachable");
358e8d8bef9SDimitry Andric }
359e8d8bef9SDimitry Andric 
3600b57cec5SDimitry Andric static void BeginEmitFunction(raw_ostream &OS, StringRef RetType,
3610b57cec5SDimitry Andric                               StringRef Decl, bool AddOverride) {
3620b57cec5SDimitry Andric   OS << "#ifdef GET_DAGISEL_DECL\n";
3630b57cec5SDimitry Andric   OS << RetType << ' ' << Decl;
3640b57cec5SDimitry Andric   if (AddOverride)
3650b57cec5SDimitry Andric     OS << " override";
3660b57cec5SDimitry Andric   OS << ";\n"
3670b57cec5SDimitry Andric         "#endif\n"
3680b57cec5SDimitry Andric         "#if defined(GET_DAGISEL_BODY) || DAGISEL_INLINE\n";
3690b57cec5SDimitry Andric   OS << RetType << " DAGISEL_CLASS_COLONCOLON " << Decl << "\n";
3700b57cec5SDimitry Andric   if (AddOverride) {
3710b57cec5SDimitry Andric     OS << "#if DAGISEL_INLINE\n"
3720b57cec5SDimitry Andric           "  override\n"
3730b57cec5SDimitry Andric           "#endif\n";
3740b57cec5SDimitry Andric   }
3750b57cec5SDimitry Andric }
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric static void EndEmitFunction(raw_ostream &OS) {
3780b57cec5SDimitry Andric   OS << "#endif // GET_DAGISEL_BODY\n\n";
3790b57cec5SDimitry Andric }
3800b57cec5SDimitry Andric 
3810b57cec5SDimitry Andric void MatcherTableEmitter::EmitPatternMatchTable(raw_ostream &OS) {
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric   assert(isUInt<16>(VecPatterns.size()) &&
3840b57cec5SDimitry Andric          "Using only 16 bits to encode offset into Pattern Table");
3850b57cec5SDimitry Andric   assert(VecPatterns.size() == VecIncludeStrings.size() &&
3860b57cec5SDimitry Andric          "The sizes of Pattern and include vectors should be the same");
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric   BeginEmitFunction(OS, "StringRef", "getPatternForIndex(unsigned Index)",
3890b57cec5SDimitry Andric                     true /*AddOverride*/);
3900b57cec5SDimitry Andric   OS << "{\n";
3910b57cec5SDimitry Andric   OS << "static const char *PATTERN_MATCH_TABLE[] = {\n";
3920b57cec5SDimitry Andric 
3930b57cec5SDimitry Andric   for (const auto &It : VecPatterns) {
3940b57cec5SDimitry Andric     OS << "\"" << It.first << "\",\n";
3950b57cec5SDimitry Andric   }
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric   OS << "\n};";
3980b57cec5SDimitry Andric   OS << "\nreturn StringRef(PATTERN_MATCH_TABLE[Index]);";
3990b57cec5SDimitry Andric   OS << "\n}\n";
4000b57cec5SDimitry Andric   EndEmitFunction(OS);
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric   BeginEmitFunction(OS, "StringRef", "getIncludePathForIndex(unsigned Index)",
4030b57cec5SDimitry Andric                     true /*AddOverride*/);
4040b57cec5SDimitry Andric   OS << "{\n";
4050b57cec5SDimitry Andric   OS << "static const char *INCLUDE_PATH_TABLE[] = {\n";
4060b57cec5SDimitry Andric 
4070b57cec5SDimitry Andric   for (const auto &It : VecIncludeStrings) {
4080b57cec5SDimitry Andric     OS << "\"" << It << "\",\n";
4090b57cec5SDimitry Andric   }
4100b57cec5SDimitry Andric 
4110b57cec5SDimitry Andric   OS << "\n};";
4120b57cec5SDimitry Andric   OS << "\nreturn StringRef(INCLUDE_PATH_TABLE[Index]);";
4130b57cec5SDimitry Andric   OS << "\n}\n";
4140b57cec5SDimitry Andric   EndEmitFunction(OS);
4150b57cec5SDimitry Andric }
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric /// EmitMatcher - Emit bytes for the specified matcher and return
4180b57cec5SDimitry Andric /// the number of bytes emitted.
419*0fca6ea1SDimitry Andric unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N,
420*0fca6ea1SDimitry Andric                                           const unsigned Indent,
421*0fca6ea1SDimitry Andric                                           unsigned CurrentIdx,
4220b57cec5SDimitry Andric                                           raw_ostream &OS) {
4235ffd83dbSDimitry Andric   OS.indent(Indent);
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric   switch (N->getKind()) {
4260b57cec5SDimitry Andric   case Matcher::Scope: {
4270b57cec5SDimitry Andric     const ScopeMatcher *SM = cast<ScopeMatcher>(N);
4280b57cec5SDimitry Andric     unsigned StartIdx = CurrentIdx;
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric     // Emit all of the children.
4310b57cec5SDimitry Andric     for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) {
4320b57cec5SDimitry Andric       if (i == 0) {
4330b57cec5SDimitry Andric         OS << "OPC_Scope, ";
4340b57cec5SDimitry Andric         ++CurrentIdx;
4350b57cec5SDimitry Andric       } else {
4360b57cec5SDimitry Andric         if (!OmitComments) {
4370b57cec5SDimitry Andric           OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
4385ffd83dbSDimitry Andric           OS.indent(Indent) << "/*Scope*/ ";
4390b57cec5SDimitry Andric         } else
4405ffd83dbSDimitry Andric           OS.indent(Indent);
4410b57cec5SDimitry Andric       }
4420b57cec5SDimitry Andric 
443fe6060f1SDimitry Andric       unsigned ChildSize = SM->getChild(i)->getSize();
444fe6060f1SDimitry Andric       unsigned VBRSize = EmitVBRValue(ChildSize, OS);
4450b57cec5SDimitry Andric       if (!OmitComments) {
446e8d8bef9SDimitry Andric         OS << "/*->" << CurrentIdx + VBRSize + ChildSize << "*/";
4470b57cec5SDimitry Andric         if (i == 0)
4480b57cec5SDimitry Andric           OS << " // " << SM->getNumChildren() << " children in Scope";
4490b57cec5SDimitry Andric       }
450e8d8bef9SDimitry Andric       OS << '\n';
4510b57cec5SDimitry Andric 
452e8d8bef9SDimitry Andric       ChildSize = EmitMatcherList(SM->getChild(i), Indent + 1,
453e8d8bef9SDimitry Andric                                   CurrentIdx + VBRSize, OS);
454e8d8bef9SDimitry Andric       assert(ChildSize == SM->getChild(i)->getSize() &&
455e8d8bef9SDimitry Andric              "Emitted child size does not match calculated size");
456e8d8bef9SDimitry Andric       CurrentIdx += VBRSize + ChildSize;
4570b57cec5SDimitry Andric     }
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric     // Emit a zero as a sentinel indicating end of 'Scope'.
4600b57cec5SDimitry Andric     if (!OmitComments)
4610b57cec5SDimitry Andric       OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
4625ffd83dbSDimitry Andric     OS.indent(Indent) << "0, ";
4630b57cec5SDimitry Andric     if (!OmitComments)
4640b57cec5SDimitry Andric       OS << "/*End of Scope*/";
4650b57cec5SDimitry Andric     OS << '\n';
4660b57cec5SDimitry Andric     return CurrentIdx - StartIdx + 1;
4670b57cec5SDimitry Andric   }
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric   case Matcher::RecordNode:
4700b57cec5SDimitry Andric     OS << "OPC_RecordNode,";
4710b57cec5SDimitry Andric     if (!OmitComments)
472*0fca6ea1SDimitry Andric       OS << " // #" << cast<RecordMatcher>(N)->getResultNo() << " = "
4730b57cec5SDimitry Andric          << cast<RecordMatcher>(N)->getWhatFor();
4740b57cec5SDimitry Andric     OS << '\n';
4750b57cec5SDimitry Andric     return 1;
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric   case Matcher::RecordChild:
478*0fca6ea1SDimitry Andric     OS << "OPC_RecordChild" << cast<RecordChildMatcher>(N)->getChildNo() << ',';
4790b57cec5SDimitry Andric     if (!OmitComments)
480*0fca6ea1SDimitry Andric       OS << " // #" << cast<RecordChildMatcher>(N)->getResultNo() << " = "
4810b57cec5SDimitry Andric          << cast<RecordChildMatcher>(N)->getWhatFor();
4820b57cec5SDimitry Andric     OS << '\n';
4830b57cec5SDimitry Andric     return 1;
4840b57cec5SDimitry Andric 
4850b57cec5SDimitry Andric   case Matcher::RecordMemRef:
4860b57cec5SDimitry Andric     OS << "OPC_RecordMemRef,\n";
4870b57cec5SDimitry Andric     return 1;
4880b57cec5SDimitry Andric 
4890b57cec5SDimitry Andric   case Matcher::CaptureGlueInput:
4900b57cec5SDimitry Andric     OS << "OPC_CaptureGlueInput,\n";
4910b57cec5SDimitry Andric     return 1;
4920b57cec5SDimitry Andric 
4930b57cec5SDimitry Andric   case Matcher::MoveChild: {
4940b57cec5SDimitry Andric     const auto *MCM = cast<MoveChildMatcher>(N);
4950b57cec5SDimitry Andric 
4960b57cec5SDimitry Andric     OS << "OPC_MoveChild";
4970b57cec5SDimitry Andric     // Handle the specialized forms.
4980b57cec5SDimitry Andric     if (MCM->getChildNo() >= 8)
4990b57cec5SDimitry Andric       OS << ", ";
5000b57cec5SDimitry Andric     OS << MCM->getChildNo() << ",\n";
5010b57cec5SDimitry Andric     return (MCM->getChildNo() >= 8) ? 2 : 1;
5020b57cec5SDimitry Andric   }
5030b57cec5SDimitry Andric 
5045f757f3fSDimitry Andric   case Matcher::MoveSibling: {
5055f757f3fSDimitry Andric     const auto *MSM = cast<MoveSiblingMatcher>(N);
5065f757f3fSDimitry Andric 
5075f757f3fSDimitry Andric     OS << "OPC_MoveSibling";
5085f757f3fSDimitry Andric     // Handle the specialized forms.
5095f757f3fSDimitry Andric     if (MSM->getSiblingNo() >= 8)
5105f757f3fSDimitry Andric       OS << ", ";
5115f757f3fSDimitry Andric     OS << MSM->getSiblingNo() << ",\n";
5125f757f3fSDimitry Andric     return (MSM->getSiblingNo() >= 8) ? 2 : 1;
5135f757f3fSDimitry Andric   }
5145f757f3fSDimitry Andric 
5150b57cec5SDimitry Andric   case Matcher::MoveParent:
5160b57cec5SDimitry Andric     OS << "OPC_MoveParent,\n";
5170b57cec5SDimitry Andric     return 1;
5180b57cec5SDimitry Andric 
5190b57cec5SDimitry Andric   case Matcher::CheckSame:
520*0fca6ea1SDimitry Andric     OS << "OPC_CheckSame, " << cast<CheckSameMatcher>(N)->getMatchNumber()
521*0fca6ea1SDimitry Andric        << ",\n";
5220b57cec5SDimitry Andric     return 2;
5230b57cec5SDimitry Andric 
5240b57cec5SDimitry Andric   case Matcher::CheckChildSame:
525*0fca6ea1SDimitry Andric     OS << "OPC_CheckChild" << cast<CheckChildSameMatcher>(N)->getChildNo()
526*0fca6ea1SDimitry Andric        << "Same, " << cast<CheckChildSameMatcher>(N)->getMatchNumber() << ",\n";
5270b57cec5SDimitry Andric     return 2;
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric   case Matcher::CheckPatternPredicate: {
5300b57cec5SDimitry Andric     StringRef Pred = cast<CheckPatternPredicateMatcher>(N)->getPredicate();
5315f757f3fSDimitry Andric     unsigned PredNo = getPatternPredicate(Pred);
5325f757f3fSDimitry Andric     if (PredNo > 255)
533297eecfbSDimitry Andric       OS << "OPC_CheckPatternPredicateTwoByte, TARGET_VAL(" << PredNo << "),";
534297eecfbSDimitry Andric     else if (PredNo < 8)
535297eecfbSDimitry Andric       OS << "OPC_CheckPatternPredicate" << PredNo << ',';
5365f757f3fSDimitry Andric     else
5375f757f3fSDimitry Andric       OS << "OPC_CheckPatternPredicate, " << PredNo << ',';
5380b57cec5SDimitry Andric     if (!OmitComments)
5390b57cec5SDimitry Andric       OS << " // " << Pred;
5400b57cec5SDimitry Andric     OS << '\n';
541297eecfbSDimitry Andric     return 2 + (PredNo > 255) - (PredNo < 8);
5420b57cec5SDimitry Andric   }
5430b57cec5SDimitry Andric   case Matcher::CheckPredicate: {
5440b57cec5SDimitry Andric     TreePredicateFn Pred = cast<CheckPredicateMatcher>(N)->getPredicate();
5450b57cec5SDimitry Andric     unsigned OperandBytes = 0;
5467a6dacacSDimitry Andric     unsigned PredNo = getNodePredicate(Pred);
5470b57cec5SDimitry Andric 
5480b57cec5SDimitry Andric     if (Pred.usesOperands()) {
5490b57cec5SDimitry Andric       unsigned NumOps = cast<CheckPredicateMatcher>(N)->getNumOperands();
5500b57cec5SDimitry Andric       OS << "OPC_CheckPredicateWithOperands, " << NumOps << "/*#Ops*/, ";
5510b57cec5SDimitry Andric       for (unsigned i = 0; i < NumOps; ++i)
5520b57cec5SDimitry Andric         OS << cast<CheckPredicateMatcher>(N)->getOperandNo(i) << ", ";
5530b57cec5SDimitry Andric       OperandBytes = 1 + NumOps;
5540b57cec5SDimitry Andric     } else {
5557a6dacacSDimitry Andric       if (PredNo < 8) {
5567a6dacacSDimitry Andric         OperandBytes = -1;
5577a6dacacSDimitry Andric         OS << "OPC_CheckPredicate" << PredNo << ", ";
5587a6dacacSDimitry Andric       } else
5590b57cec5SDimitry Andric         OS << "OPC_CheckPredicate, ";
5600b57cec5SDimitry Andric     }
5610b57cec5SDimitry Andric 
5627a6dacacSDimitry Andric     if (PredNo >= 8 || Pred.usesOperands())
5637a6dacacSDimitry Andric       OS << PredNo << ',';
5640b57cec5SDimitry Andric     if (!OmitComments)
5650b57cec5SDimitry Andric       OS << " // " << Pred.getFnName();
5660b57cec5SDimitry Andric     OS << '\n';
5670b57cec5SDimitry Andric     return 2 + OperandBytes;
5680b57cec5SDimitry Andric   }
5690b57cec5SDimitry Andric 
5700b57cec5SDimitry Andric   case Matcher::CheckOpcode:
5710b57cec5SDimitry Andric     OS << "OPC_CheckOpcode, TARGET_VAL("
5720b57cec5SDimitry Andric        << cast<CheckOpcodeMatcher>(N)->getOpcode().getEnumName() << "),\n";
5730b57cec5SDimitry Andric     return 3;
5740b57cec5SDimitry Andric 
5750b57cec5SDimitry Andric   case Matcher::SwitchOpcode:
5760b57cec5SDimitry Andric   case Matcher::SwitchType: {
5770b57cec5SDimitry Andric     unsigned StartIdx = CurrentIdx;
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric     unsigned NumCases;
5800b57cec5SDimitry Andric     if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {
5810b57cec5SDimitry Andric       OS << "OPC_SwitchOpcode ";
5820b57cec5SDimitry Andric       NumCases = SOM->getNumCases();
5830b57cec5SDimitry Andric     } else {
5840b57cec5SDimitry Andric       OS << "OPC_SwitchType ";
5850b57cec5SDimitry Andric       NumCases = cast<SwitchTypeMatcher>(N)->getNumCases();
5860b57cec5SDimitry Andric     }
5870b57cec5SDimitry Andric 
5880b57cec5SDimitry Andric     if (!OmitComments)
5890b57cec5SDimitry Andric       OS << "/*" << NumCases << " cases */";
5900b57cec5SDimitry Andric     OS << ", ";
5910b57cec5SDimitry Andric     ++CurrentIdx;
5920b57cec5SDimitry Andric 
5930b57cec5SDimitry Andric     // For each case we emit the size, then the opcode, then the matcher.
5940b57cec5SDimitry Andric     for (unsigned i = 0, e = NumCases; i != e; ++i) {
5950b57cec5SDimitry Andric       const Matcher *Child;
5960b57cec5SDimitry Andric       unsigned IdxSize;
5970b57cec5SDimitry Andric       if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {
5980b57cec5SDimitry Andric         Child = SOM->getCaseMatcher(i);
5990b57cec5SDimitry Andric         IdxSize = 2; // size of opcode in table is 2 bytes.
6000b57cec5SDimitry Andric       } else {
6010b57cec5SDimitry Andric         Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i);
6020b57cec5SDimitry Andric         IdxSize = 1; // size of type in table is 1 byte.
6030b57cec5SDimitry Andric       }
6040b57cec5SDimitry Andric 
6050b57cec5SDimitry Andric       if (i != 0) {
6060b57cec5SDimitry Andric         if (!OmitComments)
6070b57cec5SDimitry Andric           OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
6085ffd83dbSDimitry Andric         OS.indent(Indent);
6090b57cec5SDimitry Andric         if (!OmitComments)
610*0fca6ea1SDimitry Andric           OS << (isa<SwitchOpcodeMatcher>(N) ? "/*SwitchOpcode*/ "
611*0fca6ea1SDimitry Andric                                              : "/*SwitchType*/ ");
6120b57cec5SDimitry Andric       }
6130b57cec5SDimitry Andric 
614fe6060f1SDimitry Andric       unsigned ChildSize = Child->getSize();
615e8d8bef9SDimitry Andric       CurrentIdx += EmitVBRValue(ChildSize, OS) + IdxSize;
6160b57cec5SDimitry Andric       if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
6170b57cec5SDimitry Andric         OS << "TARGET_VAL(" << SOM->getCaseOpcode(i).getEnumName() << "),";
6180b57cec5SDimitry Andric       else
6190b57cec5SDimitry Andric         OS << getEnumName(cast<SwitchTypeMatcher>(N)->getCaseType(i)) << ',';
6200b57cec5SDimitry Andric       if (!OmitComments)
6210b57cec5SDimitry Andric         OS << "// ->" << CurrentIdx + ChildSize;
6220b57cec5SDimitry Andric       OS << '\n';
623e8d8bef9SDimitry Andric 
624e8d8bef9SDimitry Andric       ChildSize = EmitMatcherList(Child, Indent + 1, CurrentIdx, OS);
625e8d8bef9SDimitry Andric       assert(ChildSize == Child->getSize() &&
626e8d8bef9SDimitry Andric              "Emitted child size does not match calculated size");
6270b57cec5SDimitry Andric       CurrentIdx += ChildSize;
6280b57cec5SDimitry Andric     }
6290b57cec5SDimitry Andric 
6300b57cec5SDimitry Andric     // Emit the final zero to terminate the switch.
6310b57cec5SDimitry Andric     if (!OmitComments)
6320b57cec5SDimitry Andric       OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
6335ffd83dbSDimitry Andric     OS.indent(Indent) << "0,";
6340b57cec5SDimitry Andric     if (!OmitComments)
635*0fca6ea1SDimitry Andric       OS << (isa<SwitchOpcodeMatcher>(N) ? " // EndSwitchOpcode"
636*0fca6ea1SDimitry Andric                                          : " // EndSwitchType");
6370b57cec5SDimitry Andric 
6380b57cec5SDimitry Andric     OS << '\n';
639e8d8bef9SDimitry Andric     return CurrentIdx - StartIdx + 1;
6400b57cec5SDimitry Andric   }
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric   case Matcher::CheckType:
6430b57cec5SDimitry Andric     if (cast<CheckTypeMatcher>(N)->getResNo() == 0) {
6445f757f3fSDimitry Andric       MVT::SimpleValueType VT = cast<CheckTypeMatcher>(N)->getType();
6455f757f3fSDimitry Andric       switch (VT) {
6465f757f3fSDimitry Andric       case MVT::i32:
6475f757f3fSDimitry Andric       case MVT::i64:
6485f757f3fSDimitry Andric         OS << "OPC_CheckTypeI" << MVT(VT).getSizeInBits() << ",\n";
6495f757f3fSDimitry Andric         return 1;
6505f757f3fSDimitry Andric       default:
6515f757f3fSDimitry Andric         OS << "OPC_CheckType, " << getEnumName(VT) << ",\n";
6520b57cec5SDimitry Andric         return 2;
6530b57cec5SDimitry Andric       }
6545f757f3fSDimitry Andric     }
6555f757f3fSDimitry Andric     OS << "OPC_CheckTypeRes, " << cast<CheckTypeMatcher>(N)->getResNo() << ", "
6565f757f3fSDimitry Andric        << getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
6570b57cec5SDimitry Andric     return 3;
6580b57cec5SDimitry Andric 
6595f757f3fSDimitry Andric   case Matcher::CheckChildType: {
6605f757f3fSDimitry Andric     MVT::SimpleValueType VT = cast<CheckChildTypeMatcher>(N)->getType();
6615f757f3fSDimitry Andric     switch (VT) {
6625f757f3fSDimitry Andric     case MVT::i32:
6635f757f3fSDimitry Andric     case MVT::i64:
6645f757f3fSDimitry Andric       OS << "OPC_CheckChild" << cast<CheckChildTypeMatcher>(N)->getChildNo()
6655f757f3fSDimitry Andric          << "TypeI" << MVT(VT).getSizeInBits() << ",\n";
6665f757f3fSDimitry Andric       return 1;
6675f757f3fSDimitry Andric     default:
6685f757f3fSDimitry Andric       OS << "OPC_CheckChild" << cast<CheckChildTypeMatcher>(N)->getChildNo()
6695f757f3fSDimitry Andric          << "Type, " << getEnumName(VT) << ",\n";
6700b57cec5SDimitry Andric       return 2;
6715f757f3fSDimitry Andric     }
6725f757f3fSDimitry Andric   }
6730b57cec5SDimitry Andric 
6740b57cec5SDimitry Andric   case Matcher::CheckInteger: {
6750b57cec5SDimitry Andric     OS << "OPC_CheckInteger, ";
676fe6060f1SDimitry Andric     unsigned Bytes =
677fe6060f1SDimitry Andric         1 + EmitSignedVBRValue(cast<CheckIntegerMatcher>(N)->getValue(), OS);
6780b57cec5SDimitry Andric     OS << '\n';
6790b57cec5SDimitry Andric     return Bytes;
6800b57cec5SDimitry Andric   }
6810b57cec5SDimitry Andric   case Matcher::CheckChildInteger: {
6820b57cec5SDimitry Andric     OS << "OPC_CheckChild" << cast<CheckChildIntegerMatcher>(N)->getChildNo()
6830b57cec5SDimitry Andric        << "Integer, ";
684fe6060f1SDimitry Andric     unsigned Bytes = 1 + EmitSignedVBRValue(
685fe6060f1SDimitry Andric                              cast<CheckChildIntegerMatcher>(N)->getValue(), OS);
6860b57cec5SDimitry Andric     OS << '\n';
6870b57cec5SDimitry Andric     return Bytes;
6880b57cec5SDimitry Andric   }
6890b57cec5SDimitry Andric   case Matcher::CheckCondCode:
6900b57cec5SDimitry Andric     OS << "OPC_CheckCondCode, ISD::"
6910b57cec5SDimitry Andric        << cast<CheckCondCodeMatcher>(N)->getCondCodeName() << ",\n";
6920b57cec5SDimitry Andric     return 2;
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric   case Matcher::CheckChild2CondCode:
6950b57cec5SDimitry Andric     OS << "OPC_CheckChild2CondCode, ISD::"
6960b57cec5SDimitry Andric        << cast<CheckChild2CondCodeMatcher>(N)->getCondCodeName() << ",\n";
6970b57cec5SDimitry Andric     return 2;
6980b57cec5SDimitry Andric 
6990b57cec5SDimitry Andric   case Matcher::CheckValueType:
700*0fca6ea1SDimitry Andric     OS << "OPC_CheckValueType, "
701*0fca6ea1SDimitry Andric        << getEnumName(cast<CheckValueTypeMatcher>(N)->getVT()) << ",\n";
7020b57cec5SDimitry Andric     return 2;
7030b57cec5SDimitry Andric 
7040b57cec5SDimitry Andric   case Matcher::CheckComplexPat: {
7050b57cec5SDimitry Andric     const CheckComplexPatMatcher *CCPM = cast<CheckComplexPatMatcher>(N);
7060b57cec5SDimitry Andric     const ComplexPattern &Pattern = CCPM->getPattern();
707297eecfbSDimitry Andric     unsigned PatternNo = getComplexPat(Pattern);
708297eecfbSDimitry Andric     if (PatternNo < 8)
709297eecfbSDimitry Andric       OS << "OPC_CheckComplexPat" << PatternNo << ", /*#*/"
710297eecfbSDimitry Andric          << CCPM->getMatchNumber() << ',';
711297eecfbSDimitry Andric     else
712297eecfbSDimitry Andric       OS << "OPC_CheckComplexPat, /*CP*/" << PatternNo << ", /*#*/"
7130b57cec5SDimitry Andric          << CCPM->getMatchNumber() << ',';
7140b57cec5SDimitry Andric 
7150b57cec5SDimitry Andric     if (!OmitComments) {
7160b57cec5SDimitry Andric       OS << " // " << Pattern.getSelectFunc();
7170b57cec5SDimitry Andric       OS << ":$" << CCPM->getName();
7180b57cec5SDimitry Andric       for (unsigned i = 0, e = Pattern.getNumOperands(); i != e; ++i)
7190b57cec5SDimitry Andric         OS << " #" << CCPM->getFirstResult() + i;
7200b57cec5SDimitry Andric 
7210b57cec5SDimitry Andric       if (Pattern.hasProperty(SDNPHasChain))
7220b57cec5SDimitry Andric         OS << " + chain result";
7230b57cec5SDimitry Andric     }
7240b57cec5SDimitry Andric     OS << '\n';
725297eecfbSDimitry Andric     return PatternNo < 8 ? 2 : 3;
7260b57cec5SDimitry Andric   }
7270b57cec5SDimitry Andric 
7280b57cec5SDimitry Andric   case Matcher::CheckAndImm: {
7290b57cec5SDimitry Andric     OS << "OPC_CheckAndImm, ";
730*0fca6ea1SDimitry Andric     unsigned Bytes =
731*0fca6ea1SDimitry Andric         1 + EmitVBRValue(cast<CheckAndImmMatcher>(N)->getValue(), OS);
7320b57cec5SDimitry Andric     OS << '\n';
7330b57cec5SDimitry Andric     return Bytes;
7340b57cec5SDimitry Andric   }
7350b57cec5SDimitry Andric 
7360b57cec5SDimitry Andric   case Matcher::CheckOrImm: {
7370b57cec5SDimitry Andric     OS << "OPC_CheckOrImm, ";
738*0fca6ea1SDimitry Andric     unsigned Bytes =
739*0fca6ea1SDimitry Andric         1 + EmitVBRValue(cast<CheckOrImmMatcher>(N)->getValue(), OS);
7400b57cec5SDimitry Andric     OS << '\n';
7410b57cec5SDimitry Andric     return Bytes;
7420b57cec5SDimitry Andric   }
7430b57cec5SDimitry Andric 
7440b57cec5SDimitry Andric   case Matcher::CheckFoldableChainNode:
7450b57cec5SDimitry Andric     OS << "OPC_CheckFoldableChainNode,\n";
7460b57cec5SDimitry Andric     return 1;
7470b57cec5SDimitry Andric 
7480b57cec5SDimitry Andric   case Matcher::CheckImmAllOnesV:
7490b57cec5SDimitry Andric     OS << "OPC_CheckImmAllOnesV,\n";
7500b57cec5SDimitry Andric     return 1;
7510b57cec5SDimitry Andric 
7520b57cec5SDimitry Andric   case Matcher::CheckImmAllZerosV:
7530b57cec5SDimitry Andric     OS << "OPC_CheckImmAllZerosV,\n";
7540b57cec5SDimitry Andric     return 1;
7550b57cec5SDimitry Andric 
7560b57cec5SDimitry Andric   case Matcher::EmitInteger: {
7570b57cec5SDimitry Andric     int64_t Val = cast<EmitIntegerMatcher>(N)->getValue();
7585f757f3fSDimitry Andric     MVT::SimpleValueType VT = cast<EmitIntegerMatcher>(N)->getVT();
7595f757f3fSDimitry Andric     unsigned OpBytes;
7605f757f3fSDimitry Andric     switch (VT) {
7615f757f3fSDimitry Andric     case MVT::i8:
7625f757f3fSDimitry Andric     case MVT::i16:
7635f757f3fSDimitry Andric     case MVT::i32:
7645f757f3fSDimitry Andric     case MVT::i64:
7655f757f3fSDimitry Andric       OpBytes = 1;
7665f757f3fSDimitry Andric       OS << "OPC_EmitInteger" << MVT(VT).getSizeInBits() << ", ";
7675f757f3fSDimitry Andric       break;
7685f757f3fSDimitry Andric     default:
7695f757f3fSDimitry Andric       OpBytes = 2;
7705f757f3fSDimitry Andric       OS << "OPC_EmitInteger, " << getEnumName(VT) << ", ";
7715f757f3fSDimitry Andric       break;
7725f757f3fSDimitry Andric     }
7735f757f3fSDimitry Andric     unsigned Bytes = OpBytes + EmitSignedVBRValue(Val, OS);
7740b57cec5SDimitry Andric     OS << '\n';
7750b57cec5SDimitry Andric     return Bytes;
7760b57cec5SDimitry Andric   }
7770b57cec5SDimitry Andric   case Matcher::EmitStringInteger: {
7780b57cec5SDimitry Andric     const std::string &Val = cast<EmitStringIntegerMatcher>(N)->getValue();
7795f757f3fSDimitry Andric     MVT::SimpleValueType VT = cast<EmitStringIntegerMatcher>(N)->getVT();
7805ffd83dbSDimitry Andric     // These should always fit into 7 bits.
7815f757f3fSDimitry Andric     unsigned OpBytes;
7825f757f3fSDimitry Andric     switch (VT) {
7835f757f3fSDimitry Andric     case MVT::i32:
7845f757f3fSDimitry Andric       OpBytes = 1;
7855f757f3fSDimitry Andric       OS << "OPC_EmitStringInteger" << MVT(VT).getSizeInBits() << ", ";
7865f757f3fSDimitry Andric       break;
7875f757f3fSDimitry Andric     default:
7885f757f3fSDimitry Andric       OpBytes = 2;
7895f757f3fSDimitry Andric       OS << "OPC_EmitStringInteger, " << getEnumName(VT) << ", ";
7905f757f3fSDimitry Andric       break;
7915f757f3fSDimitry Andric     }
7925f757f3fSDimitry Andric     OS << Val << ",\n";
7935f757f3fSDimitry Andric     return OpBytes + 1;
7940b57cec5SDimitry Andric   }
7950b57cec5SDimitry Andric 
7960b57cec5SDimitry Andric   case Matcher::EmitRegister: {
7970b57cec5SDimitry Andric     const EmitRegisterMatcher *Matcher = cast<EmitRegisterMatcher>(N);
7980b57cec5SDimitry Andric     const CodeGenRegister *Reg = Matcher->getReg();
799cb14a3feSDimitry Andric     MVT::SimpleValueType VT = Matcher->getVT();
8000b57cec5SDimitry Andric     // If the enum value of the register is larger than one byte can handle,
8010b57cec5SDimitry Andric     // use EmitRegister2.
8020b57cec5SDimitry Andric     if (Reg && Reg->EnumValue > 255) {
803cb14a3feSDimitry Andric       OS << "OPC_EmitRegister2, " << getEnumName(VT) << ", ";
8040b57cec5SDimitry Andric       OS << "TARGET_VAL(" << getQualifiedName(Reg->TheDef) << "),\n";
8050b57cec5SDimitry Andric       return 4;
806cb14a3feSDimitry Andric     }
807cb14a3feSDimitry Andric     unsigned OpBytes;
808cb14a3feSDimitry Andric     switch (VT) {
809cb14a3feSDimitry Andric     case MVT::i32:
810cb14a3feSDimitry Andric     case MVT::i64:
811cb14a3feSDimitry Andric       OpBytes = 1;
812cb14a3feSDimitry Andric       OS << "OPC_EmitRegisterI" << MVT(VT).getSizeInBits() << ", ";
813cb14a3feSDimitry Andric       break;
814cb14a3feSDimitry Andric     default:
815cb14a3feSDimitry Andric       OpBytes = 2;
816cb14a3feSDimitry Andric       OS << "OPC_EmitRegister, " << getEnumName(VT) << ", ";
817cb14a3feSDimitry Andric       break;
818cb14a3feSDimitry Andric     }
8190b57cec5SDimitry Andric     if (Reg) {
8200b57cec5SDimitry Andric       OS << getQualifiedName(Reg->TheDef) << ",\n";
8210b57cec5SDimitry Andric     } else {
8220b57cec5SDimitry Andric       OS << "0 ";
8230b57cec5SDimitry Andric       if (!OmitComments)
8240b57cec5SDimitry Andric         OS << "/*zero_reg*/";
8250b57cec5SDimitry Andric       OS << ",\n";
8260b57cec5SDimitry Andric     }
827cb14a3feSDimitry Andric     return OpBytes + 1;
8280b57cec5SDimitry Andric   }
8290b57cec5SDimitry Andric 
8305f757f3fSDimitry Andric   case Matcher::EmitConvertToTarget: {
8315f757f3fSDimitry Andric     unsigned Slot = cast<EmitConvertToTargetMatcher>(N)->getSlot();
8325f757f3fSDimitry Andric     if (Slot < 8) {
8335f757f3fSDimitry Andric       OS << "OPC_EmitConvertToTarget" << Slot << ",\n";
8345f757f3fSDimitry Andric       return 1;
8355f757f3fSDimitry Andric     }
8365f757f3fSDimitry Andric     OS << "OPC_EmitConvertToTarget, " << Slot << ",\n";
8370b57cec5SDimitry Andric     return 2;
8385f757f3fSDimitry Andric   }
8390b57cec5SDimitry Andric 
8400b57cec5SDimitry Andric   case Matcher::EmitMergeInputChains: {
8410b57cec5SDimitry Andric     const EmitMergeInputChainsMatcher *MN =
8420b57cec5SDimitry Andric         cast<EmitMergeInputChainsMatcher>(N);
8430b57cec5SDimitry Andric 
8440b57cec5SDimitry Andric     // Handle the specialized forms OPC_EmitMergeInputChains1_0, 1_1, and 1_2.
8450b57cec5SDimitry Andric     if (MN->getNumNodes() == 1 && MN->getNode(0) < 3) {
8460b57cec5SDimitry Andric       OS << "OPC_EmitMergeInputChains1_" << MN->getNode(0) << ",\n";
8470b57cec5SDimitry Andric       return 1;
8480b57cec5SDimitry Andric     }
8490b57cec5SDimitry Andric 
8500b57cec5SDimitry Andric     OS << "OPC_EmitMergeInputChains, " << MN->getNumNodes() << ", ";
8510b57cec5SDimitry Andric     for (unsigned i = 0, e = MN->getNumNodes(); i != e; ++i)
8520b57cec5SDimitry Andric       OS << MN->getNode(i) << ", ";
8530b57cec5SDimitry Andric     OS << '\n';
8540b57cec5SDimitry Andric     return 2 + MN->getNumNodes();
8550b57cec5SDimitry Andric   }
8568bcb0991SDimitry Andric   case Matcher::EmitCopyToReg: {
8578bcb0991SDimitry Andric     const auto *C2RMatcher = cast<EmitCopyToRegMatcher>(N);
8588bcb0991SDimitry Andric     int Bytes = 3;
8598bcb0991SDimitry Andric     const CodeGenRegister *Reg = C2RMatcher->getDestPhysReg();
8605f757f3fSDimitry Andric     unsigned Slot = C2RMatcher->getSrcSlot();
8618bcb0991SDimitry Andric     if (Reg->EnumValue > 255) {
8628bcb0991SDimitry Andric       assert(isUInt<16>(Reg->EnumValue) && "not handled");
8635f757f3fSDimitry Andric       OS << "OPC_EmitCopyToRegTwoByte, " << Slot << ", "
8648bcb0991SDimitry Andric          << "TARGET_VAL(" << getQualifiedName(Reg->TheDef) << "),\n";
8658bcb0991SDimitry Andric       ++Bytes;
8668bcb0991SDimitry Andric     } else {
8675f757f3fSDimitry Andric       if (Slot < 8) {
8685f757f3fSDimitry Andric         OS << "OPC_EmitCopyToReg" << Slot << ", "
8695f757f3fSDimitry Andric            << getQualifiedName(Reg->TheDef) << ",\n";
8705f757f3fSDimitry Andric         --Bytes;
8715f757f3fSDimitry Andric       } else
8725f757f3fSDimitry Andric         OS << "OPC_EmitCopyToReg, " << Slot << ", "
8738bcb0991SDimitry Andric            << getQualifiedName(Reg->TheDef) << ",\n";
8748bcb0991SDimitry Andric     }
8758bcb0991SDimitry Andric 
8768bcb0991SDimitry Andric     return Bytes;
8778bcb0991SDimitry Andric   }
8780b57cec5SDimitry Andric   case Matcher::EmitNodeXForm: {
8790b57cec5SDimitry Andric     const EmitNodeXFormMatcher *XF = cast<EmitNodeXFormMatcher>(N);
8800b57cec5SDimitry Andric     OS << "OPC_EmitNodeXForm, " << getNodeXFormID(XF->getNodeXForm()) << ", "
8810b57cec5SDimitry Andric        << XF->getSlot() << ',';
8820b57cec5SDimitry Andric     if (!OmitComments)
8830b57cec5SDimitry Andric       OS << " // " << XF->getNodeXForm()->getName();
8840b57cec5SDimitry Andric     OS << '\n';
8850b57cec5SDimitry Andric     return 3;
8860b57cec5SDimitry Andric   }
8870b57cec5SDimitry Andric 
8880b57cec5SDimitry Andric   case Matcher::EmitNode:
8890b57cec5SDimitry Andric   case Matcher::MorphNodeTo: {
8900b57cec5SDimitry Andric     auto NumCoveredBytes = 0;
8910b57cec5SDimitry Andric     if (InstrumentCoverage) {
8920b57cec5SDimitry Andric       if (const MorphNodeToMatcher *SNT = dyn_cast<MorphNodeToMatcher>(N)) {
8930b57cec5SDimitry Andric         NumCoveredBytes = 3;
8940b57cec5SDimitry Andric         OS << "OPC_Coverage, ";
8950b57cec5SDimitry Andric         std::string src =
8960b57cec5SDimitry Andric             GetPatFromTreePatternNode(SNT->getPattern().getSrcPattern());
8970b57cec5SDimitry Andric         std::string dst =
8980b57cec5SDimitry Andric             GetPatFromTreePatternNode(SNT->getPattern().getDstPattern());
8990b57cec5SDimitry Andric         Record *PatRecord = SNT->getPattern().getSrcRecord();
9000b57cec5SDimitry Andric         std::string include_src = getIncludePath(PatRecord);
9010b57cec5SDimitry Andric         unsigned Offset =
9020b57cec5SDimitry Andric             getPatternIdxFromTable(src + " -> " + dst, std::move(include_src));
9030b57cec5SDimitry Andric         OS << "TARGET_VAL(" << Offset << "),\n";
9045ffd83dbSDimitry Andric         OS.indent(FullIndexWidth + Indent);
9050b57cec5SDimitry Andric       }
9060b57cec5SDimitry Andric     }
9070b57cec5SDimitry Andric     const EmitNodeMatcherCommon *EN = cast<EmitNodeMatcherCommon>(N);
9085f757f3fSDimitry Andric     bool IsEmitNode = isa<EmitNodeMatcher>(EN);
9095f757f3fSDimitry Andric     OS << (IsEmitNode ? "OPC_EmitNode" : "OPC_MorphNodeTo");
9100b57cec5SDimitry Andric     bool CompressVTs = EN->getNumVTs() < 3;
9115f757f3fSDimitry Andric     bool CompressNodeInfo = false;
9125f757f3fSDimitry Andric     if (CompressVTs) {
9130b57cec5SDimitry Andric       OS << EN->getNumVTs();
9145f757f3fSDimitry Andric       if (!EN->hasChain() && !EN->hasInGlue() && !EN->hasOutGlue() &&
9155f757f3fSDimitry Andric           !EN->hasMemRefs() && EN->getNumFixedArityOperands() == -1) {
9165f757f3fSDimitry Andric         CompressNodeInfo = true;
9175f757f3fSDimitry Andric         OS << "None";
9185f757f3fSDimitry Andric       } else if (EN->hasChain() && !EN->hasInGlue() && !EN->hasOutGlue() &&
9195f757f3fSDimitry Andric                  !EN->hasMemRefs() && EN->getNumFixedArityOperands() == -1) {
9205f757f3fSDimitry Andric         CompressNodeInfo = true;
9215f757f3fSDimitry Andric         OS << "Chain";
9225f757f3fSDimitry Andric       } else if (!IsEmitNode && !EN->hasChain() && EN->hasInGlue() &&
9235f757f3fSDimitry Andric                  !EN->hasOutGlue() && !EN->hasMemRefs() &&
9245f757f3fSDimitry Andric                  EN->getNumFixedArityOperands() == -1) {
9255f757f3fSDimitry Andric         CompressNodeInfo = true;
9265f757f3fSDimitry Andric         OS << "GlueInput";
9275f757f3fSDimitry Andric       } else if (!IsEmitNode && !EN->hasChain() && !EN->hasInGlue() &&
9285f757f3fSDimitry Andric                  EN->hasOutGlue() && !EN->hasMemRefs() &&
9295f757f3fSDimitry Andric                  EN->getNumFixedArityOperands() == -1) {
9305f757f3fSDimitry Andric         CompressNodeInfo = true;
9315f757f3fSDimitry Andric         OS << "GlueOutput";
9325f757f3fSDimitry Andric       }
9335f757f3fSDimitry Andric     }
9340b57cec5SDimitry Andric 
93506c3fb27SDimitry Andric     const CodeGenInstruction &CGI = EN->getInstruction();
93606c3fb27SDimitry Andric     OS << ", TARGET_VAL(" << CGI.Namespace << "::" << CGI.TheDef->getName()
9375f757f3fSDimitry Andric        << ")";
9380b57cec5SDimitry Andric 
9395f757f3fSDimitry Andric     if (!CompressNodeInfo) {
9405f757f3fSDimitry Andric       OS << ", 0";
9415f757f3fSDimitry Andric       if (EN->hasChain())
9425f757f3fSDimitry Andric         OS << "|OPFL_Chain";
9435f757f3fSDimitry Andric       if (EN->hasInGlue())
9445f757f3fSDimitry Andric         OS << "|OPFL_GlueInput";
9455f757f3fSDimitry Andric       if (EN->hasOutGlue())
9465f757f3fSDimitry Andric         OS << "|OPFL_GlueOutput";
9475f757f3fSDimitry Andric       if (EN->hasMemRefs())
9485f757f3fSDimitry Andric         OS << "|OPFL_MemRefs";
9490b57cec5SDimitry Andric       if (EN->getNumFixedArityOperands() != -1)
9500b57cec5SDimitry Andric         OS << "|OPFL_Variadic" << EN->getNumFixedArityOperands();
9515f757f3fSDimitry Andric     }
9520b57cec5SDimitry Andric     OS << ",\n";
9530b57cec5SDimitry Andric 
9545ffd83dbSDimitry Andric     OS.indent(FullIndexWidth + Indent + 4);
9550b57cec5SDimitry Andric     if (!CompressVTs) {
9560b57cec5SDimitry Andric       OS << EN->getNumVTs();
9570b57cec5SDimitry Andric       if (!OmitComments)
9580b57cec5SDimitry Andric         OS << "/*#VTs*/";
9590b57cec5SDimitry Andric       OS << ", ";
9600b57cec5SDimitry Andric     }
9610b57cec5SDimitry Andric     for (unsigned i = 0, e = EN->getNumVTs(); i != e; ++i)
9620b57cec5SDimitry Andric       OS << getEnumName(EN->getVT(i)) << ", ";
9630b57cec5SDimitry Andric 
9640b57cec5SDimitry Andric     OS << EN->getNumOperands();
9650b57cec5SDimitry Andric     if (!OmitComments)
9660b57cec5SDimitry Andric       OS << "/*#Ops*/";
9670b57cec5SDimitry Andric     OS << ", ";
9680b57cec5SDimitry Andric     unsigned NumOperandBytes = 0;
9690b57cec5SDimitry Andric     for (unsigned i = 0, e = EN->getNumOperands(); i != e; ++i)
9700b57cec5SDimitry Andric       NumOperandBytes += EmitVBRValue(EN->getOperand(i), OS);
9710b57cec5SDimitry Andric 
9720b57cec5SDimitry Andric     if (!OmitComments) {
9730b57cec5SDimitry Andric       // Print the result #'s for EmitNode.
9740b57cec5SDimitry Andric       if (const EmitNodeMatcher *E = dyn_cast<EmitNodeMatcher>(EN)) {
9750b57cec5SDimitry Andric         if (unsigned NumResults = EN->getNumVTs()) {
9760b57cec5SDimitry Andric           OS << " // Results =";
9770b57cec5SDimitry Andric           unsigned First = E->getFirstResultSlot();
9780b57cec5SDimitry Andric           for (unsigned i = 0; i != NumResults; ++i)
9790b57cec5SDimitry Andric             OS << " #" << First + i;
9800b57cec5SDimitry Andric         }
9810b57cec5SDimitry Andric       }
9820b57cec5SDimitry Andric       OS << '\n';
9830b57cec5SDimitry Andric 
9840b57cec5SDimitry Andric       if (const MorphNodeToMatcher *SNT = dyn_cast<MorphNodeToMatcher>(N)) {
985*0fca6ea1SDimitry Andric         OS.indent(FullIndexWidth + Indent)
986*0fca6ea1SDimitry Andric             << "// Src: " << SNT->getPattern().getSrcPattern()
987*0fca6ea1SDimitry Andric             << " - Complexity = " << SNT->getPattern().getPatternComplexity(CGP)
988*0fca6ea1SDimitry Andric             << '\n';
989*0fca6ea1SDimitry Andric         OS.indent(FullIndexWidth + Indent)
990*0fca6ea1SDimitry Andric             << "// Dst: " << SNT->getPattern().getDstPattern() << '\n';
9910b57cec5SDimitry Andric       }
9920b57cec5SDimitry Andric     } else
9930b57cec5SDimitry Andric       OS << '\n';
9940b57cec5SDimitry Andric 
9955f757f3fSDimitry Andric     return 4 + !CompressVTs + !CompressNodeInfo + EN->getNumVTs() +
9965f757f3fSDimitry Andric            NumOperandBytes + NumCoveredBytes;
9970b57cec5SDimitry Andric   }
9980b57cec5SDimitry Andric   case Matcher::CompleteMatch: {
9990b57cec5SDimitry Andric     const CompleteMatchMatcher *CM = cast<CompleteMatchMatcher>(N);
10000b57cec5SDimitry Andric     auto NumCoveredBytes = 0;
10010b57cec5SDimitry Andric     if (InstrumentCoverage) {
10020b57cec5SDimitry Andric       NumCoveredBytes = 3;
10030b57cec5SDimitry Andric       OS << "OPC_Coverage, ";
10040b57cec5SDimitry Andric       std::string src =
10050b57cec5SDimitry Andric           GetPatFromTreePatternNode(CM->getPattern().getSrcPattern());
10060b57cec5SDimitry Andric       std::string dst =
10070b57cec5SDimitry Andric           GetPatFromTreePatternNode(CM->getPattern().getDstPattern());
10080b57cec5SDimitry Andric       Record *PatRecord = CM->getPattern().getSrcRecord();
10090b57cec5SDimitry Andric       std::string include_src = getIncludePath(PatRecord);
10100b57cec5SDimitry Andric       unsigned Offset =
10110b57cec5SDimitry Andric           getPatternIdxFromTable(src + " -> " + dst, std::move(include_src));
10120b57cec5SDimitry Andric       OS << "TARGET_VAL(" << Offset << "),\n";
10135ffd83dbSDimitry Andric       OS.indent(FullIndexWidth + Indent);
10140b57cec5SDimitry Andric     }
10150b57cec5SDimitry Andric     OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";
10160b57cec5SDimitry Andric     unsigned NumResultBytes = 0;
10170b57cec5SDimitry Andric     for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
10180b57cec5SDimitry Andric       NumResultBytes += EmitVBRValue(CM->getResult(i), OS);
10190b57cec5SDimitry Andric     OS << '\n';
10200b57cec5SDimitry Andric     if (!OmitComments) {
1021*0fca6ea1SDimitry Andric       OS.indent(FullIndexWidth + Indent)
1022*0fca6ea1SDimitry Andric           << " // Src: " << CM->getPattern().getSrcPattern()
1023*0fca6ea1SDimitry Andric           << " - Complexity = " << CM->getPattern().getPatternComplexity(CGP)
1024*0fca6ea1SDimitry Andric           << '\n';
1025*0fca6ea1SDimitry Andric       OS.indent(FullIndexWidth + Indent)
1026*0fca6ea1SDimitry Andric           << " // Dst: " << CM->getPattern().getDstPattern();
10270b57cec5SDimitry Andric     }
10280b57cec5SDimitry Andric     OS << '\n';
10290b57cec5SDimitry Andric     return 2 + NumResultBytes + NumCoveredBytes;
10300b57cec5SDimitry Andric   }
10310b57cec5SDimitry Andric   }
10320b57cec5SDimitry Andric   llvm_unreachable("Unreachable");
10330b57cec5SDimitry Andric }
10340b57cec5SDimitry Andric 
1035e8d8bef9SDimitry Andric /// This function traverses the matcher tree and emits all the nodes.
1036e8d8bef9SDimitry Andric /// The nodes have already been sized.
1037*0fca6ea1SDimitry Andric unsigned MatcherTableEmitter::EmitMatcherList(const Matcher *N,
1038*0fca6ea1SDimitry Andric                                               const unsigned Indent,
1039*0fca6ea1SDimitry Andric                                               unsigned CurrentIdx,
10400b57cec5SDimitry Andric                                               raw_ostream &OS) {
10410b57cec5SDimitry Andric   unsigned Size = 0;
10420b57cec5SDimitry Andric   while (N) {
10430b57cec5SDimitry Andric     if (!OmitComments)
10440b57cec5SDimitry Andric       OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
10450b57cec5SDimitry Andric     unsigned MatcherSize = EmitMatcher(N, Indent, CurrentIdx, OS);
10460b57cec5SDimitry Andric     Size += MatcherSize;
10470b57cec5SDimitry Andric     CurrentIdx += MatcherSize;
10480b57cec5SDimitry Andric 
10490b57cec5SDimitry Andric     // If there are other nodes in this list, iterate to them, otherwise we're
10500b57cec5SDimitry Andric     // done.
10510b57cec5SDimitry Andric     N = N->getNext();
10520b57cec5SDimitry Andric   }
10530b57cec5SDimitry Andric   return Size;
10540b57cec5SDimitry Andric }
10550b57cec5SDimitry Andric 
10560b57cec5SDimitry Andric void MatcherTableEmitter::EmitNodePredicatesFunction(
10577a6dacacSDimitry Andric     const std::vector<TreePattern *> &Preds, StringRef Decl, raw_ostream &OS) {
10580b57cec5SDimitry Andric   if (Preds.empty())
10590b57cec5SDimitry Andric     return;
10600b57cec5SDimitry Andric 
10610b57cec5SDimitry Andric   BeginEmitFunction(OS, "bool", Decl, true /*AddOverride*/);
10620b57cec5SDimitry Andric   OS << "{\n";
10630b57cec5SDimitry Andric   OS << "  switch (PredNo) {\n";
10640b57cec5SDimitry Andric   OS << "  default: llvm_unreachable(\"Invalid predicate in table?\");\n";
10650b57cec5SDimitry Andric   for (unsigned i = 0, e = Preds.size(); i != e; ++i) {
10660b57cec5SDimitry Andric     // Emit the predicate code corresponding to this pattern.
10677a6dacacSDimitry Andric     TreePredicateFn PredFn(Preds[i]);
10680b57cec5SDimitry Andric     assert(!PredFn.isAlwaysTrue() && "No code in this predicate");
1069fe6060f1SDimitry Andric     std::string PredFnCodeStr = PredFn.getCodeToRunOnSDNode();
10700b57cec5SDimitry Andric 
1071fe6060f1SDimitry Andric     OS << "  case " << i << ": {\n";
1072fe6060f1SDimitry Andric     for (auto *SimilarPred : NodePredicatesByCodeToRun[PredFnCodeStr])
1073fe6060f1SDimitry Andric       OS << "    // " << TreePredicateFn(SimilarPred).getFnName() << '\n';
1074fe6060f1SDimitry Andric     OS << PredFnCodeStr << "\n  }\n";
10750b57cec5SDimitry Andric   }
10760b57cec5SDimitry Andric   OS << "  }\n";
10770b57cec5SDimitry Andric   OS << "}\n";
10780b57cec5SDimitry Andric   EndEmitFunction(OS);
10790b57cec5SDimitry Andric }
10800b57cec5SDimitry Andric 
10810b57cec5SDimitry Andric void MatcherTableEmitter::EmitPredicateFunctions(raw_ostream &OS) {
10820b57cec5SDimitry Andric   // Emit pattern predicates.
10830b57cec5SDimitry Andric   if (!PatternPredicates.empty()) {
10840b57cec5SDimitry Andric     BeginEmitFunction(OS, "bool",
1085*0fca6ea1SDimitry Andric                       "CheckPatternPredicate(unsigned PredNo) const",
1086*0fca6ea1SDimitry Andric                       true /*AddOverride*/);
10870b57cec5SDimitry Andric     OS << "{\n";
10880b57cec5SDimitry Andric     OS << "  switch (PredNo) {\n";
10890b57cec5SDimitry Andric     OS << "  default: llvm_unreachable(\"Invalid predicate in table?\");\n";
10900b57cec5SDimitry Andric     for (unsigned i = 0, e = PatternPredicates.size(); i != e; ++i)
10910b57cec5SDimitry Andric       OS << "  case " << i << ": return " << PatternPredicates[i] << ";\n";
10920b57cec5SDimitry Andric     OS << "  }\n";
10930b57cec5SDimitry Andric     OS << "}\n";
10940b57cec5SDimitry Andric     EndEmitFunction(OS);
10950b57cec5SDimitry Andric   }
10960b57cec5SDimitry Andric 
10970b57cec5SDimitry Andric   // Emit Node predicates.
10980b57cec5SDimitry Andric   EmitNodePredicatesFunction(
10990b57cec5SDimitry Andric       NodePredicates, "CheckNodePredicate(SDNode *Node, unsigned PredNo) const",
11000b57cec5SDimitry Andric       OS);
11010b57cec5SDimitry Andric   EmitNodePredicatesFunction(
11020b57cec5SDimitry Andric       NodePredicatesWithOperands,
11030b57cec5SDimitry Andric       "CheckNodePredicateWithOperands(SDNode *Node, unsigned PredNo, "
11040b57cec5SDimitry Andric       "const SmallVectorImpl<SDValue> &Operands) const",
11050b57cec5SDimitry Andric       OS);
11060b57cec5SDimitry Andric 
11070b57cec5SDimitry Andric   // Emit CompletePattern matchers.
11080b57cec5SDimitry Andric   // FIXME: This should be const.
11090b57cec5SDimitry Andric   if (!ComplexPatterns.empty()) {
1110*0fca6ea1SDimitry Andric     BeginEmitFunction(
1111*0fca6ea1SDimitry Andric         OS, "bool",
11120b57cec5SDimitry Andric         "CheckComplexPattern(SDNode *Root, SDNode *Parent,\n"
11130b57cec5SDimitry Andric         "      SDValue N, unsigned PatternNo,\n"
11140b57cec5SDimitry Andric         "      SmallVectorImpl<std::pair<SDValue, SDNode *>> &Result)",
11150b57cec5SDimitry Andric         true /*AddOverride*/);
11160b57cec5SDimitry Andric     OS << "{\n";
11170b57cec5SDimitry Andric     OS << "  unsigned NextRes = Result.size();\n";
11180b57cec5SDimitry Andric     OS << "  switch (PatternNo) {\n";
11190b57cec5SDimitry Andric     OS << "  default: llvm_unreachable(\"Invalid pattern # in table?\");\n";
11200b57cec5SDimitry Andric     for (unsigned i = 0, e = ComplexPatterns.size(); i != e; ++i) {
11210b57cec5SDimitry Andric       const ComplexPattern &P = *ComplexPatterns[i];
11220b57cec5SDimitry Andric       unsigned NumOps = P.getNumOperands();
11230b57cec5SDimitry Andric 
11240b57cec5SDimitry Andric       if (P.hasProperty(SDNPHasChain))
11250b57cec5SDimitry Andric         ++NumOps; // Get the chained node too.
11260b57cec5SDimitry Andric 
11270b57cec5SDimitry Andric       OS << "  case " << i << ":\n";
11280b57cec5SDimitry Andric       if (InstrumentCoverage)
11290b57cec5SDimitry Andric         OS << "  {\n";
11300b57cec5SDimitry Andric       OS << "    Result.resize(NextRes+" << NumOps << ");\n";
11310b57cec5SDimitry Andric       if (InstrumentCoverage)
11320b57cec5SDimitry Andric         OS << "    bool Succeeded = " << P.getSelectFunc();
11330b57cec5SDimitry Andric       else
11340b57cec5SDimitry Andric         OS << "  return " << P.getSelectFunc();
11350b57cec5SDimitry Andric 
11360b57cec5SDimitry Andric       OS << "(";
11370b57cec5SDimitry Andric       // If the complex pattern wants the root of the match, pass it in as the
11380b57cec5SDimitry Andric       // first argument.
11390b57cec5SDimitry Andric       if (P.hasProperty(SDNPWantRoot))
11400b57cec5SDimitry Andric         OS << "Root, ";
11410b57cec5SDimitry Andric 
11420b57cec5SDimitry Andric       // If the complex pattern wants the parent of the operand being matched,
11430b57cec5SDimitry Andric       // pass it in as the next argument.
11440b57cec5SDimitry Andric       if (P.hasProperty(SDNPWantParent))
11450b57cec5SDimitry Andric         OS << "Parent, ";
11460b57cec5SDimitry Andric 
11470b57cec5SDimitry Andric       OS << "N";
11480b57cec5SDimitry Andric       for (unsigned i = 0; i != NumOps; ++i)
11490b57cec5SDimitry Andric         OS << ", Result[NextRes+" << i << "].first";
11500b57cec5SDimitry Andric       OS << ");\n";
11510b57cec5SDimitry Andric       if (InstrumentCoverage) {
11520b57cec5SDimitry Andric         OS << "    if (Succeeded)\n";
11530b57cec5SDimitry Andric         OS << "       dbgs() << \"\\nCOMPLEX_PATTERN: " << P.getSelectFunc()
11540b57cec5SDimitry Andric            << "\\n\" ;\n";
11550b57cec5SDimitry Andric         OS << "    return Succeeded;\n";
11560b57cec5SDimitry Andric         OS << "    }\n";
11570b57cec5SDimitry Andric       }
11580b57cec5SDimitry Andric     }
11590b57cec5SDimitry Andric     OS << "  }\n";
11600b57cec5SDimitry Andric     OS << "}\n";
11610b57cec5SDimitry Andric     EndEmitFunction(OS);
11620b57cec5SDimitry Andric   }
11630b57cec5SDimitry Andric 
11640b57cec5SDimitry Andric   // Emit SDNodeXForm handlers.
11650b57cec5SDimitry Andric   // FIXME: This should be const.
11660b57cec5SDimitry Andric   if (!NodeXForms.empty()) {
11670b57cec5SDimitry Andric     BeginEmitFunction(OS, "SDValue",
1168*0fca6ea1SDimitry Andric                       "RunSDNodeXForm(SDValue V, unsigned XFormNo)",
1169*0fca6ea1SDimitry Andric                       true /*AddOverride*/);
11700b57cec5SDimitry Andric     OS << "{\n";
11710b57cec5SDimitry Andric     OS << "  switch (XFormNo) {\n";
11720b57cec5SDimitry Andric     OS << "  default: llvm_unreachable(\"Invalid xform # in table?\");\n";
11730b57cec5SDimitry Andric 
11740b57cec5SDimitry Andric     // FIXME: The node xform could take SDValue's instead of SDNode*'s.
11750b57cec5SDimitry Andric     for (unsigned i = 0, e = NodeXForms.size(); i != e; ++i) {
11760b57cec5SDimitry Andric       const CodeGenDAGPatterns::NodeXForm &Entry =
11770b57cec5SDimitry Andric           CGP.getSDNodeTransform(NodeXForms[i]);
11780b57cec5SDimitry Andric 
11790b57cec5SDimitry Andric       Record *SDNode = Entry.first;
11800b57cec5SDimitry Andric       const std::string &Code = Entry.second;
11810b57cec5SDimitry Andric 
11820b57cec5SDimitry Andric       OS << "  case " << i << ": {  ";
11830b57cec5SDimitry Andric       if (!OmitComments)
11840b57cec5SDimitry Andric         OS << "// " << NodeXForms[i]->getName();
11850b57cec5SDimitry Andric       OS << '\n';
11860b57cec5SDimitry Andric 
11875ffd83dbSDimitry Andric       std::string ClassName =
11885ffd83dbSDimitry Andric           std::string(CGP.getSDNodeInfo(SDNode).getSDClassName());
11890b57cec5SDimitry Andric       if (ClassName == "SDNode")
11900b57cec5SDimitry Andric         OS << "    SDNode *N = V.getNode();\n";
11910b57cec5SDimitry Andric       else
11920b57cec5SDimitry Andric         OS << "    " << ClassName << " *N = cast<" << ClassName
11930b57cec5SDimitry Andric            << ">(V.getNode());\n";
11940b57cec5SDimitry Andric       OS << Code << "\n  }\n";
11950b57cec5SDimitry Andric     }
11960b57cec5SDimitry Andric     OS << "  }\n";
11970b57cec5SDimitry Andric     OS << "}\n";
11980b57cec5SDimitry Andric     EndEmitFunction(OS);
11990b57cec5SDimitry Andric   }
12000b57cec5SDimitry Andric }
12010b57cec5SDimitry Andric 
12020b57cec5SDimitry Andric static StringRef getOpcodeString(Matcher::KindTy Kind) {
12030b57cec5SDimitry Andric   switch (Kind) {
12045f757f3fSDimitry Andric   case Matcher::Scope:
12055f757f3fSDimitry Andric     return "OPC_Scope";
12065f757f3fSDimitry Andric   case Matcher::RecordNode:
12075f757f3fSDimitry Andric     return "OPC_RecordNode";
12085f757f3fSDimitry Andric   case Matcher::RecordChild:
12095f757f3fSDimitry Andric     return "OPC_RecordChild";
12105f757f3fSDimitry Andric   case Matcher::RecordMemRef:
12115f757f3fSDimitry Andric     return "OPC_RecordMemRef";
12125f757f3fSDimitry Andric   case Matcher::CaptureGlueInput:
12135f757f3fSDimitry Andric     return "OPC_CaptureGlueInput";
12145f757f3fSDimitry Andric   case Matcher::MoveChild:
12155f757f3fSDimitry Andric     return "OPC_MoveChild";
12165f757f3fSDimitry Andric   case Matcher::MoveSibling:
12175f757f3fSDimitry Andric     return "OPC_MoveSibling";
12185f757f3fSDimitry Andric   case Matcher::MoveParent:
12195f757f3fSDimitry Andric     return "OPC_MoveParent";
12205f757f3fSDimitry Andric   case Matcher::CheckSame:
12215f757f3fSDimitry Andric     return "OPC_CheckSame";
12225f757f3fSDimitry Andric   case Matcher::CheckChildSame:
12235f757f3fSDimitry Andric     return "OPC_CheckChildSame";
12240b57cec5SDimitry Andric   case Matcher::CheckPatternPredicate:
12255f757f3fSDimitry Andric     return "OPC_CheckPatternPredicate";
12265f757f3fSDimitry Andric   case Matcher::CheckPredicate:
12275f757f3fSDimitry Andric     return "OPC_CheckPredicate";
12285f757f3fSDimitry Andric   case Matcher::CheckOpcode:
12295f757f3fSDimitry Andric     return "OPC_CheckOpcode";
12305f757f3fSDimitry Andric   case Matcher::SwitchOpcode:
12315f757f3fSDimitry Andric     return "OPC_SwitchOpcode";
12325f757f3fSDimitry Andric   case Matcher::CheckType:
12335f757f3fSDimitry Andric     return "OPC_CheckType";
12345f757f3fSDimitry Andric   case Matcher::SwitchType:
12355f757f3fSDimitry Andric     return "OPC_SwitchType";
12365f757f3fSDimitry Andric   case Matcher::CheckChildType:
12375f757f3fSDimitry Andric     return "OPC_CheckChildType";
12385f757f3fSDimitry Andric   case Matcher::CheckInteger:
12395f757f3fSDimitry Andric     return "OPC_CheckInteger";
12405f757f3fSDimitry Andric   case Matcher::CheckChildInteger:
12415f757f3fSDimitry Andric     return "OPC_CheckChildInteger";
12425f757f3fSDimitry Andric   case Matcher::CheckCondCode:
12435f757f3fSDimitry Andric     return "OPC_CheckCondCode";
12445f757f3fSDimitry Andric   case Matcher::CheckChild2CondCode:
12455f757f3fSDimitry Andric     return "OPC_CheckChild2CondCode";
12465f757f3fSDimitry Andric   case Matcher::CheckValueType:
12475f757f3fSDimitry Andric     return "OPC_CheckValueType";
12485f757f3fSDimitry Andric   case Matcher::CheckComplexPat:
12495f757f3fSDimitry Andric     return "OPC_CheckComplexPat";
12505f757f3fSDimitry Andric   case Matcher::CheckAndImm:
12515f757f3fSDimitry Andric     return "OPC_CheckAndImm";
12525f757f3fSDimitry Andric   case Matcher::CheckOrImm:
12535f757f3fSDimitry Andric     return "OPC_CheckOrImm";
12540b57cec5SDimitry Andric   case Matcher::CheckFoldableChainNode:
12555f757f3fSDimitry Andric     return "OPC_CheckFoldableChainNode";
12565f757f3fSDimitry Andric   case Matcher::CheckImmAllOnesV:
12575f757f3fSDimitry Andric     return "OPC_CheckImmAllOnesV";
12585f757f3fSDimitry Andric   case Matcher::CheckImmAllZerosV:
12595f757f3fSDimitry Andric     return "OPC_CheckImmAllZerosV";
12605f757f3fSDimitry Andric   case Matcher::EmitInteger:
12615f757f3fSDimitry Andric     return "OPC_EmitInteger";
12625f757f3fSDimitry Andric   case Matcher::EmitStringInteger:
12635f757f3fSDimitry Andric     return "OPC_EmitStringInteger";
12645f757f3fSDimitry Andric   case Matcher::EmitRegister:
12655f757f3fSDimitry Andric     return "OPC_EmitRegister";
12665f757f3fSDimitry Andric   case Matcher::EmitConvertToTarget:
12675f757f3fSDimitry Andric     return "OPC_EmitConvertToTarget";
12685f757f3fSDimitry Andric   case Matcher::EmitMergeInputChains:
12695f757f3fSDimitry Andric     return "OPC_EmitMergeInputChains";
12705f757f3fSDimitry Andric   case Matcher::EmitCopyToReg:
12715f757f3fSDimitry Andric     return "OPC_EmitCopyToReg";
12725f757f3fSDimitry Andric   case Matcher::EmitNode:
12735f757f3fSDimitry Andric     return "OPC_EmitNode";
12745f757f3fSDimitry Andric   case Matcher::MorphNodeTo:
12755f757f3fSDimitry Andric     return "OPC_MorphNodeTo";
12765f757f3fSDimitry Andric   case Matcher::EmitNodeXForm:
12775f757f3fSDimitry Andric     return "OPC_EmitNodeXForm";
12785f757f3fSDimitry Andric   case Matcher::CompleteMatch:
12795f757f3fSDimitry Andric     return "OPC_CompleteMatch";
12800b57cec5SDimitry Andric   }
12810b57cec5SDimitry Andric 
12820b57cec5SDimitry Andric   llvm_unreachable("Unhandled opcode?");
12830b57cec5SDimitry Andric }
12840b57cec5SDimitry Andric 
1285*0fca6ea1SDimitry Andric void MatcherTableEmitter::EmitHistogram(const Matcher *M, raw_ostream &OS) {
12860b57cec5SDimitry Andric   if (OmitComments)
12870b57cec5SDimitry Andric     return;
12880b57cec5SDimitry Andric 
12890b57cec5SDimitry Andric   OS << "  // Opcode Histogram:\n";
1290e8d8bef9SDimitry Andric   for (unsigned i = 0, e = OpcodeCounts.size(); i != e; ++i) {
12910b57cec5SDimitry Andric     OS << "  // #"
12920b57cec5SDimitry Andric        << left_justify(getOpcodeString((Matcher::KindTy)i), HistOpcWidth)
1293e8d8bef9SDimitry Andric        << " = " << OpcodeCounts[i] << '\n';
12940b57cec5SDimitry Andric   }
12950b57cec5SDimitry Andric   OS << '\n';
12960b57cec5SDimitry Andric }
12970b57cec5SDimitry Andric 
1298*0fca6ea1SDimitry Andric void llvm::EmitMatcherTable(Matcher *TheMatcher, const CodeGenDAGPatterns &CGP,
12990b57cec5SDimitry Andric                             raw_ostream &OS) {
13000b57cec5SDimitry Andric   OS << "#if defined(GET_DAGISEL_DECL) && defined(GET_DAGISEL_BODY)\n";
13010b57cec5SDimitry Andric   OS << "#error GET_DAGISEL_DECL and GET_DAGISEL_BODY cannot be both defined, ";
13020b57cec5SDimitry Andric   OS << "undef both for inline definitions\n";
13030b57cec5SDimitry Andric   OS << "#endif\n\n";
13040b57cec5SDimitry Andric 
13050b57cec5SDimitry Andric   // Emit a check for omitted class name.
13060b57cec5SDimitry Andric   OS << "#ifdef GET_DAGISEL_BODY\n";
13070b57cec5SDimitry Andric   OS << "#define LOCAL_DAGISEL_STRINGIZE(X) LOCAL_DAGISEL_STRINGIZE_(X)\n";
13080b57cec5SDimitry Andric   OS << "#define LOCAL_DAGISEL_STRINGIZE_(X) #X\n";
13090b57cec5SDimitry Andric   OS << "static_assert(sizeof(LOCAL_DAGISEL_STRINGIZE(GET_DAGISEL_BODY)) > 1,"
13100b57cec5SDimitry Andric         "\n";
13110b57cec5SDimitry Andric   OS << "   \"GET_DAGISEL_BODY is empty: it should be defined with the class "
13120b57cec5SDimitry Andric         "name\");\n";
13130b57cec5SDimitry Andric   OS << "#undef LOCAL_DAGISEL_STRINGIZE_\n";
13140b57cec5SDimitry Andric   OS << "#undef LOCAL_DAGISEL_STRINGIZE\n";
13150b57cec5SDimitry Andric   OS << "#endif\n\n";
13160b57cec5SDimitry Andric 
13170b57cec5SDimitry Andric   OS << "#if !defined(GET_DAGISEL_DECL) && !defined(GET_DAGISEL_BODY)\n";
13180b57cec5SDimitry Andric   OS << "#define DAGISEL_INLINE 1\n";
13190b57cec5SDimitry Andric   OS << "#else\n";
13200b57cec5SDimitry Andric   OS << "#define DAGISEL_INLINE 0\n";
13210b57cec5SDimitry Andric   OS << "#endif\n\n";
13220b57cec5SDimitry Andric 
13230b57cec5SDimitry Andric   OS << "#if !DAGISEL_INLINE\n";
13240b57cec5SDimitry Andric   OS << "#define DAGISEL_CLASS_COLONCOLON GET_DAGISEL_BODY ::\n";
13250b57cec5SDimitry Andric   OS << "#else\n";
13260b57cec5SDimitry Andric   OS << "#define DAGISEL_CLASS_COLONCOLON\n";
13270b57cec5SDimitry Andric   OS << "#endif\n\n";
13280b57cec5SDimitry Andric 
13290b57cec5SDimitry Andric   BeginEmitFunction(OS, "void", "SelectCode(SDNode *N)", false /*AddOverride*/);
1330297eecfbSDimitry Andric   MatcherTableEmitter MatcherEmitter(TheMatcher, CGP);
13310b57cec5SDimitry Andric 
1332e8d8bef9SDimitry Andric   // First we size all the children of the three kinds of matchers that have
1333e8d8bef9SDimitry Andric   // them. This is done by sharing the code in EmitMatcher(). but we don't
1334e8d8bef9SDimitry Andric   // want to emit anything, so we turn off comments and use a null stream.
1335e8d8bef9SDimitry Andric   bool SaveOmitComments = OmitComments;
1336e8d8bef9SDimitry Andric   OmitComments = true;
1337e8d8bef9SDimitry Andric   raw_null_ostream NullOS;
1338e8d8bef9SDimitry Andric   unsigned TotalSize = MatcherEmitter.SizeMatcherList(TheMatcher, NullOS);
1339e8d8bef9SDimitry Andric   OmitComments = SaveOmitComments;
1340e8d8bef9SDimitry Andric 
1341e8d8bef9SDimitry Andric   // Now that the matchers are sized, we can emit the code for them to the
1342e8d8bef9SDimitry Andric   // final stream.
13430b57cec5SDimitry Andric   OS << "{\n";
13440b57cec5SDimitry Andric   OS << "  // Some target values are emitted as 2 bytes, TARGET_VAL handles\n";
13450b57cec5SDimitry Andric   OS << "  // this.\n";
13460b57cec5SDimitry Andric   OS << "  #define TARGET_VAL(X) X & 255, unsigned(X) >> 8\n";
13470b57cec5SDimitry Andric   OS << "  static const unsigned char MatcherTable[] = {\n";
1348e8d8bef9SDimitry Andric   TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 1, 0, OS);
1349*0fca6ea1SDimitry Andric   OS << "    0\n  }; // Total Array size is " << (TotalSize + 1)
1350*0fca6ea1SDimitry Andric      << " bytes\n\n";
13510b57cec5SDimitry Andric 
13520b57cec5SDimitry Andric   MatcherEmitter.EmitHistogram(TheMatcher, OS);
13530b57cec5SDimitry Andric 
13540b57cec5SDimitry Andric   OS << "  #undef TARGET_VAL\n";
13550b57cec5SDimitry Andric   OS << "  SelectCodeCommon(N, MatcherTable, sizeof(MatcherTable));\n";
13560b57cec5SDimitry Andric   OS << "}\n";
13570b57cec5SDimitry Andric   EndEmitFunction(OS);
13580b57cec5SDimitry Andric 
13590b57cec5SDimitry Andric   // Next up, emit the function for node and pattern predicates:
13600b57cec5SDimitry Andric   MatcherEmitter.EmitPredicateFunctions(OS);
13610b57cec5SDimitry Andric 
13620b57cec5SDimitry Andric   if (InstrumentCoverage)
13630b57cec5SDimitry Andric     MatcherEmitter.EmitPatternMatchTable(OS);
13640b57cec5SDimitry Andric 
13650b57cec5SDimitry Andric   // Clean up the preprocessor macros.
13660b57cec5SDimitry Andric   OS << "\n";
13670b57cec5SDimitry Andric   OS << "#ifdef DAGISEL_INLINE\n";
13680b57cec5SDimitry Andric   OS << "#undef DAGISEL_INLINE\n";
13690b57cec5SDimitry Andric   OS << "#endif\n";
13700b57cec5SDimitry Andric   OS << "#ifdef DAGISEL_CLASS_COLONCOLON\n";
13710b57cec5SDimitry Andric   OS << "#undef DAGISEL_CLASS_COLONCOLON\n";
13720b57cec5SDimitry Andric   OS << "#endif\n";
13730b57cec5SDimitry Andric   OS << "#ifdef GET_DAGISEL_DECL\n";
13740b57cec5SDimitry Andric   OS << "#undef GET_DAGISEL_DECL\n";
13750b57cec5SDimitry Andric   OS << "#endif\n";
13760b57cec5SDimitry Andric   OS << "#ifdef GET_DAGISEL_BODY\n";
13770b57cec5SDimitry Andric   OS << "#undef GET_DAGISEL_BODY\n";
13780b57cec5SDimitry Andric   OS << "#endif\n";
13790b57cec5SDimitry Andric }
1380