1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[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:
Craig Topper 2016-01-24 07:13:28 +00:00
parent 5ab451ac92
commit eb67a46511

View File

@ -49,7 +49,7 @@ private:
void EmitPrintAliasInstruction(raw_ostream &O); void EmitPrintAliasInstruction(raw_ostream &O);
void FindUniqueOperandCommands(std::vector<std::string> &UOC, void FindUniqueOperandCommands(std::vector<std::string> &UOC,
std::vector<unsigned> &InstIdxs, std::vector<std::vector<unsigned>> &InstIdxs,
std::vector<unsigned> &InstOpsUsed, std::vector<unsigned> &InstOpsUsed,
bool PassSubtarget) const; bool PassSubtarget) const;
}; };
@ -136,10 +136,9 @@ static void EmitInstructions(std::vector<AsmWriterInst> &Insts,
void AsmWriterEmitter:: void AsmWriterEmitter::
FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands, FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
std::vector<unsigned> &InstIdxs, std::vector<std::vector<unsigned>> &InstIdxs,
std::vector<unsigned> &InstOpsUsed, std::vector<unsigned> &InstOpsUsed,
bool PassSubtarget) const { bool PassSubtarget) const {
InstIdxs.assign(Instructions.size(), ~0U);
// This vector parallels UniqueOperandCommands, keeping track of which // This vector parallels UniqueOperandCommands, keeping track of which
// instructions each case are used for. It is a comma separated string of // 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); UniqueOperandCommands.end(), Command);
if (I != UniqueOperandCommands.end()) { if (I != UniqueOperandCommands.end()) {
size_t idx = I - UniqueOperandCommands.begin(); size_t idx = I - UniqueOperandCommands.begin();
InstIdxs[i] = idx;
InstrsForCase[idx] += ", "; InstrsForCase[idx] += ", ";
InstrsForCase[idx] += Inst.CGI->TheDef->getName(); InstrsForCase[idx] += Inst.CGI->TheDef->getName();
InstIdxs[idx].push_back(i);
} else { } else {
InstIdxs[i] = UniqueOperandCommands.size();
UniqueOperandCommands.push_back(std::move(Command)); UniqueOperandCommands.push_back(std::move(Command));
InstrsForCase.push_back(Inst.CGI->TheDef->getName()); InstrsForCase.push_back(Inst.CGI->TheDef->getName());
InstIdxs.emplace_back();
InstIdxs.back().push_back(i);
// This command matches one operand so far. // This command matches one operand so far.
InstOpsUsed.push_back(1); 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 // 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 // that uses it. If the next command of all instructions in the set are
// identical, fold it into the command. // identical, fold it into the command.
for (unsigned CommandIdx = 0, e = UniqueOperandCommands.size(); for (size_t CommandIdx = 0, e = UniqueOperandCommands.size();
CommandIdx != e; ++CommandIdx) { CommandIdx != e; ++CommandIdx) {
for (unsigned Op = 1; ; ++Op) { const auto &Idxs = InstIdxs[CommandIdx];
// Scan for the first instruction in the set.
auto NIT = std::find(InstIdxs.begin(), InstIdxs.end(), CommandIdx);
if (NIT == InstIdxs.end()) break; // No commonality.
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 // If this instruction has no more operands, we isn't anything to merge
// into this command. // into this command.
const AsmWriterInst &FirstInst = Instructions[NIT-InstIdxs.begin()];
if (FirstInst.Operands.size() == Op) if (FirstInst.Operands.size() == Op)
break; break;
// Otherwise, scan to see if all of the other instructions in this command // Otherwise, scan to see if all of the other instructions in this command
// set share the operand. // set share the operand.
bool AllSame = true; if (std::any_of(Idxs.begin()+1, Idxs.end(),
[&](unsigned Idx) {
for (NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx); const AsmWriterInst &OtherInst = Instructions[Idx];
NIT != InstIdxs.end(); return OtherInst.Operands.size() == Op ||
NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx)) { OtherInst.Operands[Op] != FirstInst.Operands[Op];
// Okay, found another instruction in this command set. If the operand }))
// matches, we're ok, otherwise bail out. break;
const AsmWriterInst &OtherInst = Instructions[NIT-InstIdxs.begin()];
if (OtherInst.Operands.size() == Op ||
OtherInst.Operands[Op] != FirstInst.Operands[Op]) {
AllSame = false;
break;
}
}
if (!AllSame) break;
// Okay, everything in this command set has the same next operand. Add it // Okay, everything in this command set has the same next operand. Add it
// to UniqueOperandCommands and remember that it was consumed. // to UniqueOperandCommands and remember that it was consumed.
@ -328,7 +318,7 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
while (1) { while (1) {
std::vector<std::string> UniqueOperandCommands; std::vector<std::string> UniqueOperandCommands;
std::vector<unsigned> InstIdxs; std::vector<std::vector<unsigned>> InstIdxs;
std::vector<unsigned> NumInstOpsHandled; std::vector<unsigned> NumInstOpsHandled;
FindUniqueOperandCommands(UniqueOperandCommands, InstIdxs, FindUniqueOperandCommands(UniqueOperandCommands, InstIdxs,
NumInstOpsHandled, PassSubtarget); 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. // Otherwise, we can include this in the initial lookup table. Add it in.
for (size_t i = 0, e = Instructions.size(); i != e; ++i) for (size_t i = 0, e = InstIdxs.size(); i != e; ++i) {
if (InstIdxs[i] != ~0U) unsigned NumOps = NumInstOpsHandled[i];
OpcodeInfo[Instructions[i].CGIIndex] |= for (unsigned Idx : InstIdxs[i]) {
(uint64_t)InstIdxs[i] << (OpcodeInfoBits-BitsLeft); OpcodeInfo[Instructions[Idx].CGIIndex] |=
BitsLeft -= NumBits; (uint64_t)i << (OpcodeInfoBits-BitsLeft);
// Remove the info about this operand from the instruction.
// Remove the info about this operand. AsmWriterInst &Inst = Instructions[Idx];
for (size_t i = 0, e = Instructions.size(); i != e; ++i) { if (!Inst.Operands.empty()) {
AsmWriterInst &Inst = Instructions[i]; assert(NumOps <= Inst.Operands.size() &&
if (!Inst.Operands.empty()) { "Can't remove this many ops!");
unsigned NumOps = NumInstOpsHandled[InstIdxs[i]]; Inst.Operands.erase(Inst.Operands.begin(),
assert(NumOps <= Inst.Operands.size() && Inst.Operands.begin()+NumOps);
"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. // Remember the handlers for this set of operands.
TableDrivenOperandPrinters.push_back(std::move(UniqueOperandCommands)); TableDrivenOperandPrinters.push_back(std::move(UniqueOperandCommands));