//===-- Writer.cpp - Library for writing LLVM bytecode files --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This library implements the functionality defined in llvm/Bytecode/Writer.h
//
// Note that this file uses an unusual technique of outputting all the bytecode
// to a vector of unsigned char, then copies the vector to an ostream.  The
// reason for this is that we must do "seeking" in the stream to do back-
// patching, and some very important ostreams that we want to support (like
// pipes) do not support seeking.  :( :( :(
//
//===----------------------------------------------------------------------===//

#include "WriterInternals.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/SymbolTable.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/Compressor.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
#include <cstring>
#include <algorithm>
using namespace llvm;

/// This value needs to be incremented every time the bytecode format changes
/// so that the reader can distinguish which format of the bytecode file has
/// been written.
/// @brief The bytecode version number
const unsigned BCVersionNum = 5;

static RegisterPass<WriteBytecodePass> X("emitbytecode", "Bytecode Writer");

static Statistic<>
BytesWritten("bytecodewriter", "Number of bytecode bytes written");

//===----------------------------------------------------------------------===//
//===                           Output Primitives                          ===//
//===----------------------------------------------------------------------===//

// output - If a position is specified, it must be in the valid portion of the
// string... note that this should be inlined always so only the relevant IF
// body should be included.
inline void BytecodeWriter::output(unsigned i, int pos) {
  if (pos == -1) { // Be endian clean, little endian is our friend
    Out.push_back((unsigned char)i);
    Out.push_back((unsigned char)(i >> 8));
    Out.push_back((unsigned char)(i >> 16));
    Out.push_back((unsigned char)(i >> 24));
  } else {
    Out[pos  ] = (unsigned char)i;
    Out[pos+1] = (unsigned char)(i >> 8);
    Out[pos+2] = (unsigned char)(i >> 16);
    Out[pos+3] = (unsigned char)(i >> 24);
  }
}

inline void BytecodeWriter::output(int i) {
  output((unsigned)i);
}

/// output_vbr - Output an unsigned value, by using the least number of bytes
/// possible.  This is useful because many of our "infinite" values are really
/// very small most of the time; but can be large a few times.
/// Data format used:  If you read a byte with the high bit set, use the low
/// seven bits as data and then read another byte.
inline void BytecodeWriter::output_vbr(uint64_t i) {
  while (1) {
    if (i < 0x80) { // done?
      Out.push_back((unsigned char)i);   // We know the high bit is clear...
      return;
    }

    // Nope, we are bigger than a character, output the next 7 bits and set the
    // high bit to say that there is more coming...
    Out.push_back(0x80 | ((unsigned char)i & 0x7F));
    i >>= 7;  // Shift out 7 bits now...
  }
}

inline void BytecodeWriter::output_vbr(unsigned i) {
  while (1) {
    if (i < 0x80) { // done?
      Out.push_back((unsigned char)i);   // We know the high bit is clear...
      return;
    }

    // Nope, we are bigger than a character, output the next 7 bits and set the
    // high bit to say that there is more coming...
    Out.push_back(0x80 | ((unsigned char)i & 0x7F));
    i >>= 7;  // Shift out 7 bits now...
  }
}

inline void BytecodeWriter::output_typeid(unsigned i) {
  if (i <= 0x00FFFFFF)
    this->output_vbr(i);
  else {
    this->output_vbr(0x00FFFFFF);
    this->output_vbr(i);
  }
}

inline void BytecodeWriter::output_vbr(int64_t i) {
  if (i < 0)
    output_vbr(((uint64_t)(-i) << 1) | 1); // Set low order sign bit...
  else
    output_vbr((uint64_t)i << 1);          // Low order bit is clear.
}


inline void BytecodeWriter::output_vbr(int i) {
  if (i < 0)
    output_vbr(((unsigned)(-i) << 1) | 1); // Set low order sign bit...
  else
    output_vbr((unsigned)i << 1);          // Low order bit is clear.
}

inline void BytecodeWriter::output(const std::string &s) {
  unsigned Len = s.length();
  output_vbr(Len );             // Strings may have an arbitrary length...
  Out.insert(Out.end(), s.begin(), s.end());
}

inline void BytecodeWriter::output_data(const void *Ptr, const void *End) {
  Out.insert(Out.end(), (const unsigned char*)Ptr, (const unsigned char*)End);
}

inline void BytecodeWriter::output_float(float& FloatVal) {
  /// FIXME: This isn't optimal, it has size problems on some platforms
  /// where FP is not IEEE.
  union {
    float f;
    uint32_t i;
  } FloatUnion;
  FloatUnion.f = FloatVal;
  Out.push_back( static_cast<unsigned char>( (FloatUnion.i & 0xFF )));
  Out.push_back( static_cast<unsigned char>( (FloatUnion.i >> 8) & 0xFF));
  Out.push_back( static_cast<unsigned char>( (FloatUnion.i >> 16) & 0xFF));
  Out.push_back( static_cast<unsigned char>( (FloatUnion.i >> 24) & 0xFF));
}

inline void BytecodeWriter::output_double(double& DoubleVal) {
  /// FIXME: This isn't optimal, it has size problems on some platforms
  /// where FP is not IEEE.
  union {
    double d;
    uint64_t i;
  } DoubleUnion;
  DoubleUnion.d = DoubleVal;
  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i & 0xFF )));
  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i >> 8) & 0xFF));
  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i >> 16) & 0xFF));
  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i >> 24) & 0xFF));
  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i >> 32) & 0xFF));
  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i >> 40) & 0xFF));
  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i >> 48) & 0xFF));
  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i >> 56) & 0xFF));
}

