7575#include " llvm/TableGen/Error.h"
7676#include " llvm/TableGen/Record.h"
7777#include " llvm/TableGen/TableGenBackend.h"
78+ #include < limits>
7879#include < set>
7980#include < vector>
8081using namespace llvm ;
@@ -123,10 +124,10 @@ class CompressInstEmitter {
123124 const RecordKeeper &Records;
124125 const CodeGenTarget Target;
125126 std::vector<CompressPat> CompressPatterns;
126-
127127 void addDagOperandMapping (const Record *Rec, const DagInit *Dag,
128128 const CodeGenInstruction &Inst,
129- IndexedMap<OpData> &OperandMap, bool IsSourceInst);
129+ IndexedMap<OpData> &OperandMap, bool IsSourceInst,
130+ unsigned *SourceLastTiedOpPtr);
130131 void evaluateCompressPat (const Record *Compress);
131132 void emitCompressInstEmitter (raw_ostream &OS, EmitterType EType);
132133 bool validateTypes (const Record *DagOpType, const Record *InstOpType,
@@ -143,7 +144,8 @@ class CompressInstEmitter {
143144 IndexedMap<OpData> &SourceOperandMap,
144145 IndexedMap<OpData> &DestOperandMap,
145146 StringMap<unsigned > &SourceOperands,
146- const CodeGenInstruction &DestInst);
147+ const CodeGenInstruction &DestInst,
148+ unsigned SourceLastTiedOp);
147149
148150public:
149151 CompressInstEmitter (const RecordKeeper &R) : Records(R), Target(R) {}
@@ -206,7 +208,8 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
206208 const DagInit *Dag,
207209 const CodeGenInstruction &Inst,
208210 IndexedMap<OpData> &OperandMap,
209- bool IsSourceInst) {
211+ bool IsSourceInst,
212+ unsigned *SourceLastTiedOpPtr) {
210213 unsigned NumMIOperands = 0 ;
211214 for (const auto &Op : Inst.Operands )
212215 NumMIOperands += Op.MINumOperands ;
@@ -219,12 +222,16 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
219222 // are represented.
220223 unsigned TiedCount = 0 ;
221224 unsigned OpNo = 0 ;
225+ if (IsSourceInst)
226+ *SourceLastTiedOpPtr = std::numeric_limits<unsigned int >::max ();
222227 for (const auto &Opnd : Inst.Operands ) {
223228 int TiedOpIdx = Opnd.getTiedRegister ();
224229 if (-1 != TiedOpIdx) {
225230 // Set the entry in OperandMap for the tied operand we're skipping.
226231 OperandMap[OpNo].Kind = OperandMap[TiedOpIdx].Kind ;
227232 OperandMap[OpNo].Data = OperandMap[TiedOpIdx].Data ;
233+ if (IsSourceInst)
234+ *SourceLastTiedOpPtr = OpNo;
228235 ++OpNo;
229236 ++TiedCount;
230237 continue ;
@@ -289,15 +296,23 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
289296static bool verifyDagOpCount (const CodeGenInstruction &Inst, const DagInit *Dag,
290297 bool IsSource) {
291298 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 ) {
293305 NumMIOperands += Op.MINumOperands ;
306+ if (Op.getTiedRegister () != -1 )
307+ SourceInstTiedOpCount++;
308+ }
294309
295310 if (Dag->getNumArgs () == NumMIOperands)
296311 return true ;
297312
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 ) )
301316 PrintFatalError (Inst.TheDef ->getLoc (),
302317 " Input operands for Inst '" + Inst.TheDef ->getName () +
303318 " ' and input Dag operand count mismatch" );
@@ -381,7 +396,8 @@ void CompressInstEmitter::createDagOperandMapping(
381396void CompressInstEmitter::createInstOperandMapping (
382397 const Record *Rec, const DagInit *SourceDag, const DagInit *DestDag,
383398 IndexedMap<OpData> &SourceOperandMap, IndexedMap<OpData> &DestOperandMap,
384- StringMap<unsigned > &SourceOperands, const CodeGenInstruction &DestInst) {
399+ StringMap<unsigned > &SourceOperands, const CodeGenInstruction &DestInst,
400+ unsigned SourceLastTiedOp) {
385401 // TiedCount keeps track of the number of operands skipped in Inst
386402 // operands list to get to the corresponding Dag operand.
387403 unsigned TiedCount = 0 ;
@@ -422,10 +438,18 @@ void CompressInstEmitter::createInstOperandMapping(
422438 assert (DestDag->getArgNameStr (DagArgIdx) ==
423439 SourceDag->getArgNameStr (SourceOp->getValue ()) &&
424440 " 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 " );
429453 }
430454 }
431455}
@@ -484,23 +508,25 @@ void CompressInstEmitter::evaluateCompressPat(const Record *Rec) {
484508 // Fill the mapping from the source to destination instructions.
485509
486510 IndexedMap<OpData> SourceOperandMap;
511+ unsigned SourceLastTiedOp; // postion of the last tied operand in Source Inst
487512 // Create a mapping between source Dag operands and source Inst operands.
488513 addDagOperandMapping (Rec, SourceDag, SourceInst, SourceOperandMap,
489- /* IsSourceInst*/ true );
514+ /* IsSourceInst*/ true , &SourceLastTiedOp );
490515
491516 IndexedMap<OpData> DestOperandMap;
492517 // Create a mapping between destination Dag operands and destination Inst
493518 // operands.
494519 addDagOperandMapping (Rec, DestDag, DestInst, DestOperandMap,
495- /* IsSourceInst*/ false );
520+ /* IsSourceInst*/ false , nullptr );
496521
497522 StringMap<unsigned > SourceOperands;
498523 StringMap<unsigned > DestOperands;
499524 createDagOperandMapping (Rec, SourceOperands, DestOperands, SourceDag, DestDag,
500525 SourceOperandMap);
501526 // Create operand mapping between the source and destination instructions.
502527 createInstOperandMapping (Rec, SourceDag, DestDag, SourceOperandMap,
503- DestOperandMap, SourceOperands, DestInst);
528+ DestOperandMap, SourceOperands, DestInst,
529+ SourceLastTiedOp);
504530
505531 // Get the target features for the CompressPat.
506532 std::vector<const Record *> PatReqFeatures;
0 commit comments