mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-19 01:27:40 +00:00
AsmWriterEmitter: increase the number of bits for OpcodeInfo from 32-bit to
48-bit if necessary, in order to reduce the generated code size. We have 900 cases not covered by OpcodeInfo in ATT AsmWriter and more in Intel AsmWriter and ARM AsmWriter. This patch reduced the clang Release build size by 50k, running on a Mac Pro. llvm-svn: 163814
This commit is contained in:
parent
a6138a9115
commit
4b62c95592
@ -313,7 +313,9 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
|
||||
/// OpcodeInfo - This encodes the index of the string to use for the first
|
||||
/// chunk of the output as well as indices used for operand printing.
|
||||
std::vector<unsigned> OpcodeInfo;
|
||||
/// To reduce the number of unhandled cases, we expand the size from 32-bit
|
||||
/// to 32+16 = 48-bit.
|
||||
std::vector<std::pair<unsigned, uint16_t> > OpcodeInfo;
|
||||
|
||||
// Add all strings to the string table upfront so it can generate an optimized
|
||||
// representation.
|
||||
@ -354,7 +356,7 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
}
|
||||
|
||||
// Bias offset by one since we want 0 as a sentinel.
|
||||
OpcodeInfo.push_back(Idx+1);
|
||||
OpcodeInfo.push_back(std::make_pair(Idx+1, 0));
|
||||
}
|
||||
|
||||
// Figure out how many bits we used for the string index.
|
||||
@ -362,7 +364,7 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
|
||||
// To reduce code size, we compactify common instructions into a few bits
|
||||
// in the opcode-indexed table.
|
||||
unsigned BitsLeft = 32-AsmStrBits;
|
||||
unsigned BitsLeft = 32+16-AsmStrBits;
|
||||
|
||||
std::vector<std::vector<std::string> > TableDrivenOperandPrinters;
|
||||
|
||||
@ -380,6 +382,13 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
// ceil(log2(numentries)).
|
||||
unsigned NumBits = Log2_32_Ceil(UniqueOperandCommands.size());
|
||||
|
||||
// Check whether these Bits will fit in the first 32 bits.
|
||||
if (BitsLeft > 16 && NumBits > BitsLeft - 16)
|
||||
// We don't have enough bits in the first 32 bits, and we skip the
|
||||
// left-over bits.
|
||||
BitsLeft = 16;
|
||||
bool UseSecond = (BitsLeft <= 16);
|
||||
|
||||
// If we don't have enough bits for this operand, don't include it.
|
||||
if (NumBits > BitsLeft) {
|
||||
DEBUG(errs() << "Not enough bits to densely encode " << NumBits
|
||||
@ -390,8 +399,13 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
// Otherwise, we can include this in the initial lookup table. Add it in.
|
||||
BitsLeft -= NumBits;
|
||||
for (unsigned i = 0, e = InstIdxs.size(); i != e; ++i)
|
||||
if (InstIdxs[i] != ~0U)
|
||||
OpcodeInfo[i] |= InstIdxs[i] << (BitsLeft+AsmStrBits);
|
||||
// Update the first 32 bits or the second 16 bits.
|
||||
if (InstIdxs[i] != ~0U) {
|
||||
if (UseSecond)
|
||||
OpcodeInfo[i].second |= InstIdxs[i] << BitsLeft;
|
||||
else
|
||||
OpcodeInfo[i].first |= InstIdxs[i] << (BitsLeft-16+AsmStrBits);
|
||||
}
|
||||
|
||||
// Remove the info about this operand.
|
||||
for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
|
||||
@ -413,13 +427,25 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
|
||||
O<<" static const unsigned OpInfo[] = {\n";
|
||||
for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
|
||||
O << " " << OpcodeInfo[i] << "U,\t// "
|
||||
O << " " << OpcodeInfo[i].first << "U,\t// "
|
||||
<< NumberedInstructions[i]->TheDef->getName() << "\n";
|
||||
}
|
||||
// Add a dummy entry so the array init doesn't end with a comma.
|
||||
O << " 0U\n";
|
||||
O << " };\n\n";
|
||||
|
||||
if (BitsLeft < 16) {
|
||||
// Add a second OpInfo table only when it is necessary.
|
||||
O<<" static const short OpInfo2[] = {\n";
|
||||
for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
|
||||
O << " " << OpcodeInfo[i].second << "U,\t// "
|
||||
<< NumberedInstructions[i]->TheDef->getName() << "\n";
|
||||
}
|
||||
// Add a dummy entry so the array init doesn't end with a comma.
|
||||
O << " 0U\n";
|
||||
O << " };\n\n";
|
||||
}
|
||||
|
||||
// Emit the string itself.
|
||||
O << " const char AsmStrs[] = {\n";
|
||||
StringTable.emit(O, printChar);
|
||||
@ -428,12 +454,14 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
O << " O << \"\\t\";\n\n";
|
||||
|
||||
O << " // Emit the opcode for the instruction.\n"
|
||||
<< " unsigned Bits = OpInfo[MI->getOpcode()];\n"
|
||||
<< " assert(Bits != 0 && \"Cannot print this instruction.\");\n"
|
||||
<< " unsigned Bits = OpInfo[MI->getOpcode()];\n";
|
||||
if (BitsLeft < 16)
|
||||
O << " unsigned short Bits2 = OpInfo2[MI->getOpcode()];\n";
|
||||
O << " assert(Bits != 0 && \"Cannot print this instruction.\");\n"
|
||||
<< " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n";
|
||||
|
||||
// Output the table driven operand information.
|
||||
BitsLeft = 32-AsmStrBits;
|
||||
BitsLeft = 32+16-AsmStrBits;
|
||||
for (unsigned i = 0, e = TableDrivenOperandPrinters.size(); i != e; ++i) {
|
||||
std::vector<std::string> &Commands = TableDrivenOperandPrinters[i];
|
||||
|
||||
@ -442,6 +470,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
unsigned NumBits = Log2_32_Ceil(Commands.size());
|
||||
assert(NumBits <= BitsLeft && "consistency error");
|
||||
|
||||
// Check whether these Bits will fit in the first 32 bits.
|
||||
if (BitsLeft > 16 && NumBits > BitsLeft - 16)
|
||||
BitsLeft = 16;
|
||||
bool UseSecond = (BitsLeft <= 16);
|
||||
|
||||
// Emit code to extract this field from Bits.
|
||||
BitsLeft -= NumBits;
|
||||
|
||||
@ -450,7 +483,8 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
|
||||
if (Commands.size() == 2) {
|
||||
// Emit two possibilitys with if/else.
|
||||
O << " if ((Bits >> " << (BitsLeft+AsmStrBits) << ") & "
|
||||
O << (UseSecond ? " if ((Bits2 >> " : " if ((Bits >> ")
|
||||
<< (UseSecond ? BitsLeft : (BitsLeft-16+AsmStrBits)) << ") & "
|
||||
<< ((1 << NumBits)-1) << ") {\n"
|
||||
<< Commands[1]
|
||||
<< " } else {\n"
|
||||
@ -460,7 +494,8 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
// Emit a single possibility.
|
||||
O << Commands[0] << "\n\n";
|
||||
} else {
|
||||
O << " switch ((Bits >> " << (BitsLeft+AsmStrBits) << ") & "
|
||||
O << (UseSecond ? " switch ((Bits2 >> " : " switch ((Bits >> ")
|
||||
<< (UseSecond ? BitsLeft : (BitsLeft-16+AsmStrBits)) << ") & "
|
||||
<< ((1 << NumBits)-1) << ") {\n"
|
||||
<< " default: // unreachable.\n";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user