inline BytecodeBlock::BytecodeBlock(unsigned ID, BytecodeWriter& w,
                                    bool elideIfEmpty, bool hasLongFormat )
  : Id(ID), Writer(w), ElideIfEmpty(elideIfEmpty), HasLongFormat(hasLongFormat){

  if (HasLongFormat) {
    w.output(ID);
    w.output(0U); // For length in long format
  } else {
    w.output(0U); /// Place holder for ID and length for this block
  }
  Loc = w.size();
}

inline BytecodeBlock::~BytecodeBlock() { // Do backpatch when block goes out
                                         // of scope...
  if (Loc == Writer.size() && ElideIfEmpty) {
    // If the block is empty, and we are allowed to, do not emit the block at
    // all!
    Writer.resize(Writer.size()-(HasLongFormat?8:4));
    return;
  }

  if (HasLongFormat)
    Writer.output(unsigned(Writer.size()-Loc), int(Loc-4));
  else
    Writer.output(unsigned(Writer.size()-Loc) << 5 | (Id & 0x1F), int(Loc-4));
}

//===----------------------------------------------------------------------===//
//===                           Constant Output                            ===//
//===----------------------------------------------------------------------===//

void BytecodeWriter::outputType(const Type *T) {
  output_vbr((unsigned)T->getTypeID());

  // That's all there is to handling primitive types...
  if (T->isPrimitiveType()) {
    return;     // We might do this if we alias a prim type: %x = type int
  }

  switch (T->getTypeID()) {   // Handle derived types now.
  case Type::FunctionTyID: {
    const FunctionType *MT = cast<FunctionType>(T);
    int Slot = Table.getSlot(MT->getReturnType());
    assert(Slot != -1 && "Type used but not available!!");
    output_typeid((unsigned)Slot);

    // Output the number of arguments to function (+1 if varargs):
    output_vbr((unsigned)MT->getNumParams()+MT->isVarArg());

    // Output all of the arguments...
    FunctionType::param_iterator I = MT->param_begin();
    for (; I != MT->param_end(); ++I) {
      Slot = Table.getSlot(*I);
      assert(Slot != -1 && "Type used but not available!!");
      output_typeid((unsigned)Slot);
    }

    // Terminate list with VoidTy if we are a varargs function...
    if (MT->isVarArg())
      output_typeid((unsigned)Type::VoidTyID);
    break;
  }

  case Type::ArrayTyID: {
    const ArrayType *AT = cast<ArrayType>(T);
    int Slot = Table.getSlot(AT->getElementType());
    assert(Slot != -1 && "Type used but not available!!");
    output_typeid((unsigned)Slot);
    output_vbr(AT->getNumElements());
    break;
  }

 case Type::PackedTyID: {
    const PackedType *PT = cast<PackedType>(T);
    int Slot = Table.getSlot(PT->getElementType());
    assert(Slot != -1 && "Type used but not available!!");
    output_typeid((unsigned)Slot);
    output_vbr(PT->getNumElements());
    break;
  }


  case Type::StructTyID: {
    const StructType *ST = cast<StructType>(T);

    // Output all of the element types...
    for (StructType::element_iterator I = ST->element_begin(),
           E = ST->element_end(); I != E; ++I) {
      int Slot = Table.getSlot(*I);
      assert(Slot != -1 && "Type used but not available!!");
      output_typeid((unsigned)Slot);
    }

    // Terminate list with VoidTy
    output_typeid((unsigned)Type::VoidTyID);
    break;
  }

  case Type::PointerTyID: {
    const PointerType *PT = cast<PointerType>(T);
    int Slot = Table.getSlot(PT->getElementType());
    assert(Slot != -1 && "Type used but not available!!");
    output_typeid((unsigned)Slot);
    break;
  }

  case Type::OpaqueTyID:
    // No need to emit anything, just the count of opaque types is enough.
    break;

  default:
    std::cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to serialize"
              << " Type '" << T->getDescription() << "'\n";
    break;
  }
}

