2004-01-10 19:07:06 +00:00
|
|
|
//===-- Writer.cpp - Library for writing LLVM bytecode files --------------===//
|
2005-04-21 21:48:46 +00:00
|
|
|
//
|
2003-10-20 19:43:21 +00:00
|
|
|
// 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.
|
2005-04-21 21:48:46 +00:00
|
|
|
//
|
2003-10-20 19:43:21 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2001-06-06 20:29:01 +00:00
|
|
|
//
|
|
|
|
// This library implements the functionality defined in llvm/Bytecode/Writer.h
|
|
|
|
//
|
|
|
|
// Note that this file uses an unusual technique of outputting all the bytecode
|
2004-07-25 18:07:36 +00:00
|
|
|
// to a vector of unsigned char, then copies the vector to an ostream. The
|
2001-06-06 20:29:01 +00:00
|
|
|
// 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. :( :( :(
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2006-12-19 23:16:47 +00:00
|
|
|
#define DEBUG_TYPE "bytecodewriter"
|
2001-06-06 20:29:01 +00:00
|
|
|
#include "WriterInternals.h"
|
2002-07-23 19:56:44 +00:00
|
|
|
#include "llvm/Bytecode/WriteBytecodePass.h"
|
2005-05-06 22:34:01 +00:00
|
|
|
#include "llvm/CallingConv.h"
|
2004-01-14 23:36:54 +00:00
|
|
|
#include "llvm/Constants.h"
|
|
|
|
#include "llvm/DerivedTypes.h"
|
2006-01-25 23:08:15 +00:00
|
|
|
#include "llvm/InlineAsm.h"
|
2004-07-25 18:07:36 +00:00
|
|
|
#include "llvm/Instructions.h"
|
2001-06-06 20:29:01 +00:00
|
|
|
#include "llvm/Module.h"
|
2007-01-06 07:24:44 +00:00
|
|
|
#include "llvm/TypeSymbolTable.h"
|
2007-02-05 20:47:22 +00:00
|
|
|
#include "llvm/ValueSymbolTable.h"
|
2004-07-25 18:07:36 +00:00
|
|
|
#include "llvm/Support/GetElementPtrTypeIterator.h"
|
2004-11-06 23:17:23 +00:00
|
|
|
#include "llvm/Support/Compressor.h"
|
2005-08-17 19:34:49 +00:00
|
|
|
#include "llvm/Support/MathExtras.h"
|
2006-11-29 00:19:40 +00:00
|
|
|
#include "llvm/Support/Streams.h"
|
2006-06-07 23:18:34 +00:00
|
|
|
#include "llvm/System/Program.h"
|
2004-09-01 22:55:40 +00:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
#include "llvm/ADT/Statistic.h"
|
2004-01-10 19:10:01 +00:00
|
|
|
#include <cstring>
|
2001-06-06 20:29:01 +00:00
|
|
|
#include <algorithm>
|
2004-01-10 18:49:43 +00:00
|
|
|
using namespace llvm;
|
2003-11-11 22:41:34 +00:00
|
|
|
|
2004-08-17 07:45:14 +00:00
|
|
|
/// 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
|
2006-11-08 21:27:54 +00:00
|
|
|
const unsigned BCVersionNum = 7;
|
2004-08-17 07:45:14 +00:00
|
|
|
|
2002-07-23 19:56:44 +00:00
|
|
|
static RegisterPass<WriteBytecodePass> X("emitbytecode", "Bytecode Writer");
|
|
|
|
|
2006-12-19 23:16:47 +00:00
|
|
|
STATISTIC(BytesWritten, "Number of bytecode bytes written");
|
2002-07-23 19:56:44 +00:00
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//=== Output Primitives ===//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
// output - If a position is specified, it must be in the valid portion of the
|
2005-04-21 21:48:46 +00:00
|
|
|
// string... note that this should be inlined always so only the relevant IF
|
2004-07-25 18:07:36 +00:00
|
|
|
// body should be included.
|
|
|
|
inline void BytecodeWriter::output(unsigned i, int pos) {
|
|
|
|
if (pos == -1) { // Be endian clean, little endian is our friend
|
2005-04-21 21:48:46 +00:00
|
|
|
Out.push_back((unsigned char)i);
|
2004-07-25 18:07:36 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-02-09 18:03:35 +00:00
|
|
|
inline void BytecodeWriter::output(int32_t i) {
|
|
|
|
output((uint32_t)i);
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// 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.
|
2005-04-21 21:48:46 +00:00
|
|
|
/// 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.
|
2004-07-25 18:07:36 +00:00
|
|
|
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;
|
|
|
|
}
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
// 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...
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-02-09 18:03:35 +00:00
|
|
|
inline void BytecodeWriter::output_vbr(uint32_t i) {
|
2004-07-25 18:07:36 +00:00
|
|
|
while (1) {
|
|
|
|
if (i < 0x80) { // done?
|
|
|
|
Out.push_back((unsigned char)i); // We know the high bit is clear...
|
|
|
|
return;
|
|
|
|
}
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
// 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) {
|
2005-04-21 21:48:46 +00:00
|
|
|
if (i < 0)
|
2004-07-25 18:07:36 +00:00
|
|
|
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) {
|
2005-04-21 21:48:46 +00:00
|
|
|
if (i < 0)
|
2004-07-25 18:07:36 +00:00
|
|
|
output_vbr(((unsigned)(-i) << 1) | 1); // Set low order sign bit...
|
|
|
|
else
|
|
|
|
output_vbr((unsigned)i << 1); // Low order bit is clear.
|
|
|
|
}
|
|
|
|
|
2004-08-17 07:45:14 +00:00
|
|
|
inline void BytecodeWriter::output(const std::string &s) {
|
2004-07-25 18:07:36 +00:00
|
|
|
unsigned Len = s.length();
|
2006-07-28 22:07:54 +00:00
|
|
|
output_vbr(Len); // Strings may have an arbitrary length.
|
2004-07-25 18:07:36 +00:00
|
|
|
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.
|
2005-08-17 19:34:49 +00:00
|
|
|
uint32_t i = FloatToBits(FloatVal);
|
2006-07-28 22:07:54 +00:00
|
|
|
Out.push_back( static_cast<unsigned char>( (i ) & 0xFF));
|
|
|
|
Out.push_back( static_cast<unsigned char>( (i >> 8 ) & 0xFF));
|
2005-08-17 19:34:49 +00:00
|
|
|
Out.push_back( static_cast<unsigned char>( (i >> 16) & 0xFF));
|
|
|
|
Out.push_back( static_cast<unsigned char>( (i >> 24) & 0xFF));
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline void BytecodeWriter::output_double(double& DoubleVal) {
|
|
|
|
/// FIXME: This isn't optimal, it has size problems on some platforms
|
|
|
|
/// where FP is not IEEE.
|
2005-08-17 19:34:49 +00:00
|
|
|
uint64_t i = DoubleToBits(DoubleVal);
|
2006-07-28 22:07:54 +00:00
|
|
|
Out.push_back( static_cast<unsigned char>( (i ) & 0xFF));
|
|
|
|
Out.push_back( static_cast<unsigned char>( (i >> 8 ) & 0xFF));
|
2005-08-17 19:34:49 +00:00
|
|
|
Out.push_back( static_cast<unsigned char>( (i >> 16) & 0xFF));
|
|
|
|
Out.push_back( static_cast<unsigned char>( (i >> 24) & 0xFF));
|
|
|
|
Out.push_back( static_cast<unsigned char>( (i >> 32) & 0xFF));
|
|
|
|
Out.push_back( static_cast<unsigned char>( (i >> 40) & 0xFF));
|
|
|
|
Out.push_back( static_cast<unsigned char>( (i >> 48) & 0xFF));
|
|
|
|
Out.push_back( static_cast<unsigned char>( (i >> 56) & 0xFF));
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
|
|
|
|
2005-11-12 18:34:09 +00:00
|
|
|
inline BytecodeBlock::BytecodeBlock(unsigned ID, BytecodeWriter &w,
|
|
|
|
bool elideIfEmpty, bool hasLongFormat)
|
2004-07-25 18:07:36 +00:00
|
|
|
: 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();
|
|
|
|
}
|
|
|
|
|
2004-10-14 01:35:17 +00:00
|
|
|
inline BytecodeBlock::~BytecodeBlock() { // Do backpatch when block goes out
|
2005-04-21 21:48:46 +00:00
|
|
|
// of scope...
|
2004-07-25 18:07:36 +00:00
|
|
|
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) {
|
2006-12-08 18:06:16 +00:00
|
|
|
const StructType* STy = dyn_cast<StructType>(T);
|
|
|
|
if(STy && STy->isPacked())
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
output_vbr((unsigned)Type::PackedStructTyID);
|
2006-12-08 18:06:16 +00:00
|
|
|
else
|
|
|
|
output_vbr((unsigned)T->getTypeID());
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
// That's all there is to handling primitive types...
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
if (T->isPrimitiveType())
|
2004-07-25 18:07:36 +00:00
|
|
|
return; // We might do this if we alias a prim type: %x = type int
|
|
|
|
|
|
|
|
switch (T->getTypeID()) { // Handle derived types now.
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
case Type::IntegerTyID:
|
|
|
|
output_vbr(cast<IntegerType>(T)->getBitWidth());
|
|
|
|
break;
|
2004-07-25 18:07:36 +00:00
|
|
|
case Type::FunctionTyID: {
|
|
|
|
const FunctionType *MT = cast<FunctionType>(T);
|
2007-02-10 05:17:48 +00:00
|
|
|
output_typeid(Table.getTypeSlot(MT->getReturnType()));
|
2006-12-31 05:44:24 +00:00
|
|
|
output_vbr(unsigned(MT->getParamAttrs(0)));
|
2004-07-25 18:07:36 +00:00
|
|
|
|
|
|
|
// 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();
|
2006-12-31 05:44:24 +00:00
|
|
|
unsigned Idx = 1;
|
2004-07-25 18:07:36 +00:00
|
|
|
for (; I != MT->param_end(); ++I) {
|
2007-02-10 05:17:48 +00:00
|
|
|
output_typeid(Table.getTypeSlot(*I));
|
2006-12-31 05:44:24 +00:00
|
|
|
output_vbr(unsigned(MT->getParamAttrs(Idx)));
|
|
|
|
Idx++;
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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);
|
2007-02-10 05:17:48 +00:00
|
|
|
output_typeid(Table.getTypeSlot(AT->getElementType()));
|
2004-07-25 18:07:36 +00:00
|
|
|
output_vbr(AT->getNumElements());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2004-08-20 06:00:58 +00:00
|
|
|
case Type::PackedTyID: {
|
|
|
|
const PackedType *PT = cast<PackedType>(T);
|
2007-02-10 05:17:48 +00:00
|
|
|
output_typeid(Table.getTypeSlot(PT->getElementType()));
|
2004-08-20 06:00:58 +00:00
|
|
|
output_vbr(PT->getNumElements());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
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) {
|
2007-02-10 05:17:48 +00:00
|
|
|
output_typeid(Table.getTypeSlot(*I));
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Terminate list with VoidTy
|
|
|
|
output_typeid((unsigned)Type::VoidTyID);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-02-10 05:17:48 +00:00
|
|
|
case Type::PointerTyID:
|
|
|
|
output_typeid(Table.getTypeSlot(cast<PointerType>(T)->getElementType()));
|
2004-07-25 18:07:36 +00:00
|
|
|
break;
|
|
|
|
|
2004-10-14 01:35:17 +00:00
|
|
|
case Type::OpaqueTyID:
|
2004-07-25 18:07:36 +00:00
|
|
|
// No need to emit anything, just the count of opaque types is enough.
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2006-12-07 01:30:32 +00:00
|
|
|
cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to serialize"
|
|
|
|
<< " Type '" << T->getDescription() << "'\n";
|
2004-07-25 18:07:36 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void BytecodeWriter::outputConstant(const Constant *CPV) {
|
2007-01-15 02:27:26 +00:00
|
|
|
assert(((CPV->getType()->isPrimitiveType() || CPV->getType()->isInteger()) ||
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
!CPV->isNullValue()) && "Shouldn't output null constants!");
|
2004-07-25 18:07:36 +00:00
|
|
|
|
|
|
|
// We must check for a ConstantExpr before switching by type because
|
|
|
|
// a ConstantExpr can be of any type, and has no explicit value.
|
2005-04-21 21:48:46 +00:00
|
|
|
//
|
2004-07-25 18:07:36 +00:00
|
|
|
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");
|
2006-11-27 01:05:10 +00:00
|
|
|
assert(CE->getNumOperands() != 1 || CE->isCast());
|
2004-10-16 18:18:16 +00:00
|
|
|
output_vbr(1+CE->getNumOperands()); // flags as an expr
|
2006-10-20 07:07:24 +00:00
|
|
|
output_vbr(CE->getOpcode()); // Put out the CE op code
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
for (User::const_op_iterator OI = CE->op_begin(); OI != CE->op_end(); ++OI){
|
2007-02-10 05:17:48 +00:00
|
|
|
output_vbr(Table.getSlot(*OI));
|
|
|
|
output_typeid(Table.getTypeSlot((*OI)->getType()));
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
2006-12-04 05:23:49 +00:00
|
|
|
if (CE->isCompare())
|
|
|
|
output_vbr((unsigned)CE->getPredicate());
|
2004-07-25 18:07:36 +00:00
|
|
|
return;
|
2004-10-16 18:18:16 +00:00
|
|
|
} else if (isa<UndefValue>(CPV)) {
|
|
|
|
output_vbr(1U); // 1 -> UndefValue constant.
|
|
|
|
return;
|
2004-07-25 18:07:36 +00:00
|
|
|
} else {
|
2006-10-20 07:07:24 +00:00
|
|
|
output_vbr(0U); // flag as not a ConstantExpr (i.e. 0 operands)
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
switch (CPV->getType()->getTypeID()) {
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
case Type::IntegerTyID: { // Integer types...
|
|
|
|
unsigned NumBits = cast<IntegerType>(CPV->getType())->getBitWidth();
|
2007-01-12 23:26:17 +00:00
|
|
|
if (NumBits <= 32)
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
output_vbr(uint32_t(cast<ConstantInt>(CPV)->getZExtValue()));
|
|
|
|
else if (NumBits <= 64)
|
|
|
|
output_vbr(uint64_t(cast<ConstantInt>(CPV)->getZExtValue()));
|
|
|
|
else
|
|
|
|
assert("Integer types > 64 bits not supported.");
|
2004-07-25 18:07:36 +00:00
|
|
|
break;
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
}
|
2004-07-25 18:07:36 +00:00
|
|
|
|
|
|
|
case Type::ArrayTyID: {
|
|
|
|
const ConstantArray *CPA = cast<ConstantArray>(CPV);
|
|
|
|
assert(!CPA->isString() && "Constant strings should be handled specially!");
|
|
|
|
|
2007-02-10 05:13:03 +00:00
|
|
|
for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i)
|
|
|
|
output_vbr(Table.getSlot(CPA->getOperand(i)));
|
2004-08-20 06:00:58 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case Type::PackedTyID: {
|
|
|
|
const ConstantPacked *CP = cast<ConstantPacked>(CPV);
|
2007-02-10 05:13:03 +00:00
|
|
|
for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
|
|
|
|
output_vbr(Table.getSlot(CP->getOperand(i)));
|
2004-07-25 18:07:36 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case Type::StructTyID: {
|
|
|
|
const ConstantStruct *CPS = cast<ConstantStruct>(CPV);
|
|
|
|
|
2007-02-10 05:13:03 +00:00
|
|
|
for (unsigned i = 0, e = CPS->getNumOperands(); i != e; ++i)
|
|
|
|
output_vbr(Table.getSlot(CPS->getOperand(i)));
|
2004-07-25 18:07:36 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2005-04-21 21:48:46 +00:00
|
|
|
case Type::VoidTyID:
|
2004-07-25 18:07:36 +00:00
|
|
|
case Type::LabelTyID:
|
|
|
|
default:
|
2006-12-07 01:30:32 +00:00
|
|
|
cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to serialize"
|
|
|
|
<< " type '" << *CPV->getType() << "'\n";
|
2004-07-25 18:07:36 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-01-25 23:08:15 +00:00
|
|
|
/// outputInlineAsm - InlineAsm's get emitted to the constant pool, so they can
|
|
|
|
/// be shared by multiple uses.
|
|
|
|
void BytecodeWriter::outputInlineAsm(const InlineAsm *IA) {
|
|
|
|
// Output a marker, so we know when we have one one parsing the constant pool.
|
|
|
|
// Note that this encoding is 5 bytes: not very efficient for a marker. Since
|
|
|
|
// unique inline asms are rare, this should hardly matter.
|
|
|
|
output_vbr(~0U);
|
|
|
|
|
|
|
|
output(IA->getAsmString());
|
|
|
|
output(IA->getConstraintString());
|
|
|
|
output_vbr(unsigned(IA->hasSideEffects()));
|
|
|
|
}
|
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
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);
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
// Emit all of the strings.
|
|
|
|
for (I = Table.string_begin(); I != E; ++I) {
|
|
|
|
const ConstantArray *Str = *I;
|
2007-02-10 05:17:48 +00:00
|
|
|
output_typeid(Table.getTypeSlot(Str->getType()));
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
// 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 ===//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2005-02-27 06:18:25 +00:00
|
|
|
// outputInstructionFormat0 - Output those weird instructions that have a large
|
2005-05-06 22:34:01 +00:00
|
|
|
// number of operands or have large operands themselves.
|
2004-07-25 18:07:36 +00:00
|
|
|
//
|
|
|
|
// Format: [opcode] [type] [numargs] [arg0] [arg1] ... [arg<numargs-1>]
|
|
|
|
//
|
2004-10-14 01:46:07 +00:00
|
|
|
void BytecodeWriter::outputInstructionFormat0(const Instruction *I,
|
|
|
|
unsigned Opcode,
|
|
|
|
const SlotCalculator &Table,
|
|
|
|
unsigned Type) {
|
2004-07-25 18:07:36 +00:00
|
|
|
// Opcode must have top two bits clear...
|
|
|
|
output_vbr(Opcode << 2); // Instruction Opcode ID
|
|
|
|
output_typeid(Type); // Result type
|
|
|
|
|
|
|
|
unsigned NumArgs = I->getNumOperands();
|
2006-12-06 04:27:07 +00:00
|
|
|
output_vbr(NumArgs + (isa<CastInst>(I) || isa<InvokeInst>(I) ||
|
|
|
|
isa<CmpInst>(I) || isa<VAArgInst>(I) || Opcode == 58));
|
2004-07-25 18:07:36 +00:00
|
|
|
|
|
|
|
if (!isa<GetElementPtrInst>(&I)) {
|
2007-02-10 05:13:03 +00:00
|
|
|
for (unsigned i = 0; i < NumArgs; ++i)
|
|
|
|
output_vbr(Table.getSlot(I->getOperand(i)));
|
2004-07-25 18:07:36 +00:00
|
|
|
|
|
|
|
if (isa<CastInst>(I) || isa<VAArgInst>(I)) {
|
2007-02-10 05:17:48 +00:00
|
|
|
output_typeid(Table.getTypeSlot(I->getType()));
|
2006-12-06 04:27:07 +00:00
|
|
|
} else if (isa<CmpInst>(I)) {
|
|
|
|
output_vbr(unsigned(cast<CmpInst>(I)->getPredicate()));
|
2006-11-27 01:05:10 +00:00
|
|
|
} else if (isa<InvokeInst>(I)) {
|
2005-05-06 22:34:01 +00:00
|
|
|
output_vbr(cast<InvokeInst>(I)->getCallingConv());
|
|
|
|
} else if (Opcode == 58) { // Call escape sequence
|
|
|
|
output_vbr((cast<CallInst>(I)->getCallingConv() << 1) |
|
2005-05-07 02:44:04 +00:00
|
|
|
unsigned(cast<CallInst>(I)->isTailCall()));
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
|
|
|
} else {
|
2007-02-10 05:13:03 +00:00
|
|
|
output_vbr(Table.getSlot(I->getOperand(0)));
|
2004-07-25 18:07:36 +00:00
|
|
|
|
|
|
|
// 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) {
|
2007-02-10 05:13:03 +00:00
|
|
|
unsigned Slot = Table.getSlot(I->getOperand(Idx));
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
if (isa<SequentialType>(*TI)) {
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
// These should be either 32-bits or 64-bits, however, with bit
|
|
|
|
// accurate types we just distinguish between less than or equal to
|
|
|
|
// 32-bits or greater than 32-bits.
|
2007-01-13 00:10:02 +00:00
|
|
|
unsigned BitWidth =
|
|
|
|
cast<IntegerType>(I->getOperand(Idx)->getType())->getBitWidth();
|
|
|
|
assert(BitWidth == 32 || BitWidth == 64 &&
|
|
|
|
"Invalid bitwidth for GEP index");
|
|
|
|
unsigned IdxId = BitWidth == 32 ? 0 : 1;
|
2006-12-31 05:44:24 +00:00
|
|
|
Slot = (Slot << 1) | IdxId;
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
2007-02-10 05:13:03 +00:00
|
|
|
output_vbr(Slot);
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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>]
|
|
|
|
//
|
2005-04-21 21:48:46 +00:00
|
|
|
void BytecodeWriter::outputInstrVarArgsCall(const Instruction *I,
|
|
|
|
unsigned Opcode,
|
|
|
|
const SlotCalculator &Table,
|
|
|
|
unsigned Type) {
|
2004-07-25 18:07:36 +00:00
|
|
|
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;
|
|
|
|
}
|
2006-11-27 01:05:10 +00:00
|
|
|
output_vbr(2 * I->getNumOperands()-NumFixedOperands +
|
|
|
|
unsigned(Opcode == 58 || isa<InvokeInst>(I)));
|
2004-07-25 18:07:36 +00:00
|
|
|
|
|
|
|
// The type for the function has already been emitted in the type field of the
|
|
|
|
// instruction. Just emit the slot # now.
|
2007-02-10 05:13:03 +00:00
|
|
|
for (unsigned i = 0; i != NumFixedOperands; ++i)
|
|
|
|
output_vbr(Table.getSlot(I->getOperand(i)));
|
2004-07-25 18:07:36 +00:00
|
|
|
|
|
|
|
for (unsigned i = NumFixedOperands, e = I->getNumOperands(); i != e; ++i) {
|
|
|
|
// Output Arg Type ID
|
2007-02-10 05:17:48 +00:00
|
|
|
output_typeid(Table.getTypeSlot(I->getOperand(i)->getType()));
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
// Output arg ID itself
|
2007-02-10 05:13:03 +00:00
|
|
|
output_vbr(Table.getSlot(I->getOperand(i)));
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
2006-05-26 18:42:34 +00:00
|
|
|
|
2006-11-27 01:05:10 +00:00
|
|
|
if (isa<InvokeInst>(I)) {
|
|
|
|
// Emit the tail call/calling conv for invoke instructions
|
|
|
|
output_vbr(cast<InvokeInst>(I)->getCallingConv());
|
|
|
|
} else if (Opcode == 58) {
|
2006-05-26 18:42:34 +00:00
|
|
|
const CallInst *CI = cast<CallInst>(I);
|
|
|
|
output_vbr((CI->getCallingConv() << 1) | unsigned(CI->isTailCall()));
|
|
|
|
}
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// outputInstructionFormat1 - Output one operand instructions, knowing that no
|
|
|
|
// operand index is >= 2^12.
|
|
|
|
//
|
2005-04-21 21:48:46 +00:00
|
|
|
inline void BytecodeWriter::outputInstructionFormat1(const Instruction *I,
|
|
|
|
unsigned Opcode,
|
|
|
|
unsigned *Slots,
|
|
|
|
unsigned Type) {
|
2004-07-25 18:07:36 +00:00
|
|
|
// 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)
|
|
|
|
//
|
2004-10-14 01:46:07 +00:00
|
|
|
output(1 | (Opcode << 2) | (Type << 8) | (Slots[0] << 20));
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// outputInstructionFormat2 - Output two operand instructions, knowing that no
|
|
|
|
// operand index is >= 2^8.
|
|
|
|
//
|
2005-04-21 21:48:46 +00:00
|
|
|
inline void BytecodeWriter::outputInstructionFormat2(const Instruction *I,
|
|
|
|
unsigned Opcode,
|
|
|
|
unsigned *Slots,
|
|
|
|
unsigned Type) {
|
2004-07-25 18:07:36 +00:00
|
|
|
// bits Instruction format:
|
|
|
|
// --------------------------
|
|
|
|
// 01-00: Opcode type, fixed to 2.
|
|
|
|
// 07-02: Opcode
|
|
|
|
// 15-08: Resulting type plane
|
|
|
|
// 23-16: Operand #1
|
2005-04-21 21:48:46 +00:00
|
|
|
// 31-24: Operand #2
|
2004-07-25 18:07:36 +00:00
|
|
|
//
|
2004-10-14 01:46:07 +00:00
|
|
|
output(2 | (Opcode << 2) | (Type << 8) | (Slots[0] << 16) | (Slots[1] << 24));
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// outputInstructionFormat3 - Output three operand instructions, knowing that no
|
|
|
|
// operand index is >= 2^6.
|
|
|
|
//
|
2005-04-21 21:48:46 +00:00
|
|
|
inline void BytecodeWriter::outputInstructionFormat3(const Instruction *I,
|
2004-07-25 18:07:36 +00:00
|
|
|
unsigned Opcode,
|
2005-04-21 21:48:46 +00:00
|
|
|
unsigned *Slots,
|
|
|
|
unsigned Type) {
|
2004-07-25 18:07:36 +00:00
|
|
|
// 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
|
|
|
|
//
|
2004-10-14 01:46:07 +00:00
|
|
|
output(3 | (Opcode << 2) | (Type << 8) |
|
2004-10-14 01:57:28 +00:00
|
|
|
(Slots[0] << 14) | (Slots[1] << 20) | (Slots[2] << 26));
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BytecodeWriter::outputInstruction(const Instruction &I) {
|
2006-11-27 01:05:10 +00:00
|
|
|
assert(I.getOpcode() < 57 && "Opcode too big???");
|
2004-07-25 18:07:36 +00:00
|
|
|
unsigned Opcode = I.getOpcode();
|
|
|
|
unsigned NumOperands = I.getNumOperands();
|
|
|
|
|
2005-05-06 06:13:34 +00:00
|
|
|
// Encode 'tail call' as 61, 'volatile load' as 62, and 'volatile store' as
|
|
|
|
// 63.
|
2005-05-06 22:34:01 +00:00
|
|
|
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 (isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) {
|
2004-07-25 18:07:36 +00:00
|
|
|
Opcode = 62;
|
2005-05-06 22:34:01 +00:00
|
|
|
} else if (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()) {
|
2004-07-25 18:07:36 +00:00
|
|
|
Opcode = 63;
|
2005-05-06 22:34:01 +00:00
|
|
|
}
|
2004-07-25 18:07:36 +00:00
|
|
|
|
|
|
|
// 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
|
2005-04-21 21:48:46 +00:00
|
|
|
// we take the type of the instruction itself.
|
2004-07-25 18:07:36 +00:00
|
|
|
//
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2007-02-10 05:17:48 +00:00
|
|
|
unsigned Type = Table.getTypeSlot(Ty);
|
2004-07-25 18:07:36 +00:00
|
|
|
|
|
|
|
// 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
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
for (unsigned i = 0; i != NumOperands; ++i) {
|
2007-02-10 05:13:03 +00:00
|
|
|
unsigned Slot = Table.getSlot(I.getOperand(i));
|
|
|
|
if (Slot > MaxOpSlot) MaxOpSlot = Slot;
|
|
|
|
Slots[i] = Slot;
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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!
|
2007-02-10 04:15:40 +00:00
|
|
|
Slots[1] = Table.getTypeSlot(I.getType());
|
2004-07-25 18:07:36 +00:00
|
|
|
if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1];
|
|
|
|
NumOperands++;
|
2005-11-05 22:08:14 +00:00
|
|
|
} else if (const AllocationInst *AI = dyn_cast<AllocationInst>(&I)) {
|
|
|
|
assert(NumOperands == 1 && "Bogus allocation!");
|
|
|
|
if (AI->getAlignment()) {
|
|
|
|
Slots[1] = Log2_32(AI->getAlignment())+1;
|
|
|
|
if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1];
|
|
|
|
NumOperands = 2;
|
|
|
|
}
|
2006-12-03 06:28:54 +00:00
|
|
|
} else if (isa<ICmpInst>(I) || isa<FCmpInst>(I)) {
|
|
|
|
// We need to encode the compare instruction's predicate as the third
|
|
|
|
// operand. Its not really a slot, but we don't want to break the
|
|
|
|
// instruction format for these instructions.
|
|
|
|
NumOperands++;
|
|
|
|
assert(NumOperands == 3 && "CmpInst with wrong number of operands?");
|
|
|
|
Slots[2] = unsigned(cast<CmpInst>(&I)->getPredicate());
|
|
|
|
if (Slots[2] > MaxOpSlot)
|
|
|
|
MaxOpSlot = Slots[2];
|
2004-07-25 18:07:36 +00:00
|
|
|
} 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)) {
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
// These should be either 32-bits or 64-bits, however, with bit
|
|
|
|
// accurate types we just distinguish between less than or equal to
|
|
|
|
// 32-bits or greater than 32-bits.
|
2007-01-13 00:10:02 +00:00
|
|
|
unsigned BitWidth =
|
|
|
|
cast<IntegerType>(GEP->getOperand(Idx)->getType())->getBitWidth();
|
|
|
|
assert(BitWidth == 32 || BitWidth == 64 &&
|
|
|
|
"Invalid bitwidth for GEP index");
|
|
|
|
unsigned IdxId = BitWidth == 32 ? 0 : 1;
|
2006-12-31 05:44:24 +00:00
|
|
|
Slots[Idx] = (Slots[Idx] << 1) | IdxId;
|
2004-07-25 18:07:36 +00:00
|
|
|
if (Slots[Idx] > MaxOpSlot) MaxOpSlot = Slots[Idx];
|
|
|
|
}
|
2005-05-06 22:34:01 +00:00
|
|
|
} else if (Opcode == 58) {
|
|
|
|
// If this is the escape sequence for call, emit the tailcall/cc info.
|
|
|
|
const CallInst &CI = cast<CallInst>(I);
|
|
|
|
++NumOperands;
|
2006-05-19 21:57:37 +00:00
|
|
|
if (NumOperands <= 3) {
|
|
|
|
Slots[NumOperands-1] =
|
|
|
|
(CI.getCallingConv() << 1)|unsigned(CI.isTailCall());
|
2005-05-06 22:34:01 +00:00
|
|
|
if (Slots[NumOperands-1] > MaxOpSlot)
|
|
|
|
MaxOpSlot = Slots[NumOperands-1];
|
|
|
|
}
|
2006-11-27 01:05:10 +00:00
|
|
|
} else if (isa<InvokeInst>(I)) {
|
2005-05-06 22:34:01 +00:00
|
|
|
// Invoke escape seq has at least 4 operands to encode.
|
|
|
|
++NumOperands;
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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 ===//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2005-04-21 21:48:46 +00:00
|
|
|
BytecodeWriter::BytecodeWriter(std::vector<unsigned char> &o, const Module *M)
|
2004-05-26 07:37:11 +00:00
|
|
|
: Out(o), Table(M) {
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2004-01-14 23:36:54 +00:00
|
|
|
// Emit the signature...
|
2006-07-28 22:07:54 +00:00
|
|
|
static const unsigned char *Sig = (const unsigned char*)"llvm";
|
2004-07-25 18:07:36 +00:00
|
|
|
output_data(Sig, Sig+4);
|
2001-06-06 20:29:01 +00:00
|
|
|
|
|
|
|
// Emit the top level CLASS block.
|
2004-07-25 18:07:36 +00:00
|
|
|
BytecodeBlock ModuleBlock(BytecodeFormat::ModuleBlockID, *this, false, true);
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2007-01-26 08:10:24 +00:00
|
|
|
// Output the version identifier
|
|
|
|
output_vbr(BCVersionNum);
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2004-07-04 11:45:47 +00:00
|
|
|
// The Global type plane comes first
|
2003-03-19 20:56:46 +00:00
|
|
|
{
|
2006-07-28 22:07:54 +00:00
|
|
|
BytecodeBlock CPool(BytecodeFormat::GlobalTypePlaneBlockID, *this);
|
|
|
|
outputTypes(Type::FirstDerivedTyID);
|
2003-03-19 20:56:46 +00:00
|
|
|
}
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2003-03-19 20:56:46 +00:00
|
|
|
// The ModuleInfoBlock follows directly after the type information
|
2001-09-07 16:39:41 +00:00
|
|
|
outputModuleInfoBlock(M);
|
|
|
|
|
2003-03-19 20:56:46 +00:00
|
|
|
// Output module level constants, used for global variable initializers
|
2007-02-09 07:53:20 +00:00
|
|
|
outputConstants();
|
2003-03-19 20:56:46 +00:00
|
|
|
|
2002-04-07 22:49:37 +00:00
|
|
|
// Do the whole module now! Process each function at a time...
|
2002-06-25 16:13:21 +00:00
|
|
|
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
|
2003-03-19 20:56:46 +00:00
|
|
|
outputFunction(I);
|
2001-09-07 16:39:41 +00:00
|
|
|
|
2007-01-06 07:24:44 +00:00
|
|
|
// Output the symbole table for types
|
|
|
|
outputTypeSymbolTable(M->getTypeSymbolTable());
|
|
|
|
|
|
|
|
// Output the symbol table for values
|
|
|
|
outputValueSymbolTable(M->getValueSymbolTable());
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
|
2004-10-14 01:46:07 +00:00
|
|
|
void BytecodeWriter::outputTypes(unsigned TypeNum) {
|
2004-07-04 11:45:47 +00:00
|
|
|
// 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;
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-07-04 11:45:47 +00:00
|
|
|
// Output type header: [num entries]
|
2004-07-25 18:07:36 +00:00
|
|
|
output_vbr(NumEntries);
|
2004-07-04 11:45:47 +00:00
|
|
|
|
|
|
|
for (unsigned i = TypeNum; i < TypeNum+NumEntries; ++i)
|
|
|
|
outputType(Types[i]);
|
|
|
|
}
|
|
|
|
|
2002-07-14 23:07:51 +00:00
|
|
|
// Helper function for outputConstants().
|
|
|
|
// Writes out all the constants in the plane Plane starting at entry StartNo.
|
2005-04-21 21:48:46 +00:00
|
|
|
//
|
2002-07-14 23:07:51 +00:00
|
|
|
void BytecodeWriter::outputConstantsInPlane(const std::vector<const Value*>
|
|
|
|
&Plane, unsigned StartNo) {
|
|
|
|
unsigned ValNo = StartNo;
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-01-14 23:36:54 +00:00
|
|
|
// 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++)
|
2002-07-14 23:07:51 +00:00
|
|
|
/*empty*/;
|
|
|
|
|
|
|
|
unsigned NC = ValNo; // Number of constants
|
2006-01-25 23:08:15 +00:00
|
|
|
for (; NC < Plane.size() && (isa<Constant>(Plane[NC]) ||
|
|
|
|
isa<InlineAsm>(Plane[NC])); NC++)
|
2002-07-14 23:07:51 +00:00
|
|
|
/*empty*/;
|
|
|
|
NC -= ValNo; // Convert from index into count
|
|
|
|
if (NC == 0) return; // Skip empty type planes...
|
|
|
|
|
2004-01-14 16:54:21 +00:00
|
|
|
// FIXME: Most slabs only have 1 or 2 entries! We should encode this much
|
|
|
|
// more compactly.
|
|
|
|
|
2006-10-20 07:07:24 +00:00
|
|
|
// Put out type header: [num entries][type id number]
|
2002-07-14 23:07:51 +00:00
|
|
|
//
|
2004-07-25 18:07:36 +00:00
|
|
|
output_vbr(NC);
|
2002-07-14 23:07:51 +00:00
|
|
|
|
2007-02-10 05:17:48 +00:00
|
|
|
// Put out the Type ID Number.
|
|
|
|
output_typeid(Table.getTypeSlot(Plane.front()->getType()));
|
2002-07-14 23:07:51 +00:00
|
|
|
|
|
|
|
for (unsigned i = ValNo; i < ValNo+NC; ++i) {
|
|
|
|
const Value *V = Plane[i];
|
2006-01-25 23:08:15 +00:00
|
|
|
if (const Constant *C = dyn_cast<Constant>(V))
|
2004-07-18 00:16:21 +00:00
|
|
|
outputConstant(C);
|
2006-01-25 23:08:15 +00:00
|
|
|
else
|
|
|
|
outputInlineAsm(cast<InlineAsm>(V));
|
2002-07-14 23:07:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-05-05 22:21:19 +00:00
|
|
|
static inline bool hasNullValue(const Type *Ty) {
|
|
|
|
return Ty != Type::LabelTy && Ty != Type::VoidTy && !isa<OpaqueType>(Ty);
|
2004-01-17 23:25:43 +00:00
|
|
|
}
|
|
|
|
|
2007-02-09 07:53:20 +00:00
|
|
|
void BytecodeWriter::outputConstants() {
|
2004-07-25 18:07:36 +00:00
|
|
|
BytecodeBlock CPool(BytecodeFormat::ConstantPoolBlockID, *this,
|
2004-01-15 21:06:57 +00:00
|
|
|
true /* Elide block if empty */);
|
2001-06-06 20:29:01 +00:00
|
|
|
|
|
|
|
unsigned NumPlanes = Table.getNumPlanes();
|
2003-03-19 20:56:46 +00:00
|
|
|
|
2007-02-09 07:53:20 +00:00
|
|
|
// Output module-level string constants before any other constants.
|
|
|
|
outputConstantStrings();
|
2004-01-14 23:36:54 +00:00
|
|
|
|
2004-07-04 11:45:47 +00:00
|
|
|
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;
|
2005-05-05 22:21:19 +00:00
|
|
|
if (hasNullValue(Plane[0]->getType())) {
|
2004-07-04 11:46:15 +00:00
|
|
|
// Skip zero initializer
|
2007-02-09 07:53:20 +00:00
|
|
|
ValNo = 1;
|
2003-05-22 18:35:38 +00:00
|
|
|
}
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-07-04 11:45:47 +00:00
|
|
|
// Write out constants in the plane
|
|
|
|
outputConstantsInPlane(Plane, ValNo);
|
2003-05-22 18:35:38 +00:00
|
|
|
}
|
2004-07-04 11:45:47 +00:00
|
|
|
}
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
|
2003-10-16 18:28:50 +00:00
|
|
|
static unsigned getEncodedLinkage(const GlobalValue *GV) {
|
|
|
|
switch (GV->getLinkage()) {
|
|
|
|
default: assert(0 && "Invalid linkage!");
|
2006-09-14 18:23:27 +00:00
|
|
|
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;
|
|
|
|
case GlobalValue::DLLImportLinkage: return 5;
|
|
|
|
case GlobalValue::DLLExportLinkage: return 6;
|
|
|
|
case GlobalValue::ExternalWeakLinkage: return 7;
|
2003-10-16 18:28:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-01-12 19:20:47 +00:00
|
|
|
static unsigned getEncodedVisibility(const GlobalValue *GV) {
|
|
|
|
switch (GV->getVisibility()) {
|
|
|
|
default: assert(0 && "Invalid visibility!");
|
|
|
|
case GlobalValue::DefaultVisibility: return 0;
|
|
|
|
case GlobalValue::HiddenVisibility: return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-06-06 20:29:01 +00:00
|
|
|
void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
|
2004-07-25 18:07:36 +00:00
|
|
|
BytecodeBlock ModuleInfoBlock(BytecodeFormat::ModuleGlobalInfoBlockID, *this);
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2005-11-12 01:33:40 +00:00
|
|
|
// Give numbers to sections as we encounter them.
|
|
|
|
unsigned SectionIDCounter = 0;
|
|
|
|
std::vector<std::string> SectionNames;
|
|
|
|
std::map<std::string, unsigned> SectionID;
|
|
|
|
|
2001-09-10 07:58:01 +00:00
|
|
|
// Output the types for the global variables in the module...
|
2005-05-06 20:27:03 +00:00
|
|
|
for (Module::const_global_iterator I = M->global_begin(),
|
2005-11-06 07:11:04 +00:00
|
|
|
End = M->global_end(); I != End; ++I) {
|
2007-02-10 05:17:48 +00:00
|
|
|
unsigned Slot = Table.getTypeSlot(I->getType());
|
2001-09-18 04:01:05 +00:00
|
|
|
|
2005-11-06 07:11:04 +00:00
|
|
|
assert((I->hasInitializer() || !I->hasInternalLinkage()) &&
|
|
|
|
"Global must have an initializer or have external linkage!");
|
|
|
|
|
2003-10-18 06:30:21 +00:00
|
|
|
// Fields: bit0 = isConstant, bit1 = hasInitializer, bit2-4=Linkage,
|
2005-11-06 07:11:04 +00:00
|
|
|
// bit5+ = Slot # for type.
|
2007-01-12 19:20:47 +00:00
|
|
|
bool HasExtensionWord = (I->getAlignment() != 0) ||
|
|
|
|
I->hasSection() ||
|
|
|
|
(I->getVisibility() != GlobalValue::DefaultVisibility);
|
2005-11-06 07:11:04 +00:00
|
|
|
|
|
|
|
// If we need to use the extension byte, set linkage=3(internal) and
|
|
|
|
// initializer = 0 (impossible!).
|
|
|
|
if (!HasExtensionWord) {
|
2007-02-10 05:17:48 +00:00
|
|
|
unsigned oSlot = (Slot << 5) | (getEncodedLinkage(I) << 2) |
|
2005-11-06 07:11:04 +00:00
|
|
|
(I->hasInitializer() << 1) | (unsigned)I->isConstant();
|
|
|
|
output_vbr(oSlot);
|
2006-09-14 18:23:27 +00:00
|
|
|
} else {
|
2007-02-10 05:17:48 +00:00
|
|
|
unsigned oSlot = (Slot << 5) | (3 << 2) |
|
2005-11-06 07:11:04 +00:00
|
|
|
(0 << 1) | (unsigned)I->isConstant();
|
|
|
|
output_vbr(oSlot);
|
|
|
|
|
|
|
|
// The extension word has this format: bit 0 = has initializer, bit 1-3 =
|
2007-01-12 19:20:47 +00:00
|
|
|
// linkage, bit 4-8 = alignment (log2), bit 9 = has SectionID,
|
|
|
|
// bits 10-12 = visibility, bits 13+ = future use.
|
2005-11-12 01:01:50 +00:00
|
|
|
unsigned ExtWord = (unsigned)I->hasInitializer() |
|
|
|
|
(getEncodedLinkage(I) << 1) |
|
2005-11-12 01:33:40 +00:00
|
|
|
((Log2_32(I->getAlignment())+1) << 4) |
|
2007-01-12 19:20:47 +00:00
|
|
|
((unsigned)I->hasSection() << 9) |
|
|
|
|
(getEncodedVisibility(I) << 10);
|
2005-11-06 07:11:04 +00:00
|
|
|
output_vbr(ExtWord);
|
2005-11-12 01:33:40 +00:00
|
|
|
if (I->hasSection()) {
|
|
|
|
// Give section names unique ID's.
|
|
|
|
unsigned &Entry = SectionID[I->getSection()];
|
|
|
|
if (Entry == 0) {
|
|
|
|
Entry = ++SectionIDCounter;
|
|
|
|
SectionNames.push_back(I->getSection());
|
|
|
|
}
|
|
|
|
output_vbr(Entry);
|
|
|
|
}
|
2005-11-06 07:11:04 +00:00
|
|
|
}
|
2001-09-18 04:01:05 +00:00
|
|
|
|
2001-10-13 06:48:38 +00:00
|
|
|
// If we have an initializer, output it now.
|
2007-02-10 05:13:03 +00:00
|
|
|
if (I->hasInitializer())
|
|
|
|
output_vbr(Table.getSlot((Value*)I->getInitializer()));
|
2001-09-10 07:58:01 +00:00
|
|
|
}
|
2007-02-10 05:17:48 +00:00
|
|
|
output_typeid(Table.getTypeSlot(Type::VoidTy));
|
2001-09-10 07:58:01 +00:00
|
|
|
|
2004-10-16 18:18:16 +00:00
|
|
|
// Output the types of the functions in this module.
|
2001-06-27 23:41:11 +00:00
|
|
|
for (Module::const_iterator I = M->begin(), End = M->end(); I != End; ++I) {
|
2007-02-10 05:17:48 +00:00
|
|
|
unsigned Slot = Table.getTypeSlot(I->getType());
|
2005-11-06 07:43:39 +00:00
|
|
|
assert(((Slot << 6) >> 6) == Slot && "Slot # too big!");
|
2005-11-06 07:46:13 +00:00
|
|
|
unsigned CC = I->getCallingConv()+1;
|
|
|
|
unsigned ID = (Slot << 5) | (CC & 15);
|
2005-05-06 20:42:57 +00:00
|
|
|
|
2007-01-30 20:08:39 +00:00
|
|
|
if (I->isDeclaration()) // If external, we don't have an FunctionInfo block.
|
2004-11-15 22:39:49 +00:00
|
|
|
ID |= 1 << 4;
|
2005-11-06 07:43:39 +00:00
|
|
|
|
2006-09-14 18:23:27 +00:00
|
|
|
if (I->getAlignment() || I->hasSection() || (CC & ~15) != 0 ||
|
2007-01-30 20:08:39 +00:00
|
|
|
(I->isDeclaration() && I->hasDLLImportLinkage()) ||
|
|
|
|
(I->isDeclaration() && I->hasExternalWeakLinkage())
|
2006-09-14 18:23:27 +00:00
|
|
|
)
|
2005-11-06 07:43:39 +00:00
|
|
|
ID |= 1 << 31; // Do we need an extension word?
|
|
|
|
|
2004-10-16 18:18:16 +00:00
|
|
|
output_vbr(ID);
|
2005-11-06 07:43:39 +00:00
|
|
|
|
|
|
|
if (ID & (1 << 31)) {
|
|
|
|
// Extension byte: bits 0-4 = alignment, bits 5-9 = top nibble of calling
|
2006-09-14 18:23:27 +00:00
|
|
|
// convention, bit 10 = hasSectionID., bits 11-12 = external linkage type
|
|
|
|
unsigned extLinkage = 0;
|
|
|
|
|
2007-01-30 20:08:39 +00:00
|
|
|
if (I->isDeclaration()) {
|
2006-09-14 18:23:27 +00:00
|
|
|
if (I->hasDLLImportLinkage()) {
|
|
|
|
extLinkage = 1;
|
|
|
|
} else if (I->hasExternalWeakLinkage()) {
|
|
|
|
extLinkage = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-11-12 01:33:40 +00:00
|
|
|
ID = (Log2_32(I->getAlignment())+1) | ((CC >> 4) << 5) |
|
2006-09-14 18:23:27 +00:00
|
|
|
(I->hasSection() << 10) |
|
|
|
|
((extLinkage & 3) << 11);
|
2005-11-06 07:43:39 +00:00
|
|
|
output_vbr(ID);
|
2005-11-12 01:33:40 +00:00
|
|
|
|
|
|
|
// Give section names unique ID's.
|
|
|
|
if (I->hasSection()) {
|
|
|
|
unsigned &Entry = SectionID[I->getSection()];
|
|
|
|
if (Entry == 0) {
|
|
|
|
Entry = ++SectionIDCounter;
|
|
|
|
SectionNames.push_back(I->getSection());
|
|
|
|
}
|
|
|
|
output_vbr(Entry);
|
|
|
|
}
|
2005-11-06 07:43:39 +00:00
|
|
|
}
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
2007-02-10 05:17:48 +00:00
|
|
|
output_vbr(Table.getTypeSlot(Type::VoidTy) << 5);
|
2004-07-25 18:07:36 +00:00
|
|
|
|
2004-10-16 18:18:16 +00:00
|
|
|
// Emit the list of dependent libraries for the Module.
|
2004-07-25 21:32:02 +00:00
|
|
|
Module::lib_iterator LI = M->lib_begin();
|
|
|
|
Module::lib_iterator LE = M->lib_end();
|
2004-10-16 18:18:16 +00:00
|
|
|
output_vbr(unsigned(LE - LI)); // Emit the number of dependent libraries.
|
|
|
|
for (; LI != LE; ++LI)
|
2004-08-17 07:45:14 +00:00
|
|
|
output(*LI);
|
2004-07-25 18:07:36 +00:00
|
|
|
|
|
|
|
// Output the target triple from the module
|
2004-08-17 07:45:14 +00:00
|
|
|
output(M->getTargetTriple());
|
2007-01-26 08:10:24 +00:00
|
|
|
|
|
|
|
// Output the data layout from the module
|
|
|
|
output(M->getDataLayout());
|
2005-11-12 01:33:40 +00:00
|
|
|
|
|
|
|
// Emit the table of section names.
|
|
|
|
output_vbr((unsigned)SectionNames.size());
|
|
|
|
for (unsigned i = 0, e = SectionNames.size(); i != e; ++i)
|
|
|
|
output(SectionNames[i]);
|
2006-01-23 23:43:17 +00:00
|
|
|
|
|
|
|
// Output the inline asm string.
|
2006-01-24 04:14:29 +00:00
|
|
|
output(M->getModuleInlineAsm());
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
|
2004-01-18 21:08:52 +00:00
|
|
|
void BytecodeWriter::outputInstructions(const Function *F) {
|
2004-07-25 18:07:36 +00:00
|
|
|
BytecodeBlock ILBlock(BytecodeFormat::InstructionListBlockID, *this);
|
2004-01-18 21:08:52 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2003-03-19 20:56:46 +00:00
|
|
|
void BytecodeWriter::outputFunction(const Function *F) {
|
2004-11-15 21:56:33 +00:00
|
|
|
// If this is an external function, there is nothing else to emit!
|
2007-01-30 20:08:39 +00:00
|
|
|
if (F->isDeclaration()) return;
|
2004-11-15 21:56:33 +00:00
|
|
|
|
2004-11-15 22:39:49 +00:00
|
|
|
BytecodeBlock FunctionBlock(BytecodeFormat::FunctionBlockID, *this);
|
2007-01-12 19:20:47 +00:00
|
|
|
unsigned rWord = (getEncodedVisibility(F) << 16) | getEncodedLinkage(F);
|
|
|
|
output_vbr(rWord);
|
2004-11-15 22:39:49 +00:00
|
|
|
|
2004-01-18 21:08:52 +00:00
|
|
|
// Get slot information about the function...
|
|
|
|
Table.incorporateFunction(F);
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2004-01-18 21:08:52 +00:00
|
|
|
// Output all of the instructions in the body of the function
|
|
|
|
outputInstructions(F);
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-01-18 21:08:52 +00:00
|
|
|
// If needed, output the symbol table for the function...
|
2007-01-06 07:24:44 +00:00
|
|
|
outputValueSymbolTable(F->getValueSymbolTable());
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-01-18 21:08:52 +00:00
|
|
|
Table.purgeFunction();
|
|
|
|
}
|
|
|
|
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2007-01-06 07:24:44 +00:00
|
|
|
void BytecodeWriter::outputTypeSymbolTable(const TypeSymbolTable &TST) {
|
|
|
|
// Do not output the block for an empty symbol table, it just wastes
|
2004-01-10 19:56:59 +00:00
|
|
|
// space!
|
2007-01-06 07:24:44 +00:00
|
|
|
if (TST.empty()) return;
|
2004-01-10 19:56:59 +00:00
|
|
|
|
2007-01-06 07:24:44 +00:00
|
|
|
// Create a header for the symbol table
|
|
|
|
BytecodeBlock SymTabBlock(BytecodeFormat::TypeSymbolTableBlockID, *this,
|
2004-10-14 01:46:07 +00:00
|
|
|
true/*ElideIfEmpty*/);
|
2005-04-21 21:48:46 +00:00
|
|
|
// Write the number of types
|
2007-01-06 07:24:44 +00:00
|
|
|
output_vbr(TST.size());
|
2004-08-17 02:59:02 +00:00
|
|
|
|
|
|
|
// Write each of the types
|
2007-01-06 07:24:44 +00:00
|
|
|
for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end();
|
|
|
|
TI != TE; ++TI) {
|
2004-08-17 02:59:02 +00:00
|
|
|
// Symtab entry:[def slot #][name]
|
2007-02-10 05:17:48 +00:00
|
|
|
output_typeid(Table.getTypeSlot(TI->second));
|
2005-04-21 21:48:46 +00:00
|
|
|
output(TI->first);
|
2004-05-25 17:29:59 +00:00
|
|
|
}
|
2007-01-06 07:24:44 +00:00
|
|
|
}
|
|
|
|
|
2007-02-05 20:47:22 +00:00
|
|
|
void BytecodeWriter::outputValueSymbolTable(const ValueSymbolTable &VST) {
|
2007-01-06 07:24:44 +00:00
|
|
|
// Do not output the Bytecode block for an empty symbol table, it just wastes
|
|
|
|
// space!
|
2007-02-05 20:47:22 +00:00
|
|
|
if (VST.empty()) return;
|
2007-01-06 07:24:44 +00:00
|
|
|
|
|
|
|
BytecodeBlock SymTabBlock(BytecodeFormat::ValueSymbolTableBlockID, *this,
|
|
|
|
true/*ElideIfEmpty*/);
|
2004-05-25 17:29:59 +00:00
|
|
|
|
2007-02-05 20:47:22 +00:00
|
|
|
// Organize the symbol table by type
|
|
|
|
typedef std::pair<std::string, const Value*> PlaneMapEntry;
|
|
|
|
typedef std::vector<PlaneMapEntry> PlaneMapVector;
|
|
|
|
typedef std::map<const Type*, PlaneMapVector > PlaneMap;
|
|
|
|
PlaneMap Planes;
|
|
|
|
for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end();
|
|
|
|
SI != SE; ++SI)
|
|
|
|
Planes[SI->second->getType()].push_back(
|
|
|
|
std::make_pair(SI->first,SI->second));
|
|
|
|
|
|
|
|
for (PlaneMap::const_iterator PI = Planes.begin(), PE = Planes.end();
|
|
|
|
PI != PE; ++PI) {
|
|
|
|
PlaneMapVector::const_iterator I = PI->second.begin();
|
|
|
|
PlaneMapVector::const_iterator End = PI->second.end();
|
|
|
|
|
2001-06-06 20:29:01 +00:00
|
|
|
if (I == End) continue; // Don't mess with an absent type...
|
|
|
|
|
2004-08-17 02:59:02 +00:00
|
|
|
// Write the number of values in this plane
|
2005-03-07 02:59:36 +00:00
|
|
|
output_vbr((unsigned)PI->second.size());
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2004-08-17 02:59:02 +00:00
|
|
|
// Write the slot number of the type for this plane
|
2007-02-10 05:17:48 +00:00
|
|
|
output_typeid(Table.getTypeSlot(PI->first));
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2004-08-17 02:59:02 +00:00
|
|
|
// Write each of the values in this plane
|
2001-06-27 23:41:11 +00:00
|
|
|
for (; I != End; ++I) {
|
2001-06-06 20:29:01 +00:00
|
|
|
// Symtab entry: [def slot #][name]
|
2007-02-10 05:13:03 +00:00
|
|
|
output_vbr(Table.getSlot(I->second));
|
2004-08-17 07:45:14 +00:00
|
|
|
output(I->first);
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-12-07 01:30:32 +00:00
|
|
|
void llvm::WriteBytecodeToFile(const Module *M, OStream &Out,
|
2006-07-28 22:07:54 +00:00
|
|
|
bool compress) {
|
2004-07-25 18:07:36 +00:00
|
|
|
assert(M && "You can't write a null module!!");
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2006-06-07 23:18:34 +00:00
|
|
|
// Make sure that std::cout is put into binary mode for systems
|
|
|
|
// that care.
|
2006-12-07 01:30:32 +00:00
|
|
|
if (Out == cout)
|
2006-06-07 23:18:34 +00:00
|
|
|
sys::Program::ChangeStdoutToBinary();
|
|
|
|
|
2004-11-06 23:17:23 +00:00
|
|
|
// 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).
|
2004-07-25 18:07:36 +00:00
|
|
|
std::vector<unsigned char> Buffer;
|
2004-11-06 23:17:23 +00:00
|
|
|
Buffer.reserve(256 * 1024);
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2004-11-06 23:17:23 +00:00
|
|
|
// The BytecodeWriter populates Buffer for us.
|
2004-07-25 18:07:36 +00:00
|
|
|
BytecodeWriter BCW(Buffer, M);
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2004-11-06 23:17:23 +00:00
|
|
|
// Keep track of how much we've written
|
2002-07-26 18:40:14 +00:00
|
|
|
BytesWritten += Buffer.size();
|
|
|
|
|
2004-11-06 23:17:23 +00:00
|
|
|
// Determine start and end points of the Buffer
|
2004-11-07 18:17:38 +00:00
|
|
|
const unsigned char *FirstByte = &Buffer.front();
|
2004-11-06 23:17:23 +00:00
|
|
|
|
|
|
|
// If we're supposed to compress this mess ...
|
|
|
|
if (compress) {
|
|
|
|
|
|
|
|
// We signal compression by using an alternate magic number for the
|
2004-11-07 18:17:38 +00:00
|
|
|
// file. The compressed bytecode file's magic number is "llvc" instead
|
2005-04-21 21:48:46 +00:00
|
|
|
// of "llvm".
|
2004-11-07 18:17:38 +00:00
|
|
|
char compressed_magic[4];
|
|
|
|
compressed_magic[0] = 'l';
|
|
|
|
compressed_magic[1] = 'l';
|
|
|
|
compressed_magic[2] = 'v';
|
|
|
|
compressed_magic[3] = 'c';
|
2004-11-06 23:17:23 +00:00
|
|
|
|
2006-11-29 00:19:40 +00:00
|
|
|
Out.stream()->write(compressed_magic,4);
|
2004-11-06 23:17:23 +00:00
|
|
|
|
2004-11-14 22:01:41 +00:00
|
|
|
// Compress everything after the magic number (which we altered)
|
2006-11-02 20:25:50 +00:00
|
|
|
Compressor::compressToStream(
|
2004-11-06 23:17:23 +00:00
|
|
|
(char*)(FirstByte+4), // Skip the magic number
|
|
|
|
Buffer.size()-4, // Skip the magic number
|
2006-11-29 00:19:40 +00:00
|
|
|
*Out.stream() // Where to write compressed data
|
2004-11-06 23:17:23 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// We're not compressing, so just write the entire block.
|
2006-11-29 00:19:40 +00:00
|
|
|
Out.stream()->write((char*)FirstByte, Buffer.size());
|
2001-09-07 16:39:41 +00:00
|
|
|
}
|
2004-11-06 23:17:23 +00:00
|
|
|
|
|
|
|
// make sure it hits disk now
|
2006-11-29 00:19:40 +00:00
|
|
|
Out.stream()->flush();
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|