75
75
#include " llvm/TableGen/Error.h"
76
76
#include " llvm/TableGen/Record.h"
77
77
#include " llvm/TableGen/TableGenBackend.h"
78
+ #include < limits>
78
79
#include < set>
79
80
#include < vector>
80
81
using namespace llvm ;
@@ -123,10 +124,10 @@ class CompressInstEmitter {
123
124
const RecordKeeper &Records;
124
125
const CodeGenTarget Target;
125
126
std::vector<CompressPat> CompressPatterns;
126
-
127
127
void addDagOperandMapping (const Record *Rec, const DagInit *Dag,
128
128
const CodeGenInstruction &Inst,
129
- IndexedMap<OpData> &OperandMap, bool IsSourceInst);
129
+ IndexedMap<OpData> &OperandMap, bool IsSourceInst,
130
+ unsigned *SourceLastTiedOpPtr);
130
131
void evaluateCompressPat (const Record *Compress);
131
132
void emitCompressInstEmitter (raw_ostream &OS, EmitterType EType);
132
133
bool validateTypes (const Record *DagOpType, const Record *InstOpType,
@@ -143,7 +144,8 @@ class CompressInstEmitter {
143
144
IndexedMap<OpData> &SourceOperandMap,
144
145
IndexedMap<OpData> &DestOperandMap,
145
146
StringMap<unsigned > &SourceOperands,
146
- const CodeGenInstruction &DestInst);
147
+ const CodeGenInstruction &DestInst,
148
+ unsigned SourceLastTiedOp);
147
149
148
150
public:
149
151
CompressInstEmitter (const RecordKeeper &R) : Records(R), Target(R) {}
@@ -206,7 +208,8 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
206
208
const DagInit *Dag,
207
209
const CodeGenInstruction &Inst,
208
210
IndexedMap<OpData> &OperandMap,
209
- bool IsSourceInst) {
211
+ bool IsSourceInst,
212
+ unsigned *SourceLastTiedOpPtr) {
210
213
unsigned NumMIOperands = 0 ;
211
214
for (const auto &Op : Inst.Operands )
212
215
NumMIOperands += Op.MINumOperands ;
@@ -219,12 +222,16 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
219
222
// are represented.
220
223
unsigned TiedCount = 0 ;
221
224
unsigned OpNo = 0 ;
225
+ if (IsSourceInst)
226
+ *SourceLastTiedOpPtr = std::numeric_limits<unsigned int >::max ();
222
227
for (const auto &Opnd : Inst.Operands ) {
223
228
int TiedOpIdx = Opnd.getTiedRegister ();
224
229
if (-1 != TiedOpIdx) {
225
230
// Set the entry in OperandMap for the tied operand we're skipping.
226
231
OperandMap[OpNo].Kind = OperandMap[TiedOpIdx].Kind ;
227
232
OperandMap[OpNo].Data = OperandMap[TiedOpIdx].Data ;
233
+ if (IsSourceInst)
234
+ *SourceLastTiedOpPtr = OpNo;
228
235
++OpNo;
229
236
++TiedCount;
230
237
continue ;
@@ -289,15 +296,23 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
289
296
static bool verifyDagOpCount (const CodeGenInstruction &Inst, const DagInit *Dag,
290
297
bool IsSource) {
291
298
unsigned NumMIOperands = 0 ;
292
- for (const auto &Op : Inst.Operands )
299
+
300
+ // Use this to count number of tied Operands in Source Inst in this function.
301
+ // This counter is required here to error out when there is a Source
302
+ // Inst with two or more tied operands.
303
+ unsigned SourceInstTiedOpCount = 0 ;
304
+ for (const auto &Op : Inst.Operands ) {
293
305
NumMIOperands += Op.MINumOperands ;
306
+ if (Op.getTiedRegister () != -1 )
307
+ SourceInstTiedOpCount++;
308
+ }
294
309
295
310
if (Dag->getNumArgs () == NumMIOperands)
296
311
return true ;
297
312
298
- // Source instructions are non compressed instructions and don't have tied
299
- // operands .
300
- if (IsSource)
313
+ // Source instructions are non compressed instructions and have at most one
314
+ // tied operand .
315
+ if (IsSource && (SourceInstTiedOpCount >= 2 ) )
301
316
PrintFatalError (Inst.TheDef ->getLoc (),
302
317
" Input operands for Inst '" + Inst.TheDef ->getName () +
303
318
" ' and input Dag operand count mismatch" );
@@ -381,7 +396,8 @@ void CompressInstEmitter::createDagOperandMapping(
381
396
void CompressInstEmitter::createInstOperandMapping (
382
397
const Record *Rec, const DagInit *SourceDag, const DagInit *DestDag,
383
398
IndexedMap<OpData> &SourceOperandMap, IndexedMap<OpData> &DestOperandMap,
384
- StringMap<unsigned > &SourceOperands, const CodeGenInstruction &DestInst) {
399
+ StringMap<unsigned > &SourceOperands, const CodeGenInstruction &DestInst,
400
+ unsigned SourceLastTiedOp) {
385
401
// TiedCount keeps track of the number of operands skipped in Inst
386
402
// operands list to get to the corresponding Dag operand.
387
403
unsigned TiedCount = 0 ;
@@ -422,10 +438,18 @@ void CompressInstEmitter::createInstOperandMapping(
422
438
assert (DestDag->getArgNameStr (DagArgIdx) ==
423
439
SourceDag->getArgNameStr (SourceOp->getValue ()) &&
424
440
" Incorrect operand mapping detected!\n " );
425
- DestOperandMap[OpNo].Data .Operand = SourceOp->getValue ();
426
- SourceOperandMap[SourceOp->getValue ()].Data .Operand = OpNo;
427
- LLVM_DEBUG (dbgs () << " " << SourceOp->getValue () << " ====> " << OpNo
428
- << " \n " );
441
+
442
+ // Following four lines ensure the correct handling of a single tied
443
+ // operand in the Source Inst. SourceDagOp points to the position of
444
+ // appropriate Dag argument which is not correct in presence of tied
445
+ // operand in the Source Inst and must be incremented by 1 to reflect
446
+ // correct position of the operand in Source Inst
447
+ unsigned SourceDagOp = SourceOp->getValue ();
448
+ if (SourceDagOp >= SourceLastTiedOp)
449
+ SourceDagOp++;
450
+ DestOperandMap[OpNo].Data .Operand = SourceDagOp;
451
+ SourceOperandMap[SourceDagOp].Data .Operand = OpNo;
452
+ LLVM_DEBUG (dbgs () << " " << SourceDagOp << " ====> " << OpNo << " \n " );
429
453
}
430
454
}
431
455
}
@@ -484,23 +508,25 @@ void CompressInstEmitter::evaluateCompressPat(const Record *Rec) {
484
508
// Fill the mapping from the source to destination instructions.
485
509
486
510
IndexedMap<OpData> SourceOperandMap;
511
+ unsigned SourceLastTiedOp; // postion of the last tied operand in Source Inst
487
512
// Create a mapping between source Dag operands and source Inst operands.
488
513
addDagOperandMapping (Rec, SourceDag, SourceInst, SourceOperandMap,
489
- /* IsSourceInst*/ true );
514
+ /* IsSourceInst*/ true , &SourceLastTiedOp );
490
515
491
516
IndexedMap<OpData> DestOperandMap;
492
517
// Create a mapping between destination Dag operands and destination Inst
493
518
// operands.
494
519
addDagOperandMapping (Rec, DestDag, DestInst, DestOperandMap,
495
- /* IsSourceInst*/ false );
520
+ /* IsSourceInst*/ false , nullptr );
496
521
497
522
StringMap<unsigned > SourceOperands;
498
523
StringMap<unsigned > DestOperands;
499
524
createDagOperandMapping (Rec, SourceOperands, DestOperands, SourceDag, DestDag,
500
525
SourceOperandMap);
501
526
// Create operand mapping between the source and destination instructions.
502
527
createInstOperandMapping (Rec, SourceDag, DestDag, SourceOperandMap,
503
- DestOperandMap, SourceOperands, DestInst);
528
+ DestOperandMap, SourceOperands, DestInst,
529
+ SourceLastTiedOp);
504
530
505
531
// Get the target features for the CompressPat.
506
532
std::vector<const Record *> PatReqFeatures;
0 commit comments