void BytecodeWriter::outputConstant(const Constant *CPV) {
  assert((CPV->getType()->isPrimitiveType() || !CPV->isNullValue()) &&
         "Shouldn't output null constants!");

  // We must check for a ConstantExpr before switching by type because
  // a ConstantExpr can be of any type, and has no explicit value.
  //
  if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
    // FIXME: Encoding of constant exprs could be much more compact!
    assert(CE->getNumOperands() > 0 && "ConstantExpr with 0 operands");
    assert(CE->getNumOperands() != 1 || CE->getOpcode() == Instruction::Cast);
    output_vbr(1+CE->getNumOperands());   // flags as an expr
    output_vbr(CE->getOpcode());        // flags as an expr

    for (User::const_op_iterator OI = CE->op_begin(); OI != CE->op_end(); ++OI){
      int Slot = Table.getSlot(*OI);
      assert(Slot != -1 && "Unknown constant used in ConstantExpr!!");
      output_vbr((unsigned)Slot);
      Slot = Table.getSlot((*OI)->getType());
      output_typeid((unsigned)Slot);
    }
    return;
  } else if (isa<UndefValue>(CPV)) {
    output_vbr(1U);       // 1 -> UndefValue constant.
    return;
  } else {
    output_vbr(0U);       // flag as not a ConstantExpr
  }

  switch (CPV->getType()->getTypeID()) {
  case Type::BoolTyID:    // Boolean Types
    if (cast<ConstantBool>(CPV)->getValue())
      output_vbr(1U);
    else
      output_vbr(0U);
    break;

  case Type::UByteTyID:   // Unsigned integer types...
  case Type::UShortTyID:
  case Type::UIntTyID:
  case Type::ULongTyID:
    output_vbr(cast<ConstantUInt>(CPV)->getValue());
    break;

  case Type::SByteTyID:   // Signed integer types...
  case Type::ShortTyID:
  case Type::IntTyID:
  case Type::LongTyID:
    output_vbr(cast<ConstantSInt>(CPV)->getValue());
    break;

  case Type::ArrayTyID: {
    const ConstantArray *CPA = cast<ConstantArray>(CPV);
    assert(!CPA->isString() && "Constant strings should be handled specially!");

    for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i) {
      int Slot = Table.getSlot(CPA->getOperand(i));
      assert(Slot != -1 && "Constant used but not available!!");
      output_vbr((unsigned)Slot);
    }
    break;
  }

  case Type::PackedTyID: {
    const ConstantPacked *CP = cast<ConstantPacked>(CPV);

    for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) {
      int Slot = Table.getSlot(CP->getOperand(i));
      assert(Slot != -1 && "Constant used but not available!!");
      output_vbr((unsigned)Slot);
    }
    break;
  }

  case Type::StructTyID: {
    const ConstantStruct *CPS = cast<ConstantStruct>(CPV);

    for (unsigned i = 0, e = CPS->getNumOperands(); i != e; ++i) {
      int Slot = Table.getSlot(CPS->getOperand(i));
      assert(Slot != -1 && "Constant used but not available!!");
      output_vbr((unsigned)Slot);
    }
    break;
  }

  case Type::PointerTyID:
    assert(0 && "No non-null, non-constant-expr constants allowed!");
    abort();

  case Type::FloatTyID: {   // Floating point types...
    float Tmp = (float)cast<ConstantFP>(CPV)->getValue();
    output_float(Tmp);
    break;
  }
  case Type::DoubleTyID: {
    double Tmp = cast<ConstantFP>(CPV)->getValue();
    output_double(Tmp);
    break;
  }

  case Type::VoidTyID:
  case Type::LabelTyID:
  default:
    std::cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to serialize"
              << " type '" << *CPV->getType() << "'\n";
    break;
  }
  return;
}

void BytecodeWriter::outputConstantStrings() {
  SlotCalculator::string_iterator I = Table.string_begin();
  SlotCalculator::string_iterator E = Table.string_end();
  if (I == E) return;  // No strings to emit

  // If we have != 0 strings to emit, output them now.  Strings are emitted into
  // the 'void' type plane.
  output_vbr(unsigned(E-I));
  output_typeid(Type::VoidTyID);

  // Emit all of the strings.
  for (I = Table.string_begin(); I != E; ++I) {
    const ConstantArray *Str = *I;
    int Slot = Table.getSlot(Str->getType());
    assert(Slot != -1 && "Constant string of unknown type?");
    output_typeid((unsigned)Slot);

    // Now that we emitted the type (which indicates the size of the string),
    // emit all of the characters.
    std::string Val = Str->getAsString();
    output_data(Val.c_str(), Val.c_str()+Val.size());
  }
}

//===----------------------------------------------------------------------===//
//===                           Instruction Output                         ===//
//===----------------------------------------------------------------------===//
typedef unsigned char uchar;

// outputInstructionFormat0 - Output those weird instructions that have a large
// number of operands or have large operands themselves.
//
// Format: [opcode] [type] [numargs] [arg0] [arg1] ... [arg<numargs-1>]
//
void BytecodeWriter::outputInstructionFormat0(const Instruction *I,
                                              unsigned Opcode,
                                              const SlotCalculator &Table,
                                              unsigned Type) {
  // Opcode must have top two bits clear...
  output_vbr(Opcode << 2);                  // Instruction Opcode ID
  output_typeid(Type);                      // Result type

  unsigned NumArgs = I->getNumOperands();
  output_vbr(NumArgs + (isa<CastInst>(I) || isa<VANextInst>(I) ||
                        isa<VAArgInst>(I) || Opcode == 56 || Opcode == 58));

  if (!isa<GetElementPtrInst>(&I)) {
    for (unsigned i = 0; i < NumArgs; ++i) {
      int Slot = Table.getSlot(I->getOperand(i));
      assert(Slot >= 0 && "No slot number for value!?!?");
      output_vbr((unsigned)Slot);
    }

    if (isa<CastInst>(I) || isa<VAArgInst>(I)) {
      int Slot = Table.getSlot(I->getType());
      assert(Slot != -1 && "Cast return type unknown?");
      output_typeid((unsigned)Slot);
    } else if (const VANextInst *VAI = dyn_cast<VANextInst>(I)) {
      int Slot = Table.getSlot(VAI->getArgType());
      assert(Slot != -1 && "VarArg argument type unknown?");
      output_typeid((unsigned)Slot);
    } else if (Opcode == 56) {  // Invoke escape sequence
      output_vbr(cast<InvokeInst>(I)->getCallingConv());
    } else if (Opcode == 58) {  // Call escape sequence
      output_vbr((cast<CallInst>(I)->getCallingConv() << 1) |
                 unsigned(cast<CallInst>(I)->isTailCall()));
    }
  } else {
    int Slot = Table.getSlot(I->getOperand(0));
    assert(Slot >= 0 && "No slot number for value!?!?");
    output_vbr(unsigned(Slot));

    // We need to encode the type of sequential type indices into their slot #
    unsigned Idx = 1;
    for (gep_type_iterator TI = gep_type_begin(I), E = gep_type_end(I);
         Idx != NumArgs; ++TI, ++Idx) {
      Slot = Table.getSlot(I->getOperand(Idx));
      assert(Slot >= 0 && "No slot number for value!?!?");

      if (isa<SequentialType>(*TI)) {
        unsigned IdxId;
        switch (I->getOperand(Idx)->getType()->getTypeID()) {
        default: assert(0 && "Unknown index type!");
        case Type::UIntTyID:  IdxId = 0; break;
        case Type::IntTyID:   IdxId = 1; break;
        case Type::ULongTyID: IdxId = 2; break;
        case Type::LongTyID:  IdxId = 3; break;
        }
        Slot = (Slot << 2) | IdxId;
      }
      output_vbr(unsigned(Slot));
    }
  }
}


