summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-07-18 18:28:27 +0000
committerChris Lattner <sabre@nondot.org>2006-07-18 18:28:27 +0000
commit96c1ade5c3927cb0e835af721cbf37f9605cc678 (patch)
tree29d1a67b4fd9461ae5c8e279771802a33c4209b6 /utils
parentb84628679ad7240a63d267fc6388efbc1e91f588 (diff)
downloadllvm-96c1ade5c3927cb0e835af721cbf37f9605cc678.tar.gz
llvm-96c1ade5c3927cb0e835af721cbf37f9605cc678.tar.bz2
llvm-96c1ade5c3927cb0e835af721cbf37f9605cc678.tar.xz
Maximally group commands. When all instructions within a command set have a
series of identical commands, handle them all with one switch. In the case of the x86 at&t asm printer, only 3 switches are needed for all instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29184 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/AsmWriterEmitter.cpp80
-rw-r--r--utils/TableGen/AsmWriterEmitter.h3
2 files changed, 70 insertions, 13 deletions
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
index 016bac5c76..432dc6a291 100644
--- a/utils/TableGen/AsmWriterEmitter.cpp
+++ b/utils/TableGen/AsmWriterEmitter.cpp
@@ -330,15 +330,16 @@ static void EmitInstructions(std::vector<AsmWriterInst> &Insts,
void AsmWriterEmitter::
FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
- std::vector<unsigned> &InstIdxs) const {
- InstIdxs.clear();
- InstIdxs.resize(NumberedInstructions.size());
+ std::vector<unsigned> &InstIdxs,
+ std::vector<unsigned> &InstOpsUsed) const {
+ InstIdxs.assign(NumberedInstructions.size(), 0);
// This vector parallels UniqueOperandCommands, keeping track of which
// instructions each case are used for. It is a comma separated string of
// enums.
std::vector<std::string> InstrsForCase;
InstrsForCase.resize(UniqueOperandCommands.size());
+ InstOpsUsed.assign(UniqueOperandCommands.size(), 0);
for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
const AsmWriterInst *Inst = getAsmWriterInstByID(i);
@@ -369,6 +370,61 @@ FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
InstIdxs[i] = UniqueOperandCommands.size();
UniqueOperandCommands.push_back(Command);
InstrsForCase.push_back(Inst->CGI->TheDef->getName());
+
+ // This command matches one operand so far.
+ InstOpsUsed.push_back(1);
+ }
+ }
+
+ // 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();
+ CommandIdx != e; ++CommandIdx) {
+
+ for (unsigned Op = 1; ; ++Op) {
+ // Scan for the first instruction in the set.
+ std::vector<unsigned>::iterator NIT =
+ std::find(InstIdxs.begin(), InstIdxs.end(), CommandIdx);
+ if (NIT == InstIdxs.end()) break; // No commonality.
+
+ // If this instruction has no more operands, we isn't anything to merge
+ // into this command.
+ const AsmWriterInst *FirstInst =
+ getAsmWriterInstByID(NIT-InstIdxs.begin());
+ if (!FirstInst || 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;
+
+ NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx);
+ 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 =
+ getAsmWriterInstByID(NIT-InstIdxs.begin());
+ if (!OtherInst || 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
+ // to UniqueOperandCommands and remember that it was consumed.
+ std::string Command = " " + FirstInst->Operands[Op].getCode() + "\n";
+
+ // If this is the last operand, emit a return after the code.
+ if (FirstInst->Operands.size() == Op+1)
+ Command += " return true;\n";
+
+ UniqueOperandCommands[CommandIdx] += Command;
+ InstOpsUsed[CommandIdx]++;
}
}
@@ -475,13 +531,13 @@ void AsmWriterEmitter::run(std::ostream &O) {
}
std::vector<unsigned> InstIdxs;
- FindUniqueOperandCommands(UniqueOperandCommands, InstIdxs);
+ std::vector<unsigned> NumInstOpsHandled;
+ FindUniqueOperandCommands(UniqueOperandCommands, InstIdxs,
+ NumInstOpsHandled);
// If we ran out of operands to print, we're done.
if (UniqueOperandCommands.empty()) break;
- // FIXME: GROW THEM MAXIMALLY.
-
// Compute the number of bits we need to represent these cases, this is
// ceil(log2(numentries)).
unsigned NumBits = Log2_32_Ceil(UniqueOperandCommands.size());
@@ -501,8 +557,11 @@ void AsmWriterEmitter::run(std::ostream &O) {
// Remove the info about this operand.
for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
if (AsmWriterInst *Inst = getAsmWriterInstByID(i))
- if (!Inst->Operands.empty())
- Inst->Operands.erase(Inst->Operands.begin());
+ if (!Inst->Operands.empty()) {
+ unsigned NumOps = NumInstOpsHandled[InstIdxs[i]];
+ Inst->Operands.erase(Inst->Operands.begin(),
+ Inst->Operands.begin()+NumOps);
+ }
}
// Remember the handlers for this set of operands.
@@ -575,10 +634,7 @@ void AsmWriterEmitter::run(std::ostream &O) {
O << "\n // Fragment " << i << " encoded into " << NumBits
<< " bits for " << Commands.size() << " unique commands.\n";
- if (Commands.size() == 1) {
- // Only one possibility, just emit it.
- O << Commands[0];
- } else if (Commands.size() == 2) {
+ if (Commands.size() == 2) {
// Emit two possibilitys with if/else.
O << " if ((Bits >> " << (BitsLeft+AsmStrBits) << ") & "
<< ((1 << NumBits)-1) << ") {\n"
diff --git a/utils/TableGen/AsmWriterEmitter.h b/utils/TableGen/AsmWriterEmitter.h
index 5def47efdd..7932b1a693 100644
--- a/utils/TableGen/AsmWriterEmitter.h
+++ b/utils/TableGen/AsmWriterEmitter.h
@@ -43,7 +43,8 @@ private:
return I->second;
}
void FindUniqueOperandCommands(std::vector<std::string> &UOC,
- std::vector<unsigned> &InstIdxs) const;
+ std::vector<unsigned> &InstIdxs,
+ std::vector<unsigned> &InstOpsUsed) const;
};
}
#endif