DAGISelMatcherEmitter.cpp revision bd8227f5298f0ab7b96203a6d3875e5d26573376
1da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner//===- DAGISelMatcherEmitter.cpp - Matcher Emitter ------------------------===//
2da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner//
3da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner//                     The LLVM Compiler Infrastructure
4da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner//
5da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner// This file is distributed under the University of Illinois Open Source
6da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner// License. See LICENSE.TXT for details.
7da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner//
8da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner//===----------------------------------------------------------------------===//
9da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner//
10da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner// This file contains code to generate C++ code a matcher.
11da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner//
12da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner//===----------------------------------------------------------------------===//
13da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
14da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "DAGISelMatcher.h"
15da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "CodeGenDAGPatterns.h"
16e609a513f3c072bba28412c681465332a2822d9aChris Lattner#include "llvm/ADT/DenseMap.h"
17da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "llvm/ADT/SmallString.h"
18050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "llvm/ADT/StringMap.h"
19da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "llvm/Support/FormattedStream.h"
20da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattnerusing namespace llvm;
21da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
22da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattnernamespace {
23da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattnerenum {
245be6e5990b1da82e31f4236d1b392e52637cbe2eChris Lattner  CommentIndent = 30
25da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner};
26da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner}
27da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
28da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner/// ClassifyInt - Classify an integer by size, return '1','2','4','8' if this
29da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner/// fits in 1, 2, 4, or 8 sign extended bytes.
30da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattnerstatic char ClassifyInt(int64_t Val) {
31da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  if (Val == int8_t(Val))  return '1';
32da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  if (Val == int16_t(Val)) return '2';
33da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  if (Val == int32_t(Val)) return '4';
34da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  return '8';
35da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner}
36da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
37da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner/// EmitInt - Emit the specified integer, returning the number of bytes emitted.
38da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattnerstatic unsigned EmitInt(int64_t Val, formatted_raw_ostream &OS) {
39da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  unsigned BytesEmitted = 1;
40da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  OS << (int)(unsigned char)Val << ", ";
41da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  if (Val == int8_t(Val)) {
42da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    OS << "\n";
43da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return BytesEmitted;
44da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  }
45da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
46da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  OS << (int)(unsigned char)(Val >> 8) << ", ";
47da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  ++BytesEmitted;
48da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
49da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  if (Val != int16_t(Val)) {
50da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    OS << (int)(unsigned char)(Val >> 16) << ','
51da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner       << (int)(unsigned char)(Val >> 24) << ',';
52da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    BytesEmitted += 2;
53da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
54da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    if (Val != int32_t(Val)) {
55da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      OS << (int)(unsigned char)(Val >> 32) << ','
56da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner         << (int)(unsigned char)(Val >> 40) << ','
57da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner         << (int)(unsigned char)(Val >> 48) << ','
58da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner         << (int)(unsigned char)(Val >> 56) << ',';
59da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      BytesEmitted += 4;
60da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    }
61da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  }
62da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
63da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  OS.PadToColumn(CommentIndent) << "// " << Val << '\n';
64da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  return BytesEmitted;
65da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner}
66da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
67e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattnernamespace {
68e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattnerclass MatcherTableEmitter {
69e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner  formatted_raw_ostream &OS;
70050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner
71050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  StringMap<unsigned> NodePredicateMap, PatternPredicateMap;
72050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  std::vector<std::string> NodePredicates, PatternPredicates;
73e609a513f3c072bba28412c681465332a2822d9aChris Lattner
74e609a513f3c072bba28412c681465332a2822d9aChris Lattner  DenseMap<const ComplexPattern*, unsigned> ComplexPatternMap;
75e609a513f3c072bba28412c681465332a2822d9aChris Lattner  std::vector<const ComplexPattern*> ComplexPatterns;
76e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattnerpublic:
77e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner  MatcherTableEmitter(formatted_raw_ostream &os) : OS(os) {}
78e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner
79bd8227f5298f0ab7b96203a6d3875e5d26573376Chris Lattner  unsigned EmitMatcherList(const MatcherNode *N, unsigned Indent);
80050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner
81050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  void EmitPredicateFunctions();
82e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattnerprivate:
83e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner  unsigned EmitMatcher(const MatcherNode *N, unsigned Indent);
84050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner
85050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  unsigned getNodePredicate(StringRef PredName) {
86050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    unsigned &Entry = NodePredicateMap[PredName];
87050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    if (Entry == 0) {
88050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner      NodePredicates.push_back(PredName.str());
89050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner      Entry = NodePredicates.size();
90050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    }
91050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    return Entry-1;
92050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  }
93050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  unsigned getPatternPredicate(StringRef PredName) {
94050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    unsigned &Entry = PatternPredicateMap[PredName];
95050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    if (Entry == 0) {
96050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner      PatternPredicates.push_back(PredName.str());
97050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner      Entry = PatternPredicates.size();
98050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    }
99050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    return Entry-1;
100050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  }
101e609a513f3c072bba28412c681465332a2822d9aChris Lattner
102e609a513f3c072bba28412c681465332a2822d9aChris Lattner  unsigned getComplexPat(const ComplexPattern &P) {
103e609a513f3c072bba28412c681465332a2822d9aChris Lattner    unsigned &Entry = ComplexPatternMap[&P];
104e609a513f3c072bba28412c681465332a2822d9aChris Lattner    if (Entry == 0) {
105e609a513f3c072bba28412c681465332a2822d9aChris Lattner      ComplexPatterns.push_back(&P);
106e609a513f3c072bba28412c681465332a2822d9aChris Lattner      Entry = ComplexPatterns.size();
107e609a513f3c072bba28412c681465332a2822d9aChris Lattner    }
108e609a513f3c072bba28412c681465332a2822d9aChris Lattner    return Entry-1;
109e609a513f3c072bba28412c681465332a2822d9aChris Lattner  }
110e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner};
111e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner} // end anonymous namespace.
112e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner
113da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner/// EmitMatcherOpcodes - Emit bytes for the specified matcher and return
114da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner/// the number of bytes emitted.
115e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattnerunsigned MatcherTableEmitter::
116e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris LattnerEmitMatcher(const MatcherNode *N, unsigned Indent) {
117da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  OS.PadToColumn(Indent*2);
118da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
119da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  switch (N->getKind()) {
120da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  case MatcherNode::Push: assert(0 && "Should be handled by caller");
121da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  case MatcherNode::EmitNode:
1225be6e5990b1da82e31f4236d1b392e52637cbe2eChris Lattner    OS << "// Src: "
1235be6e5990b1da82e31f4236d1b392e52637cbe2eChris Lattner       << *cast<EmitNodeMatcherNode>(N)->getPattern().getSrcPattern() << '\n';
1245be6e5990b1da82e31f4236d1b392e52637cbe2eChris Lattner    OS.PadToColumn(Indent*2) << "// Dst: "
1255be6e5990b1da82e31f4236d1b392e52637cbe2eChris Lattner       << *cast<EmitNodeMatcherNode>(N)->getPattern().getDstPattern() << "\n";
1265be6e5990b1da82e31f4236d1b392e52637cbe2eChris Lattner    OS.PadToColumn(Indent*2) << "OPC_Emit, /*XXX*/\n\n";
127da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return 1;
128da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  case MatcherNode::Record:
129c96087b3433582f1c2bdb4f0ad3dad7f0b350339Chris Lattner    OS << "OPC_Record,";
130c96087b3433582f1c2bdb4f0ad3dad7f0b350339Chris Lattner    OS.PadToColumn(CommentIndent) << "// "
131c96087b3433582f1c2bdb4f0ad3dad7f0b350339Chris Lattner       << cast<RecordMatcherNode>(N)->getWhatFor() << '\n';
132da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return 1;
133da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  case MatcherNode::MoveChild:
134da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    OS << "OPC_MoveChild, "
135da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner       << cast<MoveChildMatcherNode>(N)->getChildNo() << ",\n";
136da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return 2;
137da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
138da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  case MatcherNode::MoveParent:
139da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    OS << "OPC_MoveParent,\n";
140da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return 1;
141da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
142da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  case MatcherNode::CheckSame:
143da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    OS << "OPC_CheckSame, "
144da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner       << cast<CheckSameMatcherNode>(N)->getMatchNumber() << ",\n";
145da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return 2;
146da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
147050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  case MatcherNode::CheckPatternPredicate: {
148050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    StringRef Pred = cast<CheckPatternPredicateMatcherNode>(N)->getPredicate();
149050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    OS << "OPC_CheckPatternPredicate, " << getPatternPredicate(Pred) << ',';
150050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    OS.PadToColumn(CommentIndent) << "// " << Pred << '\n';
151da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return 2;
152050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  }
153050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  case MatcherNode::CheckPredicate: {
154050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    StringRef Pred = cast<CheckPredicateMatcherNode>(N)->getPredicateName();
155050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    OS << "OPC_CheckPredicate, " << getNodePredicate(Pred) << ',';
156050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    OS.PadToColumn(CommentIndent) << "// " << Pred << '\n';
157da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return 2;
158050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  }
159050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner
160da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  case MatcherNode::CheckOpcode:
161da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    OS << "OPC_CheckOpcode, "
162da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner       << cast<CheckOpcodeMatcherNode>(N)->getOpcodeName() << ",\n";
163da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return 2;
164da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
165da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  case MatcherNode::CheckType:
166da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    OS << "OPC_CheckType, "
167da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner       << getEnumName(cast<CheckTypeMatcherNode>(N)->getType()) << ",\n";
168da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return 2;
169da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
170da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  case MatcherNode::CheckInteger: {
171da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    int64_t Val = cast<CheckIntegerMatcherNode>(N)->getValue();
172da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    OS << "OPC_CheckInteger" << ClassifyInt(Val) << ", ";
173da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return EmitInt(Val, OS)+1;
174da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  }
175da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  case MatcherNode::CheckCondCode:
176da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    OS << "OPC_CheckCondCode, ISD::"
177da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner       << cast<CheckCondCodeMatcherNode>(N)->getCondCodeName() << ",\n";
178da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return 2;
179da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
180da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  case MatcherNode::CheckValueType:
181da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    OS << "OPC_CheckValueType, MVT::"
182da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner       << cast<CheckValueTypeMatcherNode>(N)->getTypeName() << ",\n";
183da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return 2;
184da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
1855be6e5990b1da82e31f4236d1b392e52637cbe2eChris Lattner  case MatcherNode::CheckComplexPat: {
1865be6e5990b1da82e31f4236d1b392e52637cbe2eChris Lattner    const ComplexPattern &Pattern =
1875be6e5990b1da82e31f4236d1b392e52637cbe2eChris Lattner      cast<CheckComplexPatMatcherNode>(N)->getPattern();
1885be6e5990b1da82e31f4236d1b392e52637cbe2eChris Lattner    OS << "OPC_CheckComplexPat, " << getComplexPat(Pattern) << ',';
189781f359c1a7f590c4f8828ad9d542606c3a0ee12Chris Lattner    OS.PadToColumn(CommentIndent) << "// " << Pattern.getSelectFunc();
190781f359c1a7f590c4f8828ad9d542606c3a0ee12Chris Lattner    OS << ": " << Pattern.getNumOperands() << " operands";
191781f359c1a7f590c4f8828ad9d542606c3a0ee12Chris Lattner    if (Pattern.hasProperty(SDNPHasChain))
192781f359c1a7f590c4f8828ad9d542606c3a0ee12Chris Lattner      OS << " + chain result and input";
193781f359c1a7f590c4f8828ad9d542606c3a0ee12Chris Lattner    OS << '\n';
194da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return 2;
1955be6e5990b1da82e31f4236d1b392e52637cbe2eChris Lattner  }
196da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
197da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  case MatcherNode::CheckAndImm: {
198da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    int64_t Val = cast<CheckAndImmMatcherNode>(N)->getValue();
199da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    OS << "OPC_CheckAndImm" << ClassifyInt(Val) << ", ";
200da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return EmitInt(Val, OS)+1;
201da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  }
202da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
203da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  case MatcherNode::CheckOrImm: {
204da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    int64_t Val = cast<CheckOrImmMatcherNode>(N)->getValue();
205da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    OS << "OPC_CheckOrImm" << ClassifyInt(Val) << ", ";
206da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    return EmitInt(Val, OS)+1;
207da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  }
20821390d79843050ae8b3226860cadc16ff51d0dcfChris Lattner  case MatcherNode::CheckFoldableChainNode:
20921390d79843050ae8b3226860cadc16ff51d0dcfChris Lattner    OS << "OPC_CheckFoldableChainNode,\n";
210e39650a805425ffdbd79692c7d1bad80f7332daeChris Lattner    return 1;
2119a747f1305e76025df2323a03b805a284f2cde77Chris Lattner  case MatcherNode::CheckChainCompatible:
2129a747f1305e76025df2323a03b805a284f2cde77Chris Lattner    OS << "OPC_CheckChainCompatible, "
2139a747f1305e76025df2323a03b805a284f2cde77Chris Lattner       << cast<CheckChainCompatibleMatcherNode>(N)->getPreviousOp() << ",\n";
2149a747f1305e76025df2323a03b805a284f2cde77Chris Lattner    return 2;
215da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  }
216da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  assert(0 && "Unreachable");
217da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  return 0;
218da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner}
219da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
220bd8227f5298f0ab7b96203a6d3875e5d26573376Chris Lattner/// EmitMatcherList - Emit the bytes for the specified matcher subtree.
221e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattnerunsigned MatcherTableEmitter::
222bd8227f5298f0ab7b96203a6d3875e5d26573376Chris LattnerEmitMatcherList(const MatcherNode *N, unsigned Indent) {
223da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  unsigned Size = 0;
2248ef9c7958ad7a23ad15d7ff59e1377aec10ca42aChris Lattner  while (N) {
225da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    // Push is a special case since it is binary.
226da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    if (const PushMatcherNode *PMN = dyn_cast<PushMatcherNode>(N)) {
227da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      // We need to encode the child and the offset of the failure code before
228da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      // emitting either of them.  Handle this by buffering the output into a
229da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      // string while we get the size.
230da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      SmallString<128> TmpBuf;
231bd8227f5298f0ab7b96203a6d3875e5d26573376Chris Lattner      unsigned NextSize;
232da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      {
233da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner        raw_svector_ostream OS(TmpBuf);
234da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner        formatted_raw_ostream FOS(OS);
235bd8227f5298f0ab7b96203a6d3875e5d26573376Chris Lattner        NextSize = EmitMatcherList(cast<PushMatcherNode>(N)->getNext(),
236bd8227f5298f0ab7b96203a6d3875e5d26573376Chris Lattner                                   Indent+1);
237da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      }
238da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
239bd8227f5298f0ab7b96203a6d3875e5d26573376Chris Lattner      if (NextSize > 255) {
240da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner        errs() <<
241da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner          "Tblgen internal error: can't handle predicate this complex yet\n";
242da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner        exit(1);
243da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      }
244da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
245da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      OS.PadToColumn(Indent*2);
246bd8227f5298f0ab7b96203a6d3875e5d26573376Chris Lattner      OS << "OPC_Push, " << NextSize << ",\n";
247da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      OS << TmpBuf.str();
248da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
249bd8227f5298f0ab7b96203a6d3875e5d26573376Chris Lattner      Size += 2 + NextSize;
250da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
251da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      N = PMN->getFailure();
252da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      continue;
253da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    }
254da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
255e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner    Size += EmitMatcher(N, Indent);
256da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
257bd8227f5298f0ab7b96203a6d3875e5d26573376Chris Lattner    // If there are other nodes in this list, iterate to them, otherwise we're
258da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    // done.
259bd8227f5298f0ab7b96203a6d3875e5d26573376Chris Lattner    N = N->getNext();
260da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  }
2618ef9c7958ad7a23ad15d7ff59e1377aec10ca42aChris Lattner  return Size;
262da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner}
263da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
264050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattnervoid MatcherTableEmitter::EmitPredicateFunctions() {
265e609a513f3c072bba28412c681465332a2822d9aChris Lattner  // Emit pattern predicates.
266050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  OS << "bool CheckPatternPredicate(unsigned PredNo) const {\n";
267050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  OS << "  switch (PredNo) {\n";
268050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  OS << "  default: assert(0 && \"Invalid predicate in table?\");\n";
269050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  for (unsigned i = 0, e = PatternPredicates.size(); i != e; ++i)
270050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    OS << "  case " << i << ": return "  << PatternPredicates[i] << ";\n";
271050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  OS << "  }\n";
272050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  OS << "}\n\n";
273050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner
274e609a513f3c072bba28412c681465332a2822d9aChris Lattner  // Emit Node predicates.
275050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  OS << "bool CheckNodePredicate(SDNode *N, unsigned PredNo) const {\n";
276050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  OS << "  switch (PredNo) {\n";
277050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  OS << "  default: assert(0 && \"Invalid predicate in table?\");\n";
278050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  for (unsigned i = 0, e = NodePredicates.size(); i != e; ++i)
279050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    OS << "  case " << i << ": return "  << NodePredicates[i] << "(N);\n";
280050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  OS << "  }\n";
281050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  OS << "}\n\n";
282e609a513f3c072bba28412c681465332a2822d9aChris Lattner
283e609a513f3c072bba28412c681465332a2822d9aChris Lattner  // Emit CompletePattern matchers.
284e609a513f3c072bba28412c681465332a2822d9aChris Lattner  OS << "bool CheckComplexPattern(SDNode *Root, SDValue N,\n";
285e609a513f3c072bba28412c681465332a2822d9aChris Lattner  OS << "      unsigned PatternNo, SmallVectorImpl<SDValue> &Result) {\n";
286e609a513f3c072bba28412c681465332a2822d9aChris Lattner  OS << "  switch (PatternNo) {\n";
287e609a513f3c072bba28412c681465332a2822d9aChris Lattner  OS << "  default: assert(0 && \"Invalid pattern # in table?\");\n";
288e609a513f3c072bba28412c681465332a2822d9aChris Lattner  for (unsigned i = 0, e = ComplexPatterns.size(); i != e; ++i) {
289e609a513f3c072bba28412c681465332a2822d9aChris Lattner    const ComplexPattern &P = *ComplexPatterns[i];
290e609a513f3c072bba28412c681465332a2822d9aChris Lattner    unsigned NumOps = P.getNumOperands();
291e609a513f3c072bba28412c681465332a2822d9aChris Lattner    if (P.hasProperty(SDNPHasChain))
292e609a513f3c072bba28412c681465332a2822d9aChris Lattner      NumOps += 2; // Input and output chains.
293e609a513f3c072bba28412c681465332a2822d9aChris Lattner    OS << "  case " << i << ":\n";
294e609a513f3c072bba28412c681465332a2822d9aChris Lattner    OS << "    Result.resize(Result.size()+" << NumOps << ");\n";
295e609a513f3c072bba28412c681465332a2822d9aChris Lattner    OS << "    return "  << P.getSelectFunc() << "(Root, N";
296e609a513f3c072bba28412c681465332a2822d9aChris Lattner    for (unsigned i = 0; i != NumOps; ++i)
297e609a513f3c072bba28412c681465332a2822d9aChris Lattner      OS << ", Result[Result.size()-" << (NumOps-i) << ']';
298e609a513f3c072bba28412c681465332a2822d9aChris Lattner    OS << ");\n";
299e609a513f3c072bba28412c681465332a2822d9aChris Lattner  }
300e609a513f3c072bba28412c681465332a2822d9aChris Lattner  OS << "  }\n";
301e609a513f3c072bba28412c681465332a2822d9aChris Lattner  OS << "}\n\n";
302050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner}
303050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner
304050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner
305da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattnervoid llvm::EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &O) {
306da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  formatted_raw_ostream OS(O);
307da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
308da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  OS << "// The main instruction selector code.\n";
309da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  OS << "SDNode *SelectCode2(SDNode *N) {\n";
310da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
311e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner  MatcherTableEmitter MatcherEmitter(OS);
312e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner
313da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  OS << "  static const unsigned char MatcherTable[] = {\n";
314bd8227f5298f0ab7b96203a6d3875e5d26573376Chris Lattner  unsigned TotalSize = MatcherEmitter.EmitMatcherList(Matcher, 2);
315da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  OS << "    0\n  }; // Total Array size is " << (TotalSize+1) << " bytes\n\n";
316e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner  OS << "  return SelectCodeCommon(N, MatcherTable,sizeof(MatcherTable));\n}\n";
317050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  OS << "\n";
318050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner
319050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  // Next up, emit the function for node and pattern predicates:
320050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  MatcherEmitter.EmitPredicateFunctions();
321da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner}
322