// outputInstrVarArgsCall - Output the absurdly annoying varargs function calls.
// This are more annoying than most because the signature of the call does not
// tell us anything about the types of the arguments in the varargs portion.
// Because of this, we encode (as type 0) all of the argument types explicitly
// before the argument value.  This really sucks, but you shouldn't be using
// varargs functions in your code! *death to printf*!
//
// Format: [opcode] [type] [numargs] [arg0] [arg1] ... [arg<numargs-1>]
//
void BytecodeWriter::outputInstrVarArgsCall(const Instruction *I,
                                            unsigned Opcode,
                                            const SlotCalculator &Table,
                                            unsigned Type) {
  assert(isa<CallInst>(I) || isa<InvokeInst>(I));
  // Opcode must have top two bits clear...
  output_vbr(Opcode << 2);                  // Instruction Opcode ID
  output_typeid(Type);                      // Result type (varargs type)

  const PointerType *PTy = cast<PointerType>(I->getOperand(0)->getType());
  const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
  unsigned NumParams = FTy->getNumParams();

  unsigned NumFixedOperands;
  if (isa<CallInst>(I)) {
    // Output an operand for the callee and each fixed argument, then two for
    // each variable argument.
    NumFixedOperands = 1+NumParams;
  } else {
    assert(isa<InvokeInst>(I) && "Not call or invoke??");
    // Output an operand for the callee and destinations, then two for each
    // variable argument.
    NumFixedOperands = 3+NumParams;
  }
  output_vbr(2 * I->getNumOperands()-NumFixedOperands);

  // The type for the function has already been emitted in the type field of the
  // instruction.  Just emit the slot # now.
  for (unsigned i = 0; i != NumFixedOperands; ++i) {
    int Slot = Table.getSlot(I->getOperand(i));
    assert(Slot >= 0 && "No slot number for value!?!?");
    output_vbr((unsigned)Slot);
  }

  for (unsigned i = NumFixedOperands, e = I->getNumOperands(); i != e; ++i) {
    // Output Arg Type ID
    int Slot = Table.getSlot(I->getOperand(i)->getType());
    assert(Slot >= 0 && "No slot number for value!?!?");
    output_typeid((unsigned)Slot);

    // Output arg ID itself
    Slot = Table.getSlot(I->getOperand(i));
    assert(Slot >= 0 && "No slot number for value!?!?");
    output_vbr((unsigned)Slot);
  }
}


// outputInstructionFormat1 - Output one operand instructions, knowing that no
// operand index is >= 2^12.
//
inline void BytecodeWriter::outputInstructionFormat1(const Instruction *I,
                                                     unsigned Opcode,
                                                     unsigned *Slots,
                                                     unsigned Type) {
  // bits   Instruction format:
  // --------------------------
  // 01-00: Opcode type, fixed to 1.
  // 07-02: Opcode
  // 19-08: Resulting type plane
  // 31-20: Operand #1 (if set to (2^12-1), then zero operands)
  //
  output(1 | (Opcode << 2) | (Type << 8) | (Slots[0] << 20));
}


// outputInstructionFormat2 - Output two operand instructions, knowing that no
// operand index is >= 2^8.
//
inline void BytecodeWriter::outputInstructionFormat2(const Instruction *I,
                                                     unsigned Opcode,
                                                     unsigned *Slots,
                                                     unsigned Type) {
  // bits   Instruction format:
  // --------------------------
  // 01-00: Opcode type, fixed to 2.
  // 07-02: Opcode
  // 15-08: Resulting type plane
  // 23-16: Operand #1
  // 31-24: Operand #2
  //
  output(2 | (Opcode << 2) | (Type << 8) | (Slots[0] << 16) | (Slots[1] << 24));
}


