forked from OSchip/llvm-project
[TableGen] In AsmWriterEmitter unique command search, rather than storing a mapping from instruction to unique command, instead store a list of which instructions each unique command corresponds to.
This simplifies the complexity of the code that tries to find further operands to merge into the unique command. llvm-svn: 258656
This commit is contained in:
parent
dcd6c79d55
commit
5dd7a2cc24
|
@ -49,7 +49,7 @@ private:
|
|||
void EmitPrintAliasInstruction(raw_ostream &O);
|
||||
|
||||
void FindUniqueOperandCommands(std::vector<std::string> &UOC,
|
||||
std::vector<unsigned> &InstIdxs,
|
||||
std::vector<std::vector<unsigned>> &InstIdxs,
|
||||
std::vector<unsigned> &InstOpsUsed,
|
||||
bool PassSubtarget) const;
|
||||
};
|
||||
|
@ -136,10 +136,9 @@ static void EmitInstructions(std::vector<AsmWriterInst> &Insts,
|
|||
|
||||
void AsmWriterEmitter::
|
||||
FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
|
||||
std::vector<unsigned> &InstIdxs,
|
||||
std::vector<std::vector<unsigned>> &InstIdxs,
|
||||
std::vector<unsigned> &InstOpsUsed,
|
||||
bool PassSubtarget) const {
|
||||
InstIdxs.assign(Instructions.size(), ~0U);
|
||||
|
||||
// This vector parallels UniqueOperandCommands, keeping track of which
|
||||
// instructions each case are used for. It is a comma separated string of
|
||||
|
@ -161,13 +160,14 @@ FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
|
|||
UniqueOperandCommands.end(), Command);
|
||||
if (I != UniqueOperandCommands.end()) {
|
||||
size_t idx = I - UniqueOperandCommands.begin();
|
||||
InstIdxs[i] = idx;
|
||||
InstrsForCase[idx] += ", ";
|
||||
InstrsForCase[idx] += Inst.CGI->TheDef->getName();
|
||||
InstIdxs[idx].push_back(i);
|
||||
} else {
|
||||
InstIdxs[i] = UniqueOperandCommands.size();
|
||||
UniqueOperandCommands.push_back(std::move(Command));
|
||||
InstrsForCase.push_back(Inst.CGI->TheDef->getName());
|
||||
InstIdxs.emplace_back();
|
||||
InstIdxs.back().push_back(i);
|
||||
|
||||
// This command matches one operand so far.
|
||||
InstOpsUsed.push_back(1);
|
||||
|
@ -177,38 +177,28 @@ FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
|
|||
// For each entry of UniqueOperandCommands, there is a set of instructions
|
||||
// that uses it. If the next command of all instructions in the set are
|
||||
// identical, fold it into the command.
|
||||
for (unsigned CommandIdx = 0, e = UniqueOperandCommands.size();
|
||||
for (size_t CommandIdx = 0, e = UniqueOperandCommands.size();
|
||||
CommandIdx != e; ++CommandIdx) {
|
||||
|
||||
for (unsigned Op = 1; ; ++Op) {
|
||||
// Scan for the first instruction in the set.
|
||||
auto NIT = std::find(InstIdxs.begin(), InstIdxs.end(), CommandIdx);
|
||||
if (NIT == InstIdxs.end()) break; // No commonality.
|
||||
const auto &Idxs = InstIdxs[CommandIdx];
|
||||
|
||||
for (unsigned Op = 1; ; ++Op) {
|
||||
// Find the first instruction in the set.
|
||||
const AsmWriterInst &FirstInst = Instructions[Idxs.front()];
|
||||
// If this instruction has no more operands, we isn't anything to merge
|
||||
// into this command.
|
||||
const AsmWriterInst &FirstInst = Instructions[NIT-InstIdxs.begin()];
|
||||
if (FirstInst.Operands.size() == Op)
|
||||
break;
|
||||
|
||||
// Otherwise, scan to see if all of the other instructions in this command
|
||||
// set share the operand.
|
||||
bool AllSame = true;
|
||||
|
||||
for (NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx);
|
||||
NIT != InstIdxs.end();
|
||||
NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx)) {
|
||||
// Okay, found another instruction in this command set. If the operand
|
||||
// matches, we're ok, otherwise bail out.
|
||||
const AsmWriterInst &OtherInst = Instructions[NIT-InstIdxs.begin()];
|
||||
|
||||
if (OtherInst.Operands.size() == Op ||
|
||||
OtherInst.Operands[Op] != FirstInst.Operands[Op]) {
|
||||
AllSame = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!AllSame) break;
|
||||
if (std::any_of(Idxs.begin()+1, Idxs.end(),
|
||||
[&](unsigned Idx) {
|
||||
const AsmWriterInst &OtherInst = Instructions[Idx];
|
||||
return OtherInst.Operands.size() == Op ||
|
||||
OtherInst.Operands[Op] != FirstInst.Operands[Op];
|
||||
}))
|
||||
break;
|
||||
|
||||
// Okay, everything in this command set has the same next operand. Add it
|
||||
// to UniqueOperandCommands and remember that it was consumed.
|
||||
|
@ -328,7 +318,7 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
|||
|
||||
while (1) {
|
||||
std::vector<std::string> UniqueOperandCommands;
|
||||
std::vector<unsigned> InstIdxs;
|
||||
std::vector<std::vector<unsigned>> InstIdxs;
|
||||
std::vector<unsigned> NumInstOpsHandled;
|
||||
FindUniqueOperandCommands(UniqueOperandCommands, InstIdxs,
|
||||
NumInstOpsHandled, PassSubtarget);
|
||||
|
@ -348,23 +338,22 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
|||
}
|
||||
|
||||
// Otherwise, we can include this in the initial lookup table. Add it in.
|
||||
for (size_t i = 0, e = Instructions.size(); i != e; ++i)
|
||||
if (InstIdxs[i] != ~0U)
|
||||
OpcodeInfo[Instructions[i].CGIIndex] |=
|
||||
(uint64_t)InstIdxs[i] << (OpcodeInfoBits-BitsLeft);
|
||||
BitsLeft -= NumBits;
|
||||
|
||||
// Remove the info about this operand.
|
||||
for (size_t i = 0, e = Instructions.size(); i != e; ++i) {
|
||||
AsmWriterInst &Inst = Instructions[i];
|
||||
if (!Inst.Operands.empty()) {
|
||||
unsigned NumOps = NumInstOpsHandled[InstIdxs[i]];
|
||||
assert(NumOps <= Inst.Operands.size() &&
|
||||
"Can't remove this many ops!");
|
||||
Inst.Operands.erase(Inst.Operands.begin(),
|
||||
Inst.Operands.begin()+NumOps);
|
||||
for (size_t i = 0, e = InstIdxs.size(); i != e; ++i) {
|
||||
unsigned NumOps = NumInstOpsHandled[i];
|
||||
for (unsigned Idx : InstIdxs[i]) {
|
||||
OpcodeInfo[Instructions[Idx].CGIIndex] |=
|
||||
(uint64_t)i << (OpcodeInfoBits-BitsLeft);
|
||||
// Remove the info about this operand from the instruction.
|
||||
AsmWriterInst &Inst = Instructions[Idx];
|
||||
if (!Inst.Operands.empty()) {
|
||||
assert(NumOps <= Inst.Operands.size() &&
|
||||
"Can't remove this many ops!");
|
||||
Inst.Operands.erase(Inst.Operands.begin(),
|
||||
Inst.Operands.begin()+NumOps);
|
||||
}
|
||||
}
|
||||
}
|
||||
BitsLeft -= NumBits;
|
||||
|
||||
// Remember the handlers for this set of operands.
|
||||
TableDrivenOperandPrinters.push_back(std::move(UniqueOperandCommands));
|
||||
|
|
Loading…
Reference in New Issue