@@ -175,10 +175,11 @@ void FastISelEmitter::run(std::ostream &OS) {
175
175
OS << " namespace " << InstNS.substr (0 , InstNS.size () - 2 ) << " {\n " ;
176
176
OS << " \n " ;
177
177
178
- typedef std::map<MVT::SimpleValueType, InstructionMemo> TypeMap;
179
- typedef std::map<std::string, TypeMap> OpcodeTypeMap;
180
- typedef std::map<OperandsSignature, OpcodeTypeMap> OperandsOpcodeTypeMap;
181
- OperandsOpcodeTypeMap SimplePatterns;
178
+ typedef std::map<std::string, InstructionMemo> PredMap;
179
+ typedef std::map<MVT::SimpleValueType, PredMap> TypePredMap;
180
+ typedef std::map<std::string, TypePredMap> OpcodeTypePredMap;
181
+ typedef std::map<OperandsSignature, OpcodeTypePredMap> OperandsOpcodeTypePredMap;
182
+ OperandsOpcodeTypePredMap SimplePatterns;
182
183
183
184
for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin (),
184
185
E = CGP.ptm_end (); I != E; ++I) {
@@ -230,27 +231,32 @@ void FastISelEmitter::run(std::ostream &OS) {
230
231
if (!Operands.initialize (InstPatNode, Target, VT, DstRC))
231
232
continue ;
232
233
234
+ // Get the predicate that guards this pattern.
235
+ std::string PredicateCheck = Pattern.getPredicateCheck ();
236
+
233
237
// Ok, we found a pattern that we can handle. Remember it.
234
238
InstructionMemo Memo = {
235
239
Pattern.getDstPattern ()->getOperator ()->getName (),
236
240
DstRC
237
241
};
238
- SimplePatterns[Operands][OpcodeName][VT] = Memo;
242
+ assert (!SimplePatterns[Operands][OpcodeName][VT].count (PredicateCheck) &&
243
+ " Duplicate pattern!" );
244
+ SimplePatterns[Operands][OpcodeName][VT][PredicateCheck] = Memo;
239
245
}
240
246
241
247
// Declare the target FastISel class.
242
248
OS << " class FastISel : public llvm::FastISel {\n " ;
243
- for (OperandsOpcodeTypeMap ::const_iterator OI = SimplePatterns.begin (),
249
+ for (OperandsOpcodeTypePredMap ::const_iterator OI = SimplePatterns.begin (),
244
250
OE = SimplePatterns.end (); OI != OE; ++OI) {
245
251
const OperandsSignature &Operands = OI->first ;
246
- const OpcodeTypeMap &OTM = OI->second ;
252
+ const OpcodeTypePredMap &OTM = OI->second ;
247
253
248
- for (OpcodeTypeMap ::const_iterator I = OTM.begin (), E = OTM.end ();
254
+ for (OpcodeTypePredMap ::const_iterator I = OTM.begin (), E = OTM.end ();
249
255
I != E; ++I) {
250
256
const std::string &Opcode = I->first ;
251
- const TypeMap &TM = I->second ;
257
+ const TypePredMap &TM = I->second ;
252
258
253
- for (TypeMap ::const_iterator TI = TM.begin (), TE = TM.end ();
259
+ for (TypePredMap ::const_iterator TI = TM.begin (), TE = TM.end ();
254
260
TI != TE; ++TI) {
255
261
MVT::SimpleValueType VT = TI->first ;
256
262
@@ -279,8 +285,19 @@ void FastISelEmitter::run(std::ostream &OS) {
279
285
Operands.PrintParameters (OS);
280
286
OS << " );\n " ;
281
287
}
288
+ OS << " \n " ;
289
+
290
+ // Declare the Subtarget member, which is used for predicate checks.
291
+ OS << " const " << InstNS.substr (0 , InstNS.size () - 2 )
292
+ << " Subtarget *Subtarget;\n " ;
293
+ OS << " \n " ;
294
+
295
+ // Declare the constructor.
282
296
OS << " public:\n " ;
283
- OS << " explicit FastISel(MachineFunction &mf) : llvm::FastISel(mf) {}\n " ;
297
+ OS << " explicit FastISel(MachineFunction &mf)\n " ;
298
+ OS << " : llvm::FastISel(mf),\n " ;
299
+ OS << " Subtarget(&TM.getSubtarget<" << InstNS.substr (0 , InstNS.size () - 2 )
300
+ << " Subtarget>()) {}\n " ;
284
301
OS << " };\n " ;
285
302
OS << " \n " ;
286
303
@@ -291,40 +308,61 @@ void FastISelEmitter::run(std::ostream &OS) {
291
308
OS << " \n " ;
292
309
293
310
// Now emit code for all the patterns that we collected.
294
- for (OperandsOpcodeTypeMap ::const_iterator OI = SimplePatterns.begin (),
311
+ for (OperandsOpcodeTypePredMap ::const_iterator OI = SimplePatterns.begin (),
295
312
OE = SimplePatterns.end (); OI != OE; ++OI) {
296
313
const OperandsSignature &Operands = OI->first ;
297
- const OpcodeTypeMap &OTM = OI->second ;
314
+ const OpcodeTypePredMap &OTM = OI->second ;
298
315
299
- for (OpcodeTypeMap ::const_iterator I = OTM.begin (), E = OTM.end ();
316
+ for (OpcodeTypePredMap ::const_iterator I = OTM.begin (), E = OTM.end ();
300
317
I != E; ++I) {
301
318
const std::string &Opcode = I->first ;
302
- const TypeMap &TM = I->second ;
319
+ const TypePredMap &TM = I->second ;
303
320
304
321
OS << " // FastEmit functions for " << Opcode << " .\n " ;
305
322
OS << " \n " ;
306
323
307
324
// Emit one function for each opcode,type pair.
308
- for (TypeMap ::const_iterator TI = TM.begin (), TE = TM.end ();
325
+ for (TypePredMap ::const_iterator TI = TM.begin (), TE = TM.end ();
309
326
TI != TE; ++TI) {
310
327
MVT::SimpleValueType VT = TI->first ;
311
- const InstructionMemo &Memo = TI->second ;
312
-
328
+ const PredMap &PM = TI->second ;
329
+ bool HasPred = false ;
330
+
313
331
OS << " unsigned FastISel::FastEmit_"
314
332
<< getLegalCName (Opcode)
315
333
<< " _" << getLegalCName (getName (VT)) << " _" ;
316
334
Operands.PrintManglingSuffix (OS);
317
335
OS << " (" ;
318
336
Operands.PrintParameters (OS);
319
337
OS << " ) {\n " ;
320
- OS << " return FastEmitInst_" ;
321
- Operands.PrintManglingSuffix (OS);
322
- OS << " (" << InstNS << Memo.Name << " , " ;
323
- OS << InstNS << Memo.RC ->getName () << " RegisterClass" ;
324
- if (!Operands.empty ())
325
- OS << " , " ;
326
- Operands.PrintArguments (OS);
327
- OS << " );\n " ;
338
+
339
+ // Emit code for each possible instruction. There may be
340
+ // multiple if there are subtarget concerns.
341
+ for (PredMap::const_iterator PI = PM.begin (), PE = PM.end ();
342
+ PI != PE; ++PI) {
343
+ std::string PredicateCheck = PI->first ;
344
+ const InstructionMemo &Memo = PI->second ;
345
+
346
+ if (PredicateCheck.empty ()) {
347
+ assert (!HasPred && " Multiple instructions match, at least one has "
348
+ " a predicate and at least one doesn't!" );
349
+ } else {
350
+ OS << " if (" + PredicateCheck + " )\n " ;
351
+ OS << " " ;
352
+ HasPred = true ;
353
+ }
354
+ OS << " return FastEmitInst_" ;
355
+ Operands.PrintManglingSuffix (OS);
356
+ OS << " (" << InstNS << Memo.Name << " , " ;
357
+ OS << InstNS << Memo.RC ->getName () << " RegisterClass" ;
358
+ if (!Operands.empty ())
359
+ OS << " , " ;
360
+ Operands.PrintArguments (OS);
361
+ OS << " );\n " ;
362
+ }
363
+ // Return 0 if none of the predicates were satisfied.
364
+ if (HasPred)
365
+ OS << " return 0;\n " ;
328
366
OS << " }\n " ;
329
367
OS << " \n " ;
330
368
}
@@ -339,7 +377,7 @@ void FastISelEmitter::run(std::ostream &OS) {
339
377
Operands.PrintParameters (OS);
340
378
OS << " ) {\n " ;
341
379
OS << " switch (VT) {\n " ;
342
- for (TypeMap ::const_iterator TI = TM.begin (), TE = TM.end ();
380
+ for (TypePredMap ::const_iterator TI = TM.begin (), TE = TM.end ();
343
381
TI != TE; ++TI) {
344
382
MVT::SimpleValueType VT = TI->first ;
345
383
std::string TypeName = getName (VT);
@@ -366,7 +404,7 @@ void FastISelEmitter::run(std::ostream &OS) {
366
404
Operands.PrintParameters (OS);
367
405
OS << " ) {\n " ;
368
406
OS << " switch (Opcode) {\n " ;
369
- for (OpcodeTypeMap ::const_iterator I = OTM.begin (), E = OTM.end ();
407
+ for (OpcodeTypePredMap ::const_iterator I = OTM.begin (), E = OTM.end ();
370
408
I != E; ++I) {
371
409
const std::string &Opcode = I->first ;
372
410
0 commit comments