// outputInstructionFormat3 - Output three operand instructions, knowing that no
// operand index is >= 2^6.
//
inline void BytecodeWriter::outputInstructionFormat3(const Instruction *I,
                                                     unsigned Opcode,
                                                     unsigned *Slots,
                                                     unsigned Type) {
  // bits   Instruction format:
  // --------------------------
  // 01-00: Opcode type, fixed to 3.
  // 07-02: Opcode
  // 13-08: Resulting type plane
  // 19-14: Operand #1
  // 25-20: Operand #2
  // 31-26: Operand #3
  //
  output(3 | (Opcode << 2) | (Type << 8) |
          (Slots[0] << 14) | (Slots[1] << 20) | (Slots[2] << 26));
}

void BytecodeWriter::outputInstruction(const Instruction &I) {
  assert(I.getOpcode() < 62 && "Opcode too big???");
  unsigned Opcode = I.getOpcode();
  unsigned NumOperands = I.getNumOperands();

  // Encode 'tail call' as 61, 'volatile load' as 62, and 'volatile store' as
  // 63.
  if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
    if (CI->getCallingConv() == CallingConv::C) {
      if (CI->isTailCall())
        Opcode = 61;   // CCC + Tail Call
      else
        ;     // Opcode = Instruction::Call
    } else if (CI->getCallingConv() == CallingConv::Fast) {
      if (CI->isTailCall())
        Opcode = 59;    // FastCC + TailCall
      else
        Opcode = 60;    // FastCC + Not Tail Call
    } else {
      Opcode = 58;      // Call escape sequence.
    }
  } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
    if (II->getCallingConv() == CallingConv::Fast)
      Opcode = 57;      // FastCC invoke.
    else if (II->getCallingConv() != CallingConv::C)
      Opcode = 56;      // Invoke escape sequence.
      
  } else if (isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) {
    Opcode = 62;
  } else if (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()) {
    Opcode = 63;
  }

  // Figure out which type to encode with the instruction.  Typically we want
  // the type of the first parameter, as opposed to the type of the instruction
  // (for example, with setcc, we always know it returns bool, but the type of
  // the first param is actually interesting).  But if we have no arguments
  // we take the type of the instruction itself.
  //
  const Type *Ty;
  switch (I.getOpcode()) {
  case Instruction::Select:
  case Instruction::Malloc:
  case Instruction::Alloca:
    Ty = I.getType();  // These ALWAYS want to encode the return type
    break;
  case Instruction::Store:
    Ty = I.getOperand(1)->getType();  // Encode the pointer type...
    assert(isa<PointerType>(Ty) && "Store to nonpointer type!?!?");
    break;
  default:              // Otherwise use the default behavior...
    Ty = NumOperands ? I.getOperand(0)->getType() : I.getType();
    break;
  }

  unsigned Type;
  int Slot = Table.getSlot(Ty);
  assert(Slot != -1 && "Type not available!!?!");
  Type = (unsigned)Slot;

  // Varargs calls and invokes are encoded entirely different from any other
  // instructions.
  if (const CallInst *CI = dyn_cast<CallInst>(&I)){
    const PointerType *Ty =cast<PointerType>(CI->getCalledValue()->getType());
    if (cast<FunctionType>(Ty->getElementType())->isVarArg()) {
      outputInstrVarArgsCall(CI, Opcode, Table, Type);
      return;
    }
  } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
    const PointerType *Ty =cast<PointerType>(II->getCalledValue()->getType());
    if (cast<FunctionType>(Ty->getElementType())->isVarArg()) {
      outputInstrVarArgsCall(II, Opcode, Table, Type);
      return;
    }
  }

  if (NumOperands <= 3) {
    // Make sure that we take the type number into consideration.  We don't want
    // to overflow the field size for the instruction format we select.
    //
    unsigned MaxOpSlot = Type;
    unsigned Slots[3]; Slots[0] = (1 << 12)-1;   // Marker to signify 0 operands

    for (unsigned i = 0; i != NumOperands; ++i) {
      int slot = Table.getSlot(I.getOperand(i));
      assert(slot != -1 && "Broken bytecode!");
      if (unsigned(slot) > MaxOpSlot) MaxOpSlot = unsigned(slot);
      Slots[i] = unsigned(slot);
    }

    // Handle the special cases for various instructions...
    if (isa<CastInst>(I) || isa<VAArgInst>(I)) {
      // Cast has to encode the destination type as the second argument in the
      // packet, or else we won't know what type to cast to!
      Slots[1] = Table.getSlot(I.getType());
      assert(Slots[1] != ~0U && "Cast return type unknown?");
      if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1];
      NumOperands++;
    } else if (const VANextInst *VANI = dyn_cast<VANextInst>(&I)) {
      Slots[1] = Table.getSlot(VANI->getArgType());
      assert(Slots[1] != ~0U && "va_next return type unknown?");
      if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1];
      NumOperands++;
    } else if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(&I)) {
      // We need to encode the type of sequential type indices into their slot #
      unsigned Idx = 1;
      for (gep_type_iterator I = gep_type_begin(GEP), E = gep_type_end(GEP);
           I != E; ++I, ++Idx)
        if (isa<SequentialType>(*I)) {
          unsigned IdxId;
          switch (GEP->getOperand(Idx)->getType()->getTypeID()) {
          default: assert(0 && "Unknown index type!");
          case Type::UIntTyID:  IdxId = 0; break;
          case Type::IntTyID:   IdxId = 1; break;
          case Type::ULongTyID: IdxId = 2; break;
          case Type::LongTyID:  IdxId = 3; break;
          }
          Slots[Idx] = (Slots[Idx] << 2) | IdxId;
          if (Slots[Idx] > MaxOpSlot) MaxOpSlot = Slots[Idx];
        }
    } else if (Opcode == 58) {
      // If this is the escape sequence for call, emit the tailcall/cc info.
      const CallInst &CI = cast<CallInst>(I);
      ++NumOperands;
      if (NumOperands < 3) {
        Slots[NumOperands-1] = (CI.getCallingConv() << 1)|unsigned(CI.isTailCall());
        if (Slots[NumOperands-1] > MaxOpSlot)
          MaxOpSlot = Slots[NumOperands-1];
      }
    } else if (Opcode == 56) {
      // Invoke escape seq has at least 4 operands to encode.
      ++NumOperands;
    }

    // Decide which instruction encoding to use.  This is determined primarily
    // by the number of operands, and secondarily by whether or not the max
    // operand will fit into the instruction encoding.  More operands == fewer
    // bits per operand.
    //
    switch (NumOperands) {
    case 0:
    case 1:
      if (MaxOpSlot < (1 << 12)-1) { // -1 because we use 4095 to indicate 0 ops
        outputInstructionFormat1(&I, Opcode, Slots, Type);
        return;
      }
      break;

    case 2:
      if (MaxOpSlot < (1 << 8)) {
        outputInstructionFormat2(&I, Opcode, Slots, Type);
        return;
      }
      break;

    case 3:
      if (MaxOpSlot < (1 << 6)) {
        outputInstructionFormat3(&I, Opcode, Slots, Type);
        return;
      }
      break;
    default:
      break;
    }
  }

  // If we weren't handled before here, we either have a large number of
  // operands or a large operand index that we are referring to.
  outputInstructionFormat0(&I, Opcode, Table, Type);
}

