Add support for writing bytecode files with compactiontables for bytecode files.
[oota-llvm.git] / lib / Bytecode / Writer / InstructionWriter.cpp
index faa576ecb46592e02501f403b8f66045eee41cd4..b93a812d52c4e9980189dc503c76932f3c7252bc 100644 (file)
 #include "llvm/Instructions.h"
 #include "Support/Statistic.h"
 #include <algorithm>
+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;
 
@@ -32,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
@@ -57,6 +78,7 @@ static void outputInstructionFormat0(const Instruction *I, unsigned Opcode,
   }
 
   align32(Out);    // We must maintain correct alignment!
+  BytesOversizedInstrs += Out.size();
 }
 
 
@@ -180,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();
 
@@ -194,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;
@@ -274,6 +295,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:
@@ -281,6 +306,9 @@ void BytecodeWriter::processInstruction(const Instruction &I) {
       outputInstructionFormat2(&I, Opcode, Table, Slots, Type, Out);
       return;
     }
+    if (Type >= (1 << 8)) 
+      NumOversidedBecauseOfTypes++;
+    NumOversized2OpInstrs++;
     break;
 
   case 3:
@@ -288,6 +316,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;
   }
 
@@ -295,3 +329,4 @@ void BytecodeWriter::processInstruction(const Instruction &I) {
   // operands or a large operand index that we are referring to.
   outputInstructionFormat0(&I, Opcode, Table, Type, Out);
 }
+