Skip to content

Commit 6ff3b43

Browse files
authored
[TableGen] More generically handle tied source operands in CompressInstEmitter. (#146183)
Move the creation of OperandMap from createDagOperandMapping to the loop in addDagOperandMapping. Expand it to store the DAG operand number and the MI operand number which will be different when there are tied operands. Rename createDagOperandMapping to checkDagOperandMapping to better describe the remaining code. I didn't lift the restriction that a source instruction can only have one tied operand, but we should be able to if we have a use case. There's a slight difference in the generate output. We now check that operand 0 and 2 of QC_MVEQI are equal instead of operand 1 and 2. This should be equivalent since operand 0 and 1 have a tied constraint.
1 parent 8eb61d9 commit 6ff3b43

File tree

1 file changed

+74
-93
lines changed

1 file changed

+74
-93
lines changed

llvm/utils/TableGen/CompressInstEmitter.cpp

Lines changed: 74 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -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

151151
public:
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(
394387
void 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

Comments
 (0)