@@ -98,6 +98,10 @@ class CompressInstEmitter {
98
98
// Tied operand index within the instruction.
99
99
int TiedOpIdx = -1 ;
100
100
};
101
+ struct ArgData {
102
+ unsigned DAGOpNo;
103
+ unsigned MIOpNo;
104
+ };
101
105
struct CompressPat {
102
106
// The source instruction definition.
103
107
CodeGenInstruction Source;
@@ -126,27 +130,23 @@ class CompressInstEmitter {
126
130
std::vector<CompressPat> CompressPatterns;
127
131
void addDagOperandMapping (const Record *Rec, const DagInit *Dag,
128
132
const CodeGenInstruction &Inst,
129
- IndexedMap<OpData> &OperandMap, bool IsSourceInst,
130
- unsigned *SourceLastTiedOpPtr );
133
+ IndexedMap<OpData> &OperandMap,
134
+ StringMap<ArgData> &Operands, bool IsSourceInst );
131
135
void evaluateCompressPat (const Record *Compress);
132
136
void emitCompressInstEmitter (raw_ostream &OS, EmitterType EType);
133
137
bool validateTypes (const Record *DagOpType, const Record *InstOpType,
134
138
bool IsSourceInst);
135
139
bool validateRegister (const Record *Reg, const Record *RegClass);
136
- void createDagOperandMapping (const Record *Rec,
137
- StringMap<unsigned > &SourceOperands,
138
- StringMap<unsigned > &DestOperands,
139
- const DagInit *SourceDag, const DagInit *DestDag,
140
- IndexedMap<OpData> &SourceOperandMap,
141
- bool HasSourceTiedOp);
140
+ void checkDagOperandMapping (const Record *Rec,
141
+ const StringMap<ArgData> &DestOperands,
142
+ const DagInit *SourceDag, const DagInit *DestDag);
142
143
143
144
void createInstOperandMapping (const Record *Rec, const DagInit *SourceDag,
144
145
const DagInit *DestDag,
145
146
IndexedMap<OpData> &SourceOperandMap,
146
147
IndexedMap<OpData> &DestOperandMap,
147
- StringMap<unsigned > &SourceOperands,
148
- const CodeGenInstruction &DestInst,
149
- unsigned SourceLastTiedOp);
148
+ StringMap<ArgData> &SourceOperands,
149
+ const CodeGenInstruction &DestInst);
150
150
151
151
public:
152
152
CompressInstEmitter (const RecordKeeper &R) : Records(R), Target(R) {}
@@ -198,6 +198,10 @@ bool CompressInstEmitter::validateTypes(const Record *DagOpType,
198
198
return true ;
199
199
}
200
200
201
+ static bool validateArgsTypes (const Init *Arg1, const Init *Arg2) {
202
+ return cast<DefInit>(Arg1)->getDef () == cast<DefInit>(Arg2)->getDef ();
203
+ }
204
+
201
205
// / The patterns in the Dag contain different types of operands:
202
206
// / Register operands, e.g.: GPRC:$rs1; Fixed registers, e.g: X1; Immediate
203
207
// / operands, e.g.: simm6:$imm; Fixed immediate operands, e.g.: 0. This function
@@ -209,8 +213,8 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
209
213
const DagInit *Dag,
210
214
const CodeGenInstruction &Inst,
211
215
IndexedMap<OpData> &OperandMap,
212
- bool IsSourceInst ,
213
- unsigned *SourceLastTiedOpPtr ) {
216
+ StringMap<ArgData> &Operands ,
217
+ bool IsSourceInst ) {
214
218
unsigned NumMIOperands = 0 ;
215
219
if (!Inst.Operands .empty ())
216
220
NumMIOperands =
@@ -224,16 +228,12 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
224
228
// are represented.
225
229
unsigned TiedCount = 0 ;
226
230
unsigned OpNo = 0 ;
227
- if (IsSourceInst)
228
- *SourceLastTiedOpPtr = std::numeric_limits<unsigned int >::max ();
229
231
for (const auto &Opnd : Inst.Operands ) {
230
232
int TiedOpIdx = Opnd.getTiedRegister ();
231
233
if (-1 != TiedOpIdx) {
232
234
assert ((unsigned )TiedOpIdx < OpNo);
233
235
// Set the entry in OperandMap for the tied operand we're skipping.
234
236
OperandMap[OpNo] = OperandMap[TiedOpIdx];
235
- if (IsSourceInst)
236
- *SourceLastTiedOpPtr = OpNo;
237
237
++OpNo;
238
238
++TiedCount;
239
239
continue ;
@@ -290,6 +290,30 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
290
290
} else {
291
291
llvm_unreachable (" Unhandled CompressPat argument type!" );
292
292
}
293
+
294
+ // Create a mapping between the operand name in the Dag (e.g. $rs1) and
295
+ // its index in the list of Dag operands and check that operands with the
296
+ // same name have the same type. For example in 'C_ADD $rs1, $rs2' we
297
+ // generate the mapping $rs1 --> 0, $rs2 ---> 1. If the operand appears
298
+ // twice in the same Dag (tied in the compressed instruction), we note
299
+ // the previous index in the TiedOpIdx field.
300
+ StringRef ArgName = Dag->getArgNameStr (DAGOpNo);
301
+ if (ArgName.empty ())
302
+ continue ;
303
+
304
+ if (IsSourceInst) {
305
+ auto It = Operands.find (ArgName);
306
+ if (It != Operands.end ()) {
307
+ OperandMap[OpNo].TiedOpIdx = It->getValue ().MIOpNo ;
308
+ if (!validateArgsTypes (Dag->getArg (It->getValue ().DAGOpNo ),
309
+ Dag->getArg (DAGOpNo)))
310
+ PrintFatalError (Rec->getLoc (),
311
+ " Input Operand '" + ArgName +
312
+ " ' has a mismatched tied operand!" );
313
+ }
314
+ }
315
+
316
+ Operands[ArgName] = {DAGOpNo, OpNo};
293
317
}
294
318
}
295
319
}
@@ -331,60 +355,29 @@ static bool verifyDagOpCount(const CodeGenInstruction &Inst, const DagInit *Dag,
331
355
return true ;
332
356
}
333
357
334
- static bool validateArgsTypes (const Init *Arg1, const Init *Arg2) {
335
- return cast<DefInit>(Arg1)->getDef () == cast<DefInit>(Arg2)->getDef ();
336
- }
337
-
338
- // Creates a mapping between the operand name in the Dag (e.g. $rs1) and
339
- // its index in the list of Dag operands and checks that operands with the same
340
- // name have the same types. For example in 'C_ADD $rs1, $rs2' we generate the
341
- // mapping $rs1 --> 0, $rs2 ---> 1. If the operand appears twice in the (tied)
342
- // same Dag we use the last occurrence for indexing.
343
- void CompressInstEmitter::createDagOperandMapping (
344
- const Record *Rec, StringMap<unsigned > &SourceOperands,
345
- StringMap<unsigned > &DestOperands, const DagInit *SourceDag,
346
- const DagInit *DestDag, IndexedMap<OpData> &SourceOperandMap,
347
- bool HasSourceTiedOp) {
348
- for (unsigned I = 0 ; I < DestDag->getNumArgs (); ++I) {
349
- // Skip fixed immediates and registers, they were handled in
350
- // addDagOperandMapping.
351
- if (" " == DestDag->getArgNameStr (I))
352
- continue ;
353
- DestOperands[DestDag->getArgNameStr (I)] = I;
354
- }
358
+ // Check that all names in the source DAG appear in the destionation DAG.
359
+ void CompressInstEmitter::checkDagOperandMapping (
360
+ const Record *Rec, const StringMap<ArgData> &DestOperands,
361
+ const DagInit *SourceDag, const DagInit *DestDag) {
355
362
356
363
for (unsigned I = 0 ; I < SourceDag->getNumArgs (); ++I) {
357
364
// Skip fixed immediates and registers, they were handled in
358
365
// addDagOperandMapping.
359
- if (" " == SourceDag->getArgNameStr (I))
366
+ StringRef ArgName = SourceDag->getArgNameStr (I);
367
+ if (ArgName.empty ())
360
368
continue ;
361
369
362
- StringMap<unsigned >::iterator It =
363
- SourceOperands.find (SourceDag->getArgNameStr (I));
364
- if (It != SourceOperands.end ()) {
365
- // Operand sharing the same name in the Dag should be mapped as tied.
366
- if (HasSourceTiedOp)
367
- SourceOperandMap[I + 1 ].TiedOpIdx = It->getValue () + 1 ;
368
- else
369
- SourceOperandMap[I].TiedOpIdx = It->getValue ();
370
- if (!validateArgsTypes (SourceDag->getArg (It->getValue ()),
371
- SourceDag->getArg (I)))
372
- PrintFatalError (Rec->getLoc (),
373
- " Input Operand '" + SourceDag->getArgNameStr (I) +
374
- " ' has a mismatched tied operand!\n " );
375
- }
376
- It = DestOperands.find (SourceDag->getArgNameStr (I));
370
+ auto It = DestOperands.find (ArgName);
377
371
if (It == DestOperands.end ())
378
- PrintFatalError (Rec->getLoc (), " Operand " + SourceDag-> getArgNameStr (I) +
372
+ PrintFatalError (Rec->getLoc (), " Operand " + ArgName +
379
373
" defined in Input Dag but not used in"
380
- " Output Dag!\n " );
374
+ " Output Dag!" );
381
375
// Input Dag operand types must match output Dag operand type.
382
- if (!validateArgsTypes (DestDag->getArg (It->getValue ()),
376
+ if (!validateArgsTypes (DestDag->getArg (It->getValue (). DAGOpNo ),
383
377
SourceDag->getArg (I)))
384
378
PrintFatalError (Rec->getLoc (), " Type mismatch between Input and "
385
379
" Output Dag operand '" +
386
- SourceDag->getArgNameStr (I) + " '!" );
387
- SourceOperands[SourceDag->getArgNameStr (I)] = I;
380
+ ArgName + " '!" );
388
381
}
389
382
}
390
383
@@ -394,8 +387,7 @@ void CompressInstEmitter::createDagOperandMapping(
394
387
void CompressInstEmitter::createInstOperandMapping (
395
388
const Record *Rec, const DagInit *SourceDag, const DagInit *DestDag,
396
389
IndexedMap<OpData> &SourceOperandMap, IndexedMap<OpData> &DestOperandMap,
397
- StringMap<unsigned > &SourceOperands, const CodeGenInstruction &DestInst,
398
- unsigned SourceLastTiedOp) {
390
+ StringMap<ArgData> &SourceOperands, const CodeGenInstruction &DestInst) {
399
391
// TiedCount keeps track of the number of operands skipped in Inst
400
392
// operands list to get to the corresponding Dag operand.
401
393
unsigned TiedCount = 0 ;
@@ -425,29 +417,21 @@ void CompressInstEmitter::createInstOperandMapping(
425
417
continue ;
426
418
427
419
unsigned DagArgIdx = OpNo - TiedCount;
428
- StringMap< unsigned >::iterator SourceOp =
429
- SourceOperands.find (DestDag-> getArgNameStr (DagArgIdx) );
420
+ StringRef ArgName = DestDag-> getArgNameStr (DagArgIdx);
421
+ auto SourceOp = SourceOperands.find (ArgName );
430
422
if (SourceOp == SourceOperands.end ())
431
423
PrintFatalError (Rec->getLoc (),
432
- " Output Dag operand '" +
433
- DestDag->getArgNameStr (DagArgIdx) +
424
+ " Output Dag operand '" + ArgName +
434
425
" ' has no matching input Dag operand." );
435
426
436
- assert (DestDag-> getArgNameStr (DagArgIdx) ==
437
- SourceDag->getArgNameStr (SourceOp->getValue ()) &&
427
+ assert (ArgName ==
428
+ SourceDag->getArgNameStr (SourceOp->getValue (). DAGOpNo ) &&
438
429
" Incorrect operand mapping detected!\n " );
439
430
440
- // Following four lines ensure the correct handling of a single tied
441
- // operand in the Source Inst. SourceDagOp points to the position of
442
- // appropriate Dag argument which is not correct in presence of tied
443
- // operand in the Source Inst and must be incremented by 1 to reflect
444
- // correct position of the operand in Source Inst
445
- unsigned SourceDagOp = SourceOp->getValue ();
446
- if (SourceDagOp >= SourceLastTiedOp)
447
- SourceDagOp++;
448
- DestOperandMap[OpNo].Data .Operand = SourceDagOp;
449
- SourceOperandMap[SourceDagOp].Data .Operand = OpNo;
450
- LLVM_DEBUG (dbgs () << " " << SourceDagOp << " ====> " << OpNo << " \n " );
431
+ unsigned SourceOpNo = SourceOp->getValue ().MIOpNo ;
432
+ DestOperandMap[OpNo].Data .Operand = SourceOpNo;
433
+ SourceOperandMap[SourceOpNo].Data .Operand = OpNo;
434
+ LLVM_DEBUG (dbgs () << " " << SourceOpNo << " ====> " << OpNo << " \n " );
451
435
}
452
436
}
453
437
}
@@ -506,27 +490,24 @@ void CompressInstEmitter::evaluateCompressPat(const Record *Rec) {
506
490
// Fill the mapping from the source to destination instructions.
507
491
508
492
IndexedMap<OpData> SourceOperandMap;
509
- unsigned SourceLastTiedOp; // postion of the last tied operand in Source Inst
493
+ // Map from arg name to DAG operand number and MI operand number.
494
+ StringMap<ArgData> SourceOperands;
510
495
// Create a mapping between source Dag operands and source Inst operands.
511
496
addDagOperandMapping (Rec, SourceDag, SourceInst, SourceOperandMap,
512
- /* IsSourceInst*/ true , &SourceLastTiedOp );
497
+ SourceOperands, /* IsSourceInst*/ true );
513
498
514
499
IndexedMap<OpData> DestOperandMap;
500
+ // Map from arg name to DAG operand number and MI operand number.
501
+ StringMap<ArgData> DestOperands;
515
502
// Create a mapping between destination Dag operands and destination Inst
516
503
// operands.
517
- addDagOperandMapping (Rec, DestDag, DestInst, DestOperandMap,
518
- /* IsSourceInst*/ false , nullptr );
519
-
520
- StringMap<unsigned > SourceOperands;
521
- StringMap<unsigned > DestOperands;
522
- bool HasSourceTiedOp =
523
- SourceLastTiedOp != std::numeric_limits<unsigned int >::max ();
524
- createDagOperandMapping (Rec, SourceOperands, DestOperands, SourceDag, DestDag,
525
- SourceOperandMap, HasSourceTiedOp);
504
+ addDagOperandMapping (Rec, DestDag, DestInst, DestOperandMap, DestOperands,
505
+ /* IsSourceInst*/ false );
506
+
507
+ checkDagOperandMapping (Rec, DestOperands, SourceDag, DestDag);
526
508
// Create operand mapping between the source and destination instructions.
527
509
createInstOperandMapping (Rec, SourceDag, DestDag, SourceOperandMap,
528
- DestOperandMap, SourceOperands, DestInst,
529
- SourceLastTiedOp);
510
+ DestOperandMap, SourceOperands, DestInst);
530
511
531
512
// Get the target features for the CompressPat.
532
513
std::vector<const Record *> PatReqFeatures;
@@ -624,7 +605,7 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
624
605
if (!AsmWriter->getValueAsInt (" PassSubtarget" ))
625
606
PrintFatalError (AsmWriter->getLoc (),
626
607
" 'PassSubtarget' is false. SubTargetInfo object is needed "
627
- " for target features.\n " );
608
+ " for target features." );
628
609
629
610
StringRef TargetName = Target.getName ();
630
611
@@ -780,7 +761,7 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
780
761
<< " ).getReg() == MI.getOperand("
781
762
<< SourceOperandMap[OpNo].TiedOpIdx << " ).getReg()) &&\n " ;
782
763
else
783
- PrintFatalError (" Unexpected tied operand types!\n " );
764
+ PrintFatalError (" Unexpected tied operand types!" );
784
765
}
785
766
for (unsigned SubOp = 0 ; SubOp != SourceOperand.MINumOperands ; ++SubOp) {
786
767
// Check for fixed immediates\registers in the source instruction.
0 commit comments