blob: 3d2791d22e5d11809a6b88cee6859897f51be4a7 [file] [log] [blame]
Chris Lattnerda272d12010-02-15 08:04:42 +00001//===- DAGISelMatcherEmitter.cpp - Matcher Emitter ------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains code to generate C++ code a matcher.
11//
12//===----------------------------------------------------------------------===//
13
14#include "DAGISelMatcher.h"
15#include "CodeGenDAGPatterns.h"
16#include "llvm/ADT/SmallString.h"
17#include "llvm/Support/Casting.h"
18#include "llvm/Support/FormattedStream.h"
19using namespace llvm;
20
21namespace {
22enum {
23 CommentIndent = 25
24};
25}
26
Chris Lattnerda272d12010-02-15 08:04:42 +000027/// ClassifyInt - Classify an integer by size, return '1','2','4','8' if this
28/// fits in 1, 2, 4, or 8 sign extended bytes.
29static char ClassifyInt(int64_t Val) {
30 if (Val == int8_t(Val)) return '1';
31 if (Val == int16_t(Val)) return '2';
32 if (Val == int32_t(Val)) return '4';
33 return '8';
34}
35
36/// EmitInt - Emit the specified integer, returning the number of bytes emitted.
37static unsigned EmitInt(int64_t Val, formatted_raw_ostream &OS) {
38 unsigned BytesEmitted = 1;
39 OS << (int)(unsigned char)Val << ", ";
40 if (Val == int8_t(Val)) {
41 OS << "\n";
42 return BytesEmitted;
43 }
44
45 OS << (int)(unsigned char)(Val >> 8) << ", ";
46 ++BytesEmitted;
47
48 if (Val != int16_t(Val)) {
49 OS << (int)(unsigned char)(Val >> 16) << ','
50 << (int)(unsigned char)(Val >> 24) << ',';
51 BytesEmitted += 2;
52
53 if (Val != int32_t(Val)) {
54 OS << (int)(unsigned char)(Val >> 32) << ','
55 << (int)(unsigned char)(Val >> 40) << ','
56 << (int)(unsigned char)(Val >> 48) << ','
57 << (int)(unsigned char)(Val >> 56) << ',';
58 BytesEmitted += 4;
59 }
60 }
61
62 OS.PadToColumn(CommentIndent) << "// " << Val << '\n';
63 return BytesEmitted;
64}
65
Chris Lattnere02ea542010-02-16 06:52:01 +000066namespace {
67class MatcherTableEmitter {
68 formatted_raw_ostream &OS;
69public:
70 MatcherTableEmitter(formatted_raw_ostream &os) : OS(os) {}
71
72 unsigned EmitMatcherAndChildren(const MatcherNode *N, unsigned Indent);
73private:
74 unsigned EmitMatcher(const MatcherNode *N, unsigned Indent);
75};
76} // end anonymous namespace.
77
Chris Lattnerda272d12010-02-15 08:04:42 +000078/// EmitMatcherOpcodes - Emit bytes for the specified matcher and return
79/// the number of bytes emitted.
Chris Lattnere02ea542010-02-16 06:52:01 +000080unsigned MatcherTableEmitter::
81EmitMatcher(const MatcherNode *N, unsigned Indent) {
Chris Lattnerda272d12010-02-15 08:04:42 +000082 OS.PadToColumn(Indent*2);
83
84 switch (N->getKind()) {
85 case MatcherNode::Push: assert(0 && "Should be handled by caller");
86 case MatcherNode::EmitNode:
87 OS << "OPC_Emit, /*XXX*/";
88 OS.PadToColumn(CommentIndent) << "// Src: "
89 << *cast<EmitNodeMatcherNode>(N)->getPattern().getSrcPattern() << '\n';
90 OS.PadToColumn(CommentIndent) << "// Dst: "
91 << *cast<EmitNodeMatcherNode>(N)->getPattern().getDstPattern() << '\n';
92 return 1;
93 case MatcherNode::Record:
94 OS << "OPC_Record,\n";
95 return 1;
96 case MatcherNode::MoveChild:
97 OS << "OPC_MoveChild, "
98 << cast<MoveChildMatcherNode>(N)->getChildNo() << ",\n";
99 return 2;
100
101 case MatcherNode::MoveParent:
102 OS << "OPC_MoveParent,\n";
103 return 1;
104
105 case MatcherNode::CheckSame:
106 OS << "OPC_CheckSame, "
107 << cast<CheckSameMatcherNode>(N)->getMatchNumber() << ",\n";
108 return 2;
109
110 case MatcherNode::CheckPatternPredicate:
111 OS << "OPC_CheckPatternPredicate, /*XXX*/0,";
112 OS.PadToColumn(CommentIndent) << "// "
113 << cast<CheckPatternPredicateMatcherNode>(N)->getPredicate() << '\n';
114 return 2;
115
116 case MatcherNode::CheckPredicate:
117 OS << "OPC_CheckPredicate, /*XXX*/0,";
118 OS.PadToColumn(CommentIndent) << "// "
119 << cast<CheckPredicateMatcherNode>(N)->getPredicateName() << '\n';
120 return 2;
121
122 case MatcherNode::CheckOpcode:
123 OS << "OPC_CheckOpcode, "
124 << cast<CheckOpcodeMatcherNode>(N)->getOpcodeName() << ",\n";
125 return 2;
126
127 case MatcherNode::CheckType:
128 OS << "OPC_CheckType, "
129 << getEnumName(cast<CheckTypeMatcherNode>(N)->getType()) << ",\n";
130 return 2;
131
132 case MatcherNode::CheckInteger: {
133 int64_t Val = cast<CheckIntegerMatcherNode>(N)->getValue();
134 OS << "OPC_CheckInteger" << ClassifyInt(Val) << ", ";
135 return EmitInt(Val, OS)+1;
136 }
137 case MatcherNode::CheckCondCode:
138 OS << "OPC_CheckCondCode, ISD::"
139 << cast<CheckCondCodeMatcherNode>(N)->getCondCodeName() << ",\n";
140 return 2;
141
142 case MatcherNode::CheckValueType:
143 OS << "OPC_CheckValueType, MVT::"
144 << cast<CheckValueTypeMatcherNode>(N)->getTypeName() << ",\n";
145 return 2;
146
147 case MatcherNode::CheckComplexPat:
148 OS << "OPC_CheckComplexPat, 0/*XXX*/,\n";
149 return 2;
150
151 case MatcherNode::CheckAndImm: {
152 int64_t Val = cast<CheckAndImmMatcherNode>(N)->getValue();
153 OS << "OPC_CheckAndImm" << ClassifyInt(Val) << ", ";
154 return EmitInt(Val, OS)+1;
155 }
156
157 case MatcherNode::CheckOrImm: {
158 int64_t Val = cast<CheckOrImmMatcherNode>(N)->getValue();
159 OS << "OPC_CheckOrImm" << ClassifyInt(Val) << ", ";
160 return EmitInt(Val, OS)+1;
161 }
Chris Lattnere39650a2010-02-16 06:10:58 +0000162 case MatcherNode::CheckProfitableToFold:
163 OS << "OPC_IsProfitableToFold,\n";
164 return 1;
165 case MatcherNode::CheckLegalToFold:
166 OS << "OPC_IsLegalToFold,\n";
167 return 1;
Chris Lattnerda272d12010-02-15 08:04:42 +0000168 }
169 assert(0 && "Unreachable");
170 return 0;
171}
172
173/// EmitMatcherAndChildren - Emit the bytes for the specified matcher subtree.
Chris Lattnere02ea542010-02-16 06:52:01 +0000174unsigned MatcherTableEmitter::
175EmitMatcherAndChildren(const MatcherNode *N, unsigned Indent) {
Chris Lattnerda272d12010-02-15 08:04:42 +0000176 unsigned Size = 0;
177 while (1) {
178 // Push is a special case since it is binary.
179 if (const PushMatcherNode *PMN = dyn_cast<PushMatcherNode>(N)) {
180 // We need to encode the child and the offset of the failure code before
181 // emitting either of them. Handle this by buffering the output into a
182 // string while we get the size.
183 SmallString<128> TmpBuf;
184 unsigned ChildSize;
185 {
186 raw_svector_ostream OS(TmpBuf);
187 formatted_raw_ostream FOS(OS);
188 ChildSize =
Chris Lattnere02ea542010-02-16 06:52:01 +0000189 EmitMatcherAndChildren(cast<PushMatcherNode>(N)->getChild(),Indent+1);
Chris Lattnerda272d12010-02-15 08:04:42 +0000190 }
191
192 if (ChildSize > 255) {
193 errs() <<
194 "Tblgen internal error: can't handle predicate this complex yet\n";
195 exit(1);
196 }
197
198 OS.PadToColumn(Indent*2);
199 OS << "OPC_Push, " << ChildSize << ",\n";
200 OS << TmpBuf.str();
201
202 Size += 2 + ChildSize;
203
204 N = PMN->getFailure();
205 continue;
206 }
207
Chris Lattnere02ea542010-02-16 06:52:01 +0000208 Size += EmitMatcher(N, Indent);
Chris Lattnerda272d12010-02-15 08:04:42 +0000209
210 // If there are children of this node, iterate to them, otherwise we're
211 // done.
212 if (const MatcherNodeWithChild *MNWC = dyn_cast<MatcherNodeWithChild>(N))
213 N = MNWC->getChild();
214 else
215 return Size;
216 }
217}
218
219void llvm::EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &O) {
220 formatted_raw_ostream OS(O);
221
222 OS << "// The main instruction selector code.\n";
223 OS << "SDNode *SelectCode2(SDNode *N) {\n";
224
Chris Lattnere02ea542010-02-16 06:52:01 +0000225 MatcherTableEmitter MatcherEmitter(OS);
226
Chris Lattnerda272d12010-02-15 08:04:42 +0000227 OS << " static const unsigned char MatcherTable[] = {\n";
Chris Lattnere02ea542010-02-16 06:52:01 +0000228 unsigned TotalSize = MatcherEmitter.EmitMatcherAndChildren(Matcher, 2);
Chris Lattnerda272d12010-02-15 08:04:42 +0000229 OS << " 0\n }; // Total Array size is " << (TotalSize+1) << " bytes\n\n";
Chris Lattnere02ea542010-02-16 06:52:01 +0000230 OS << " return SelectCodeCommon(N, MatcherTable,sizeof(MatcherTable));\n}\n";
Chris Lattnerda272d12010-02-15 08:04:42 +0000231}