//===-- 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. :( :( :(
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "bytecodewriter"
#include "WriterInternals.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/InlineAsm.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/TypeSymbolTable.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/Compressor.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Streams.h"
#include "llvm/System/Program.h"
#include "llvm/ADT/SmallVector.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 = 7;
static RegisterPass<WriteBytecodePass> X("emitbytecode", "Bytecode Writer");
STATISTIC(BytesWritten, "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(int32_t i) {
output((uint32_t)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(uint32_t i) {
while (1) {
if (i < 0x80) { // done?
Out.push_back((unsigned char)i<