1 //===- DAGISelMatcherEmitter.cpp - Matcher Emitter ------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains code to generate C++ code a matcher.
12 //===----------------------------------------------------------------------===//
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"
27 /// ClassifyInt - Classify an integer by size, return '1','2','4','8' if this
28 /// fits in 1, 2, 4, or 8 sign extended bytes.
29 static 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';
36 /// EmitInt - Emit the specified integer, returning the number of bytes emitted.
37 static 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)) {
45 OS << (int)(unsigned char)(Val >> 8) << ", ";
48 if (Val != int16_t(Val)) {
49 OS << (int)(unsigned char)(Val >> 16) << ','
50 << (int)(unsigned char)(Val >> 24) << ',';
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) << ',';
62 OS.PadToColumn(CommentIndent) << "// " << Val << '\n';
67 class MatcherTableEmitter {
68 formatted_raw_ostream &OS;
70 MatcherTableEmitter(formatted_raw_ostream &os) : OS(os) {}
72 unsigned EmitMatcherAndChildren(const MatcherNode *N, unsigned Indent);
74 unsigned EmitMatcher(const MatcherNode *N, unsigned Indent);
76 } // end anonymous namespace.
78 /// EmitMatcherOpcodes - Emit bytes for the specified matcher and return
79 /// the number of bytes emitted.
80 unsigned MatcherTableEmitter::
81 EmitMatcher(const MatcherNode *N, unsigned Indent) {
82 OS.PadToColumn(Indent*2);
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';
93 case MatcherNode::Record:
94 OS << "OPC_Record,\n";
96 case MatcherNode::MoveChild:
97 OS << "OPC_MoveChild, "
98 << cast<MoveChildMatcherNode>(N)->getChildNo() << ",\n";
101 case MatcherNode::MoveParent:
102 OS << "OPC_MoveParent,\n";
105 case MatcherNode::CheckSame:
106 OS << "OPC_CheckSame, "
107 << cast<CheckSameMatcherNode>(N)->getMatchNumber() << ",\n";
110 case MatcherNode::CheckPatternPredicate:
111 OS << "OPC_CheckPatternPredicate, /*XXX*/0,";
112 OS.PadToColumn(CommentIndent) << "// "
113 << cast<CheckPatternPredicateMatcherNode>(N)->getPredicate() << '\n';
116 case MatcherNode::CheckPredicate:
117 OS << "OPC_CheckPredicate, /*XXX*/0,";
118 OS.PadToColumn(CommentIndent) << "// "
119 << cast<CheckPredicateMatcherNode>(N)->getPredicateName() << '\n';
122 case MatcherNode::CheckOpcode:
123 OS << "OPC_CheckOpcode, "
124 << cast<CheckOpcodeMatcherNode>(N)->getOpcodeName() << ",\n";
127 case MatcherNode::CheckType:
128 OS << "OPC_CheckType, "
129 << getEnumName(cast<CheckTypeMatcherNode>(N)->getType()) << ",\n";
132 case MatcherNode::CheckInteger: {
133 int64_t Val = cast<CheckIntegerMatcherNode>(N)->getValue();
134 OS << "OPC_CheckInteger" << ClassifyInt(Val) << ", ";
135 return EmitInt(Val, OS)+1;
137 case MatcherNode::CheckCondCode:
138 OS << "OPC_CheckCondCode, ISD::"
139 << cast<CheckCondCodeMatcherNode>(N)->getCondCodeName() << ",\n";
142 case MatcherNode::CheckValueType:
143 OS << "OPC_CheckValueType, MVT::"
144 << cast<CheckValueTypeMatcherNode>(N)->getTypeName() << ",\n";
147 case MatcherNode::CheckComplexPat:
148 OS << "OPC_CheckComplexPat, 0/*XXX*/,\n";
151 case MatcherNode::CheckAndImm: {
152 int64_t Val = cast<CheckAndImmMatcherNode>(N)->getValue();
153 OS << "OPC_CheckAndImm" << ClassifyInt(Val) << ", ";
154 return EmitInt(Val, OS)+1;
157 case MatcherNode::CheckOrImm: {
158 int64_t Val = cast<CheckOrImmMatcherNode>(N)->getValue();
159 OS << "OPC_CheckOrImm" << ClassifyInt(Val) << ", ";
160 return EmitInt(Val, OS)+1;
162 case MatcherNode::CheckProfitableToFold:
163 OS << "OPC_IsProfitableToFold,\n";
165 case MatcherNode::CheckLegalToFold:
166 OS << "OPC_IsLegalToFold,\n";
169 assert(0 && "Unreachable");
173 /// EmitMatcherAndChildren - Emit the bytes for the specified matcher subtree.
174 unsigned MatcherTableEmitter::
175 EmitMatcherAndChildren(const MatcherNode *N, unsigned Indent) {
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;
186 raw_svector_ostream OS(TmpBuf);
187 formatted_raw_ostream FOS(OS);
189 EmitMatcherAndChildren(cast<PushMatcherNode>(N)->getChild(),Indent+1);
192 if (ChildSize > 255) {
194 "Tblgen internal error: can't handle predicate this complex yet\n";
198 OS.PadToColumn(Indent*2);
199 OS << "OPC_Push, " << ChildSize << ",\n";
202 Size += 2 + ChildSize;
204 N = PMN->getFailure();
208 Size += EmitMatcher(N, Indent);
210 // If there are children of this node, iterate to them, otherwise we're
212 if (const MatcherNodeWithChild *MNWC = dyn_cast<MatcherNodeWithChild>(N))
213 N = MNWC->getChild();
219 void llvm::EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &O) {
220 formatted_raw_ostream OS(O);
222 OS << "// The main instruction selector code.\n";
223 OS << "SDNode *SelectCode2(SDNode *N) {\n";
225 MatcherTableEmitter MatcherEmitter(OS);
227 OS << " static const unsigned char MatcherTable[] = {\n";
228 unsigned TotalSize = MatcherEmitter.EmitMatcherAndChildren(Matcher, 2);
229 OS << " 0\n }; // Total Array size is " << (TotalSize+1) << " bytes\n\n";
230 OS << " return SelectCodeCommon(N, MatcherTable,sizeof(MatcherTable));\n}\n";