//===----------------------------------------------------------------------===//
//===                              Block Output                            ===//
//===----------------------------------------------------------------------===//

BytecodeWriter::BytecodeWriter(std::vector<unsigned char> &o, const Module *M)
  : Out(o), Table(M) {

  // Emit the signature...
  static const unsigned char *Sig =  (const unsigned char*)"llvm";
  output_data(Sig, Sig+4);

  // Emit the top level CLASS block.
  BytecodeBlock ModuleBlock(BytecodeFormat::ModuleBlockID, *this, false, true);

  bool isBigEndian      = M->getEndianness() == Module::BigEndian;
  bool hasLongPointers  = M->getPointerSize() == Module::Pointer64;
  bool hasNoEndianness  = M->getEndianness() == Module::AnyEndianness;
  bool hasNoPointerSize = M->getPointerSize() == Module::AnyPointerSize;

  // Output the version identifier and other information.
  unsigned Version = (BCVersionNum << 4) |
                     (unsigned)isBigEndian | (hasLongPointers << 1) |
                     (hasNoEndianness << 2) |
                     (hasNoPointerSize << 3);
  output_vbr(Version);

  // The Global type plane comes first
  {
      BytecodeBlock CPool(BytecodeFormat::GlobalTypePlaneBlockID, *this );
      outputTypes(Type::FirstDerivedTyID);
  }

  // The ModuleInfoBlock follows directly after the type information
  outputModuleInfoBlock(M);

  // Output module level constants, used for global variable initializers
  outputConstants(false);

  // Do the whole module now! Process each function at a time...
  for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
    outputFunction(I);

  // If needed, output the symbol table for the module...
  outputSymbolTable(M->getSymbolTable());
}

void BytecodeWriter::outputTypes(unsigned TypeNum) {
  // Write the type plane for types first because earlier planes (e.g. for a
  // primitive type like float) may have constants constructed using types
  // coming later (e.g., via getelementptr from a pointer type).  The type
  // plane is needed before types can be fwd or bkwd referenced.
  const std::vector<const Type*>& Types = Table.getTypes();
  assert(!Types.empty() && "No types at all?");
  assert(TypeNum <= Types.size() && "Invalid TypeNo index");

  unsigned NumEntries = Types.size() - TypeNum;

  // Output type header: [num entries]
  output_vbr(NumEntries);

  for (unsigned i = TypeNum; i < TypeNum+NumEntries; ++i)
    outputType(Types[i]);
}

// Helper function for outputConstants().
// Writes out all the constants in the plane Plane starting at entry StartNo.
//
void BytecodeWriter::outputConstantsInPlane(const std::vector<const Value*>
                                            &Plane, unsigned StartNo) {
  unsigned ValNo = StartNo;

  // Scan through and ignore function arguments, global values, and constant
  // strings.
  for (; ValNo < Plane.size() &&
         (isa<Argument>(Plane[ValNo]) || isa<GlobalValue>(Plane[ValNo]) ||
          (isa<ConstantArray>(Plane[ValNo]) &&
           cast<ConstantArray>(Plane[ValNo])->isString())); ValNo++)
    /*empty*/;

  unsigned NC = ValNo;              // Number of constants
  for (; NC < Plane.size() && (isa<Constant>(Plane[NC])); NC++)
    /*empty*/;
  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.

  // Output type header: [num entries][type id number]
  //
  output_vbr(NC);

  // Output the Type ID Number...
  int Slot = Table.getSlot(Plane.front()->getType());
  assert (Slot != -1 && "Type in constant pool but not in function!!");
  output_typeid((unsigned)Slot);

  for (unsigned i = ValNo; i < ValNo+NC; ++i) {
    const Value *V = Plane[i];
    if (const Constant *C = dyn_cast<Constant>(V)) {
      outputConstant(C);
    }
  }
}

