@@ -126,27 +126,24 @@ class CompressInstEmitter {
126126 std::vector<CompressPat> CompressPatterns;
127127 void addDagOperandMapping (const Record *Rec, const DagInit *Dag,
128128 const CodeGenInstruction &Inst,
129- IndexedMap<OpData> &OperandMap, bool IsSourceInst,
130- unsigned *SourceLastTiedOpPtr);
129+ IndexedMap<OpData> &OperandMap,
130+ StringMap<std::pair<unsigned , unsigned >> &Operands,
131+ bool IsSourceInst);
131132 void evaluateCompressPat (const Record *Compress);
132133 void emitCompressInstEmitter (raw_ostream &OS, EmitterType EType);
133134 bool validateTypes (const Record *DagOpType, const Record *InstOpType,
134135 bool IsSourceInst);
135136 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);
142-
143- void createInstOperandMapping (const Record *Rec, const DagInit *SourceDag,
144- const DagInit *DestDag,
145- IndexedMap<OpData> &SourceOperandMap,
146- IndexedMap<OpData> &DestOperandMap,
147- StringMap<unsigned > &SourceOperands,
148- const CodeGenInstruction &DestInst,
149- unsigned SourceLastTiedOp);
137+ void checkDagOperandMapping (
138+ const Record *Rec,
139+ const StringMap<std::pair<unsigned , unsigned >> &DestOperands,
140+ const DagInit *SourceDag, const DagInit *DestDag);
141+
142+ void createInstOperandMapping (
143+ const Record *Rec, const DagInit *SourceDag, const DagInit *DestDag,
144+ IndexedMap<OpData> &SourceOperandMap, IndexedMap<OpData> &DestOperandMap,
145+ StringMap<std::pair<unsigned , unsigned >> &SourceOperands,
146+ const CodeGenInstruction &DestInst);
150147
151148public:
152149 CompressInstEmitter (const RecordKeeper &R) : Records(R), Target(R) {}
@@ -198,19 +195,21 @@ bool CompressInstEmitter::validateTypes(const Record *DagOpType,
198195 return true ;
199196}
200197
198+ static bool validateArgsTypes (const Init *Arg1, const Init *Arg2) {
199+ return cast<DefInit>(Arg1)->getDef () == cast<DefInit>(Arg2)->getDef ();
200+ }
201+
201202// / The patterns in the Dag contain different types of operands:
202203// / Register operands, e.g.: GPRC:$rs1; Fixed registers, e.g: X1; Immediate
203204// / operands, e.g.: simm6:$imm; Fixed immediate operands, e.g.: 0. This function
204205// / maps Dag operands to its corresponding instruction operands. For register
205206// / operands and fixed registers it expects the Dag operand type to be contained
206207// / in the instantiated instruction operand type. For immediate operands and
207208// / immediates no validation checks are enforced at pattern validation time.
208- void CompressInstEmitter::addDagOperandMapping (const Record *Rec,
209- const DagInit *Dag,
210- const CodeGenInstruction &Inst,
211- IndexedMap<OpData> &OperandMap,
212- bool IsSourceInst,
213- unsigned *SourceLastTiedOpPtr) {
209+ void CompressInstEmitter::addDagOperandMapping (
210+ const Record *Rec, const DagInit *Dag, const CodeGenInstruction &Inst,
211+ IndexedMap<OpData> &OperandMap,
212+ StringMap<std::pair<unsigned , unsigned >> &Operands, bool IsSourceInst) {
214213 unsigned NumMIOperands = 0 ;
215214 if (!Inst.Operands .empty ())
216215 NumMIOperands =
@@ -224,16 +223,12 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
224223 // are represented.
225224 unsigned TiedCount = 0 ;
226225 unsigned OpNo = 0 ;
227- if (IsSourceInst)
228- *SourceLastTiedOpPtr = std::numeric_limits<unsigned int >::max ();
229226 for (const auto &Opnd : Inst.Operands ) {
230227 int TiedOpIdx = Opnd.getTiedRegister ();
231228 if (-1 != TiedOpIdx) {
232229 assert ((unsigned )TiedOpIdx < OpNo);
233230 // Set the entry in OperandMap for the tied operand we're skipping.
234231 OperandMap[OpNo] = OperandMap[TiedOpIdx];
235- if (IsSourceInst)
236- *SourceLastTiedOpPtr = OpNo;
237232 ++OpNo;
238233 ++TiedCount;
239234 continue ;
@@ -290,6 +285,28 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
290285 } else {
291286 llvm_unreachable (" Unhandled CompressPat argument type!" );
292287 }
288+
289+ // Create a mapping between the operand name in the Dag (e.g. $rs1) and
290+ // its index in the list of Dag operands and check that operands with the
291+ // same name have the same type. For example in 'C_ADD $rs1, $rs2' we
292+ // generate the mapping $rs1 --> 0, $rs2 ---> 1. If the operand appears
293+ // twice in the (tied) same Dag we use the last occurrence for indexing.
294+ if (Dag->getArgNameStr (DAGOpNo).empty ())
295+ continue ;
296+
297+ if (IsSourceInst) {
298+ auto It = Operands.find (Dag->getArgNameStr (DAGOpNo));
299+ if (It != Operands.end ()) {
300+ OperandMap[OpNo].TiedOpIdx = It->getValue ().second ;
301+ if (!validateArgsTypes (Dag->getArg (It->getValue ().first ),
302+ Dag->getArg (DAGOpNo)))
303+ PrintFatalError (Rec->getLoc (),
304+ " Input Operand '" + Dag->getArgNameStr (DAGOpNo) +
305+ " ' has a mismatched tied operand!\n " );
306+ }
307+ }
308+
309+ Operands[Dag->getArgNameStr (DAGOpNo)] = {DAGOpNo, OpNo};
293310 }
294311 }
295312}
@@ -331,60 +348,29 @@ static bool verifyDagOpCount(const CodeGenInstruction &Inst, const DagInit *Dag,
331348 return true ;
332349}
333350
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- }
351+ // Check that all names in the source DAG appear in the destionation DAG.
352+ void CompressInstEmitter::checkDagOperandMapping (
353+ const Record *Rec,
354+ const StringMap<std::pair<unsigned , unsigned >> &DestOperands,
355+ const DagInit *SourceDag, const DagInit *DestDag) {
355356
356357 for (unsigned I = 0 ; I < SourceDag->getNumArgs (); ++I) {
357358 // Skip fixed immediates and registers, they were handled in
358359 // addDagOperandMapping.
359- if (" " == SourceDag->getArgNameStr (I))
360+ if (SourceDag->getArgNameStr (I). empty ( ))
360361 continue ;
361362
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));
363+ auto It = DestOperands.find (SourceDag->getArgNameStr (I));
377364 if (It == DestOperands.end ())
378365 PrintFatalError (Rec->getLoc (), " Operand " + SourceDag->getArgNameStr (I) +
379366 " defined in Input Dag but not used in"
380367 " Output Dag!\n " );
381368 // Input Dag operand types must match output Dag operand type.
382- if (!validateArgsTypes (DestDag->getArg (It->getValue ()),
369+ if (!validateArgsTypes (DestDag->getArg (It->getValue (). first ),
383370 SourceDag->getArg (I)))
384371 PrintFatalError (Rec->getLoc (), " Type mismatch between Input and "
385372 " Output Dag operand '" +
386373 SourceDag->getArgNameStr (I) + " '!" );
387- SourceOperands[SourceDag->getArgNameStr (I)] = I;
388374 }
389375}
390376
@@ -394,8 +380,8 @@ void CompressInstEmitter::createDagOperandMapping(
394380void CompressInstEmitter::createInstOperandMapping (
395381 const Record *Rec, const DagInit *SourceDag, const DagInit *DestDag,
396382 IndexedMap<OpData> &SourceOperandMap, IndexedMap<OpData> &DestOperandMap,
397- StringMap<unsigned > &SourceOperands, const CodeGenInstruction &DestInst ,
398- unsigned SourceLastTiedOp ) {
383+ StringMap<std::pair< unsigned , unsigned >> &SourceOperands ,
384+ const CodeGenInstruction &DestInst ) {
399385 // TiedCount keeps track of the number of operands skipped in Inst
400386 // operands list to get to the corresponding Dag operand.
401387 unsigned TiedCount = 0 ;
@@ -425,29 +411,26 @@ void CompressInstEmitter::createInstOperandMapping(
425411 continue ;
426412
427413 unsigned DagArgIdx = OpNo - TiedCount;
428- StringMap<unsigned >::iterator SourceOp =
429- SourceOperands.find (DestDag->getArgNameStr (DagArgIdx));
414+ auto SourceOp = SourceOperands.find (DestDag->getArgNameStr (DagArgIdx));
430415 if (SourceOp == SourceOperands.end ())
431416 PrintFatalError (Rec->getLoc (),
432417 " Output Dag operand '" +
433418 DestDag->getArgNameStr (DagArgIdx) +
434419 " ' has no matching input Dag operand." );
435420
436421 assert (DestDag->getArgNameStr (DagArgIdx) ==
437- SourceDag->getArgNameStr (SourceOp->getValue ()) &&
422+ SourceDag->getArgNameStr (SourceOp->getValue (). first ) &&
438423 " Incorrect operand mapping detected!\n " );
439424
440425 // Following four lines ensure the correct handling of a single tied
441426 // operand in the Source Inst. SourceDagOp points to the position of
442427 // appropriate Dag argument which is not correct in presence of tied
443428 // operand in the Source Inst and must be incremented by 1 to reflect
444429 // 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 " );
430+ unsigned SourceOpNo = SourceOp->getValue ().second ;
431+ DestOperandMap[OpNo].Data .Operand = SourceOpNo;
432+ SourceOperandMap[SourceOpNo].Data .Operand = OpNo;
433+ LLVM_DEBUG (dbgs () << " " << SourceOpNo << " ====> " << OpNo << " \n " );
451434 }
452435 }
453436}
@@ -506,27 +489,24 @@ void CompressInstEmitter::evaluateCompressPat(const Record *Rec) {
506489 // Fill the mapping from the source to destination instructions.
507490
508491 IndexedMap<OpData> SourceOperandMap;
509- unsigned SourceLastTiedOp; // postion of the last tied operand in Source Inst
492+ // Map from arg name to DAG operand number and MI operand number.
493+ StringMap<std::pair<unsigned , unsigned >> SourceOperands;
510494 // Create a mapping between source Dag operands and source Inst operands.
511495 addDagOperandMapping (Rec, SourceDag, SourceInst, SourceOperandMap,
512- /* IsSourceInst*/ true , &SourceLastTiedOp );
496+ SourceOperands, /* IsSourceInst*/ true );
513497
514498 IndexedMap<OpData> DestOperandMap;
499+ // Map from arg name to DAG operand number and MI operand number.
500+ StringMap<std::pair<unsigned , unsigned >> DestOperands;
515501 // Create a mapping between destination Dag operands and destination Inst
516502 // 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);
503+ addDagOperandMapping (Rec, DestDag, DestInst, DestOperandMap, DestOperands,
504+ /* IsSourceInst*/ false );
505+
506+ checkDagOperandMapping (Rec, DestOperands, SourceDag, DestDag);
526507 // Create operand mapping between the source and destination instructions.
527508 createInstOperandMapping (Rec, SourceDag, DestDag, SourceOperandMap,
528- DestOperandMap, SourceOperands, DestInst,
529- SourceLastTiedOp);
509+ DestOperandMap, SourceOperands, DestInst);
530510
531511 // Get the target features for the CompressPat.
532512 std::vector<const Record *> PatReqFeatures;
0 commit comments