Skip to content

Commit 6d74b3a

Browse files
committed
[TableGen] Try to more generically handle tied source operands in CompressInstEmitter.
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 9a93de5 commit 6d74b3a

File tree

1 file changed

+69
-89
lines changed

1 file changed

+69
-89
lines changed

llvm/utils/TableGen/CompressInstEmitter.cpp

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

151148
public:
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(
394380
void 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

Comments
 (0)