blob: 8007b7ed702bfd7d22add5efd542209079da73f5 [file] [log] [blame]
Dan Gohmanb0cf29c2008-08-13 20:19:35 +00001//===- FastISelEmitter.cpp - Generate an instruction selector -------------===//
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 tablegen backend emits a "fast" instruction selector.
11//
12// This instruction selection method is designed to emit very poor code
13// quickly. Also, it is not designed to do much lowering, so most illegal
14// types (e.g. i64 on 32-bit targets) and operations (e.g. calls) are not
15// supported and cannot easily be added. Blocks containing operations
16// that are not supported need to be handled by a more capable selector,
17// such as the SelectionDAG selector.
18//
19// The intended use for "fast" instruction selection is "-O0" mode
20// compilation, where the quality of the generated code is irrelevant when
21// weighed against the speed at which the code can be generated.
22//
23// If compile time is so important, you might wonder why we don't just
24// skip codegen all-together, emit LLVM bytecode files, and execute them
25// with an interpreter. The answer is that it would complicate linking and
26// debugging, and also because that isn't how a compiler is expected to
27// work in some circles.
28//
29// If you need better generated code or more lowering than what this
30// instruction selector provides, use the SelectionDAG (DAGISel) instruction
31// selector instead. If you're looking here because SelectionDAG isn't fast
32// enough, consider looking into improving the SelectionDAG infastructure
33// instead. At the time of this writing there remain several major
34// opportunities for improvement.
35//
36//===----------------------------------------------------------------------===//
37
38#include "FastISelEmitter.h"
39#include "Record.h"
40#include "llvm/Support/Debug.h"
41#include "llvm/Support/Streams.h"
42#include "llvm/ADT/VectorExtras.h"
43using namespace llvm;
44
45namespace {
46
47struct OperandsSignature {
48 std::vector<std::string> Operands;
49
50 bool operator<(const OperandsSignature &O) const {
51 return Operands < O.Operands;
52 }
53
54 bool empty() const { return Operands.empty(); }
55
56 void PrintParameters(std::ostream &OS) const {
57 for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
58 if (Operands[i] == "r") {
59 OS << "unsigned Op" << i;
60 } else {
61 assert("Unknown operand kind!");
62 abort();
63 }
64 if (i + 1 != e)
65 OS << ", ";
66 }
67 }
68
69 void PrintArguments(std::ostream &OS) const {
70 for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
71 if (Operands[i] == "r") {
72 OS << "Op" << i;
73 } else {
74 assert("Unknown operand kind!");
75 abort();
76 }
77 if (i + 1 != e)
78 OS << ", ";
79 }
80 }
81
82 void PrintManglingSuffix(std::ostream &OS) const {
83 for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
84 OS << Operands[i];
85 }
86 }
87};
88
89struct InstructionMemo {
90 std::string Name;
91 const CodeGenRegisterClass *RC;
92};
93
94}
95
96static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) {
97 return CGP.getSDNodeInfo(Op).getEnumName();
98}
99
100static std::string getLegalCName(std::string OpName) {
101 std::string::size_type pos = OpName.find("::");
102 if (pos != std::string::npos)
103 OpName.replace(pos, 2, "_");
104 return OpName;
105}
106
107void FastISelEmitter::run(std::ostream &OS) {
108 EmitSourceFileHeader("\"Fast\" Instruction Selector for the " +
109 CGP.getTargetInfo().getName() + " target", OS);
110
111 const CodeGenTarget &Target = CGP.getTargetInfo();
112
113 // Get the namespace to insert instructions into. Make sure not to pick up
114 // "TargetInstrInfo" by accidentally getting the namespace off the PHI
115 // instruction or something.
116 std::string InstNS;
117 for (CodeGenTarget::inst_iterator i = Target.inst_begin(),
118 e = Target.inst_end(); i != e; ++i) {
119 InstNS = i->second.Namespace;
120 if (InstNS != "TargetInstrInfo")
121 break;
122 }
123
124 OS << "namespace llvm {\n";
125 OS << "namespace " << InstNS << " {\n";
126 OS << "class FastISel;\n";
127 OS << "}\n";
128 OS << "}\n";
129 OS << "\n";
130
131 if (!InstNS.empty()) InstNS += "::";
132
133 typedef std::map<MVT::SimpleValueType, InstructionMemo> TypeMap;
134 typedef std::map<std::string, TypeMap> OpcodeTypeMap;
135 typedef std::map<OperandsSignature, OpcodeTypeMap> OperandsOpcodeTypeMap;
136 OperandsOpcodeTypeMap SimplePatterns;
137
138 // Create the supported type signatures.
139 OperandsSignature KnownOperands;
140 SimplePatterns[KnownOperands] = OpcodeTypeMap();
141 KnownOperands.Operands.push_back("r");
142 SimplePatterns[KnownOperands] = OpcodeTypeMap();
143 KnownOperands.Operands.push_back("r");
144 SimplePatterns[KnownOperands] = OpcodeTypeMap();
145
146 for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(),
147 E = CGP.ptm_end(); I != E; ++I) {
148 const PatternToMatch &Pattern = *I;
149
150 // For now, just look at Instructions, so that we don't have to worry
151 // about emitting multiple instructions for a pattern.
152 TreePatternNode *Dst = Pattern.getDstPattern();
153 if (Dst->isLeaf()) continue;
154 Record *Op = Dst->getOperator();
155 if (!Op->isSubClassOf("Instruction"))
156 continue;
157 CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op->getName());
158 if (II.OperandList.empty())
159 continue;
160 Record *Op0Rec = II.OperandList[0].Rec;
161 if (!Op0Rec->isSubClassOf("RegisterClass"))
162 continue;
163 const CodeGenRegisterClass *DstRC = &Target.getRegisterClass(Op0Rec);
164 if (!DstRC)
165 continue;
166
167 // Inspect the pattern.
168 TreePatternNode *InstPatNode = Pattern.getSrcPattern();
169 if (!InstPatNode) continue;
170 if (InstPatNode->isLeaf()) continue;
171
172 Record *InstPatOp = InstPatNode->getOperator();
173 std::string OpcodeName = getOpcodeName(InstPatOp, CGP);
174 MVT::SimpleValueType VT = InstPatNode->getTypeNum(0);
175
176 // For now, filter out instructions which just set a register to
177 // an Operand, like MOV32ri.
178 if (InstPatOp->isSubClassOf("Operand"))
179 continue;
180
181 // Check all the operands. For now only accept register operands.
182 OperandsSignature Operands;
183 for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) {
184 TreePatternNode *Op = InstPatNode->getChild(i);
185 if (!Op->isLeaf())
186 goto continue_label;
187 DefInit *OpDI = dynamic_cast<DefInit*>(Op->getLeafValue());
188 if (!OpDI)
189 goto continue_label;
190 Record *OpLeafRec = OpDI->getDef();
191 if (!OpLeafRec->isSubClassOf("RegisterClass"))
192 goto continue_label;
193 const CodeGenRegisterClass *RC = &Target.getRegisterClass(OpLeafRec);
194 if (!RC)
195 goto continue_label;
196 if (Op->getTypeNum(0) != VT)
197 goto continue_label;
198 Operands.Operands.push_back("r");
199 }
200
201 // If it's not a known signature, ignore it.
202 if (!SimplePatterns.count(Operands))
203 continue;
204
205 // Ok, we found a pattern that we can handle. Remember it.
206 {
207 InstructionMemo Memo = { Pattern.getDstPattern()->getOperator()->getName(),
208 DstRC };
209 SimplePatterns[Operands][OpcodeName][VT] = Memo;
210 }
211
212 continue_label:;
213 }
214
215 OS << "#include \"llvm/CodeGen/FastISel.h\"\n";
216 OS << "\n";
217 OS << "namespace llvm {\n";
218 OS << "\n";
219
220 // Declare the target FastISel class.
221 OS << "class " << InstNS << "FastISel : public llvm::FastISel {\n";
222 for (OperandsOpcodeTypeMap::const_iterator OI = SimplePatterns.begin(),
223 OE = SimplePatterns.end(); OI != OE; ++OI) {
224 const OperandsSignature &Operands = OI->first;
225 const OpcodeTypeMap &OTM = OI->second;
226
227 for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end();
228 I != E; ++I) {
229 const std::string &Opcode = I->first;
230 const TypeMap &TM = I->second;
231
232 for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end();
233 TI != TE; ++TI) {
234 MVT::SimpleValueType VT = TI->first;
235
236 OS << " unsigned FastEmit_" << getLegalCName(Opcode)
237 << "_" << getLegalCName(getName(VT)) << "(";
238 Operands.PrintParameters(OS);
239 OS << ");\n";
240 }
241
242 OS << " unsigned FastEmit_" << getLegalCName(Opcode)
243 << "(MVT::SimpleValueType VT";
244 if (!Operands.empty())
245 OS << ", ";
246 Operands.PrintParameters(OS);
247 OS << ");\n";
248 }
249
250 OS << "unsigned FastEmit_";
251 Operands.PrintManglingSuffix(OS);
252 OS << "(MVT::SimpleValueType VT, ISD::NodeType Opcode";
253 if (!Operands.empty())
254 OS << ", ";
255 Operands.PrintParameters(OS);
256 OS << ");\n";
257 }
258 OS << "public:\n";
259 OS << " FastISel(MachineBasicBlock *mbb, MachineFunction *mf, ";
260 OS << "const TargetInstrInfo *tii) : llvm::FastISel(mbb, mf, tii) {}\n";
261 OS << "};\n";
262 OS << "\n";
263
264 // Define the target FastISel creation function.
265 OS << "llvm::FastISel *" << InstNS
266 << "createFastISel(MachineBasicBlock *mbb, MachineFunction *mf, ";
267 OS << "const TargetInstrInfo *tii) {\n";
268 OS << " return new " << InstNS << "FastISel(mbb, mf, tii);\n";
269 OS << "}\n";
270 OS << "\n";
271
272 // Now emit code for all the patterns that we collected.
273 for (OperandsOpcodeTypeMap::const_iterator OI = SimplePatterns.begin(),
274 OE = SimplePatterns.end(); OI != OE; ++OI) {
275 const OperandsSignature &Operands = OI->first;
276 const OpcodeTypeMap &OTM = OI->second;
277
278 for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end();
279 I != E; ++I) {
280 const std::string &Opcode = I->first;
281 const TypeMap &TM = I->second;
282
283 OS << "// FastEmit functions for " << Opcode << ".\n";
284 OS << "\n";
285
286 // Emit one function for each opcode,type pair.
287 for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end();
288 TI != TE; ++TI) {
289 MVT::SimpleValueType VT = TI->first;
290 const InstructionMemo &Memo = TI->second;
291
292 OS << "unsigned " << InstNS << "FastISel::FastEmit_"
293 << getLegalCName(Opcode)
294 << "_" << getLegalCName(getName(VT)) << "(";
295 Operands.PrintParameters(OS);
296 OS << ") {\n";
297 OS << " return FastEmitInst_";
298 Operands.PrintManglingSuffix(OS);
299 OS << "(" << InstNS << Memo.Name << ", ";
300 OS << InstNS << Memo.RC->getName() << "RegisterClass";
301 if (!Operands.empty())
302 OS << ", ";
303 Operands.PrintArguments(OS);
304 OS << ");\n";
305 OS << "}\n";
306 OS << "\n";
307 }
308
309 // Emit one function for the opcode that demultiplexes based on the type.
310 OS << "unsigned " << InstNS << "FastISel::FastEmit_"
311 << getLegalCName(Opcode) << "(MVT::SimpleValueType VT";
312 if (!Operands.empty())
313 OS << ", ";
314 Operands.PrintParameters(OS);
315 OS << ") {\n";
316 OS << " switch (VT) {\n";
317 for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end();
318 TI != TE; ++TI) {
319 MVT::SimpleValueType VT = TI->first;
320 std::string TypeName = getName(VT);
321 OS << " case " << TypeName << ": return FastEmit_"
322 << getLegalCName(Opcode) << "_" << getLegalCName(TypeName) << "(";
323 Operands.PrintArguments(OS);
324 OS << ");\n";
325 }
326 OS << " default: return 0;\n";
327 OS << " }\n";
328 OS << "}\n";
329 OS << "\n";
330 }
331
332 // Emit one function for the operand signature that demultiplexes based
333 // on opcode and type.
334 OS << "unsigned " << InstNS << "FastISel::FastEmit_";
335 Operands.PrintManglingSuffix(OS);
336 OS << "(MVT::SimpleValueType VT, ISD::NodeType Opcode";
337 if (!Operands.empty())
338 OS << ", ";
339 Operands.PrintParameters(OS);
340 OS << ") {\n";
341 OS << " switch (Opcode) {\n";
342 for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end();
343 I != E; ++I) {
344 const std::string &Opcode = I->first;
345
346 OS << " case " << Opcode << ": return FastEmit_"
347 << getLegalCName(Opcode) << "(VT";
348 if (!Operands.empty())
349 OS << ", ";
350 Operands.PrintArguments(OS);
351 OS << ");\n";
352 }
353 OS << " default: return 0;\n";
354 OS << " }\n";
355 OS << "}\n";
356 OS << "\n";
357 }
358
359 OS << "}\n";
360}
361
362// todo: really filter out Constants