static inline bool hasNullValue(const Type *Ty) {
  return Ty != Type::LabelTy && Ty != Type::VoidTy && !isa<OpaqueType>(Ty);
}

void BytecodeWriter::outputConstants(bool isFunction) {
  BytecodeBlock CPool(BytecodeFormat::ConstantPoolBlockID, *this,
                      true  /* Elide block if empty */);

  unsigned NumPlanes = Table.getNumPlanes();

  if (isFunction)
    // Output the type plane before any constants!
    outputTypes(Table.getModuleTypeLevel());
  else
    // Output module-level string constants before any other constants.
    outputConstantStrings();

  for (unsigned pno = 0; pno != NumPlanes; pno++) {
    const std::vector<const Value*> &Plane = Table.getPlane(pno);
    if (!Plane.empty()) {              // Skip empty type planes...
      unsigned ValNo = 0;
      if (isFunction)                  // Don't re-emit module constants
        ValNo += Table.getModuleLevel(pno);

      if (hasNullValue(Plane[0]->getType())) {
        // Skip zero initializer
        if (ValNo == 0)
          ValNo = 1;
      }

      // Write out constants in the plane
      outputConstantsInPlane(Plane, ValNo);
    }
  }
}

static unsigned getEncodedLinkage(const GlobalValue *GV) {
  switch (GV->getLinkage()) {
  default: assert(0 && "Invalid linkage!");
  case GlobalValue::ExternalLinkage:  return 0;
  case GlobalValue::WeakLinkage:      return 1;
  case GlobalValue::AppendingLinkage: return 2;
  case GlobalValue::InternalLinkage:  return 3;
  case GlobalValue::LinkOnceLinkage:  return 4;
  }
}

void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
  BytecodeBlock ModuleInfoBlock(BytecodeFormat::ModuleGlobalInfoBlockID, *this);

  // Output the types for the global variables in the module...
  for (Module::const_global_iterator I = M->global_begin(),
         End = M->global_end(); I != End;++I) {
    int Slot = Table.getSlot(I->getType());
    assert(Slot != -1 && "Module global vars is broken!");

    // Fields: bit0 = isConstant, bit1 = hasInitializer, bit2-4=Linkage,
    // bit5+ = Slot # for type
    unsigned oSlot = ((unsigned)Slot << 5) | (getEncodedLinkage(I) << 2) |
                     (I->hasInitializer() << 1) | (unsigned)I->isConstant();
    output_vbr(oSlot);

    // If we have an initializer, output it now.
    if (I->hasInitializer()) {
      Slot = Table.getSlot((Value*)I->getInitializer());
      assert(Slot != -1 && "No slot for global var initializer!");
      output_vbr((unsigned)Slot);
    }
  }
  output_typeid((unsigned)Table.getSlot(Type::VoidTy));

  // Output the types of the functions in this module.
  for (Module::const_iterator I = M->begin(), End = M->end(); I != End; ++I) {
    int Slot = Table.getSlot(I->getType());
    assert(Slot != -1 && "Module slot calculator is broken!");
    assert(Slot >= Type::FirstDerivedTyID && "Derived type not in range!");
    assert(((Slot << 5) >> 5) == Slot && "Slot # too big!");
    unsigned ID = (Slot << 5);

    if (I->getCallingConv() < 15)
      ID += I->getCallingConv()+1;

    if (I->isExternal())   // If external, we don't have an FunctionInfo block.
      ID |= 1 << 4;
    output_vbr(ID);

    if (I->getCallingConv() >= 15)
      output_vbr(I->getCallingConv());
  }
  output_vbr((unsigned)Table.getSlot(Type::VoidTy) << 5);

  // Emit the list of dependent libraries for the Module.
  Module::lib_iterator LI = M->lib_begin();
  Module::lib_iterator LE = M->lib_end();
  output_vbr(unsigned(LE - LI));   // Emit the number of dependent libraries.
  for (; LI != LE; ++LI)
    output(*LI);

  // Output the target triple from the module
  output(M->getTargetTriple());
}

void BytecodeWriter::outputInstructions(const Function *F) {
  BytecodeBlock ILBlock(BytecodeFormat::InstructionListBlockID, *this);
  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);
}

void BytecodeWriter::outputFunction(const Function *F) {
  // If this is an external function, there is nothing else to emit!
  if (F->isExternal()) return;

  BytecodeBlock FunctionBlock(BytecodeFormat::FunctionBlockID, *this);
  output_vbr(getEncodedLinkage(F));

  // 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);
  } 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 (Plane.empty() || StartNo == End || End == 0) return;   // Nothing to emit
  assert(StartNo < End && "Cannot emit negative range!");
  assert(StartNo < Plane.size() && End <= Plane.size());

  // Do not emit the null initializer!
  ++StartNo;

  // Figure out which encoding to use.  By far the most common case we have is
  // to emit 0-2 entries in a compaction table plane.
  switch (End-StartNo) {
  case 0:         // Avoid emitting two vbr's if possible.
  case 1:
  case 2:
    output_vbr((PlaneNo << 2) | End-StartNo);
    break;
  default:
    // Output the number of things.
    output_vbr((unsigned(End-StartNo) << 2) | 3);
    output_typeid(PlaneNo);                 // Emit the type plane this is
    break;
  }

  for (unsigned i = StartNo; i != End; ++i)
    output_vbr(Table.getGlobalSlot(Plane[i]));
}

