@@ -98,6 +98,10 @@ class CompressInstEmitter {
9898 // Tied operand index within the instruction.
9999 int TiedOpIdx = -1 ;
100100 };
101+ struct ArgData {
102+ unsigned DAGOpNo;
103+ unsigned MIOpNo;
104+ };
101105 struct CompressPat {
102106 // The source instruction definition.
103107 CodeGenInstruction Source;
@@ -126,27 +130,23 @@ class CompressInstEmitter {
126130 std::vector<CompressPat> CompressPatterns;
127131 void addDagOperandMapping (const Record *Rec, const DagInit *Dag,
128132 const CodeGenInstruction &Inst,
129- IndexedMap<OpData> &OperandMap, bool IsSourceInst,
130- unsigned *SourceLastTiedOpPtr );
133+ IndexedMap<OpData> &OperandMap,
134+ StringMap<ArgData> &Operands, bool IsSourceInst );
131135 void evaluateCompressPat (const Record *Compress);
132136 void emitCompressInstEmitter (raw_ostream &OS, EmitterType EType);
133137 bool validateTypes (const Record *DagOpType, const Record *InstOpType,
134138 bool IsSourceInst);
135139 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);
142143
143144 void createInstOperandMapping (const Record *Rec, const DagInit *SourceDag,
144145 const DagInit *DestDag,
145146 IndexedMap<OpData> &SourceOperandMap,
146147 IndexedMap<OpData> &DestOperandMap,
147- StringMap<unsigned > &SourceOperands,
148- const CodeGenInstruction &DestInst,
149- unsigned SourceLastTiedOp);
148+ StringMap<ArgData> &SourceOperands,
149+ const CodeGenInstruction &DestInst);
150150
151151public:
152152 CompressInstEmitter (const RecordKeeper &R) : Records(R), Target(R) {}
@@ -198,6 +198,10 @@ bool CompressInstEmitter::validateTypes(const Record *DagOpType,
198198 return true ;
199199}
200200
201+ static bool validateArgsTypes (const Init *Arg1, const Init *Arg2) {
202+ return cast<DefInit>(Arg1)->getDef () == cast<DefInit>(Arg2)->getDef ();
203+ }
204+
201205// / The patterns in the Dag contain different types of operands:
202206// / Register operands, e.g.: GPRC:$rs1; Fixed registers, e.g: X1; Immediate
203207// / operands, e.g.: simm6:$imm; Fixed immediate operands, e.g.: 0. This function
@@ -209,8 +213,8 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
209213 const DagInit *Dag,
210214 const CodeGenInstruction &Inst,
211215 IndexedMap<OpData> &OperandMap,
212- bool IsSourceInst ,
213- unsigned *SourceLastTiedOpPtr ) {
216+ StringMap<ArgData> &Operands ,
217+ bool IsSourceInst ) {
214218 unsigned NumMIOperands = 0 ;
215219 if (!Inst.Operands .empty ())
216220 NumMIOperands =
@@ -224,16 +228,12 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
224228 // are represented.
225229 unsigned TiedCount = 0 ;
226230 unsigned OpNo = 0 ;
227- if (IsSourceInst)
228- *SourceLastTiedOpPtr = std::numeric_limits<unsigned int >::max ();
229231 for (const auto &Opnd : Inst.Operands ) {
230232 int TiedOpIdx = Opnd.getTiedRegister ();
231233 if (-1 != TiedOpIdx) {
232234 assert ((unsigned )TiedOpIdx < OpNo);
233235 // Set the entry in OperandMap for the tied operand we're skipping.
234236 OperandMap[OpNo] = OperandMap[TiedOpIdx];
235- if (IsSourceInst)
236- *SourceLastTiedOpPtr = OpNo;
237237 ++OpNo;
238238 ++TiedCount;
239239 continue ;
@@ -290,6 +290,30 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
290290 } else {
291291 llvm_unreachable (" Unhandled CompressPat argument type!" );
292292 }
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};
293317 }
294318 }
295319}
@@ -331,60 +355,29 @@ static bool verifyDagOpCount(const CodeGenInstruction &Inst, const DagInit *Dag,
331355 return true ;
332356}
333357
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) {
355362
356363 for (unsigned I = 0 ; I < SourceDag->getNumArgs (); ++I) {
357364 // Skip fixed immediates and registers, they were handled in
358365 // addDagOperandMapping.
359- if (" " == SourceDag->getArgNameStr (I))
366+ StringRef ArgName = SourceDag->getArgNameStr (I);
367+ if (ArgName.empty ())
360368 continue ;
361369
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);
377371 if (It == DestOperands.end ())
378- PrintFatalError (Rec->getLoc (), " Operand " + SourceDag-> getArgNameStr (I) +
372+ PrintFatalError (Rec->getLoc (), " Operand " + ArgName +
379373 " defined in Input Dag but not used in"
380- " Output Dag!\n " );
374+ " Output Dag!" );
381375 // 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 ),
383377 SourceDag->getArg (I)))
384378 PrintFatalError (Rec->getLoc (), " Type mismatch between Input and "
385379 " Output Dag operand '" +
386- SourceDag->getArgNameStr (I) + " '!" );
387- SourceOperands[SourceDag->getArgNameStr (I)] = I;
380+ ArgName + " '!" );
388381 }
389382}
390383
@@ -394,8 +387,7 @@ void CompressInstEmitter::createDagOperandMapping(
394387void CompressInstEmitter::createInstOperandMapping (
395388 const Record *Rec, const DagInit *SourceDag, const DagInit *DestDag,
396389 IndexedMap<OpData> &SourceOperandMap, IndexedMap<OpData> &DestOperandMap,
397- StringMap<unsigned > &SourceOperands, const CodeGenInstruction &DestInst,
398- unsigned SourceLastTiedOp) {
390+ StringMap<ArgData> &SourceOperands, const CodeGenInstruction &DestInst) {
399391 // TiedCount keeps track of the number of operands skipped in Inst
400392 // operands list to get to the corresponding Dag operand.
401393 unsigned TiedCount = 0 ;
@@ -425,29 +417,21 @@ void CompressInstEmitter::createInstOperandMapping(
425417 continue ;
426418
427419 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 );
430422 if (SourceOp == SourceOperands.end ())
431423 PrintFatalError (Rec->getLoc (),
432- " Output Dag operand '" +
433- DestDag->getArgNameStr (DagArgIdx) +
424+ " Output Dag operand '" + ArgName +
434425 " ' has no matching input Dag operand." );
435426
436- assert (DestDag-> getArgNameStr (DagArgIdx) ==
437- SourceDag->getArgNameStr (SourceOp->getValue ()) &&
427+ assert (ArgName ==
428+ SourceDag->getArgNameStr (SourceOp->getValue (). DAGOpNo ) &&
438429 " Incorrect operand mapping detected!\n " );
439430
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 " );
451435 }
452436 }
453437}
@@ -506,27 +490,24 @@ void CompressInstEmitter::evaluateCompressPat(const Record *Rec) {
506490 // Fill the mapping from the source to destination instructions.
507491
508492 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;
510495 // Create a mapping between source Dag operands and source Inst operands.
511496 addDagOperandMapping (Rec, SourceDag, SourceInst, SourceOperandMap,
512- /* IsSourceInst*/ true , &SourceLastTiedOp );
497+ SourceOperands, /* IsSourceInst*/ true );
513498
514499 IndexedMap<OpData> DestOperandMap;
500+ // Map from arg name to DAG operand number and MI operand number.
501+ StringMap<ArgData> DestOperands;
515502 // Create a mapping between destination Dag operands and destination Inst
516503 // 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);
526508 // Create operand mapping between the source and destination instructions.
527509 createInstOperandMapping (Rec, SourceDag, DestDag, SourceOperandMap,
528- DestOperandMap, SourceOperands, DestInst,
529- SourceLastTiedOp);
510+ DestOperandMap, SourceOperands, DestInst);
530511
531512 // Get the target features for the CompressPat.
532513 std::vector<const Record *> PatReqFeatures;
@@ -624,7 +605,7 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
624605 if (!AsmWriter->getValueAsInt (" PassSubtarget" ))
625606 PrintFatalError (AsmWriter->getLoc (),
626607 " 'PassSubtarget' is false. SubTargetInfo object is needed "
627- " for target features.\n " );
608+ " for target features." );
628609
629610 StringRef TargetName = Target.getName ();
630611
@@ -780,7 +761,7 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
780761 << " ).getReg() == MI.getOperand("
781762 << SourceOperandMap[OpNo].TiedOpIdx << " ).getReg()) &&\n " ;
782763 else
783- PrintFatalError (" Unexpected tied operand types!\n " );
764+ PrintFatalError (" Unexpected tied operand types!" );
784765 }
785766 for (unsigned SubOp = 0 ; SubOp != SourceOperand.MINumOperands ; ++SubOp) {
786767 // Check for fixed immediates\registers in the source instruction.
0 commit comments