Skip to content

Commit 3d9309f

Browse files
author
git apple-llvm automerger
committed
Merge commit '6ff3b4370017' from llvm.org/main into next
2 parents db2d107 + 6ff3b43 commit 3d9309f

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)