void BytecodeWriter::outputCompactionTypes(unsigned StartNo) {
  // Get the compaction type table from the slot calculator
  const std::vector<const Type*> &CTypes = Table.getCompactionTypes();

  // The compaction types may have been uncompactified back to the
  // global types. If so, we just write an empty table
  if (CTypes.size() == 0 ) {
    output_vbr(0U);
    return;
  }

  assert(CTypes.size() >= StartNo && "Invalid compaction types start index");

  // Determine how many types to write
  unsigned NumTypes = CTypes.size() - StartNo;

  // Output the number of types.
  output_vbr(NumTypes);

  for (unsigned i = StartNo; i < StartNo+NumTypes; ++i)
    output_typeid(Table.getGlobalSlot(CTypes[i]));
}

void BytecodeWriter::outputCompactionTable() {
  // Avoid writing the compaction table at all if there is no content.
  if (Table.getCompactionTypes().size() >= Type::FirstDerivedTyID ||
      (!Table.CompactionTableIsEmpty())) {
    BytecodeBlock CTB(BytecodeFormat::CompactionTableBlockID, *this,
                      true/*ElideIfEmpty*/);
    const std::vector<std::vector<const Value*> > &CT =
      Table.getCompactionTable();

    // First things first, emit the type compaction table if there is one.
    outputCompactionTypes(Type::FirstDerivedTyID);

    for (unsigned i = 0, e = CT.size(); i != e; ++i)
      outputCompactionTablePlane(i, CT[i], 0);
  }
}

void BytecodeWriter::outputSymbolTable(const SymbolTable &MST) {
  // Do not output the Bytecode block for an empty symbol table, it just wastes
  // space!
  if (MST.isEmpty()) return;

  BytecodeBlock SymTabBlock(BytecodeFormat::SymbolTableBlockID, *this,
                            true/*ElideIfEmpty*/);

  // Write the number of types
  output_vbr(MST.num_types());

  // Write each of the types
  for (SymbolTable::type_const_iterator TI = MST.type_begin(),
       TE = MST.type_end(); TI != TE; ++TI ) {
    // Symtab entry:[def slot #][name]
    output_typeid((unsigned)Table.getSlot(TI->second));
    output(TI->first);
  }

  // Now do each of the type planes in order.
  for (SymbolTable::plane_const_iterator PI = MST.plane_begin(),
       PE = MST.plane_end(); PI != PE;  ++PI) {
    SymbolTable::value_const_iterator I = MST.value_begin(PI->first);
    SymbolTable::value_const_iterator End = MST.value_end(PI->first);
    int Slot;

    if (I == End) continue;  // Don't mess with an absent type...

    // Write the number of values in this plane
    output_vbr((unsigned)PI->second.size());

    // Write the slot number of the type for this plane
    Slot = Table.getSlot(PI->first);
    assert(Slot != -1 && "Type in symtab, but not in table!");
    output_typeid((unsigned)Slot);

    // Write each of the values in this plane
    for (; I != End; ++I) {
      // Symtab entry: [def slot #][name]
      Slot = Table.getSlot(I->second);
      assert(Slot != -1 && "Value in symtab but has no slot number!!");
      output_vbr((unsigned)Slot);
      output(I->first);
    }
  }
}

void llvm::WriteBytecodeToFile(const Module *M, std::ostream &Out,
                               bool compress ) {
  assert(M && "You can't write a null module!!");

  // Create a vector of unsigned char for the bytecode output. We
  // reserve 256KBytes of space in the vector so that we avoid doing
  // lots of little allocations. 256KBytes is sufficient for a large
  // proportion of the bytecode files we will encounter. Larger files
  // will be automatically doubled in size as needed (std::vector
  // behavior).
  std::vector<unsigned char> Buffer;
  Buffer.reserve(256 * 1024);

  // The BytecodeWriter populates Buffer for us.
  BytecodeWriter BCW(Buffer, M);

  // Keep track of how much we've written
  BytesWritten += Buffer.size();

  // Determine start and end points of the Buffer
  const unsigned char *FirstByte = &Buffer.front();

  // If we're supposed to compress this mess ...
  if (compress) {

    // We signal compression by using an alternate magic number for the
    // file. The compressed bytecode file's magic number is "llvc" instead
    // of "llvm".
    char compressed_magic[4];
    compressed_magic[0] = 'l';
    compressed_magic[1] = 'l';
    compressed_magic[2] = 'v';
    compressed_magic[3] = 'c';

    Out.write(compressed_magic,4);

    // Compress everything after the magic number (which we altered)
    uint64_t zipSize = Compressor::compressToStream(
      (char*)(FirstByte+4),        // Skip the magic number
      Buffer.size()-4,             // Skip the magic number
      Out                          // Where to write compressed data
    );

  } else {

    // We're not compressing, so just write the entire block.
    Out.write((char*)FirstByte, Buffer.size());
  }

  // make sure it hits disk now
  Out.flush();
}

