1*9880d681SAndroid Build Coastguard Worker //===- DAGISelMatcherEmitter.cpp - Matcher Emitter ------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains code to generate C++ code for a matcher.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "DAGISelMatcher.h"
15*9880d681SAndroid Build Coastguard Worker #include "CodeGenDAGPatterns.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/DenseMap.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallString.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringMap.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/TinyPtrVector.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FormattedStream.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/TableGen/Record.h"
23*9880d681SAndroid Build Coastguard Worker using namespace llvm;
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker enum {
26*9880d681SAndroid Build Coastguard Worker CommentIndent = 30
27*9880d681SAndroid Build Coastguard Worker };
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker // To reduce generated source code size.
30*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
31*9880d681SAndroid Build Coastguard Worker OmitComments("omit-comments", cl::desc("Do not generate comments"),
32*9880d681SAndroid Build Coastguard Worker cl::init(false));
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker namespace {
35*9880d681SAndroid Build Coastguard Worker class MatcherTableEmitter {
36*9880d681SAndroid Build Coastguard Worker const CodeGenDAGPatterns &CGP;
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker DenseMap<TreePattern *, unsigned> NodePredicateMap;
39*9880d681SAndroid Build Coastguard Worker std::vector<TreePredicateFn> NodePredicates;
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Worker // We de-duplicate the predicates by code string, and use this map to track
42*9880d681SAndroid Build Coastguard Worker // all the patterns with "identical" predicates.
43*9880d681SAndroid Build Coastguard Worker StringMap<TinyPtrVector<TreePattern *>> NodePredicatesByCodeToRun;
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker StringMap<unsigned> PatternPredicateMap;
46*9880d681SAndroid Build Coastguard Worker std::vector<std::string> PatternPredicates;
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker DenseMap<const ComplexPattern*, unsigned> ComplexPatternMap;
49*9880d681SAndroid Build Coastguard Worker std::vector<const ComplexPattern*> ComplexPatterns;
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker DenseMap<Record*, unsigned> NodeXFormMap;
53*9880d681SAndroid Build Coastguard Worker std::vector<Record*> NodeXForms;
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker public:
MatcherTableEmitter(const CodeGenDAGPatterns & cgp)56*9880d681SAndroid Build Coastguard Worker MatcherTableEmitter(const CodeGenDAGPatterns &cgp)
57*9880d681SAndroid Build Coastguard Worker : CGP(cgp) {}
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker unsigned EmitMatcherList(const Matcher *N, unsigned Indent,
60*9880d681SAndroid Build Coastguard Worker unsigned StartIdx, formatted_raw_ostream &OS);
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker void EmitPredicateFunctions(formatted_raw_ostream &OS);
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker void EmitHistogram(const Matcher *N, formatted_raw_ostream &OS);
65*9880d681SAndroid Build Coastguard Worker private:
66*9880d681SAndroid Build Coastguard Worker unsigned EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
67*9880d681SAndroid Build Coastguard Worker formatted_raw_ostream &OS);
68*9880d681SAndroid Build Coastguard Worker
getNodePredicate(TreePredicateFn Pred)69*9880d681SAndroid Build Coastguard Worker unsigned getNodePredicate(TreePredicateFn Pred) {
70*9880d681SAndroid Build Coastguard Worker TreePattern *TP = Pred.getOrigPatFragRecord();
71*9880d681SAndroid Build Coastguard Worker unsigned &Entry = NodePredicateMap[TP];
72*9880d681SAndroid Build Coastguard Worker if (Entry == 0) {
73*9880d681SAndroid Build Coastguard Worker TinyPtrVector<TreePattern *> &SameCodePreds =
74*9880d681SAndroid Build Coastguard Worker NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode()];
75*9880d681SAndroid Build Coastguard Worker if (SameCodePreds.empty()) {
76*9880d681SAndroid Build Coastguard Worker // We've never seen a predicate with the same code: allocate an entry.
77*9880d681SAndroid Build Coastguard Worker NodePredicates.push_back(Pred);
78*9880d681SAndroid Build Coastguard Worker Entry = NodePredicates.size();
79*9880d681SAndroid Build Coastguard Worker } else {
80*9880d681SAndroid Build Coastguard Worker // We did see an identical predicate: re-use it.
81*9880d681SAndroid Build Coastguard Worker Entry = NodePredicateMap[SameCodePreds.front()];
82*9880d681SAndroid Build Coastguard Worker assert(Entry != 0);
83*9880d681SAndroid Build Coastguard Worker }
84*9880d681SAndroid Build Coastguard Worker // In both cases, we've never seen this particular predicate before, so
85*9880d681SAndroid Build Coastguard Worker // mark it in the list of predicates sharing the same code.
86*9880d681SAndroid Build Coastguard Worker SameCodePreds.push_back(TP);
87*9880d681SAndroid Build Coastguard Worker }
88*9880d681SAndroid Build Coastguard Worker return Entry-1;
89*9880d681SAndroid Build Coastguard Worker }
90*9880d681SAndroid Build Coastguard Worker
getPatternPredicate(StringRef PredName)91*9880d681SAndroid Build Coastguard Worker unsigned getPatternPredicate(StringRef PredName) {
92*9880d681SAndroid Build Coastguard Worker unsigned &Entry = PatternPredicateMap[PredName];
93*9880d681SAndroid Build Coastguard Worker if (Entry == 0) {
94*9880d681SAndroid Build Coastguard Worker PatternPredicates.push_back(PredName.str());
95*9880d681SAndroid Build Coastguard Worker Entry = PatternPredicates.size();
96*9880d681SAndroid Build Coastguard Worker }
97*9880d681SAndroid Build Coastguard Worker return Entry-1;
98*9880d681SAndroid Build Coastguard Worker }
getComplexPat(const ComplexPattern & P)99*9880d681SAndroid Build Coastguard Worker unsigned getComplexPat(const ComplexPattern &P) {
100*9880d681SAndroid Build Coastguard Worker unsigned &Entry = ComplexPatternMap[&P];
101*9880d681SAndroid Build Coastguard Worker if (Entry == 0) {
102*9880d681SAndroid Build Coastguard Worker ComplexPatterns.push_back(&P);
103*9880d681SAndroid Build Coastguard Worker Entry = ComplexPatterns.size();
104*9880d681SAndroid Build Coastguard Worker }
105*9880d681SAndroid Build Coastguard Worker return Entry-1;
106*9880d681SAndroid Build Coastguard Worker }
107*9880d681SAndroid Build Coastguard Worker
getNodeXFormID(Record * Rec)108*9880d681SAndroid Build Coastguard Worker unsigned getNodeXFormID(Record *Rec) {
109*9880d681SAndroid Build Coastguard Worker unsigned &Entry = NodeXFormMap[Rec];
110*9880d681SAndroid Build Coastguard Worker if (Entry == 0) {
111*9880d681SAndroid Build Coastguard Worker NodeXForms.push_back(Rec);
112*9880d681SAndroid Build Coastguard Worker Entry = NodeXForms.size();
113*9880d681SAndroid Build Coastguard Worker }
114*9880d681SAndroid Build Coastguard Worker return Entry-1;
115*9880d681SAndroid Build Coastguard Worker }
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker };
118*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace.
119*9880d681SAndroid Build Coastguard Worker
GetVBRSize(unsigned Val)120*9880d681SAndroid Build Coastguard Worker static unsigned GetVBRSize(unsigned Val) {
121*9880d681SAndroid Build Coastguard Worker if (Val <= 127) return 1;
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker unsigned NumBytes = 0;
124*9880d681SAndroid Build Coastguard Worker while (Val >= 128) {
125*9880d681SAndroid Build Coastguard Worker Val >>= 7;
126*9880d681SAndroid Build Coastguard Worker ++NumBytes;
127*9880d681SAndroid Build Coastguard Worker }
128*9880d681SAndroid Build Coastguard Worker return NumBytes+1;
129*9880d681SAndroid Build Coastguard Worker }
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker /// EmitVBRValue - Emit the specified value as a VBR, returning the number of
132*9880d681SAndroid Build Coastguard Worker /// bytes emitted.
EmitVBRValue(uint64_t Val,raw_ostream & OS)133*9880d681SAndroid Build Coastguard Worker static uint64_t EmitVBRValue(uint64_t Val, raw_ostream &OS) {
134*9880d681SAndroid Build Coastguard Worker if (Val <= 127) {
135*9880d681SAndroid Build Coastguard Worker OS << Val << ", ";
136*9880d681SAndroid Build Coastguard Worker return 1;
137*9880d681SAndroid Build Coastguard Worker }
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Worker uint64_t InVal = Val;
140*9880d681SAndroid Build Coastguard Worker unsigned NumBytes = 0;
141*9880d681SAndroid Build Coastguard Worker while (Val >= 128) {
142*9880d681SAndroid Build Coastguard Worker OS << (Val&127) << "|128,";
143*9880d681SAndroid Build Coastguard Worker Val >>= 7;
144*9880d681SAndroid Build Coastguard Worker ++NumBytes;
145*9880d681SAndroid Build Coastguard Worker }
146*9880d681SAndroid Build Coastguard Worker OS << Val;
147*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
148*9880d681SAndroid Build Coastguard Worker OS << "/*" << InVal << "*/";
149*9880d681SAndroid Build Coastguard Worker OS << ", ";
150*9880d681SAndroid Build Coastguard Worker return NumBytes+1;
151*9880d681SAndroid Build Coastguard Worker }
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Worker /// EmitMatcher - Emit bytes for the specified matcher and return
154*9880d681SAndroid Build Coastguard Worker /// the number of bytes emitted.
155*9880d681SAndroid Build Coastguard Worker unsigned MatcherTableEmitter::
EmitMatcher(const Matcher * N,unsigned Indent,unsigned CurrentIdx,formatted_raw_ostream & OS)156*9880d681SAndroid Build Coastguard Worker EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
157*9880d681SAndroid Build Coastguard Worker formatted_raw_ostream &OS) {
158*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(Indent*2);
159*9880d681SAndroid Build Coastguard Worker
160*9880d681SAndroid Build Coastguard Worker switch (N->getKind()) {
161*9880d681SAndroid Build Coastguard Worker case Matcher::Scope: {
162*9880d681SAndroid Build Coastguard Worker const ScopeMatcher *SM = cast<ScopeMatcher>(N);
163*9880d681SAndroid Build Coastguard Worker assert(SM->getNext() == nullptr && "Shouldn't have next after scope");
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Worker unsigned StartIdx = CurrentIdx;
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Worker // Emit all of the children.
168*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) {
169*9880d681SAndroid Build Coastguard Worker if (i == 0) {
170*9880d681SAndroid Build Coastguard Worker OS << "OPC_Scope, ";
171*9880d681SAndroid Build Coastguard Worker ++CurrentIdx;
172*9880d681SAndroid Build Coastguard Worker } else {
173*9880d681SAndroid Build Coastguard Worker if (!OmitComments) {
174*9880d681SAndroid Build Coastguard Worker OS << "/*" << CurrentIdx << "*/";
175*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(Indent*2) << "/*Scope*/ ";
176*9880d681SAndroid Build Coastguard Worker } else
177*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(Indent*2);
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Worker // We need to encode the child and the offset of the failure code before
181*9880d681SAndroid Build Coastguard Worker // emitting either of them. Handle this by buffering the output into a
182*9880d681SAndroid Build Coastguard Worker // string while we get the size. Unfortunately, the offset of the
183*9880d681SAndroid Build Coastguard Worker // children depends on the VBR size of the child, so for large children we
184*9880d681SAndroid Build Coastguard Worker // have to iterate a bit.
185*9880d681SAndroid Build Coastguard Worker SmallString<128> TmpBuf;
186*9880d681SAndroid Build Coastguard Worker unsigned ChildSize = 0;
187*9880d681SAndroid Build Coastguard Worker unsigned VBRSize = 0;
188*9880d681SAndroid Build Coastguard Worker do {
189*9880d681SAndroid Build Coastguard Worker VBRSize = GetVBRSize(ChildSize);
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker TmpBuf.clear();
192*9880d681SAndroid Build Coastguard Worker raw_svector_ostream OS(TmpBuf);
193*9880d681SAndroid Build Coastguard Worker formatted_raw_ostream FOS(OS);
194*9880d681SAndroid Build Coastguard Worker ChildSize = EmitMatcherList(SM->getChild(i), Indent+1,
195*9880d681SAndroid Build Coastguard Worker CurrentIdx+VBRSize, FOS);
196*9880d681SAndroid Build Coastguard Worker } while (GetVBRSize(ChildSize) != VBRSize);
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Worker assert(ChildSize != 0 && "Should not have a zero-sized child!");
199*9880d681SAndroid Build Coastguard Worker
200*9880d681SAndroid Build Coastguard Worker CurrentIdx += EmitVBRValue(ChildSize, OS);
201*9880d681SAndroid Build Coastguard Worker if (!OmitComments) {
202*9880d681SAndroid Build Coastguard Worker OS << "/*->" << CurrentIdx+ChildSize << "*/";
203*9880d681SAndroid Build Coastguard Worker
204*9880d681SAndroid Build Coastguard Worker if (i == 0)
205*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(CommentIndent) << "// " << SM->getNumChildren()
206*9880d681SAndroid Build Coastguard Worker << " children in Scope";
207*9880d681SAndroid Build Coastguard Worker }
208*9880d681SAndroid Build Coastguard Worker
209*9880d681SAndroid Build Coastguard Worker OS << '\n' << TmpBuf;
210*9880d681SAndroid Build Coastguard Worker CurrentIdx += ChildSize;
211*9880d681SAndroid Build Coastguard Worker }
212*9880d681SAndroid Build Coastguard Worker
213*9880d681SAndroid Build Coastguard Worker // Emit a zero as a sentinel indicating end of 'Scope'.
214*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
215*9880d681SAndroid Build Coastguard Worker OS << "/*" << CurrentIdx << "*/";
216*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(Indent*2) << "0, ";
217*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
218*9880d681SAndroid Build Coastguard Worker OS << "/*End of Scope*/";
219*9880d681SAndroid Build Coastguard Worker OS << '\n';
220*9880d681SAndroid Build Coastguard Worker return CurrentIdx - StartIdx + 1;
221*9880d681SAndroid Build Coastguard Worker }
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Worker case Matcher::RecordNode:
224*9880d681SAndroid Build Coastguard Worker OS << "OPC_RecordNode,";
225*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
226*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(CommentIndent) << "// #"
227*9880d681SAndroid Build Coastguard Worker << cast<RecordMatcher>(N)->getResultNo() << " = "
228*9880d681SAndroid Build Coastguard Worker << cast<RecordMatcher>(N)->getWhatFor();
229*9880d681SAndroid Build Coastguard Worker OS << '\n';
230*9880d681SAndroid Build Coastguard Worker return 1;
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Worker case Matcher::RecordChild:
233*9880d681SAndroid Build Coastguard Worker OS << "OPC_RecordChild" << cast<RecordChildMatcher>(N)->getChildNo()
234*9880d681SAndroid Build Coastguard Worker << ',';
235*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
236*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(CommentIndent) << "// #"
237*9880d681SAndroid Build Coastguard Worker << cast<RecordChildMatcher>(N)->getResultNo() << " = "
238*9880d681SAndroid Build Coastguard Worker << cast<RecordChildMatcher>(N)->getWhatFor();
239*9880d681SAndroid Build Coastguard Worker OS << '\n';
240*9880d681SAndroid Build Coastguard Worker return 1;
241*9880d681SAndroid Build Coastguard Worker
242*9880d681SAndroid Build Coastguard Worker case Matcher::RecordMemRef:
243*9880d681SAndroid Build Coastguard Worker OS << "OPC_RecordMemRef,\n";
244*9880d681SAndroid Build Coastguard Worker return 1;
245*9880d681SAndroid Build Coastguard Worker
246*9880d681SAndroid Build Coastguard Worker case Matcher::CaptureGlueInput:
247*9880d681SAndroid Build Coastguard Worker OS << "OPC_CaptureGlueInput,\n";
248*9880d681SAndroid Build Coastguard Worker return 1;
249*9880d681SAndroid Build Coastguard Worker
250*9880d681SAndroid Build Coastguard Worker case Matcher::MoveChild: {
251*9880d681SAndroid Build Coastguard Worker const auto *MCM = cast<MoveChildMatcher>(N);
252*9880d681SAndroid Build Coastguard Worker
253*9880d681SAndroid Build Coastguard Worker OS << "OPC_MoveChild";
254*9880d681SAndroid Build Coastguard Worker // Handle the specialized forms.
255*9880d681SAndroid Build Coastguard Worker if (MCM->getChildNo() >= 8)
256*9880d681SAndroid Build Coastguard Worker OS << ", ";
257*9880d681SAndroid Build Coastguard Worker OS << MCM->getChildNo() << ",\n";
258*9880d681SAndroid Build Coastguard Worker return (MCM->getChildNo() >= 8) ? 2 : 1;
259*9880d681SAndroid Build Coastguard Worker }
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Worker case Matcher::MoveParent:
262*9880d681SAndroid Build Coastguard Worker OS << "OPC_MoveParent,\n";
263*9880d681SAndroid Build Coastguard Worker return 1;
264*9880d681SAndroid Build Coastguard Worker
265*9880d681SAndroid Build Coastguard Worker case Matcher::CheckSame:
266*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckSame, "
267*9880d681SAndroid Build Coastguard Worker << cast<CheckSameMatcher>(N)->getMatchNumber() << ",\n";
268*9880d681SAndroid Build Coastguard Worker return 2;
269*9880d681SAndroid Build Coastguard Worker
270*9880d681SAndroid Build Coastguard Worker case Matcher::CheckChildSame:
271*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckChild"
272*9880d681SAndroid Build Coastguard Worker << cast<CheckChildSameMatcher>(N)->getChildNo() << "Same, "
273*9880d681SAndroid Build Coastguard Worker << cast<CheckChildSameMatcher>(N)->getMatchNumber() << ",\n";
274*9880d681SAndroid Build Coastguard Worker return 2;
275*9880d681SAndroid Build Coastguard Worker
276*9880d681SAndroid Build Coastguard Worker case Matcher::CheckPatternPredicate: {
277*9880d681SAndroid Build Coastguard Worker StringRef Pred =cast<CheckPatternPredicateMatcher>(N)->getPredicate();
278*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckPatternPredicate, " << getPatternPredicate(Pred) << ',';
279*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
280*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(CommentIndent) << "// " << Pred;
281*9880d681SAndroid Build Coastguard Worker OS << '\n';
282*9880d681SAndroid Build Coastguard Worker return 2;
283*9880d681SAndroid Build Coastguard Worker }
284*9880d681SAndroid Build Coastguard Worker case Matcher::CheckPredicate: {
285*9880d681SAndroid Build Coastguard Worker TreePredicateFn Pred = cast<CheckPredicateMatcher>(N)->getPredicate();
286*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckPredicate, " << getNodePredicate(Pred) << ',';
287*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
288*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(CommentIndent) << "// " << Pred.getFnName();
289*9880d681SAndroid Build Coastguard Worker OS << '\n';
290*9880d681SAndroid Build Coastguard Worker return 2;
291*9880d681SAndroid Build Coastguard Worker }
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Worker case Matcher::CheckOpcode:
294*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckOpcode, TARGET_VAL("
295*9880d681SAndroid Build Coastguard Worker << cast<CheckOpcodeMatcher>(N)->getOpcode().getEnumName() << "),\n";
296*9880d681SAndroid Build Coastguard Worker return 3;
297*9880d681SAndroid Build Coastguard Worker
298*9880d681SAndroid Build Coastguard Worker case Matcher::SwitchOpcode:
299*9880d681SAndroid Build Coastguard Worker case Matcher::SwitchType: {
300*9880d681SAndroid Build Coastguard Worker unsigned StartIdx = CurrentIdx;
301*9880d681SAndroid Build Coastguard Worker
302*9880d681SAndroid Build Coastguard Worker unsigned NumCases;
303*9880d681SAndroid Build Coastguard Worker if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {
304*9880d681SAndroid Build Coastguard Worker OS << "OPC_SwitchOpcode ";
305*9880d681SAndroid Build Coastguard Worker NumCases = SOM->getNumCases();
306*9880d681SAndroid Build Coastguard Worker } else {
307*9880d681SAndroid Build Coastguard Worker OS << "OPC_SwitchType ";
308*9880d681SAndroid Build Coastguard Worker NumCases = cast<SwitchTypeMatcher>(N)->getNumCases();
309*9880d681SAndroid Build Coastguard Worker }
310*9880d681SAndroid Build Coastguard Worker
311*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
312*9880d681SAndroid Build Coastguard Worker OS << "/*" << NumCases << " cases */";
313*9880d681SAndroid Build Coastguard Worker OS << ", ";
314*9880d681SAndroid Build Coastguard Worker ++CurrentIdx;
315*9880d681SAndroid Build Coastguard Worker
316*9880d681SAndroid Build Coastguard Worker // For each case we emit the size, then the opcode, then the matcher.
317*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = NumCases; i != e; ++i) {
318*9880d681SAndroid Build Coastguard Worker const Matcher *Child;
319*9880d681SAndroid Build Coastguard Worker unsigned IdxSize;
320*9880d681SAndroid Build Coastguard Worker if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {
321*9880d681SAndroid Build Coastguard Worker Child = SOM->getCaseMatcher(i);
322*9880d681SAndroid Build Coastguard Worker IdxSize = 2; // size of opcode in table is 2 bytes.
323*9880d681SAndroid Build Coastguard Worker } else {
324*9880d681SAndroid Build Coastguard Worker Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i);
325*9880d681SAndroid Build Coastguard Worker IdxSize = 1; // size of type in table is 1 byte.
326*9880d681SAndroid Build Coastguard Worker }
327*9880d681SAndroid Build Coastguard Worker
328*9880d681SAndroid Build Coastguard Worker // We need to encode the opcode and the offset of the case code before
329*9880d681SAndroid Build Coastguard Worker // emitting the case code. Handle this by buffering the output into a
330*9880d681SAndroid Build Coastguard Worker // string while we get the size. Unfortunately, the offset of the
331*9880d681SAndroid Build Coastguard Worker // children depends on the VBR size of the child, so for large children we
332*9880d681SAndroid Build Coastguard Worker // have to iterate a bit.
333*9880d681SAndroid Build Coastguard Worker SmallString<128> TmpBuf;
334*9880d681SAndroid Build Coastguard Worker unsigned ChildSize = 0;
335*9880d681SAndroid Build Coastguard Worker unsigned VBRSize = 0;
336*9880d681SAndroid Build Coastguard Worker do {
337*9880d681SAndroid Build Coastguard Worker VBRSize = GetVBRSize(ChildSize);
338*9880d681SAndroid Build Coastguard Worker
339*9880d681SAndroid Build Coastguard Worker TmpBuf.clear();
340*9880d681SAndroid Build Coastguard Worker raw_svector_ostream OS(TmpBuf);
341*9880d681SAndroid Build Coastguard Worker formatted_raw_ostream FOS(OS);
342*9880d681SAndroid Build Coastguard Worker ChildSize = EmitMatcherList(Child, Indent+1, CurrentIdx+VBRSize+IdxSize,
343*9880d681SAndroid Build Coastguard Worker FOS);
344*9880d681SAndroid Build Coastguard Worker } while (GetVBRSize(ChildSize) != VBRSize);
345*9880d681SAndroid Build Coastguard Worker
346*9880d681SAndroid Build Coastguard Worker assert(ChildSize != 0 && "Should not have a zero-sized child!");
347*9880d681SAndroid Build Coastguard Worker
348*9880d681SAndroid Build Coastguard Worker if (i != 0) {
349*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
350*9880d681SAndroid Build Coastguard Worker OS << "/*" << CurrentIdx << "*/";
351*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(Indent*2);
352*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
353*9880d681SAndroid Build Coastguard Worker OS << (isa<SwitchOpcodeMatcher>(N) ?
354*9880d681SAndroid Build Coastguard Worker "/*SwitchOpcode*/ " : "/*SwitchType*/ ");
355*9880d681SAndroid Build Coastguard Worker }
356*9880d681SAndroid Build Coastguard Worker
357*9880d681SAndroid Build Coastguard Worker // Emit the VBR.
358*9880d681SAndroid Build Coastguard Worker CurrentIdx += EmitVBRValue(ChildSize, OS);
359*9880d681SAndroid Build Coastguard Worker
360*9880d681SAndroid Build Coastguard Worker if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
361*9880d681SAndroid Build Coastguard Worker OS << "TARGET_VAL(" << SOM->getCaseOpcode(i).getEnumName() << "),";
362*9880d681SAndroid Build Coastguard Worker else
363*9880d681SAndroid Build Coastguard Worker OS << getEnumName(cast<SwitchTypeMatcher>(N)->getCaseType(i)) << ',';
364*9880d681SAndroid Build Coastguard Worker
365*9880d681SAndroid Build Coastguard Worker CurrentIdx += IdxSize;
366*9880d681SAndroid Build Coastguard Worker
367*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
368*9880d681SAndroid Build Coastguard Worker OS << "// ->" << CurrentIdx+ChildSize;
369*9880d681SAndroid Build Coastguard Worker OS << '\n';
370*9880d681SAndroid Build Coastguard Worker OS << TmpBuf;
371*9880d681SAndroid Build Coastguard Worker CurrentIdx += ChildSize;
372*9880d681SAndroid Build Coastguard Worker }
373*9880d681SAndroid Build Coastguard Worker
374*9880d681SAndroid Build Coastguard Worker // Emit the final zero to terminate the switch.
375*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
376*9880d681SAndroid Build Coastguard Worker OS << "/*" << CurrentIdx << "*/";
377*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(Indent*2) << "0, ";
378*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
379*9880d681SAndroid Build Coastguard Worker OS << (isa<SwitchOpcodeMatcher>(N) ?
380*9880d681SAndroid Build Coastguard Worker "// EndSwitchOpcode" : "// EndSwitchType");
381*9880d681SAndroid Build Coastguard Worker
382*9880d681SAndroid Build Coastguard Worker OS << '\n';
383*9880d681SAndroid Build Coastguard Worker ++CurrentIdx;
384*9880d681SAndroid Build Coastguard Worker return CurrentIdx-StartIdx;
385*9880d681SAndroid Build Coastguard Worker }
386*9880d681SAndroid Build Coastguard Worker
387*9880d681SAndroid Build Coastguard Worker case Matcher::CheckType:
388*9880d681SAndroid Build Coastguard Worker assert(cast<CheckTypeMatcher>(N)->getResNo() == 0 &&
389*9880d681SAndroid Build Coastguard Worker "FIXME: Add support for CheckType of resno != 0");
390*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckType, "
391*9880d681SAndroid Build Coastguard Worker << getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
392*9880d681SAndroid Build Coastguard Worker return 2;
393*9880d681SAndroid Build Coastguard Worker
394*9880d681SAndroid Build Coastguard Worker case Matcher::CheckChildType:
395*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckChild"
396*9880d681SAndroid Build Coastguard Worker << cast<CheckChildTypeMatcher>(N)->getChildNo() << "Type, "
397*9880d681SAndroid Build Coastguard Worker << getEnumName(cast<CheckChildTypeMatcher>(N)->getType()) << ",\n";
398*9880d681SAndroid Build Coastguard Worker return 2;
399*9880d681SAndroid Build Coastguard Worker
400*9880d681SAndroid Build Coastguard Worker case Matcher::CheckInteger: {
401*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckInteger, ";
402*9880d681SAndroid Build Coastguard Worker unsigned Bytes=1+EmitVBRValue(cast<CheckIntegerMatcher>(N)->getValue(), OS);
403*9880d681SAndroid Build Coastguard Worker OS << '\n';
404*9880d681SAndroid Build Coastguard Worker return Bytes;
405*9880d681SAndroid Build Coastguard Worker }
406*9880d681SAndroid Build Coastguard Worker case Matcher::CheckChildInteger: {
407*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckChild" << cast<CheckChildIntegerMatcher>(N)->getChildNo()
408*9880d681SAndroid Build Coastguard Worker << "Integer, ";
409*9880d681SAndroid Build Coastguard Worker unsigned Bytes=1+EmitVBRValue(cast<CheckChildIntegerMatcher>(N)->getValue(),
410*9880d681SAndroid Build Coastguard Worker OS);
411*9880d681SAndroid Build Coastguard Worker OS << '\n';
412*9880d681SAndroid Build Coastguard Worker return Bytes;
413*9880d681SAndroid Build Coastguard Worker }
414*9880d681SAndroid Build Coastguard Worker case Matcher::CheckCondCode:
415*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckCondCode, ISD::"
416*9880d681SAndroid Build Coastguard Worker << cast<CheckCondCodeMatcher>(N)->getCondCodeName() << ",\n";
417*9880d681SAndroid Build Coastguard Worker return 2;
418*9880d681SAndroid Build Coastguard Worker
419*9880d681SAndroid Build Coastguard Worker case Matcher::CheckValueType:
420*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckValueType, MVT::"
421*9880d681SAndroid Build Coastguard Worker << cast<CheckValueTypeMatcher>(N)->getTypeName() << ",\n";
422*9880d681SAndroid Build Coastguard Worker return 2;
423*9880d681SAndroid Build Coastguard Worker
424*9880d681SAndroid Build Coastguard Worker case Matcher::CheckComplexPat: {
425*9880d681SAndroid Build Coastguard Worker const CheckComplexPatMatcher *CCPM = cast<CheckComplexPatMatcher>(N);
426*9880d681SAndroid Build Coastguard Worker const ComplexPattern &Pattern = CCPM->getPattern();
427*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckComplexPat, /*CP*/" << getComplexPat(Pattern) << ", /*#*/"
428*9880d681SAndroid Build Coastguard Worker << CCPM->getMatchNumber() << ',';
429*9880d681SAndroid Build Coastguard Worker
430*9880d681SAndroid Build Coastguard Worker if (!OmitComments) {
431*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(CommentIndent) << "// " << Pattern.getSelectFunc();
432*9880d681SAndroid Build Coastguard Worker OS << ":$" << CCPM->getName();
433*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Pattern.getNumOperands(); i != e; ++i)
434*9880d681SAndroid Build Coastguard Worker OS << " #" << CCPM->getFirstResult()+i;
435*9880d681SAndroid Build Coastguard Worker
436*9880d681SAndroid Build Coastguard Worker if (Pattern.hasProperty(SDNPHasChain))
437*9880d681SAndroid Build Coastguard Worker OS << " + chain result";
438*9880d681SAndroid Build Coastguard Worker }
439*9880d681SAndroid Build Coastguard Worker OS << '\n';
440*9880d681SAndroid Build Coastguard Worker return 3;
441*9880d681SAndroid Build Coastguard Worker }
442*9880d681SAndroid Build Coastguard Worker
443*9880d681SAndroid Build Coastguard Worker case Matcher::CheckAndImm: {
444*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckAndImm, ";
445*9880d681SAndroid Build Coastguard Worker unsigned Bytes=1+EmitVBRValue(cast<CheckAndImmMatcher>(N)->getValue(), OS);
446*9880d681SAndroid Build Coastguard Worker OS << '\n';
447*9880d681SAndroid Build Coastguard Worker return Bytes;
448*9880d681SAndroid Build Coastguard Worker }
449*9880d681SAndroid Build Coastguard Worker
450*9880d681SAndroid Build Coastguard Worker case Matcher::CheckOrImm: {
451*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckOrImm, ";
452*9880d681SAndroid Build Coastguard Worker unsigned Bytes = 1+EmitVBRValue(cast<CheckOrImmMatcher>(N)->getValue(), OS);
453*9880d681SAndroid Build Coastguard Worker OS << '\n';
454*9880d681SAndroid Build Coastguard Worker return Bytes;
455*9880d681SAndroid Build Coastguard Worker }
456*9880d681SAndroid Build Coastguard Worker
457*9880d681SAndroid Build Coastguard Worker case Matcher::CheckFoldableChainNode:
458*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckFoldableChainNode,\n";
459*9880d681SAndroid Build Coastguard Worker return 1;
460*9880d681SAndroid Build Coastguard Worker
461*9880d681SAndroid Build Coastguard Worker case Matcher::EmitInteger: {
462*9880d681SAndroid Build Coastguard Worker int64_t Val = cast<EmitIntegerMatcher>(N)->getValue();
463*9880d681SAndroid Build Coastguard Worker OS << "OPC_EmitInteger, "
464*9880d681SAndroid Build Coastguard Worker << getEnumName(cast<EmitIntegerMatcher>(N)->getVT()) << ", ";
465*9880d681SAndroid Build Coastguard Worker unsigned Bytes = 2+EmitVBRValue(Val, OS);
466*9880d681SAndroid Build Coastguard Worker OS << '\n';
467*9880d681SAndroid Build Coastguard Worker return Bytes;
468*9880d681SAndroid Build Coastguard Worker }
469*9880d681SAndroid Build Coastguard Worker case Matcher::EmitStringInteger: {
470*9880d681SAndroid Build Coastguard Worker const std::string &Val = cast<EmitStringIntegerMatcher>(N)->getValue();
471*9880d681SAndroid Build Coastguard Worker // These should always fit into one byte.
472*9880d681SAndroid Build Coastguard Worker OS << "OPC_EmitInteger, "
473*9880d681SAndroid Build Coastguard Worker << getEnumName(cast<EmitStringIntegerMatcher>(N)->getVT()) << ", "
474*9880d681SAndroid Build Coastguard Worker << Val << ",\n";
475*9880d681SAndroid Build Coastguard Worker return 3;
476*9880d681SAndroid Build Coastguard Worker }
477*9880d681SAndroid Build Coastguard Worker
478*9880d681SAndroid Build Coastguard Worker case Matcher::EmitRegister: {
479*9880d681SAndroid Build Coastguard Worker const EmitRegisterMatcher *Matcher = cast<EmitRegisterMatcher>(N);
480*9880d681SAndroid Build Coastguard Worker const CodeGenRegister *Reg = Matcher->getReg();
481*9880d681SAndroid Build Coastguard Worker // If the enum value of the register is larger than one byte can handle,
482*9880d681SAndroid Build Coastguard Worker // use EmitRegister2.
483*9880d681SAndroid Build Coastguard Worker if (Reg && Reg->EnumValue > 255) {
484*9880d681SAndroid Build Coastguard Worker OS << "OPC_EmitRegister2, " << getEnumName(Matcher->getVT()) << ", ";
485*9880d681SAndroid Build Coastguard Worker OS << "TARGET_VAL(" << getQualifiedName(Reg->TheDef) << "),\n";
486*9880d681SAndroid Build Coastguard Worker return 4;
487*9880d681SAndroid Build Coastguard Worker } else {
488*9880d681SAndroid Build Coastguard Worker OS << "OPC_EmitRegister, " << getEnumName(Matcher->getVT()) << ", ";
489*9880d681SAndroid Build Coastguard Worker if (Reg) {
490*9880d681SAndroid Build Coastguard Worker OS << getQualifiedName(Reg->TheDef) << ",\n";
491*9880d681SAndroid Build Coastguard Worker } else {
492*9880d681SAndroid Build Coastguard Worker OS << "0 ";
493*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
494*9880d681SAndroid Build Coastguard Worker OS << "/*zero_reg*/";
495*9880d681SAndroid Build Coastguard Worker OS << ",\n";
496*9880d681SAndroid Build Coastguard Worker }
497*9880d681SAndroid Build Coastguard Worker return 3;
498*9880d681SAndroid Build Coastguard Worker }
499*9880d681SAndroid Build Coastguard Worker }
500*9880d681SAndroid Build Coastguard Worker
501*9880d681SAndroid Build Coastguard Worker case Matcher::EmitConvertToTarget:
502*9880d681SAndroid Build Coastguard Worker OS << "OPC_EmitConvertToTarget, "
503*9880d681SAndroid Build Coastguard Worker << cast<EmitConvertToTargetMatcher>(N)->getSlot() << ",\n";
504*9880d681SAndroid Build Coastguard Worker return 2;
505*9880d681SAndroid Build Coastguard Worker
506*9880d681SAndroid Build Coastguard Worker case Matcher::EmitMergeInputChains: {
507*9880d681SAndroid Build Coastguard Worker const EmitMergeInputChainsMatcher *MN =
508*9880d681SAndroid Build Coastguard Worker cast<EmitMergeInputChainsMatcher>(N);
509*9880d681SAndroid Build Coastguard Worker
510*9880d681SAndroid Build Coastguard Worker // Handle the specialized forms OPC_EmitMergeInputChains1_0, 1_1, and 1_2.
511*9880d681SAndroid Build Coastguard Worker if (MN->getNumNodes() == 1 && MN->getNode(0) < 3) {
512*9880d681SAndroid Build Coastguard Worker OS << "OPC_EmitMergeInputChains1_" << MN->getNode(0) << ",\n";
513*9880d681SAndroid Build Coastguard Worker return 1;
514*9880d681SAndroid Build Coastguard Worker }
515*9880d681SAndroid Build Coastguard Worker
516*9880d681SAndroid Build Coastguard Worker OS << "OPC_EmitMergeInputChains, " << MN->getNumNodes() << ", ";
517*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = MN->getNumNodes(); i != e; ++i)
518*9880d681SAndroid Build Coastguard Worker OS << MN->getNode(i) << ", ";
519*9880d681SAndroid Build Coastguard Worker OS << '\n';
520*9880d681SAndroid Build Coastguard Worker return 2+MN->getNumNodes();
521*9880d681SAndroid Build Coastguard Worker }
522*9880d681SAndroid Build Coastguard Worker case Matcher::EmitCopyToReg:
523*9880d681SAndroid Build Coastguard Worker OS << "OPC_EmitCopyToReg, "
524*9880d681SAndroid Build Coastguard Worker << cast<EmitCopyToRegMatcher>(N)->getSrcSlot() << ", "
525*9880d681SAndroid Build Coastguard Worker << getQualifiedName(cast<EmitCopyToRegMatcher>(N)->getDestPhysReg())
526*9880d681SAndroid Build Coastguard Worker << ",\n";
527*9880d681SAndroid Build Coastguard Worker return 3;
528*9880d681SAndroid Build Coastguard Worker case Matcher::EmitNodeXForm: {
529*9880d681SAndroid Build Coastguard Worker const EmitNodeXFormMatcher *XF = cast<EmitNodeXFormMatcher>(N);
530*9880d681SAndroid Build Coastguard Worker OS << "OPC_EmitNodeXForm, " << getNodeXFormID(XF->getNodeXForm()) << ", "
531*9880d681SAndroid Build Coastguard Worker << XF->getSlot() << ',';
532*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
533*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(CommentIndent) << "// "<<XF->getNodeXForm()->getName();
534*9880d681SAndroid Build Coastguard Worker OS <<'\n';
535*9880d681SAndroid Build Coastguard Worker return 3;
536*9880d681SAndroid Build Coastguard Worker }
537*9880d681SAndroid Build Coastguard Worker
538*9880d681SAndroid Build Coastguard Worker case Matcher::EmitNode:
539*9880d681SAndroid Build Coastguard Worker case Matcher::MorphNodeTo: {
540*9880d681SAndroid Build Coastguard Worker const EmitNodeMatcherCommon *EN = cast<EmitNodeMatcherCommon>(N);
541*9880d681SAndroid Build Coastguard Worker OS << (isa<EmitNodeMatcher>(EN) ? "OPC_EmitNode" : "OPC_MorphNodeTo");
542*9880d681SAndroid Build Coastguard Worker bool CompressVTs = EN->getNumVTs() < 3;
543*9880d681SAndroid Build Coastguard Worker if (CompressVTs)
544*9880d681SAndroid Build Coastguard Worker OS << EN->getNumVTs();
545*9880d681SAndroid Build Coastguard Worker
546*9880d681SAndroid Build Coastguard Worker OS << ", TARGET_VAL(" << EN->getOpcodeName() << "), 0";
547*9880d681SAndroid Build Coastguard Worker
548*9880d681SAndroid Build Coastguard Worker if (EN->hasChain()) OS << "|OPFL_Chain";
549*9880d681SAndroid Build Coastguard Worker if (EN->hasInFlag()) OS << "|OPFL_GlueInput";
550*9880d681SAndroid Build Coastguard Worker if (EN->hasOutFlag()) OS << "|OPFL_GlueOutput";
551*9880d681SAndroid Build Coastguard Worker if (EN->hasMemRefs()) OS << "|OPFL_MemRefs";
552*9880d681SAndroid Build Coastguard Worker if (EN->getNumFixedArityOperands() != -1)
553*9880d681SAndroid Build Coastguard Worker OS << "|OPFL_Variadic" << EN->getNumFixedArityOperands();
554*9880d681SAndroid Build Coastguard Worker OS << ",\n";
555*9880d681SAndroid Build Coastguard Worker
556*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(Indent*2+4);
557*9880d681SAndroid Build Coastguard Worker if (!CompressVTs) {
558*9880d681SAndroid Build Coastguard Worker OS << EN->getNumVTs();
559*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
560*9880d681SAndroid Build Coastguard Worker OS << "/*#VTs*/";
561*9880d681SAndroid Build Coastguard Worker OS << ", ";
562*9880d681SAndroid Build Coastguard Worker }
563*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = EN->getNumVTs(); i != e; ++i)
564*9880d681SAndroid Build Coastguard Worker OS << getEnumName(EN->getVT(i)) << ", ";
565*9880d681SAndroid Build Coastguard Worker
566*9880d681SAndroid Build Coastguard Worker OS << EN->getNumOperands();
567*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
568*9880d681SAndroid Build Coastguard Worker OS << "/*#Ops*/";
569*9880d681SAndroid Build Coastguard Worker OS << ", ";
570*9880d681SAndroid Build Coastguard Worker unsigned NumOperandBytes = 0;
571*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = EN->getNumOperands(); i != e; ++i)
572*9880d681SAndroid Build Coastguard Worker NumOperandBytes += EmitVBRValue(EN->getOperand(i), OS);
573*9880d681SAndroid Build Coastguard Worker
574*9880d681SAndroid Build Coastguard Worker if (!OmitComments) {
575*9880d681SAndroid Build Coastguard Worker // Print the result #'s for EmitNode.
576*9880d681SAndroid Build Coastguard Worker if (const EmitNodeMatcher *E = dyn_cast<EmitNodeMatcher>(EN)) {
577*9880d681SAndroid Build Coastguard Worker if (unsigned NumResults = EN->getNumVTs()) {
578*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(CommentIndent) << "// Results =";
579*9880d681SAndroid Build Coastguard Worker unsigned First = E->getFirstResultSlot();
580*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i != NumResults; ++i)
581*9880d681SAndroid Build Coastguard Worker OS << " #" << First+i;
582*9880d681SAndroid Build Coastguard Worker }
583*9880d681SAndroid Build Coastguard Worker }
584*9880d681SAndroid Build Coastguard Worker OS << '\n';
585*9880d681SAndroid Build Coastguard Worker
586*9880d681SAndroid Build Coastguard Worker if (const MorphNodeToMatcher *SNT = dyn_cast<MorphNodeToMatcher>(N)) {
587*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(Indent*2) << "// Src: "
588*9880d681SAndroid Build Coastguard Worker << *SNT->getPattern().getSrcPattern() << " - Complexity = "
589*9880d681SAndroid Build Coastguard Worker << SNT->getPattern().getPatternComplexity(CGP) << '\n';
590*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(Indent*2) << "// Dst: "
591*9880d681SAndroid Build Coastguard Worker << *SNT->getPattern().getDstPattern() << '\n';
592*9880d681SAndroid Build Coastguard Worker }
593*9880d681SAndroid Build Coastguard Worker } else
594*9880d681SAndroid Build Coastguard Worker OS << '\n';
595*9880d681SAndroid Build Coastguard Worker
596*9880d681SAndroid Build Coastguard Worker return 5 + !CompressVTs + EN->getNumVTs() + NumOperandBytes;
597*9880d681SAndroid Build Coastguard Worker }
598*9880d681SAndroid Build Coastguard Worker case Matcher::CompleteMatch: {
599*9880d681SAndroid Build Coastguard Worker const CompleteMatchMatcher *CM = cast<CompleteMatchMatcher>(N);
600*9880d681SAndroid Build Coastguard Worker OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";
601*9880d681SAndroid Build Coastguard Worker unsigned NumResultBytes = 0;
602*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
603*9880d681SAndroid Build Coastguard Worker NumResultBytes += EmitVBRValue(CM->getResult(i), OS);
604*9880d681SAndroid Build Coastguard Worker OS << '\n';
605*9880d681SAndroid Build Coastguard Worker if (!OmitComments) {
606*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(Indent*2) << "// Src: "
607*9880d681SAndroid Build Coastguard Worker << *CM->getPattern().getSrcPattern() << " - Complexity = "
608*9880d681SAndroid Build Coastguard Worker << CM->getPattern().getPatternComplexity(CGP) << '\n';
609*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(Indent*2) << "// Dst: "
610*9880d681SAndroid Build Coastguard Worker << *CM->getPattern().getDstPattern();
611*9880d681SAndroid Build Coastguard Worker }
612*9880d681SAndroid Build Coastguard Worker OS << '\n';
613*9880d681SAndroid Build Coastguard Worker return 2 + NumResultBytes;
614*9880d681SAndroid Build Coastguard Worker }
615*9880d681SAndroid Build Coastguard Worker }
616*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unreachable");
617*9880d681SAndroid Build Coastguard Worker }
618*9880d681SAndroid Build Coastguard Worker
619*9880d681SAndroid Build Coastguard Worker /// EmitMatcherList - Emit the bytes for the specified matcher subtree.
620*9880d681SAndroid Build Coastguard Worker unsigned MatcherTableEmitter::
EmitMatcherList(const Matcher * N,unsigned Indent,unsigned CurrentIdx,formatted_raw_ostream & OS)621*9880d681SAndroid Build Coastguard Worker EmitMatcherList(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
622*9880d681SAndroid Build Coastguard Worker formatted_raw_ostream &OS) {
623*9880d681SAndroid Build Coastguard Worker unsigned Size = 0;
624*9880d681SAndroid Build Coastguard Worker while (N) {
625*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
626*9880d681SAndroid Build Coastguard Worker OS << "/*" << CurrentIdx << "*/";
627*9880d681SAndroid Build Coastguard Worker unsigned MatcherSize = EmitMatcher(N, Indent, CurrentIdx, OS);
628*9880d681SAndroid Build Coastguard Worker Size += MatcherSize;
629*9880d681SAndroid Build Coastguard Worker CurrentIdx += MatcherSize;
630*9880d681SAndroid Build Coastguard Worker
631*9880d681SAndroid Build Coastguard Worker // If there are other nodes in this list, iterate to them, otherwise we're
632*9880d681SAndroid Build Coastguard Worker // done.
633*9880d681SAndroid Build Coastguard Worker N = N->getNext();
634*9880d681SAndroid Build Coastguard Worker }
635*9880d681SAndroid Build Coastguard Worker return Size;
636*9880d681SAndroid Build Coastguard Worker }
637*9880d681SAndroid Build Coastguard Worker
EmitPredicateFunctions(formatted_raw_ostream & OS)638*9880d681SAndroid Build Coastguard Worker void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) {
639*9880d681SAndroid Build Coastguard Worker // Emit pattern predicates.
640*9880d681SAndroid Build Coastguard Worker if (!PatternPredicates.empty()) {
641*9880d681SAndroid Build Coastguard Worker OS << "bool CheckPatternPredicate(unsigned PredNo) const override {\n";
642*9880d681SAndroid Build Coastguard Worker OS << " switch (PredNo) {\n";
643*9880d681SAndroid Build Coastguard Worker OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n";
644*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = PatternPredicates.size(); i != e; ++i)
645*9880d681SAndroid Build Coastguard Worker OS << " case " << i << ": return " << PatternPredicates[i] << ";\n";
646*9880d681SAndroid Build Coastguard Worker OS << " }\n";
647*9880d681SAndroid Build Coastguard Worker OS << "}\n\n";
648*9880d681SAndroid Build Coastguard Worker }
649*9880d681SAndroid Build Coastguard Worker
650*9880d681SAndroid Build Coastguard Worker // Emit Node predicates.
651*9880d681SAndroid Build Coastguard Worker if (!NodePredicates.empty()) {
652*9880d681SAndroid Build Coastguard Worker OS << "bool CheckNodePredicate(SDNode *Node,\n";
653*9880d681SAndroid Build Coastguard Worker OS << " unsigned PredNo) const override {\n";
654*9880d681SAndroid Build Coastguard Worker OS << " switch (PredNo) {\n";
655*9880d681SAndroid Build Coastguard Worker OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n";
656*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = NodePredicates.size(); i != e; ++i) {
657*9880d681SAndroid Build Coastguard Worker // Emit the predicate code corresponding to this pattern.
658*9880d681SAndroid Build Coastguard Worker TreePredicateFn PredFn = NodePredicates[i];
659*9880d681SAndroid Build Coastguard Worker
660*9880d681SAndroid Build Coastguard Worker assert(!PredFn.isAlwaysTrue() && "No code in this predicate");
661*9880d681SAndroid Build Coastguard Worker OS << " case " << i << ": { \n";
662*9880d681SAndroid Build Coastguard Worker for (auto *SimilarPred :
663*9880d681SAndroid Build Coastguard Worker NodePredicatesByCodeToRun[PredFn.getCodeToRunOnSDNode()])
664*9880d681SAndroid Build Coastguard Worker OS << " // " << TreePredicateFn(SimilarPred).getFnName() <<'\n';
665*9880d681SAndroid Build Coastguard Worker
666*9880d681SAndroid Build Coastguard Worker OS << PredFn.getCodeToRunOnSDNode() << "\n }\n";
667*9880d681SAndroid Build Coastguard Worker }
668*9880d681SAndroid Build Coastguard Worker OS << " }\n";
669*9880d681SAndroid Build Coastguard Worker OS << "}\n\n";
670*9880d681SAndroid Build Coastguard Worker }
671*9880d681SAndroid Build Coastguard Worker
672*9880d681SAndroid Build Coastguard Worker // Emit CompletePattern matchers.
673*9880d681SAndroid Build Coastguard Worker // FIXME: This should be const.
674*9880d681SAndroid Build Coastguard Worker if (!ComplexPatterns.empty()) {
675*9880d681SAndroid Build Coastguard Worker OS << "bool CheckComplexPattern(SDNode *Root, SDNode *Parent,\n";
676*9880d681SAndroid Build Coastguard Worker OS << " SDValue N, unsigned PatternNo,\n";
677*9880d681SAndroid Build Coastguard Worker OS << " SmallVectorImpl<std::pair<SDValue, SDNode*> > &Result) override {\n";
678*9880d681SAndroid Build Coastguard Worker OS << " unsigned NextRes = Result.size();\n";
679*9880d681SAndroid Build Coastguard Worker OS << " switch (PatternNo) {\n";
680*9880d681SAndroid Build Coastguard Worker OS << " default: llvm_unreachable(\"Invalid pattern # in table?\");\n";
681*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = ComplexPatterns.size(); i != e; ++i) {
682*9880d681SAndroid Build Coastguard Worker const ComplexPattern &P = *ComplexPatterns[i];
683*9880d681SAndroid Build Coastguard Worker unsigned NumOps = P.getNumOperands();
684*9880d681SAndroid Build Coastguard Worker
685*9880d681SAndroid Build Coastguard Worker if (P.hasProperty(SDNPHasChain))
686*9880d681SAndroid Build Coastguard Worker ++NumOps; // Get the chained node too.
687*9880d681SAndroid Build Coastguard Worker
688*9880d681SAndroid Build Coastguard Worker OS << " case " << i << ":\n";
689*9880d681SAndroid Build Coastguard Worker OS << " Result.resize(NextRes+" << NumOps << ");\n";
690*9880d681SAndroid Build Coastguard Worker OS << " return " << P.getSelectFunc();
691*9880d681SAndroid Build Coastguard Worker
692*9880d681SAndroid Build Coastguard Worker OS << "(";
693*9880d681SAndroid Build Coastguard Worker // If the complex pattern wants the root of the match, pass it in as the
694*9880d681SAndroid Build Coastguard Worker // first argument.
695*9880d681SAndroid Build Coastguard Worker if (P.hasProperty(SDNPWantRoot))
696*9880d681SAndroid Build Coastguard Worker OS << "Root, ";
697*9880d681SAndroid Build Coastguard Worker
698*9880d681SAndroid Build Coastguard Worker // If the complex pattern wants the parent of the operand being matched,
699*9880d681SAndroid Build Coastguard Worker // pass it in as the next argument.
700*9880d681SAndroid Build Coastguard Worker if (P.hasProperty(SDNPWantParent))
701*9880d681SAndroid Build Coastguard Worker OS << "Parent, ";
702*9880d681SAndroid Build Coastguard Worker
703*9880d681SAndroid Build Coastguard Worker OS << "N";
704*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i != NumOps; ++i)
705*9880d681SAndroid Build Coastguard Worker OS << ", Result[NextRes+" << i << "].first";
706*9880d681SAndroid Build Coastguard Worker OS << ");\n";
707*9880d681SAndroid Build Coastguard Worker }
708*9880d681SAndroid Build Coastguard Worker OS << " }\n";
709*9880d681SAndroid Build Coastguard Worker OS << "}\n\n";
710*9880d681SAndroid Build Coastguard Worker }
711*9880d681SAndroid Build Coastguard Worker
712*9880d681SAndroid Build Coastguard Worker
713*9880d681SAndroid Build Coastguard Worker // Emit SDNodeXForm handlers.
714*9880d681SAndroid Build Coastguard Worker // FIXME: This should be const.
715*9880d681SAndroid Build Coastguard Worker if (!NodeXForms.empty()) {
716*9880d681SAndroid Build Coastguard Worker OS << "SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) override {\n";
717*9880d681SAndroid Build Coastguard Worker OS << " switch (XFormNo) {\n";
718*9880d681SAndroid Build Coastguard Worker OS << " default: llvm_unreachable(\"Invalid xform # in table?\");\n";
719*9880d681SAndroid Build Coastguard Worker
720*9880d681SAndroid Build Coastguard Worker // FIXME: The node xform could take SDValue's instead of SDNode*'s.
721*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = NodeXForms.size(); i != e; ++i) {
722*9880d681SAndroid Build Coastguard Worker const CodeGenDAGPatterns::NodeXForm &Entry =
723*9880d681SAndroid Build Coastguard Worker CGP.getSDNodeTransform(NodeXForms[i]);
724*9880d681SAndroid Build Coastguard Worker
725*9880d681SAndroid Build Coastguard Worker Record *SDNode = Entry.first;
726*9880d681SAndroid Build Coastguard Worker const std::string &Code = Entry.second;
727*9880d681SAndroid Build Coastguard Worker
728*9880d681SAndroid Build Coastguard Worker OS << " case " << i << ": { ";
729*9880d681SAndroid Build Coastguard Worker if (!OmitComments)
730*9880d681SAndroid Build Coastguard Worker OS << "// " << NodeXForms[i]->getName();
731*9880d681SAndroid Build Coastguard Worker OS << '\n';
732*9880d681SAndroid Build Coastguard Worker
733*9880d681SAndroid Build Coastguard Worker std::string ClassName = CGP.getSDNodeInfo(SDNode).getSDClassName();
734*9880d681SAndroid Build Coastguard Worker if (ClassName == "SDNode")
735*9880d681SAndroid Build Coastguard Worker OS << " SDNode *N = V.getNode();\n";
736*9880d681SAndroid Build Coastguard Worker else
737*9880d681SAndroid Build Coastguard Worker OS << " " << ClassName << " *N = cast<" << ClassName
738*9880d681SAndroid Build Coastguard Worker << ">(V.getNode());\n";
739*9880d681SAndroid Build Coastguard Worker OS << Code << "\n }\n";
740*9880d681SAndroid Build Coastguard Worker }
741*9880d681SAndroid Build Coastguard Worker OS << " }\n";
742*9880d681SAndroid Build Coastguard Worker OS << "}\n\n";
743*9880d681SAndroid Build Coastguard Worker }
744*9880d681SAndroid Build Coastguard Worker }
745*9880d681SAndroid Build Coastguard Worker
BuildHistogram(const Matcher * M,std::vector<unsigned> & OpcodeFreq)746*9880d681SAndroid Build Coastguard Worker static void BuildHistogram(const Matcher *M, std::vector<unsigned> &OpcodeFreq){
747*9880d681SAndroid Build Coastguard Worker for (; M != nullptr; M = M->getNext()) {
748*9880d681SAndroid Build Coastguard Worker // Count this node.
749*9880d681SAndroid Build Coastguard Worker if (unsigned(M->getKind()) >= OpcodeFreq.size())
750*9880d681SAndroid Build Coastguard Worker OpcodeFreq.resize(M->getKind()+1);
751*9880d681SAndroid Build Coastguard Worker OpcodeFreq[M->getKind()]++;
752*9880d681SAndroid Build Coastguard Worker
753*9880d681SAndroid Build Coastguard Worker // Handle recursive nodes.
754*9880d681SAndroid Build Coastguard Worker if (const ScopeMatcher *SM = dyn_cast<ScopeMatcher>(M)) {
755*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i)
756*9880d681SAndroid Build Coastguard Worker BuildHistogram(SM->getChild(i), OpcodeFreq);
757*9880d681SAndroid Build Coastguard Worker } else if (const SwitchOpcodeMatcher *SOM =
758*9880d681SAndroid Build Coastguard Worker dyn_cast<SwitchOpcodeMatcher>(M)) {
759*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = SOM->getNumCases(); i != e; ++i)
760*9880d681SAndroid Build Coastguard Worker BuildHistogram(SOM->getCaseMatcher(i), OpcodeFreq);
761*9880d681SAndroid Build Coastguard Worker } else if (const SwitchTypeMatcher *STM = dyn_cast<SwitchTypeMatcher>(M)) {
762*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = STM->getNumCases(); i != e; ++i)
763*9880d681SAndroid Build Coastguard Worker BuildHistogram(STM->getCaseMatcher(i), OpcodeFreq);
764*9880d681SAndroid Build Coastguard Worker }
765*9880d681SAndroid Build Coastguard Worker }
766*9880d681SAndroid Build Coastguard Worker }
767*9880d681SAndroid Build Coastguard Worker
EmitHistogram(const Matcher * M,formatted_raw_ostream & OS)768*9880d681SAndroid Build Coastguard Worker void MatcherTableEmitter::EmitHistogram(const Matcher *M,
769*9880d681SAndroid Build Coastguard Worker formatted_raw_ostream &OS) {
770*9880d681SAndroid Build Coastguard Worker if (OmitComments)
771*9880d681SAndroid Build Coastguard Worker return;
772*9880d681SAndroid Build Coastguard Worker
773*9880d681SAndroid Build Coastguard Worker std::vector<unsigned> OpcodeFreq;
774*9880d681SAndroid Build Coastguard Worker BuildHistogram(M, OpcodeFreq);
775*9880d681SAndroid Build Coastguard Worker
776*9880d681SAndroid Build Coastguard Worker OS << " // Opcode Histogram:\n";
777*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = OpcodeFreq.size(); i != e; ++i) {
778*9880d681SAndroid Build Coastguard Worker OS << " // #";
779*9880d681SAndroid Build Coastguard Worker switch ((Matcher::KindTy)i) {
780*9880d681SAndroid Build Coastguard Worker case Matcher::Scope: OS << "OPC_Scope"; break;
781*9880d681SAndroid Build Coastguard Worker case Matcher::RecordNode: OS << "OPC_RecordNode"; break;
782*9880d681SAndroid Build Coastguard Worker case Matcher::RecordChild: OS << "OPC_RecordChild"; break;
783*9880d681SAndroid Build Coastguard Worker case Matcher::RecordMemRef: OS << "OPC_RecordMemRef"; break;
784*9880d681SAndroid Build Coastguard Worker case Matcher::CaptureGlueInput: OS << "OPC_CaptureGlueInput"; break;
785*9880d681SAndroid Build Coastguard Worker case Matcher::MoveChild: OS << "OPC_MoveChild"; break;
786*9880d681SAndroid Build Coastguard Worker case Matcher::MoveParent: OS << "OPC_MoveParent"; break;
787*9880d681SAndroid Build Coastguard Worker case Matcher::CheckSame: OS << "OPC_CheckSame"; break;
788*9880d681SAndroid Build Coastguard Worker case Matcher::CheckChildSame: OS << "OPC_CheckChildSame"; break;
789*9880d681SAndroid Build Coastguard Worker case Matcher::CheckPatternPredicate:
790*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckPatternPredicate"; break;
791*9880d681SAndroid Build Coastguard Worker case Matcher::CheckPredicate: OS << "OPC_CheckPredicate"; break;
792*9880d681SAndroid Build Coastguard Worker case Matcher::CheckOpcode: OS << "OPC_CheckOpcode"; break;
793*9880d681SAndroid Build Coastguard Worker case Matcher::SwitchOpcode: OS << "OPC_SwitchOpcode"; break;
794*9880d681SAndroid Build Coastguard Worker case Matcher::CheckType: OS << "OPC_CheckType"; break;
795*9880d681SAndroid Build Coastguard Worker case Matcher::SwitchType: OS << "OPC_SwitchType"; break;
796*9880d681SAndroid Build Coastguard Worker case Matcher::CheckChildType: OS << "OPC_CheckChildType"; break;
797*9880d681SAndroid Build Coastguard Worker case Matcher::CheckInteger: OS << "OPC_CheckInteger"; break;
798*9880d681SAndroid Build Coastguard Worker case Matcher::CheckChildInteger: OS << "OPC_CheckChildInteger"; break;
799*9880d681SAndroid Build Coastguard Worker case Matcher::CheckCondCode: OS << "OPC_CheckCondCode"; break;
800*9880d681SAndroid Build Coastguard Worker case Matcher::CheckValueType: OS << "OPC_CheckValueType"; break;
801*9880d681SAndroid Build Coastguard Worker case Matcher::CheckComplexPat: OS << "OPC_CheckComplexPat"; break;
802*9880d681SAndroid Build Coastguard Worker case Matcher::CheckAndImm: OS << "OPC_CheckAndImm"; break;
803*9880d681SAndroid Build Coastguard Worker case Matcher::CheckOrImm: OS << "OPC_CheckOrImm"; break;
804*9880d681SAndroid Build Coastguard Worker case Matcher::CheckFoldableChainNode:
805*9880d681SAndroid Build Coastguard Worker OS << "OPC_CheckFoldableChainNode"; break;
806*9880d681SAndroid Build Coastguard Worker case Matcher::EmitInteger: OS << "OPC_EmitInteger"; break;
807*9880d681SAndroid Build Coastguard Worker case Matcher::EmitStringInteger: OS << "OPC_EmitStringInteger"; break;
808*9880d681SAndroid Build Coastguard Worker case Matcher::EmitRegister: OS << "OPC_EmitRegister"; break;
809*9880d681SAndroid Build Coastguard Worker case Matcher::EmitConvertToTarget: OS << "OPC_EmitConvertToTarget"; break;
810*9880d681SAndroid Build Coastguard Worker case Matcher::EmitMergeInputChains: OS << "OPC_EmitMergeInputChains"; break;
811*9880d681SAndroid Build Coastguard Worker case Matcher::EmitCopyToReg: OS << "OPC_EmitCopyToReg"; break;
812*9880d681SAndroid Build Coastguard Worker case Matcher::EmitNode: OS << "OPC_EmitNode"; break;
813*9880d681SAndroid Build Coastguard Worker case Matcher::MorphNodeTo: OS << "OPC_MorphNodeTo"; break;
814*9880d681SAndroid Build Coastguard Worker case Matcher::EmitNodeXForm: OS << "OPC_EmitNodeXForm"; break;
815*9880d681SAndroid Build Coastguard Worker case Matcher::CompleteMatch: OS << "OPC_CompleteMatch"; break;
816*9880d681SAndroid Build Coastguard Worker }
817*9880d681SAndroid Build Coastguard Worker
818*9880d681SAndroid Build Coastguard Worker OS.PadToColumn(40) << " = " << OpcodeFreq[i] << '\n';
819*9880d681SAndroid Build Coastguard Worker }
820*9880d681SAndroid Build Coastguard Worker OS << '\n';
821*9880d681SAndroid Build Coastguard Worker }
822*9880d681SAndroid Build Coastguard Worker
823*9880d681SAndroid Build Coastguard Worker
EmitMatcherTable(const Matcher * TheMatcher,const CodeGenDAGPatterns & CGP,raw_ostream & O)824*9880d681SAndroid Build Coastguard Worker void llvm::EmitMatcherTable(const Matcher *TheMatcher,
825*9880d681SAndroid Build Coastguard Worker const CodeGenDAGPatterns &CGP,
826*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
827*9880d681SAndroid Build Coastguard Worker formatted_raw_ostream OS(O);
828*9880d681SAndroid Build Coastguard Worker
829*9880d681SAndroid Build Coastguard Worker OS << "// The main instruction selector code.\n";
830*9880d681SAndroid Build Coastguard Worker OS << "SDNode *SelectCode(SDNode *N) {\n";
831*9880d681SAndroid Build Coastguard Worker
832*9880d681SAndroid Build Coastguard Worker MatcherTableEmitter MatcherEmitter(CGP);
833*9880d681SAndroid Build Coastguard Worker
834*9880d681SAndroid Build Coastguard Worker OS << " // Some target values are emitted as 2 bytes, TARGET_VAL handles\n";
835*9880d681SAndroid Build Coastguard Worker OS << " // this.\n";
836*9880d681SAndroid Build Coastguard Worker OS << " #define TARGET_VAL(X) X & 255, unsigned(X) >> 8\n";
837*9880d681SAndroid Build Coastguard Worker OS << " static const unsigned char MatcherTable[] = {\n";
838*9880d681SAndroid Build Coastguard Worker unsigned TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 6, 0, OS);
839*9880d681SAndroid Build Coastguard Worker OS << " 0\n }; // Total Array size is " << (TotalSize+1) << " bytes\n\n";
840*9880d681SAndroid Build Coastguard Worker
841*9880d681SAndroid Build Coastguard Worker MatcherEmitter.EmitHistogram(TheMatcher, OS);
842*9880d681SAndroid Build Coastguard Worker
843*9880d681SAndroid Build Coastguard Worker OS << " #undef TARGET_VAL\n";
844*9880d681SAndroid Build Coastguard Worker OS << " SelectCodeCommon(N, MatcherTable,sizeof(MatcherTable));\n";
845*9880d681SAndroid Build Coastguard Worker OS << " return nullptr;\n";
846*9880d681SAndroid Build Coastguard Worker OS << "}\n";
847*9880d681SAndroid Build Coastguard Worker
848*9880d681SAndroid Build Coastguard Worker // Next up, emit the function for node and pattern predicates:
849*9880d681SAndroid Build Coastguard Worker MatcherEmitter.EmitPredicateFunctions(OS);
850*9880d681SAndroid Build Coastguard Worker }
851