Add support for writing bytecode files with compactiontables for bytecode files.
authorChris Lattner <sabre@nondot.org>
Sun, 18 Jan 2004 21:08:52 +0000 (21:08 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 18 Jan 2004 21:08:52 +0000 (21:08 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10915 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Bytecode/Writer/ConstantWriter.cpp
lib/Bytecode/Writer/InstructionWriter.cpp
lib/Bytecode/Writer/Writer.cpp
lib/Bytecode/Writer/WriterInternals.h

index 088a5b787bc11cf844a08ab9f685802b9aa6d8a2..2b75b9b4a7955dc9cf28417a089263b97fcb2e30 100644 (file)
@@ -26,11 +26,6 @@ ConstantBytes("bytecodewriter", "Bytes of constants");
 static Statistic<> 
 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) {
   TypeBytes -= Out.size();
@@ -231,7 +226,6 @@ void BytecodeWriter::outputConstantStrings() {
   output_vbr(Type::VoidTyID, Out);
     
   ConstantBytes -= Out.size();
-  NumStrBytes -= Out.size();;
   
   // Emit all of the strings.
   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);
 
     ++NumConstants;
-    ++NumStrConstants;
   }
   ConstantBytes += Out.size();
-  NumStrBytes += Out.size();;
 }
index 0bf555d8b55494824b2ddf79f7f8164ca83fbeb9..b93a812d52c4e9980189dc503c76932f3c7252bc 100644 (file)
@@ -202,7 +202,7 @@ static void outputInstructionFormat3(const Instruction *I, unsigned Opcode,
   output(Bits, Out);
 }
 
-void BytecodeWriter::processInstruction(const Instruction &I) {
+void BytecodeWriter::outputInstruction(const Instruction &I) {
   assert(I.getOpcode() < 62 && "Opcode too big???");
   unsigned Opcode = I.getOpcode();
 
@@ -216,9 +216,8 @@ void BytecodeWriter::processInstruction(const Instruction &I) {
   int MaxOpSlot = 0;
   int Slots[3]; Slots[0] = (1 << 12)-1;   // Marker to signify 0 operands
 
-  for (unsigned i = 0; i < NumOperands; ++i) {
-    const Value *Def = I.getOperand(i);
-    int slot = Table.getSlot(Def);
+  for (unsigned i = 0; i != NumOperands; ++i) {
+    int slot = Table.getSlot(I.getOperand(i));
     assert(slot != -1 && "Broken bytecode!");
     if (slot > MaxOpSlot) MaxOpSlot = slot;
     if (i < 3) Slots[i] = slot;
index ff9e8a989b161f3477c725981d3a0e79a9dc219e..2fcc863c3c6efb3d3197b649bb17ba9bb8e1a980 100644 (file)
@@ -41,8 +41,6 @@ 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<> 
@@ -51,6 +49,8 @@ static Statistic<>
 SymTabBytes("bytecodewriter", "Bytes of symbol table");
 static Statistic<> 
 ModuleInfoBytes("bytecodewriter", "Bytes of module info");
+static Statistic<> 
+CompactionTableBytes("bytecodewriter", "Bytes of compaction tables");
 
 BytecodeWriter::BytecodeWriter(std::deque<unsigned char> &o, const Module *M) 
   : Out(o), Table(M, true) {
@@ -168,7 +168,6 @@ static inline bool hasNullValue(unsigned TyID) {
 
 void BytecodeWriter::outputConstants(bool isFunction) {
   ConstantTotalBytes -= Out.size();
-  if (isFunction) FunctionConstantTotalBytes -= Out.size();
   BytecodeBlock CPool(BytecodeFormat::ConstantPool, Out,
                       true  /* Elide block if empty */);
 
@@ -206,7 +205,6 @@ void BytecodeWriter::outputConstants(bool isFunction) {
       }
     }
   ConstantTotalBytes += Out.size();
-  if (isFunction) FunctionConstantTotalBytes += Out.size();
 }
 
 static unsigned getEncodedLinkage(const GlobalValue *GV) {
@@ -257,32 +255,75 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
   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) {
   BytecodeBlock FunctionBlock(BytecodeFormat::Function, 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...
-    Table.incorporateFunction(F);
+  // If this is an external function, there is nothing else to emit!
+  if (F->isExternal()) return;
 
-    // Output information about the constants in the function...
-    outputConstants(true);
+  // Get slot information about the function...
+  Table.incorporateFunction(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...
-    outputSymbolTable(F->getSymbolTable());
-    
-    Table.purgeFunction();
+  if (Table.getCompactionTable().empty()) {
+    // Output information about the constants in the function if the compaction
+    // table is not being used.
+    outputConstants(true);
+  } else {
+    // Otherwise, emit the compaction table.
+    outputCompactionTable();
   }
+  
+  // 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) {
index 15dbeffc8698ccdf9b35fb69884ab159e5ad8283..1e47f5ef99eab08aaeecee15ced6c1c13310cd01 100644 (file)
@@ -37,7 +37,12 @@ private:
   void outputConstants(bool isFunction);
   void outputConstantStrings();
   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 outputSymbolTable(const SymbolTable &ST);