mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-14 15:38:57 +00:00
Add support for writing bytecode files with compactiontables for bytecode files.
This shrinks the bytecode file for 176.gcc by about 200K (10%), and 254.gap by about 167K, a 25% reduction. There is still a lot of room for improvement in the encoding of the compaction table. llvm-svn: 10915
This commit is contained in:
parent
5fc855775d
commit
2258355dda
@ -26,11 +26,6 @@ ConstantBytes("bytecodewriter", "Bytes of constants");
|
|||||||
static Statistic<>
|
static Statistic<>
|
||||||
NumConstants("bytecodewriter", "Number of constants");
|
NumConstants("bytecodewriter", "Number of constants");
|
||||||
|
|
||||||
static Statistic<>
|
|
||||||
NumStrConstants("bytecodewriter", "Number of string constants");
|
|
||||||
static Statistic<>
|
|
||||||
NumStrBytes("bytecodewriter", "Number of string constant bytes");
|
|
||||||
|
|
||||||
|
|
||||||
void BytecodeWriter::outputType(const Type *T) {
|
void BytecodeWriter::outputType(const Type *T) {
|
||||||
TypeBytes -= Out.size();
|
TypeBytes -= Out.size();
|
||||||
@ -231,7 +226,6 @@ void BytecodeWriter::outputConstantStrings() {
|
|||||||
output_vbr(Type::VoidTyID, Out);
|
output_vbr(Type::VoidTyID, Out);
|
||||||
|
|
||||||
ConstantBytes -= Out.size();
|
ConstantBytes -= Out.size();
|
||||||
NumStrBytes -= Out.size();;
|
|
||||||
|
|
||||||
// Emit all of the strings.
|
// Emit all of the strings.
|
||||||
for (I = Table.string_begin(); I != E; ++I) {
|
for (I = Table.string_begin(); I != E; ++I) {
|
||||||
@ -246,8 +240,6 @@ void BytecodeWriter::outputConstantStrings() {
|
|||||||
output_data(Val.c_str(), Val.c_str()+Val.size(), Out);
|
output_data(Val.c_str(), Val.c_str()+Val.size(), Out);
|
||||||
|
|
||||||
++NumConstants;
|
++NumConstants;
|
||||||
++NumStrConstants;
|
|
||||||
}
|
}
|
||||||
ConstantBytes += Out.size();
|
ConstantBytes += Out.size();
|
||||||
NumStrBytes += Out.size();;
|
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ static void outputInstructionFormat3(const Instruction *I, unsigned Opcode,
|
|||||||
output(Bits, Out);
|
output(Bits, Out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeWriter::processInstruction(const Instruction &I) {
|
void BytecodeWriter::outputInstruction(const Instruction &I) {
|
||||||
assert(I.getOpcode() < 62 && "Opcode too big???");
|
assert(I.getOpcode() < 62 && "Opcode too big???");
|
||||||
unsigned Opcode = I.getOpcode();
|
unsigned Opcode = I.getOpcode();
|
||||||
|
|
||||||
@ -216,9 +216,8 @@ void BytecodeWriter::processInstruction(const Instruction &I) {
|
|||||||
int MaxOpSlot = 0;
|
int MaxOpSlot = 0;
|
||||||
int Slots[3]; Slots[0] = (1 << 12)-1; // Marker to signify 0 operands
|
int Slots[3]; Slots[0] = (1 << 12)-1; // Marker to signify 0 operands
|
||||||
|
|
||||||
for (unsigned i = 0; i < NumOperands; ++i) {
|
for (unsigned i = 0; i != NumOperands; ++i) {
|
||||||
const Value *Def = I.getOperand(i);
|
int slot = Table.getSlot(I.getOperand(i));
|
||||||
int slot = Table.getSlot(Def);
|
|
||||||
assert(slot != -1 && "Broken bytecode!");
|
assert(slot != -1 && "Broken bytecode!");
|
||||||
if (slot > MaxOpSlot) MaxOpSlot = slot;
|
if (slot > MaxOpSlot) MaxOpSlot = slot;
|
||||||
if (i < 3) Slots[i] = slot;
|
if (i < 3) Slots[i] = slot;
|
||||||
|
@ -41,8 +41,6 @@ static Statistic<>
|
|||||||
BytesWritten("bytecodewriter", "Number of bytecode bytes written");
|
BytesWritten("bytecodewriter", "Number of bytecode bytes written");
|
||||||
static Statistic<>
|
static Statistic<>
|
||||||
ConstantTotalBytes("bytecodewriter", "Bytes of constants total");
|
ConstantTotalBytes("bytecodewriter", "Bytes of constants total");
|
||||||
static Statistic<>
|
|
||||||
FunctionConstantTotalBytes("bytecodewriter", "Bytes of function constants total");
|
|
||||||
static Statistic<>
|
static Statistic<>
|
||||||
ConstantPlaneHeaderBytes("bytecodewriter", "Constant plane header bytes");
|
ConstantPlaneHeaderBytes("bytecodewriter", "Constant plane header bytes");
|
||||||
static Statistic<>
|
static Statistic<>
|
||||||
@ -51,6 +49,8 @@ static Statistic<>
|
|||||||
SymTabBytes("bytecodewriter", "Bytes of symbol table");
|
SymTabBytes("bytecodewriter", "Bytes of symbol table");
|
||||||
static Statistic<>
|
static Statistic<>
|
||||||
ModuleInfoBytes("bytecodewriter", "Bytes of module info");
|
ModuleInfoBytes("bytecodewriter", "Bytes of module info");
|
||||||
|
static Statistic<>
|
||||||
|
CompactionTableBytes("bytecodewriter", "Bytes of compaction tables");
|
||||||
|
|
||||||
BytecodeWriter::BytecodeWriter(std::deque<unsigned char> &o, const Module *M)
|
BytecodeWriter::BytecodeWriter(std::deque<unsigned char> &o, const Module *M)
|
||||||
: Out(o), Table(M, true) {
|
: Out(o), Table(M, true) {
|
||||||
@ -168,7 +168,6 @@ static inline bool hasNullValue(unsigned TyID) {
|
|||||||
|
|
||||||
void BytecodeWriter::outputConstants(bool isFunction) {
|
void BytecodeWriter::outputConstants(bool isFunction) {
|
||||||
ConstantTotalBytes -= Out.size();
|
ConstantTotalBytes -= Out.size();
|
||||||
if (isFunction) FunctionConstantTotalBytes -= Out.size();
|
|
||||||
BytecodeBlock CPool(BytecodeFormat::ConstantPool, Out,
|
BytecodeBlock CPool(BytecodeFormat::ConstantPool, Out,
|
||||||
true /* Elide block if empty */);
|
true /* Elide block if empty */);
|
||||||
|
|
||||||
@ -206,7 +205,6 @@ void BytecodeWriter::outputConstants(bool isFunction) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ConstantTotalBytes += Out.size();
|
ConstantTotalBytes += Out.size();
|
||||||
if (isFunction) FunctionConstantTotalBytes += Out.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned getEncodedLinkage(const GlobalValue *GV) {
|
static unsigned getEncodedLinkage(const GlobalValue *GV) {
|
||||||
@ -257,32 +255,75 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
|
|||||||
ModuleInfoBytes += Out.size();
|
ModuleInfoBytes += Out.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BytecodeWriter::outputInstructions(const Function *F) {
|
||||||
|
BytecodeBlock ILBlock(BytecodeFormat::InstructionList, Out);
|
||||||
|
InstructionBytes -= Out.size();
|
||||||
|
for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
|
||||||
|
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I)
|
||||||
|
outputInstruction(*I);
|
||||||
|
InstructionBytes += Out.size();
|
||||||
|
}
|
||||||
|
|
||||||
void BytecodeWriter::outputFunction(const Function *F) {
|
void BytecodeWriter::outputFunction(const Function *F) {
|
||||||
BytecodeBlock FunctionBlock(BytecodeFormat::Function, Out);
|
BytecodeBlock FunctionBlock(BytecodeFormat::Function, Out);
|
||||||
output_vbr(getEncodedLinkage(F), Out);
|
output_vbr(getEncodedLinkage(F), Out);
|
||||||
// Only output the constant pool and other goodies if needed...
|
|
||||||
if (!F->isExternal()) {
|
|
||||||
|
|
||||||
// Get slot information about the function...
|
// If this is an external function, there is nothing else to emit!
|
||||||
Table.incorporateFunction(F);
|
if (F->isExternal()) return;
|
||||||
|
|
||||||
// Output information about the constants in the function...
|
// Get slot information about the function...
|
||||||
|
Table.incorporateFunction(F);
|
||||||
|
|
||||||
|
if (Table.getCompactionTable().empty()) {
|
||||||
|
// Output information about the constants in the function if the compaction
|
||||||
|
// table is not being used.
|
||||||
outputConstants(true);
|
outputConstants(true);
|
||||||
|
} else {
|
||||||
{ // Output all of the instructions in the body of the function
|
// Otherwise, emit the compaction table.
|
||||||
BytecodeBlock ILBlock(BytecodeFormat::InstructionList, Out);
|
outputCompactionTable();
|
||||||
InstructionBytes -= Out.size();
|
|
||||||
for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E;++BB)
|
|
||||||
for(BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;++I)
|
|
||||||
processInstruction(*I);
|
|
||||||
InstructionBytes += Out.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If needed, output the symbol table for the function...
|
|
||||||
outputSymbolTable(F->getSymbolTable());
|
|
||||||
|
|
||||||
Table.purgeFunction();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Output all of the instructions in the body of the function
|
||||||
|
outputInstructions(F);
|
||||||
|
|
||||||
|
// If needed, output the symbol table for the function...
|
||||||
|
outputSymbolTable(F->getSymbolTable());
|
||||||
|
|
||||||
|
Table.purgeFunction();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BytecodeWriter::outputCompactionTablePlane(unsigned PlaneNo,
|
||||||
|
const std::vector<const Value*> &Plane,
|
||||||
|
unsigned StartNo) {
|
||||||
|
unsigned End = Table.getModuleLevel(PlaneNo);
|
||||||
|
if (StartNo == End || End == 0) return; // Nothing to emit
|
||||||
|
assert(StartNo < End && "Cannot emit negative range!");
|
||||||
|
assert(StartNo < Plane.size() && End <= Plane.size());
|
||||||
|
|
||||||
|
output_vbr(unsigned(End-StartNo), Out); // Output the number of things.
|
||||||
|
output_vbr(PlaneNo, Out); // Emit the type plane this is
|
||||||
|
|
||||||
|
// Do not emit the null initializer!
|
||||||
|
if (PlaneNo != Type::TypeTyID) ++StartNo;
|
||||||
|
|
||||||
|
for (unsigned i = StartNo; i != End; ++i)
|
||||||
|
output_vbr(Table.getGlobalSlot(Plane[i]), Out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BytecodeWriter::outputCompactionTable() {
|
||||||
|
CompactionTableBytes -= Out.size();
|
||||||
|
BytecodeBlock CTB(BytecodeFormat::CompactionTable, Out, true/*ElideIfEmpty*/);
|
||||||
|
const std::vector<std::vector<const Value*> > &CT =Table.getCompactionTable();
|
||||||
|
|
||||||
|
// First thing is first, emit the type compaction table if there is one.
|
||||||
|
if (CT.size() > Type::TypeTyID)
|
||||||
|
outputCompactionTablePlane(Type::TypeTyID, CT[Type::TypeTyID],
|
||||||
|
Type::FirstDerivedTyID);
|
||||||
|
|
||||||
|
for (unsigned i = 0, e = CT.size(); i != e; ++i)
|
||||||
|
if (i != Type::TypeTyID)
|
||||||
|
outputCompactionTablePlane(i, CT[i], 0);
|
||||||
|
CompactionTableBytes += Out.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeWriter::outputSymbolTable(const SymbolTable &MST) {
|
void BytecodeWriter::outputSymbolTable(const SymbolTable &MST) {
|
||||||
|
@ -37,7 +37,12 @@ private:
|
|||||||
void outputConstants(bool isFunction);
|
void outputConstants(bool isFunction);
|
||||||
void outputConstantStrings();
|
void outputConstantStrings();
|
||||||
void outputFunction(const Function *F);
|
void outputFunction(const Function *F);
|
||||||
void processInstruction(const Instruction &I);
|
void outputCompactionTable();
|
||||||
|
void outputCompactionTablePlane(unsigned PlaneNo,
|
||||||
|
const std::vector<const Value*> &TypePlane,
|
||||||
|
unsigned StartNo);
|
||||||
|
void outputInstructions(const Function *F);
|
||||||
|
void outputInstruction(const Instruction &I);
|
||||||
|
|
||||||
void outputModuleInfoBlock(const Module *C);
|
void outputModuleInfoBlock(const Module *C);
|
||||||
void outputSymbolTable(const SymbolTable &ST);
|
void outputSymbolTable(const SymbolTable &ST);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user