aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Bytecode
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-01-14 16:54:21 +0000
committerChris Lattner <sabre@nondot.org>2004-01-14 16:54:21 +0000
commitd6942d76334604f9bbd4118e6b109ecd6ea1326e (patch)
tree0ea8c15cc363dfa032012785aee898f5dffe9833 /lib/Bytecode
parentc08912f917ff3a007bfc0cfa3fa670c2441279e2 (diff)
downloadexternal_llvm-d6942d76334604f9bbd4118e6b109ecd6ea1326e.zip
external_llvm-d6942d76334604f9bbd4118e6b109ecd6ea1326e.tar.gz
external_llvm-d6942d76334604f9bbd4118e6b109ecd6ea1326e.tar.bz2
Ok, I can't handle it. This is a temporary checkin of a ton of statistics that
i'm using in my work to reduce the bytecode file sizes. These will eventually be removed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10849 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Bytecode')
-rw-r--r--lib/Bytecode/Writer/ConstantWriter.cpp25
-rw-r--r--lib/Bytecode/Writer/InstructionWriter.cpp34
-rw-r--r--lib/Bytecode/Writer/Writer.cpp50
3 files changed, 100 insertions, 9 deletions
diff --git a/lib/Bytecode/Writer/ConstantWriter.cpp b/lib/Bytecode/Writer/ConstantWriter.cpp
index 30d93c9..12043b0 100644
--- a/lib/Bytecode/Writer/ConstantWriter.cpp
+++ b/lib/Bytecode/Writer/ConstantWriter.cpp
@@ -16,15 +16,26 @@
#include "llvm/Constants.h"
#include "llvm/SymbolTable.h"
#include "llvm/DerivedTypes.h"
+#include "Support/Statistic.h"
using namespace llvm;
+static Statistic<>
+TypeBytes("bytecodewriter", "Bytes of types");
+static Statistic<>
+ConstantBytes("bytecodewriter", "Bytes of constants");
+static Statistic<>
+NumConstants("bytecodewriter", "Number of constants");
+
void BytecodeWriter::outputType(const Type *T) {
+ TypeBytes -= Out.size();
output_vbr((unsigned)T->getPrimitiveID(), Out);
// That's all there is to handling primitive types...
- if (T->isPrimitiveType())
+ if (T->isPrimitiveType()) {
+ TypeBytes += Out.size();
return; // We might do this if we alias a prim type: %x = type int
-
+ }
+
switch (T->getPrimitiveID()) { // Handle derived types now.
case Type::FunctionTyID: {
const FunctionType *MT = cast<FunctionType>(T);
@@ -95,12 +106,16 @@ void BytecodeWriter::outputType(const Type *T) {
<< " Type '" << T->getDescription() << "'\n";
break;
}
+ TypeBytes += Out.size();
}
bool BytecodeWriter::outputConstant(const Constant *CPV) {
+ ConstantBytes -= Out.size();
assert((CPV->getType()->isPrimitiveType() || !CPV->isNullValue()) &&
"Shouldn't output null constants!");
+ ++NumConstants;
+
// We must check for a ConstantExpr before switching by type because
// a ConstantExpr can be of any type, and has no explicit value.
//
@@ -117,9 +132,10 @@ bool BytecodeWriter::outputConstant(const Constant *CPV) {
Slot = Table.getSlot((*OI)->getType());
output_vbr((unsigned)Slot, Out);
}
+ ConstantBytes += Out.size();
return false;
} else {
- output_vbr((unsigned)0, Out); // flag as not a ConstantExpr
+ output_vbr(0U, Out); // flag as not a ConstantExpr
}
switch (CPV->getType()->getPrimitiveID()) {
@@ -169,7 +185,7 @@ bool BytecodeWriter::outputConstant(const Constant *CPV) {
int Slot = Table.getSlot(Vals[i]);
assert(Slot != -1 && "Constant used but not available!!");
output_vbr((unsigned)Slot, Out);
- }
+ }
break;
}
@@ -199,5 +215,6 @@ bool BytecodeWriter::outputConstant(const Constant *CPV) {
<< " type '" << CPV->getType()->getName() << "'\n";
break;
}
+ ConstantBytes += Out.size();
return false;
}
diff --git a/lib/Bytecode/Writer/InstructionWriter.cpp b/lib/Bytecode/Writer/InstructionWriter.cpp
index bc5268c..0bf555d 100644
--- a/lib/Bytecode/Writer/InstructionWriter.cpp
+++ b/lib/Bytecode/Writer/InstructionWriter.cpp
@@ -22,6 +22,23 @@ using namespace llvm;
static Statistic<>
NumInstrs("bytecodewriter", "Number of instructions");
+static Statistic<>
+NumOversizedInstrs("bytecodewriter", "Number of oversized instructions");
+static Statistic<>
+BytesOversizedInstrs("bytecodewriter", "Bytes of oversized instructions");
+
+static Statistic<>
+NumHugeOperandInstrs("bytecodewriter", "Number of instructions with > 3 operands");
+static Statistic<>
+NumOversized1OpInstrs("bytecodewriter", "Number of oversized 1 operand instrs");
+static Statistic<>
+NumOversized2OpInstrs("bytecodewriter", "Number of oversized 2 operand instrs");
+static Statistic<>
+NumOversized3OpInstrs("bytecodewriter", "Number of oversized 3 operand instrs");
+
+static Statistic<>
+NumOversidedBecauseOfTypes("bytecodewriter", "Number of oversized instructions because of their type");
+
typedef unsigned char uchar;
@@ -33,6 +50,9 @@ typedef unsigned char uchar;
static void outputInstructionFormat0(const Instruction *I, unsigned Opcode,
const SlotCalculator &Table,
unsigned Type, std::deque<uchar> &Out) {
+ NumOversizedInstrs++;
+ BytesOversizedInstrs -= Out.size();
+
// Opcode must have top two bits clear...
output_vbr(Opcode << 2, Out); // Instruction Opcode ID
output_vbr(Type, Out); // Result type
@@ -58,6 +78,7 @@ static void outputInstructionFormat0(const Instruction *I, unsigned Opcode,
}
align32(Out); // We must maintain correct alignment!
+ BytesOversizedInstrs += Out.size();
}
@@ -275,6 +296,10 @@ void BytecodeWriter::processInstruction(const Instruction &I) {
outputInstructionFormat1(&I, Opcode, Table, Slots, Type, Out);
return;
}
+ if (Type >= (1 << 12)-1)
+ NumOversidedBecauseOfTypes++;
+
+ NumOversized1OpInstrs++;
break;
case 2:
@@ -282,6 +307,9 @@ void BytecodeWriter::processInstruction(const Instruction &I) {
outputInstructionFormat2(&I, Opcode, Table, Slots, Type, Out);
return;
}
+ if (Type >= (1 << 8))
+ NumOversidedBecauseOfTypes++;
+ NumOversized2OpInstrs++;
break;
case 3:
@@ -289,6 +317,12 @@ void BytecodeWriter::processInstruction(const Instruction &I) {
outputInstructionFormat3(&I, Opcode, Table, Slots, Type, Out);
return;
}
+ if (Type >= (1 << 6))
+ NumOversidedBecauseOfTypes++;
+ NumOversized3OpInstrs++;
+ break;
+ default:
+ ++NumHugeOperandInstrs;
break;
}
diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp
index 100d34e..ca50b5a 100644
--- a/lib/Bytecode/Writer/Writer.cpp
+++ b/lib/Bytecode/Writer/Writer.cpp
@@ -29,6 +29,7 @@
#include "llvm/DerivedTypes.h"
#include "Support/STLExtras.h"
#include "Support/Statistic.h"
+#include "Support/Debug.h"
#include <cstring>
#include <algorithm>
using namespace llvm;
@@ -37,7 +38,18 @@ static RegisterPass<WriteBytecodePass> X("emitbytecode", "Bytecode Writer");
static Statistic<>
BytesWritten("bytecodewriter", "Number of bytecode bytes written");
-
+static Statistic<>
+ConstantTotalBytes("bytecodewriter", "Bytes of constants total");
+static Statistic<>
+FunctionConstantTotalBytes("bytecodewriter", "Bytes of function constants total");
+static Statistic<>
+ConstantPlaneHeaderBytes("bytecodewriter", "Constant plane header bytes");
+static Statistic<>
+InstructionBytes("bytecodewriter", "Bytes of bytes of instructions");
+static Statistic<>
+SymTabBytes("bytecodewriter", "Bytes of symbol table");
+static Statistic<>
+ModuleInfoBytes("bytecodewriter", "Bytes of module info");
BytecodeWriter::BytecodeWriter(std::deque<unsigned char> &o, const Module *M)
: Out(o), Table(M, true) {
@@ -52,8 +64,9 @@ BytecodeWriter::BytecodeWriter(std::deque<unsigned char> &o, const Module *M)
bool hasNoEndianness = M->getEndianness() == Module::AnyEndianness;
bool hasNoPointerSize = M->getPointerSize() == Module::AnyPointerSize;
- // Output the version identifier... we are currently on bytecode version #0
- unsigned Version = (0 << 4) | isBigEndian | (hasLongPointers << 1) |
+ // Output the version identifier... we are currently on bytecode version #1,
+ // which corresponds to LLVM v1.2.
+ unsigned Version = (1 << 4) | isBigEndian | (hasLongPointers << 1) |
(hasNoEndianness << 2) | (hasNoPointerSize << 3);
output_vbr(Version, Out);
align32(Out);
@@ -71,6 +84,12 @@ BytecodeWriter::BytecodeWriter(std::deque<unsigned char> &o, const Module *M)
outputConstantsInPlane(Plane, ValNo); // Write out the types
}
+ DEBUG(for (unsigned i = 0; i != Type::TypeTyID; ++i)
+ if (Table.getPlane(i).size())
+ std::cerr << " ModuleLevel["
+ << *Type::getPrimitiveType((Type::PrimitiveID)i)
+ << "] = " << Table.getPlane(i).size() << "\n");
+
// The ModuleInfoBlock follows directly after the type information
outputModuleInfoBlock(M);
@@ -104,6 +123,11 @@ void BytecodeWriter::outputConstantsInPlane(const std::vector<const Value*>
NC -= ValNo; // Convert from index into count
if (NC == 0) return; // Skip empty type planes...
+ // FIXME: Most slabs only have 1 or 2 entries! We should encode this much
+ // more compactly.
+
+ ConstantPlaneHeaderBytes -= Out.size();
+
// Output type header: [num entries][type id number]
//
output_vbr(NC, Out);
@@ -113,6 +137,9 @@ void BytecodeWriter::outputConstantsInPlane(const std::vector<const Value*>
assert (Slot != -1 && "Type in constant pool but not in function!!");
output_vbr((unsigned)Slot, Out);
+ ConstantPlaneHeaderBytes += Out.size();
+
+
//cerr << "Emitting " << NC << " constants of type '"
// << Plane.front()->getType()->getName() << "' = Slot #" << Slot << "\n";
@@ -129,6 +156,8 @@ void BytecodeWriter::outputConstantsInPlane(const std::vector<const Value*>
}
void BytecodeWriter::outputConstants(bool isFunction) {
+ ConstantTotalBytes -= Out.size();
+ if (isFunction) FunctionConstantTotalBytes -= Out.size();
BytecodeBlock CPool(BytecodeFormat::ConstantPool, Out);
unsigned NumPlanes = Table.getNumPlanes();
@@ -160,6 +189,8 @@ void BytecodeWriter::outputConstants(bool isFunction) {
outputConstantsInPlane(Plane, ValNo);
}
}
+ ConstantTotalBytes += Out.size();
+ if (isFunction) FunctionConstantTotalBytes += Out.size();
}
static unsigned getEncodedLinkage(const GlobalValue *GV) {
@@ -174,6 +205,8 @@ static unsigned getEncodedLinkage(const GlobalValue *GV) {
}
void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
+ ModuleInfoBytes -= Out.size();
+
BytecodeBlock ModuleInfoBlock(BytecodeFormat::ModuleGlobalInfo, Out);
// Output the types for the global variables in the module...
@@ -206,6 +239,8 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
output_vbr((unsigned)Table.getSlot(Type::VoidTy), Out);
align32(Out);
+
+ ModuleInfoBytes += Out.size();
}
void BytecodeWriter::outputFunction(const Function *F) {
@@ -222,10 +257,11 @@ void BytecodeWriter::outputFunction(const Function *F) {
{ // Output all of the instructions in the body of the function
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)
processInstruction(*I);
+ InstructionBytes += Out.size();
}
// If needed, output the symbol table for the function...
@@ -240,7 +276,9 @@ void BytecodeWriter::outputSymbolTable(const SymbolTable &MST) {
// space!
if (MST.begin() == MST.end()) return;
- BytecodeBlock FunctionBlock(BytecodeFormat::SymbolTable, Out);
+ SymTabBytes -= Out.size();
+
+ BytecodeBlock SymTabBlock(BytecodeFormat::SymbolTable, Out);
for (SymbolTable::const_iterator TI = MST.begin(); TI != MST.end(); ++TI) {
SymbolTable::type_const_iterator I = MST.type_begin(TI->first);
@@ -264,6 +302,8 @@ void BytecodeWriter::outputSymbolTable(const SymbolTable &MST) {
output(I->first, Out, false); // Don't force alignment...
}
}
+
+ SymTabBytes += Out.size();
}
void llvm::WriteBytecodeToFile(const Module *C, std::ostream &Out) {