2001-10-24 01:15:12 +00:00
|
|
|
//===- Reader.cpp - Code to read bytecode files ---------------------------===//
|
2005-04-21 21:44:41 +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:44:41 +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/Reader.h
|
|
|
|
//
|
2005-04-21 21:44:41 +00:00
|
|
|
// Note that this library should be as fast as possible, reentrant, and
|
2001-06-06 20:29:01 +00:00
|
|
|
// threadsafe!!
|
|
|
|
//
|
|
|
|
// TODO: Allow passing in an option to ignore the symbol table
|
|
|
|
//
|
2001-10-24 01:15:12 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
#include "Reader.h"
|
|
|
|
#include "llvm/Bytecode/BytecodeHandler.h"
|
|
|
|
#include "llvm/BasicBlock.h"
|
2005-05-06 22:34:01 +00:00
|
|
|
#include "llvm/CallingConv.h"
|
2004-06-29 23:29:38 +00:00
|
|
|
#include "llvm/Constants.h"
|
2006-01-25 23:08:15 +00:00
|
|
|
#include "llvm/InlineAsm.h"
|
2004-07-04 11:33:49 +00:00
|
|
|
#include "llvm/Instructions.h"
|
2007-01-06 07:24:44 +00:00
|
|
|
#include "llvm/TypeSymbolTable.h"
|
2001-06-06 20:29:01 +00:00
|
|
|
#include "llvm/Bytecode/Format.h"
|
2005-05-06 22:34:01 +00:00
|
|
|
#include "llvm/Config/alloca.h"
|
2004-06-29 23:29:38 +00:00
|
|
|
#include "llvm/Support/GetElementPtrTypeIterator.h"
|
2005-08-17 19:34:49 +00:00
|
|
|
#include "llvm/Support/MathExtras.h"
|
2007-01-31 19:56:15 +00:00
|
|
|
#include "llvm/ADT/SmallVector.h"
|
2004-09-01 22:55:40 +00:00
|
|
|
#include "llvm/ADT/StringExtras.h"
|
2004-06-29 23:29:38 +00:00
|
|
|
#include <sstream>
|
2004-09-03 18:19:51 +00:00
|
|
|
#include <algorithm>
|
2003-11-19 17:27:18 +00:00
|
|
|
using namespace llvm;
|
2003-11-11 22:41:34 +00:00
|
|
|
|
2004-07-11 17:28:43 +00:00
|
|
|
namespace {
|
2005-01-29 00:36:19 +00:00
|
|
|
/// @brief A class for maintaining the slot number definition
|
|
|
|
/// as a placeholder for the actual definition for forward constants defs.
|
|
|
|
class ConstantPlaceHolder : public ConstantExpr {
|
|
|
|
ConstantPlaceHolder(); // DO NOT IMPLEMENT
|
|
|
|
void operator=(const ConstantPlaceHolder &); // DO NOT IMPLEMENT
|
|
|
|
public:
|
2005-01-31 01:11:13 +00:00
|
|
|
Use Op;
|
2005-04-21 21:44:41 +00:00
|
|
|
ConstantPlaceHolder(const Type *Ty)
|
2005-01-31 01:11:13 +00:00
|
|
|
: ConstantExpr(Ty, Instruction::UserOp1, &Op, 1),
|
2006-12-31 05:44:24 +00:00
|
|
|
Op(UndefValue::get(Type::Int32Ty), this) {
|
2005-01-31 01:11:13 +00:00
|
|
|
}
|
2005-01-29 00:36:19 +00:00
|
|
|
};
|
2004-07-11 17:28:43 +00:00
|
|
|
}
|
2003-10-04 20:00:03 +00:00
|
|
|
|
2004-07-09 22:21:33 +00:00
|
|
|
// Provide some details on error
|
2006-08-22 16:09:19 +00:00
|
|
|
inline void BytecodeReader::error(const std::string& err) {
|
|
|
|
ErrorMsg = err + " (Vers=" + itostr(RevisionNum) + ", Pos="
|
|
|
|
+ itostr(At-MemStart) + ")";
|
2007-02-05 20:47:22 +00:00
|
|
|
if (Handler) Handler->handleError(ErrorMsg);
|
2006-08-22 16:09:19 +00:00
|
|
|
longjmp(context,1);
|
2004-07-09 22:21:33 +00:00
|
|
|
}
|
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Bytecode Reading Methods
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Determine if the current block being read contains any more data.
|
2004-06-29 23:29:38 +00:00
|
|
|
inline bool BytecodeReader::moreInBlock() {
|
|
|
|
return At < BlockEnd;
|
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Throw an error if we've read past the end of the current block
|
2004-06-29 23:29:38 +00:00
|
|
|
inline void BytecodeReader::checkPastBlockEnd(const char * block_name) {
|
2004-07-11 17:28:43 +00:00
|
|
|
if (At > BlockEnd)
|
2004-10-16 18:18:16 +00:00
|
|
|
error(std::string("Attempt to read past the end of ") + block_name +
|
|
|
|
" block.");
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Read a whole unsigned integer
|
2004-06-29 23:29:38 +00:00
|
|
|
inline unsigned BytecodeReader::read_uint() {
|
2005-04-21 21:44:41 +00:00
|
|
|
if (At+4 > BlockEnd)
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Ran out of data reading uint!");
|
2004-06-29 23:29:38 +00:00
|
|
|
At += 4;
|
|
|
|
return At[-4] | (At[-3] << 8) | (At[-2] << 16) | (At[-1] << 24);
|
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Read a variable-bit-rate encoded unsigned integer
|
2004-06-29 23:29:38 +00:00
|
|
|
inline unsigned BytecodeReader::read_vbr_uint() {
|
|
|
|
unsigned Shift = 0;
|
|
|
|
unsigned Result = 0;
|
2005-04-21 21:44:41 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
do {
|
2005-04-21 21:44:41 +00:00
|
|
|
if (At == BlockEnd)
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Ran out of data reading vbr_uint!");
|
2004-06-29 23:29:38 +00:00
|
|
|
Result |= (unsigned)((*At++) & 0x7F) << Shift;
|
|
|
|
Shift += 7;
|
|
|
|
} while (At[-1] & 0x80);
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Read a variable-bit-rate encoded unsigned 64-bit integer.
|
2004-06-29 23:29:38 +00:00
|
|
|
inline uint64_t BytecodeReader::read_vbr_uint64() {
|
|
|
|
unsigned Shift = 0;
|
|
|
|
uint64_t Result = 0;
|
2005-04-21 21:44:41 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
do {
|
2005-04-21 21:44:41 +00:00
|
|
|
if (At == BlockEnd)
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Ran out of data reading vbr_uint64!");
|
2004-06-29 23:29:38 +00:00
|
|
|
Result |= (uint64_t)((*At++) & 0x7F) << Shift;
|
|
|
|
Shift += 7;
|
|
|
|
} while (At[-1] & 0x80);
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Read a variable-bit-rate encoded signed 64-bit integer.
|
2004-06-29 23:29:38 +00:00
|
|
|
inline int64_t BytecodeReader::read_vbr_int64() {
|
|
|
|
uint64_t R = read_vbr_uint64();
|
|
|
|
if (R & 1) {
|
|
|
|
if (R != 1)
|
|
|
|
return -(int64_t)(R >> 1);
|
|
|
|
else // There is no such thing as -0 with integers. "-0" really means
|
|
|
|
// 0x8000000000000000.
|
|
|
|
return 1LL << 63;
|
|
|
|
} else
|
|
|
|
return (int64_t)(R >> 1);
|
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Read a pascal-style string (length followed by text)
|
2004-06-29 23:29:38 +00:00
|
|
|
inline std::string BytecodeReader::read_str() {
|
|
|
|
unsigned Size = read_vbr_uint();
|
|
|
|
const unsigned char *OldAt = At;
|
|
|
|
At += Size;
|
|
|
|
if (At > BlockEnd) // Size invalid?
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Ran out of data reading a string!");
|
2004-06-29 23:29:38 +00:00
|
|
|
return std::string((char*)OldAt, Size);
|
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Read an arbitrary block of data
|
2004-06-29 23:29:38 +00:00
|
|
|
inline void BytecodeReader::read_data(void *Ptr, void *End) {
|
|
|
|
unsigned char *Start = (unsigned char *)Ptr;
|
|
|
|
unsigned Amount = (unsigned char *)End - Start;
|
2005-04-21 21:44:41 +00:00
|
|
|
if (At+Amount > BlockEnd)
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Ran out of data!");
|
2004-06-29 23:29:38 +00:00
|
|
|
std::copy(At, At+Amount, Start);
|
|
|
|
At += Amount;
|
|
|
|
}
|
|
|
|
|
2004-07-11 17:28:43 +00:00
|
|
|
/// Read a float value in little-endian order
|
|
|
|
inline void BytecodeReader::read_float(float& FloatVal) {
|
2004-07-25 21:36:26 +00:00
|
|
|
/// 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
|
|
|
FloatVal = BitsToFloat(At[0] | (At[1] << 8) | (At[2] << 16) | (At[3] << 24));
|
2004-07-25 21:36:26 +00:00
|
|
|
At+=sizeof(uint32_t);
|
2004-07-11 17:28:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Read a double value in little-endian order
|
|
|
|
inline void BytecodeReader::read_double(double& DoubleVal) {
|
2004-07-25 21:36:26 +00:00
|
|
|
/// 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
|
|
|
DoubleVal = BitsToDouble((uint64_t(At[0]) << 0) | (uint64_t(At[1]) << 8) |
|
|
|
|
(uint64_t(At[2]) << 16) | (uint64_t(At[3]) << 24) |
|
|
|
|
(uint64_t(At[4]) << 32) | (uint64_t(At[5]) << 40) |
|
|
|
|
(uint64_t(At[6]) << 48) | (uint64_t(At[7]) << 56));
|
2004-07-25 21:36:26 +00:00
|
|
|
At+=sizeof(uint64_t);
|
2004-07-11 17:28:43 +00:00
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Read a block header and obtain its type and size
|
2004-06-29 23:29:38 +00:00
|
|
|
inline void BytecodeReader::read_block(unsigned &Type, unsigned &Size) {
|
2006-11-14 04:47:22 +00:00
|
|
|
Size = read_uint(); // Read the header
|
|
|
|
Type = Size & 0x1F; // mask low order five bits to get type
|
|
|
|
Size >>= 5; // high order 27 bits is the size
|
2004-06-29 23:29:38 +00:00
|
|
|
BlockStart = At;
|
2004-07-11 17:28:43 +00:00
|
|
|
if (At + Size > BlockEnd)
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Attempt to size a block past end of memory");
|
2004-06-29 23:29:38 +00:00
|
|
|
BlockEnd = At + Size;
|
2004-07-11 17:28:43 +00:00
|
|
|
if (Handler) Handler->handleBlock(Type, BlockStart, Size);
|
2004-07-04 11:33:49 +00:00
|
|
|
}
|
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// IR Lookup Methods
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Determine if a type id has an implicit null value
|
2004-07-11 17:28:43 +00:00
|
|
|
inline bool BytecodeReader::hasImplicitNull(unsigned TyID) {
|
2006-11-14 04:47:22 +00:00
|
|
|
return TyID != Type::LabelTyID && TyID != Type::VoidTyID;
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
|
|
|
|
Bye, Bye Compaction Tables. The benefit compaction tables provides doesn't
outweight its computational costs. This patch removes all compaction
table handling from the bcreader and bcwriter. For the record, here's the
difference betweeen having and not having compaction tables for some tests:
Test With Without Size Chg
Olden/mst 5,602 5,598 +0.1%
viterbi 18,026 17,795 +1.3%
obsequi 162,133 166,663 -2.8%
burg 224,090 228,148 -1.8%
kimwitu++ 4,933,263 5,121,159 -3.8%
176.gcc 8,470,424 9,141,539 -7.3%
It seems that it is more beneficial to larger files, but even on the largest
test case we have (176.gcc) it only amounts ot an I/O saving of 7.3%.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33661 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-30 19:36:46 +00:00
|
|
|
/// Obtain a type given a typeid and account for things like function level vs
|
|
|
|
/// module level, and the offsetting for the primitive types.
|
2004-06-29 23:29:38 +00:00
|
|
|
const Type *BytecodeReader::getType(unsigned ID) {
|
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 (ID <= Type::LastPrimitiveTyID)
|
2004-06-17 18:19:28 +00:00
|
|
|
if (const Type *T = Type::getPrimitiveType((Type::TypeID)ID))
|
2003-10-09 20:22:47 +00:00
|
|
|
return T; // Asked for a primitive type...
|
2003-10-08 21:18:57 +00:00
|
|
|
|
|
|
|
// Otherwise, derived types need offset...
|
2004-01-18 21:08:15 +00:00
|
|
|
ID -= Type::FirstDerivedTyID;
|
|
|
|
|
2003-10-08 21:18:57 +00:00
|
|
|
// Is it a module-level type?
|
2004-07-11 17:28:43 +00:00
|
|
|
if (ID < ModuleTypes.size())
|
|
|
|
return ModuleTypes[ID].get();
|
2003-10-08 21:18:57 +00:00
|
|
|
|
2004-07-11 17:28:43 +00:00
|
|
|
// Nope, is it a function-level type?
|
|
|
|
ID -= ModuleTypes.size();
|
|
|
|
if (ID < FunctionTypes.size())
|
|
|
|
return FunctionTypes[ID].get();
|
2003-10-08 21:18:57 +00:00
|
|
|
|
2004-07-11 17:28:43 +00:00
|
|
|
error("Illegal type reference!");
|
|
|
|
return Type::VoidTy;
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
|
2006-12-03 05:47:10 +00:00
|
|
|
/// This method just saves some coding. It uses read_vbr_uint to read in a
|
|
|
|
/// type id, errors that its not the type type, and then calls getType to
|
|
|
|
/// return the type value.
|
2006-11-14 04:47:22 +00:00
|
|
|
inline const Type* BytecodeReader::readType() {
|
|
|
|
return getType(read_vbr_uint());
|
2004-07-04 11:33:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the slot number associated with a type accounting for primitive
|
Bye, Bye Compaction Tables. The benefit compaction tables provides doesn't
outweight its computational costs. This patch removes all compaction
table handling from the bcreader and bcwriter. For the record, here's the
difference betweeen having and not having compaction tables for some tests:
Test With Without Size Chg
Olden/mst 5,602 5,598 +0.1%
viterbi 18,026 17,795 +1.3%
obsequi 162,133 166,663 -2.8%
burg 224,090 228,148 -1.8%
kimwitu++ 4,933,263 5,121,159 -3.8%
176.gcc 8,470,424 9,141,539 -7.3%
It seems that it is more beneficial to larger files, but even on the largest
test case we have (176.gcc) it only amounts ot an I/O saving of 7.3%.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33661 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-30 19:36:46 +00:00
|
|
|
/// types and function level vs module level.
|
2004-06-29 23:29:38 +00:00
|
|
|
unsigned BytecodeReader::getTypeSlot(const Type *Ty) {
|
|
|
|
if (Ty->isPrimitiveType())
|
|
|
|
return Ty->getTypeID();
|
2004-01-17 23:25:43 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
// Check the function level types first...
|
2004-10-16 18:18:16 +00:00
|
|
|
TypeListTy::iterator I = std::find(FunctionTypes.begin(),
|
|
|
|
FunctionTypes.end(), Ty);
|
2003-11-19 17:27:18 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
if (I != FunctionTypes.end())
|
2005-04-21 21:44:41 +00:00
|
|
|
return Type::FirstDerivedTyID + ModuleTypes.size() +
|
2004-07-11 17:28:43 +00:00
|
|
|
(&*I - &FunctionTypes[0]);
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2005-10-03 21:26:53 +00:00
|
|
|
// If we don't have our cache yet, build it now.
|
|
|
|
if (ModuleTypeIDCache.empty()) {
|
|
|
|
unsigned N = 0;
|
|
|
|
ModuleTypeIDCache.reserve(ModuleTypes.size());
|
|
|
|
for (TypeListTy::iterator I = ModuleTypes.begin(), E = ModuleTypes.end();
|
|
|
|
I != E; ++I, ++N)
|
|
|
|
ModuleTypeIDCache.push_back(std::make_pair(*I, N));
|
|
|
|
|
|
|
|
std::sort(ModuleTypeIDCache.begin(), ModuleTypeIDCache.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Binary search the cache for the entry.
|
|
|
|
std::vector<std::pair<const Type*, unsigned> >::iterator IT =
|
|
|
|
std::lower_bound(ModuleTypeIDCache.begin(), ModuleTypeIDCache.end(),
|
|
|
|
std::make_pair(Ty, 0U));
|
|
|
|
if (IT == ModuleTypeIDCache.end() || IT->first != Ty)
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Didn't find type in ModuleTypes.");
|
2005-10-03 21:26:53 +00:00
|
|
|
|
|
|
|
return Type::FirstDerivedTyID + IT->second;
|
2003-03-19 20:54:26 +00:00
|
|
|
}
|
|
|
|
|
2005-04-21 21:44:41 +00:00
|
|
|
/// Retrieve a value of a given type and slot number, possibly creating
|
|
|
|
/// it if it doesn't already exist.
|
2004-06-29 23:29:38 +00:00
|
|
|
Value * BytecodeReader::getValue(unsigned type, unsigned oNum, bool Create) {
|
2003-10-08 22:52:54 +00:00
|
|
|
assert(type != Type::LabelTyID && "getValue() cannot get blocks!");
|
2003-10-08 21:18:57 +00:00
|
|
|
unsigned Num = oNum;
|
2001-06-06 20:29:01 +00:00
|
|
|
|
Bye, Bye Compaction Tables. The benefit compaction tables provides doesn't
outweight its computational costs. This patch removes all compaction
table handling from the bcreader and bcwriter. For the record, here's the
difference betweeen having and not having compaction tables for some tests:
Test With Without Size Chg
Olden/mst 5,602 5,598 +0.1%
viterbi 18,026 17,795 +1.3%
obsequi 162,133 166,663 -2.8%
burg 224,090 228,148 -1.8%
kimwitu++ 4,933,263 5,121,159 -3.8%
176.gcc 8,470,424 9,141,539 -7.3%
It seems that it is more beneficial to larger files, but even on the largest
test case we have (176.gcc) it only amounts ot an I/O saving of 7.3%.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33661 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-30 19:36:46 +00:00
|
|
|
// By default, the global type id is the type id passed in
|
|
|
|
unsigned GlobalTyID = type;
|
2004-01-18 21:08:15 +00:00
|
|
|
|
Bye, Bye Compaction Tables. The benefit compaction tables provides doesn't
outweight its computational costs. This patch removes all compaction
table handling from the bcreader and bcwriter. For the record, here's the
difference betweeen having and not having compaction tables for some tests:
Test With Without Size Chg
Olden/mst 5,602 5,598 +0.1%
viterbi 18,026 17,795 +1.3%
obsequi 162,133 166,663 -2.8%
burg 224,090 228,148 -1.8%
kimwitu++ 4,933,263 5,121,159 -3.8%
176.gcc 8,470,424 9,141,539 -7.3%
It seems that it is more beneficial to larger files, but even on the largest
test case we have (176.gcc) it only amounts ot an I/O saving of 7.3%.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33661 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-30 19:36:46 +00:00
|
|
|
if (hasImplicitNull(GlobalTyID)) {
|
|
|
|
const Type *Ty = getType(type);
|
|
|
|
if (!isa<OpaqueType>(Ty)) {
|
|
|
|
if (Num == 0)
|
|
|
|
return Constant::getNullValue(Ty);
|
|
|
|
--Num;
|
2004-01-18 21:08:15 +00:00
|
|
|
}
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
|
Bye, Bye Compaction Tables. The benefit compaction tables provides doesn't
outweight its computational costs. This patch removes all compaction
table handling from the bcreader and bcwriter. For the record, here's the
difference betweeen having and not having compaction tables for some tests:
Test With Without Size Chg
Olden/mst 5,602 5,598 +0.1%
viterbi 18,026 17,795 +1.3%
obsequi 162,133 166,663 -2.8%
burg 224,090 228,148 -1.8%
kimwitu++ 4,933,263 5,121,159 -3.8%
176.gcc 8,470,424 9,141,539 -7.3%
It seems that it is more beneficial to larger files, but even on the largest
test case we have (176.gcc) it only amounts ot an I/O saving of 7.3%.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33661 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-30 19:36:46 +00:00
|
|
|
if (GlobalTyID < ModuleValues.size() && ModuleValues[GlobalTyID]) {
|
|
|
|
if (Num < ModuleValues[GlobalTyID]->size())
|
|
|
|
return ModuleValues[GlobalTyID]->getOperand(Num);
|
|
|
|
Num -= ModuleValues[GlobalTyID]->size();
|
|
|
|
}
|
|
|
|
|
2005-04-21 21:44:41 +00:00
|
|
|
if (FunctionValues.size() > type &&
|
|
|
|
FunctionValues[type] &&
|
2004-06-29 23:29:38 +00:00
|
|
|
Num < FunctionValues[type]->size())
|
|
|
|
return FunctionValues[type]->getOperand(Num);
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2002-08-17 22:01:27 +00:00
|
|
|
if (!Create) return 0; // Do not create a placeholder?
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2004-09-01 22:55:40 +00:00
|
|
|
// Did we already create a place holder?
|
2003-10-09 06:05:40 +00:00
|
|
|
std::pair<unsigned,unsigned> KeyValue(type, oNum);
|
2004-06-29 23:29:38 +00:00
|
|
|
ForwardReferenceMap::iterator I = ForwardReferences.lower_bound(KeyValue);
|
2003-10-09 06:05:40 +00:00
|
|
|
if (I != ForwardReferences.end() && I->first == KeyValue)
|
|
|
|
return I->second; // We have already created this placeholder
|
|
|
|
|
2004-09-01 22:55:40 +00:00
|
|
|
// If the type exists (it should)
|
|
|
|
if (const Type* Ty = getType(type)) {
|
|
|
|
// Create the place holder
|
|
|
|
Value *Val = new Argument(Ty);
|
|
|
|
ForwardReferences.insert(I, std::make_pair(KeyValue, Val));
|
|
|
|
return Val;
|
|
|
|
}
|
2006-08-22 16:09:19 +00:00
|
|
|
error("Can't create placeholder for value of type slot #" + utostr(type));
|
|
|
|
return 0; // just silence warning, error calls longjmp
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
|
2003-10-08 22:52:54 +00:00
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Just like getValue, except that it returns a null pointer
|
|
|
|
/// only on error. It always returns a constant (meaning that if the value is
|
|
|
|
/// defined, but is not a constant, that is an error). If the specified
|
2005-04-21 21:44:41 +00:00
|
|
|
/// constant hasn't been parsed yet, a placeholder is defined and used.
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Later, after the real value is parsed, the placeholder is eliminated.
|
2004-06-29 23:29:38 +00:00
|
|
|
Constant* BytecodeReader::getConstantValue(unsigned TypeSlot, unsigned Slot) {
|
2003-11-19 06:01:12 +00:00
|
|
|
if (Value *V = getValue(TypeSlot, Slot, false))
|
2003-10-09 20:41:16 +00:00
|
|
|
if (Constant *C = dyn_cast<Constant>(V))
|
|
|
|
return C; // If we already have the value parsed, just return it
|
|
|
|
else
|
2005-04-21 21:44:41 +00:00
|
|
|
error("Value for slot " + utostr(Slot) +
|
2004-07-18 00:12:03 +00:00
|
|
|
" is expected to be a constant!");
|
2002-10-14 03:33:02 +00:00
|
|
|
|
2004-12-09 06:19:44 +00:00
|
|
|
std::pair<unsigned, unsigned> Key(TypeSlot, Slot);
|
2003-11-19 17:27:18 +00:00
|
|
|
ConstantRefsType::iterator I = ConstantFwdRefs.lower_bound(Key);
|
2003-03-19 20:54:26 +00:00
|
|
|
|
2003-11-19 17:27:18 +00:00
|
|
|
if (I != ConstantFwdRefs.end() && I->first == Key) {
|
|
|
|
return I->second;
|
2002-10-14 03:33:02 +00:00
|
|
|
} else {
|
|
|
|
// Create a placeholder for the constant reference and
|
|
|
|
// keep track of the fact that we have a forward ref to recycle it
|
2004-12-09 06:19:44 +00:00
|
|
|
Constant *C = new ConstantPlaceHolder(getType(TypeSlot));
|
2005-04-21 21:44:41 +00:00
|
|
|
|
2002-10-14 03:33:02 +00:00
|
|
|
// Keep track of the fact that we have a forward ref to recycle it
|
2003-11-19 17:27:18 +00:00
|
|
|
ConstantFwdRefs.insert(I, std::make_pair(Key, C));
|
2002-10-14 03:33:02 +00:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// IR Construction Methods
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// As values are created, they are inserted into the appropriate place
|
|
|
|
/// with this method. The ValueTable argument must be one of ModuleValues
|
|
|
|
/// or FunctionValues data members of this class.
|
2005-04-21 21:44:41 +00:00
|
|
|
unsigned BytecodeReader::insertValue(Value *Val, unsigned type,
|
2004-07-11 17:28:43 +00:00
|
|
|
ValueTable &ValueTab) {
|
2004-06-29 23:29:38 +00:00
|
|
|
if (ValueTab.size() <= type)
|
|
|
|
ValueTab.resize(type+1);
|
|
|
|
|
|
|
|
if (!ValueTab[type]) ValueTab[type] = new ValueList();
|
|
|
|
|
|
|
|
ValueTab[type]->push_back(Val);
|
|
|
|
|
2005-05-05 20:57:00 +00:00
|
|
|
bool HasOffset = hasImplicitNull(type) && !isa<OpaqueType>(Val->getType());
|
2004-06-29 23:29:38 +00:00
|
|
|
return ValueTab[type]->size()-1 + HasOffset;
|
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Insert the arguments of a function as new values in the reader.
|
2004-07-11 17:28:43 +00:00
|
|
|
void BytecodeReader::insertArguments(Function* F) {
|
2004-06-29 23:29:38 +00:00
|
|
|
const FunctionType *FT = F->getFunctionType();
|
2005-03-15 04:54:21 +00:00
|
|
|
Function::arg_iterator AI = F->arg_begin();
|
2004-06-29 23:29:38 +00:00
|
|
|
for (FunctionType::param_iterator It = FT->param_begin();
|
|
|
|
It != FT->param_end(); ++It, ++AI)
|
|
|
|
insertValue(AI, getTypeSlot(AI->getType()), FunctionValues);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Bytecode Parsing Methods
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// This method parses a single instruction. The instruction is
|
|
|
|
/// inserted at the end of the \p BB provided. The arguments of
|
2004-09-28 16:57:46 +00:00
|
|
|
/// the instruction are provided in the \p Oprnds vector.
|
2007-02-07 05:08:39 +00:00
|
|
|
void BytecodeReader::ParseInstruction(SmallVector<unsigned, 8> &Oprnds,
|
2004-07-11 17:28:43 +00:00
|
|
|
BasicBlock* BB) {
|
2004-06-29 23:29:38 +00:00
|
|
|
BufPtr SaveAt = At;
|
|
|
|
|
|
|
|
// Clear instruction data
|
|
|
|
Oprnds.clear();
|
|
|
|
unsigned iType = 0;
|
|
|
|
unsigned Opcode = 0;
|
|
|
|
unsigned Op = read_uint();
|
|
|
|
|
|
|
|
// bits Instruction format: Common to all formats
|
|
|
|
// --------------------------
|
|
|
|
// 01-00: Opcode type, fixed to 1.
|
|
|
|
// 07-02: Opcode
|
|
|
|
Opcode = (Op >> 2) & 63;
|
|
|
|
Oprnds.resize((Op >> 0) & 03);
|
|
|
|
|
|
|
|
// Extract the operands
|
|
|
|
switch (Oprnds.size()) {
|
|
|
|
case 1:
|
|
|
|
// bits Instruction format:
|
|
|
|
// --------------------------
|
|
|
|
// 19-08: Resulting type plane
|
|
|
|
// 31-20: Operand #1 (if set to (2^12-1), then zero operands)
|
|
|
|
//
|
|
|
|
iType = (Op >> 8) & 4095;
|
|
|
|
Oprnds[0] = (Op >> 20) & 4095;
|
|
|
|
if (Oprnds[0] == 4095) // Handle special encoding for 0 operands...
|
|
|
|
Oprnds.resize(0);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
// bits Instruction format:
|
|
|
|
// --------------------------
|
|
|
|
// 15-08: Resulting type plane
|
|
|
|
// 23-16: Operand #1
|
2005-04-21 21:44:41 +00:00
|
|
|
// 31-24: Operand #2
|
2004-06-29 23:29:38 +00:00
|
|
|
//
|
|
|
|
iType = (Op >> 8) & 255;
|
|
|
|
Oprnds[0] = (Op >> 16) & 255;
|
|
|
|
Oprnds[1] = (Op >> 24) & 255;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
// bits Instruction format:
|
|
|
|
// --------------------------
|
|
|
|
// 13-08: Resulting type plane
|
|
|
|
// 19-14: Operand #1
|
|
|
|
// 25-20: Operand #2
|
|
|
|
// 31-26: Operand #3
|
|
|
|
//
|
|
|
|
iType = (Op >> 8) & 63;
|
|
|
|
Oprnds[0] = (Op >> 14) & 63;
|
|
|
|
Oprnds[1] = (Op >> 20) & 63;
|
|
|
|
Oprnds[2] = (Op >> 26) & 63;
|
|
|
|
break;
|
|
|
|
case 0:
|
|
|
|
At -= 4; // Hrm, try this again...
|
|
|
|
Opcode = read_vbr_uint();
|
|
|
|
Opcode >>= 2;
|
|
|
|
iType = read_vbr_uint();
|
|
|
|
|
|
|
|
unsigned NumOprnds = read_vbr_uint();
|
|
|
|
Oprnds.resize(NumOprnds);
|
|
|
|
|
|
|
|
if (NumOprnds == 0)
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Zero-argument instruction found; this is invalid.");
|
2004-06-29 23:29:38 +00:00
|
|
|
|
|
|
|
for (unsigned i = 0; i != NumOprnds; ++i)
|
|
|
|
Oprnds[i] = read_vbr_uint();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-11-14 04:47:22 +00:00
|
|
|
const Type *InstTy = getType(iType);
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
// Make the necessary adjustments for dealing with backwards compatibility
|
|
|
|
// of opcodes.
|
2006-12-03 05:47:10 +00:00
|
|
|
Instruction* Result = 0;
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2006-12-03 05:47:10 +00:00
|
|
|
// First, handle the easy binary operators case
|
|
|
|
if (Opcode >= Instruction::BinaryOpsBegin &&
|
2006-12-03 06:28:54 +00:00
|
|
|
Opcode < Instruction::BinaryOpsEnd && Oprnds.size() == 2) {
|
2006-12-03 05:47:10 +00:00
|
|
|
Result = BinaryOperator::create(Instruction::BinaryOps(Opcode),
|
|
|
|
getValue(iType, Oprnds[0]),
|
|
|
|
getValue(iType, Oprnds[1]));
|
2006-12-03 06:28:54 +00:00
|
|
|
} else {
|
2006-10-26 06:15:43 +00:00
|
|
|
// Indicate that we don't think this is a call instruction (yet).
|
|
|
|
// Process based on the Opcode read
|
|
|
|
switch (Opcode) {
|
|
|
|
default: // There was an error, this shouldn't happen.
|
|
|
|
if (Result == 0)
|
|
|
|
error("Illegal instruction read!");
|
|
|
|
break;
|
|
|
|
case Instruction::VAArg:
|
|
|
|
if (Oprnds.size() != 2)
|
|
|
|
error("Invalid VAArg instruction!");
|
|
|
|
Result = new VAArgInst(getValue(iType, Oprnds[0]),
|
2006-11-14 04:47:22 +00:00
|
|
|
getType(Oprnds[1]));
|
2006-10-26 06:15:43 +00:00
|
|
|
break;
|
|
|
|
case Instruction::ExtractElement: {
|
|
|
|
if (Oprnds.size() != 2)
|
|
|
|
error("Invalid extractelement instruction!");
|
|
|
|
Value *V1 = getValue(iType, Oprnds[0]);
|
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
|
|
|
Value *V2 = getValue(Int32TySlot, Oprnds[1]);
|
2006-10-26 06:15:43 +00:00
|
|
|
|
|
|
|
if (!ExtractElementInst::isValidOperands(V1, V2))
|
|
|
|
error("Invalid extractelement instruction!");
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
Result = new ExtractElementInst(V1, V2);
|
|
|
|
break;
|
2004-10-16 18:18:16 +00:00
|
|
|
}
|
2006-10-26 06:15:43 +00:00
|
|
|
case Instruction::InsertElement: {
|
|
|
|
const PackedType *PackedTy = dyn_cast<PackedType>(InstTy);
|
|
|
|
if (!PackedTy || Oprnds.size() != 3)
|
|
|
|
error("Invalid insertelement instruction!");
|
2006-04-08 04:09:19 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
Value *V1 = getValue(iType, Oprnds[0]);
|
|
|
|
Value *V2 = getValue(getTypeSlot(PackedTy->getElementType()),Oprnds[1]);
|
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
|
|
|
Value *V3 = getValue(Int32TySlot, Oprnds[2]);
|
2006-10-26 06:15:43 +00:00
|
|
|
|
|
|
|
if (!InsertElementInst::isValidOperands(V1, V2, V3))
|
|
|
|
error("Invalid insertelement instruction!");
|
|
|
|
Result = new InsertElementInst(V1, V2, V3);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Instruction::ShuffleVector: {
|
|
|
|
const PackedType *PackedTy = dyn_cast<PackedType>(InstTy);
|
|
|
|
if (!PackedTy || Oprnds.size() != 3)
|
|
|
|
error("Invalid shufflevector instruction!");
|
|
|
|
Value *V1 = getValue(iType, Oprnds[0]);
|
|
|
|
Value *V2 = getValue(iType, Oprnds[1]);
|
|
|
|
const PackedType *EltTy =
|
2006-12-31 05:44:24 +00:00
|
|
|
PackedType::get(Type::Int32Ty, PackedTy->getNumElements());
|
2006-10-26 06:15:43 +00:00
|
|
|
Value *V3 = getValue(getTypeSlot(EltTy), Oprnds[2]);
|
|
|
|
if (!ShuffleVectorInst::isValidOperands(V1, V2, V3))
|
|
|
|
error("Invalid shufflevector instruction!");
|
|
|
|
Result = new ShuffleVectorInst(V1, V2, V3);
|
|
|
|
break;
|
|
|
|
}
|
2006-11-27 01:05:10 +00:00
|
|
|
case Instruction::Trunc:
|
|
|
|
if (Oprnds.size() != 2)
|
|
|
|
error("Invalid cast instruction!");
|
|
|
|
Result = new TruncInst(getValue(iType, Oprnds[0]),
|
|
|
|
getType(Oprnds[1]));
|
|
|
|
break;
|
|
|
|
case Instruction::ZExt:
|
|
|
|
if (Oprnds.size() != 2)
|
|
|
|
error("Invalid cast instruction!");
|
|
|
|
Result = new ZExtInst(getValue(iType, Oprnds[0]),
|
|
|
|
getType(Oprnds[1]));
|
|
|
|
break;
|
|
|
|
case Instruction::SExt:
|
2006-10-26 06:15:43 +00:00
|
|
|
if (Oprnds.size() != 2)
|
|
|
|
error("Invalid Cast instruction!");
|
2006-11-27 01:05:10 +00:00
|
|
|
Result = new SExtInst(getValue(iType, Oprnds[0]),
|
2006-11-14 04:47:22 +00:00
|
|
|
getType(Oprnds[1]));
|
2006-10-26 06:15:43 +00:00
|
|
|
break;
|
2006-11-27 01:05:10 +00:00
|
|
|
case Instruction::FPTrunc:
|
|
|
|
if (Oprnds.size() != 2)
|
|
|
|
error("Invalid cast instruction!");
|
|
|
|
Result = new FPTruncInst(getValue(iType, Oprnds[0]),
|
|
|
|
getType(Oprnds[1]));
|
|
|
|
break;
|
|
|
|
case Instruction::FPExt:
|
|
|
|
if (Oprnds.size() != 2)
|
|
|
|
error("Invalid cast instruction!");
|
|
|
|
Result = new FPExtInst(getValue(iType, Oprnds[0]),
|
|
|
|
getType(Oprnds[1]));
|
|
|
|
break;
|
|
|
|
case Instruction::UIToFP:
|
|
|
|
if (Oprnds.size() != 2)
|
|
|
|
error("Invalid cast instruction!");
|
|
|
|
Result = new UIToFPInst(getValue(iType, Oprnds[0]),
|
|
|
|
getType(Oprnds[1]));
|
|
|
|
break;
|
|
|
|
case Instruction::SIToFP:
|
|
|
|
if (Oprnds.size() != 2)
|
|
|
|
error("Invalid cast instruction!");
|
|
|
|
Result = new SIToFPInst(getValue(iType, Oprnds[0]),
|
|
|
|
getType(Oprnds[1]));
|
|
|
|
break;
|
|
|
|
case Instruction::FPToUI:
|
|
|
|
if (Oprnds.size() != 2)
|
|
|
|
error("Invalid cast instruction!");
|
|
|
|
Result = new FPToUIInst(getValue(iType, Oprnds[0]),
|
|
|
|
getType(Oprnds[1]));
|
|
|
|
break;
|
|
|
|
case Instruction::FPToSI:
|
|
|
|
if (Oprnds.size() != 2)
|
|
|
|
error("Invalid cast instruction!");
|
|
|
|
Result = new FPToSIInst(getValue(iType, Oprnds[0]),
|
|
|
|
getType(Oprnds[1]));
|
|
|
|
break;
|
|
|
|
case Instruction::IntToPtr:
|
|
|
|
if (Oprnds.size() != 2)
|
|
|
|
error("Invalid cast instruction!");
|
|
|
|
Result = new IntToPtrInst(getValue(iType, Oprnds[0]),
|
|
|
|
getType(Oprnds[1]));
|
|
|
|
break;
|
|
|
|
case Instruction::PtrToInt:
|
|
|
|
if (Oprnds.size() != 2)
|
|
|
|
error("Invalid cast instruction!");
|
|
|
|
Result = new PtrToIntInst(getValue(iType, Oprnds[0]),
|
|
|
|
getType(Oprnds[1]));
|
|
|
|
break;
|
|
|
|
case Instruction::BitCast:
|
|
|
|
if (Oprnds.size() != 2)
|
|
|
|
error("Invalid cast instruction!");
|
|
|
|
Result = new BitCastInst(getValue(iType, Oprnds[0]),
|
|
|
|
getType(Oprnds[1]));
|
|
|
|
break;
|
2006-10-26 06:15:43 +00:00
|
|
|
case Instruction::Select:
|
|
|
|
if (Oprnds.size() != 3)
|
|
|
|
error("Invalid Select instruction!");
|
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
|
|
|
Result = new SelectInst(getValue(BoolTySlot, Oprnds[0]),
|
2006-10-26 06:15:43 +00:00
|
|
|
getValue(iType, Oprnds[1]),
|
|
|
|
getValue(iType, Oprnds[2]));
|
|
|
|
break;
|
|
|
|
case Instruction::PHI: {
|
|
|
|
if (Oprnds.size() == 0 || (Oprnds.size() & 1))
|
|
|
|
error("Invalid phi node encountered!");
|
|
|
|
|
|
|
|
PHINode *PN = new PHINode(InstTy);
|
|
|
|
PN->reserveOperandSpace(Oprnds.size());
|
|
|
|
for (unsigned i = 0, e = Oprnds.size(); i != e; i += 2)
|
|
|
|
PN->addIncoming(
|
|
|
|
getValue(iType, Oprnds[i]), getBasicBlock(Oprnds[i+1]));
|
|
|
|
Result = PN;
|
|
|
|
break;
|
|
|
|
}
|
2006-12-03 06:28:54 +00:00
|
|
|
case Instruction::ICmp:
|
|
|
|
case Instruction::FCmp:
|
2006-12-03 17:17:02 +00:00
|
|
|
if (Oprnds.size() != 3)
|
|
|
|
error("Cmp instructions requires 3 operands");
|
2006-12-03 06:28:54 +00:00
|
|
|
// These instructions encode the comparison predicate as the 3rd operand.
|
|
|
|
Result = CmpInst::create(Instruction::OtherOps(Opcode),
|
|
|
|
static_cast<unsigned short>(Oprnds[2]),
|
|
|
|
getValue(iType, Oprnds[0]), getValue(iType, Oprnds[1]));
|
|
|
|
break;
|
2006-10-26 06:15:43 +00:00
|
|
|
case Instruction::Ret:
|
|
|
|
if (Oprnds.size() == 0)
|
|
|
|
Result = new ReturnInst();
|
|
|
|
else if (Oprnds.size() == 1)
|
|
|
|
Result = new ReturnInst(getValue(iType, Oprnds[0]));
|
|
|
|
else
|
|
|
|
error("Unrecognized instruction!");
|
|
|
|
break;
|
2005-05-06 22:34:01 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
case Instruction::Br:
|
|
|
|
if (Oprnds.size() == 1)
|
|
|
|
Result = new BranchInst(getBasicBlock(Oprnds[0]));
|
|
|
|
else if (Oprnds.size() == 3)
|
|
|
|
Result = new BranchInst(getBasicBlock(Oprnds[0]),
|
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
|
|
|
getBasicBlock(Oprnds[1]), getValue(BoolTySlot, Oprnds[2]));
|
2006-10-26 06:15:43 +00:00
|
|
|
else
|
|
|
|
error("Invalid number of operands for a 'br' instruction!");
|
|
|
|
break;
|
|
|
|
case Instruction::Switch: {
|
|
|
|
if (Oprnds.size() & 1)
|
|
|
|
error("Switch statement with odd number of arguments!");
|
|
|
|
|
|
|
|
SwitchInst *I = new SwitchInst(getValue(iType, Oprnds[0]),
|
|
|
|
getBasicBlock(Oprnds[1]),
|
|
|
|
Oprnds.size()/2-1);
|
|
|
|
for (unsigned i = 2, e = Oprnds.size(); i != e; i += 2)
|
|
|
|
I->addCase(cast<ConstantInt>(getValue(iType, Oprnds[i])),
|
|
|
|
getBasicBlock(Oprnds[i+1]));
|
|
|
|
Result = I;
|
|
|
|
break;
|
2006-05-26 18:42:34 +00:00
|
|
|
}
|
2006-10-26 06:15:43 +00:00
|
|
|
case 58: // Call with extra operand for calling conv
|
|
|
|
case 59: // tail call, Fast CC
|
|
|
|
case 60: // normal call, Fast CC
|
|
|
|
case 61: // tail call, C Calling Conv
|
|
|
|
case Instruction::Call: { // Normal Call, C Calling Convention
|
|
|
|
if (Oprnds.size() == 0)
|
|
|
|
error("Invalid call instruction encountered!");
|
|
|
|
Value *F = getValue(iType, Oprnds[0]);
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
unsigned CallingConv = CallingConv::C;
|
|
|
|
bool isTailCall = false;
|
|
|
|
|
|
|
|
if (Opcode == 61 || Opcode == 59)
|
|
|
|
isTailCall = true;
|
|
|
|
|
|
|
|
if (Opcode == 58) {
|
|
|
|
isTailCall = Oprnds.back() & 1;
|
|
|
|
CallingConv = Oprnds.back() >> 1;
|
|
|
|
Oprnds.pop_back();
|
|
|
|
} else if (Opcode == 59 || Opcode == 60) {
|
|
|
|
CallingConv = CallingConv::Fast;
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
2006-10-26 06:15:43 +00:00
|
|
|
|
|
|
|
// Check to make sure we have a pointer to function type
|
|
|
|
const PointerType *PTy = dyn_cast<PointerType>(F->getType());
|
|
|
|
if (PTy == 0) error("Call to non function pointer value!");
|
|
|
|
const FunctionType *FTy = dyn_cast<FunctionType>(PTy->getElementType());
|
|
|
|
if (FTy == 0) error("Call to non function pointer value!");
|
|
|
|
|
|
|
|
std::vector<Value *> Params;
|
|
|
|
if (!FTy->isVarArg()) {
|
|
|
|
FunctionType::param_iterator It = FTy->param_begin();
|
|
|
|
|
|
|
|
for (unsigned i = 1, e = Oprnds.size(); i != e; ++i) {
|
|
|
|
if (It == FTy->param_end())
|
|
|
|
error("Invalid call instruction!");
|
|
|
|
Params.push_back(getValue(getTypeSlot(*It++), Oprnds[i]));
|
|
|
|
}
|
|
|
|
if (It != FTy->param_end())
|
|
|
|
error("Invalid call instruction!");
|
|
|
|
} else {
|
|
|
|
Oprnds.erase(Oprnds.begin(), Oprnds.begin()+1);
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
unsigned FirstVariableOperand;
|
|
|
|
if (Oprnds.size() < FTy->getNumParams())
|
|
|
|
error("Call instruction missing operands!");
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
// Read all of the fixed arguments
|
|
|
|
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
|
|
|
|
Params.push_back(
|
|
|
|
getValue(getTypeSlot(FTy->getParamType(i)),Oprnds[i]));
|
2005-04-21 21:44:41 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
FirstVariableOperand = FTy->getNumParams();
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
if ((Oprnds.size()-FirstVariableOperand) & 1)
|
|
|
|
error("Invalid call instruction!"); // Must be pairs of type/value
|
2005-04-21 21:44:41 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
for (unsigned i = FirstVariableOperand, e = Oprnds.size();
|
|
|
|
i != e; i += 2)
|
|
|
|
Params.push_back(getValue(Oprnds[i], Oprnds[i+1]));
|
|
|
|
}
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
Result = new CallInst(F, Params);
|
|
|
|
if (isTailCall) cast<CallInst>(Result)->setTailCall();
|
|
|
|
if (CallingConv) cast<CallInst>(Result)->setCallingConv(CallingConv);
|
|
|
|
break;
|
2005-05-06 22:34:01 +00:00
|
|
|
}
|
2006-10-26 06:15:43 +00:00
|
|
|
case Instruction::Invoke: { // Invoke C CC
|
|
|
|
if (Oprnds.size() < 3)
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Invalid invoke instruction!");
|
2006-10-26 06:15:43 +00:00
|
|
|
Value *F = getValue(iType, Oprnds[0]);
|
|
|
|
|
|
|
|
// Check to make sure we have a pointer to function type
|
|
|
|
const PointerType *PTy = dyn_cast<PointerType>(F->getType());
|
|
|
|
if (PTy == 0)
|
|
|
|
error("Invoke to non function pointer value!");
|
|
|
|
const FunctionType *FTy = dyn_cast<FunctionType>(PTy->getElementType());
|
|
|
|
if (FTy == 0)
|
|
|
|
error("Invoke to non function pointer value!");
|
|
|
|
|
|
|
|
std::vector<Value *> Params;
|
|
|
|
BasicBlock *Normal, *Except;
|
2006-11-27 01:05:10 +00:00
|
|
|
unsigned CallingConv = Oprnds.back();
|
|
|
|
Oprnds.pop_back();
|
2005-04-21 21:44:41 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
if (!FTy->isVarArg()) {
|
|
|
|
Normal = getBasicBlock(Oprnds[1]);
|
|
|
|
Except = getBasicBlock(Oprnds[2]);
|
2005-04-21 21:44:41 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
FunctionType::param_iterator It = FTy->param_begin();
|
|
|
|
for (unsigned i = 3, e = Oprnds.size(); i != e; ++i) {
|
|
|
|
if (It == FTy->param_end())
|
|
|
|
error("Invalid invoke instruction!");
|
|
|
|
Params.push_back(getValue(getTypeSlot(*It++), Oprnds[i]));
|
|
|
|
}
|
|
|
|
if (It != FTy->param_end())
|
|
|
|
error("Invalid invoke instruction!");
|
|
|
|
} else {
|
|
|
|
Oprnds.erase(Oprnds.begin(), Oprnds.begin()+1);
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
Normal = getBasicBlock(Oprnds[0]);
|
|
|
|
Except = getBasicBlock(Oprnds[1]);
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
unsigned FirstVariableArgument = FTy->getNumParams()+2;
|
|
|
|
for (unsigned i = 2; i != FirstVariableArgument; ++i)
|
|
|
|
Params.push_back(getValue(getTypeSlot(FTy->getParamType(i-2)),
|
|
|
|
Oprnds[i]));
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
// Must be type/value pairs. If not, error out.
|
|
|
|
if (Oprnds.size()-FirstVariableArgument & 1)
|
|
|
|
error("Invalid invoke instruction!");
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
for (unsigned i = FirstVariableArgument; i < Oprnds.size(); i += 2)
|
|
|
|
Params.push_back(getValue(Oprnds[i], Oprnds[i+1]));
|
|
|
|
}
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2006-10-26 06:15:43 +00:00
|
|
|
Result = new InvokeInst(F, Normal, Except, Params);
|
|
|
|
if (CallingConv) cast<InvokeInst>(Result)->setCallingConv(CallingConv);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Instruction::Malloc: {
|
|
|
|
unsigned Align = 0;
|
|
|
|
if (Oprnds.size() == 2)
|
|
|
|
Align = (1 << Oprnds[1]) >> 1;
|
|
|
|
else if (Oprnds.size() > 2)
|
|
|
|
error("Invalid malloc instruction!");
|
|
|
|
if (!isa<PointerType>(InstTy))
|
|
|
|
error("Invalid malloc instruction!");
|
|
|
|
|
|
|
|
Result = new MallocInst(cast<PointerType>(InstTy)->getElementType(),
|
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
|
|
|
getValue(Int32TySlot, Oprnds[0]), Align);
|
2006-10-26 06:15:43 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Instruction::Alloca: {
|
|
|
|
unsigned Align = 0;
|
|
|
|
if (Oprnds.size() == 2)
|
|
|
|
Align = (1 << Oprnds[1]) >> 1;
|
|
|
|
else if (Oprnds.size() > 2)
|
|
|
|
error("Invalid alloca instruction!");
|
|
|
|
if (!isa<PointerType>(InstTy))
|
|
|
|
error("Invalid alloca instruction!");
|
|
|
|
|
|
|
|
Result = new AllocaInst(cast<PointerType>(InstTy)->getElementType(),
|
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
|
|
|
getValue(Int32TySlot, Oprnds[0]), Align);
|
2006-10-26 06:15:43 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Instruction::Free:
|
|
|
|
if (!isa<PointerType>(InstTy))
|
|
|
|
error("Invalid free instruction!");
|
|
|
|
Result = new FreeInst(getValue(iType, Oprnds[0]));
|
|
|
|
break;
|
|
|
|
case Instruction::GetElementPtr: {
|
|
|
|
if (Oprnds.size() == 0 || !isa<PointerType>(InstTy))
|
2005-04-21 21:44:41 +00:00
|
|
|
error("Invalid getelementptr instruction!");
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2007-01-31 19:56:15 +00:00
|
|
|
SmallVector<Value*, 8> Idx;
|
2006-10-26 06:15:43 +00:00
|
|
|
|
|
|
|
const Type *NextTy = InstTy;
|
|
|
|
for (unsigned i = 1, e = Oprnds.size(); i != e; ++i) {
|
|
|
|
const CompositeType *TopTy = dyn_cast_or_null<CompositeType>(NextTy);
|
|
|
|
if (!TopTy)
|
|
|
|
error("Invalid getelementptr instruction!");
|
|
|
|
|
|
|
|
unsigned ValIdx = Oprnds[i];
|
|
|
|
unsigned IdxTy = 0;
|
2006-11-14 04:47:22 +00:00
|
|
|
// Struct indices are always uints, sequential type indices can be
|
|
|
|
// any of the 32 or 64-bit integer types. The actual choice of
|
2006-12-31 05:44:24 +00:00
|
|
|
// type is encoded in the low bit of the slot number.
|
2006-11-14 04:47:22 +00:00
|
|
|
if (isa<StructType>(TopTy))
|
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
|
|
|
IdxTy = Int32TySlot;
|
2006-11-14 04:47:22 +00:00
|
|
|
else {
|
2006-12-31 05:44:24 +00:00
|
|
|
switch (ValIdx & 1) {
|
2006-11-14 04:47:22 +00:00
|
|
|
default:
|
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 0: IdxTy = Int32TySlot; break;
|
|
|
|
case 1: IdxTy = Int64TySlot; break;
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
2006-12-31 05:44:24 +00:00
|
|
|
ValIdx >>= 1;
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
2006-10-26 06:15:43 +00:00
|
|
|
Idx.push_back(getValue(IdxTy, ValIdx));
|
2007-01-31 19:56:15 +00:00
|
|
|
NextTy = GetElementPtrInst::getIndexedType(InstTy, &Idx[0], Idx.size(),
|
|
|
|
true);
|
2006-10-26 06:15:43 +00:00
|
|
|
}
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2007-01-31 19:56:15 +00:00
|
|
|
Result = new GetElementPtrInst(getValue(iType, Oprnds[0]),
|
|
|
|
&Idx[0], Idx.size());
|
2006-10-26 06:15:43 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 62: // volatile load
|
|
|
|
case Instruction::Load:
|
|
|
|
if (Oprnds.size() != 1 || !isa<PointerType>(InstTy))
|
|
|
|
error("Invalid load instruction!");
|
|
|
|
Result = new LoadInst(getValue(iType, Oprnds[0]), "", Opcode == 62);
|
|
|
|
break;
|
|
|
|
case 63: // volatile store
|
|
|
|
case Instruction::Store: {
|
|
|
|
if (!isa<PointerType>(InstTy) || Oprnds.size() != 2)
|
|
|
|
error("Invalid store instruction!");
|
|
|
|
|
|
|
|
Value *Ptr = getValue(iType, Oprnds[1]);
|
|
|
|
const Type *ValTy = cast<PointerType>(Ptr->getType())->getElementType();
|
|
|
|
Result = new StoreInst(getValue(getTypeSlot(ValTy), Oprnds[0]), Ptr,
|
|
|
|
Opcode == 63);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Instruction::Unwind:
|
|
|
|
if (Oprnds.size() != 0) error("Invalid unwind instruction!");
|
|
|
|
Result = new UnwindInst();
|
|
|
|
break;
|
|
|
|
case Instruction::Unreachable:
|
|
|
|
if (Oprnds.size() != 0) error("Invalid unreachable instruction!");
|
|
|
|
Result = new UnreachableInst();
|
|
|
|
break;
|
|
|
|
} // end switch(Opcode)
|
2006-12-03 05:47:10 +00:00
|
|
|
} // end if !Result
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2006-01-19 07:02:16 +00:00
|
|
|
BB->getInstList().push_back(Result);
|
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
unsigned TypeSlot;
|
|
|
|
if (Result->getType() == InstTy)
|
|
|
|
TypeSlot = iType;
|
|
|
|
else
|
|
|
|
TypeSlot = getTypeSlot(Result->getType());
|
|
|
|
|
2007-02-05 20:47:22 +00:00
|
|
|
// We have enough info to inform the handler now.
|
|
|
|
if (Handler)
|
2007-02-07 05:08:39 +00:00
|
|
|
Handler->handleInstruction(Opcode, InstTy, &Oprnds[0], Oprnds.size(),
|
|
|
|
Result, At-SaveAt);
|
2007-02-05 20:47:22 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
insertValue(Result, TypeSlot, FunctionValues);
|
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Get a particular numbered basic block, which might be a forward reference.
|
2006-11-14 04:47:22 +00:00
|
|
|
/// This works together with ParseInstructionList to handle these forward
|
|
|
|
/// references in a clean manner. This function is used when constructing
|
|
|
|
/// phi, br, switch, and other instructions that reference basic blocks.
|
|
|
|
/// Blocks are numbered sequentially as they appear in the function.
|
2004-06-29 23:29:38 +00:00
|
|
|
BasicBlock *BytecodeReader::getBasicBlock(unsigned ID) {
|
|
|
|
// Make sure there is room in the table...
|
|
|
|
if (ParsedBasicBlocks.size() <= ID) ParsedBasicBlocks.resize(ID+1);
|
|
|
|
|
2006-11-14 04:47:22 +00:00
|
|
|
// First check to see if this is a backwards reference, i.e. this block
|
|
|
|
// has already been created, or if the forward reference has already
|
2004-06-29 23:29:38 +00:00
|
|
|
// been created.
|
|
|
|
if (ParsedBasicBlocks[ID])
|
|
|
|
return ParsedBasicBlocks[ID];
|
|
|
|
|
|
|
|
// Otherwise, the basic block has not yet been created. Do so and add it to
|
|
|
|
// the ParsedBasicBlocks list.
|
|
|
|
return ParsedBasicBlocks[ID] = new BasicBlock();
|
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Parse all of the BasicBlock's & Instruction's in the body of a function.
|
2005-04-21 21:44:41 +00:00
|
|
|
/// In post 1.0 bytecode files, we no longer emit basic block individually,
|
2004-07-04 11:33:49 +00:00
|
|
|
/// in order to avoid per-basic-block overhead.
|
2006-11-14 04:47:22 +00:00
|
|
|
/// @returns the number of basic blocks encountered.
|
2004-06-29 23:29:38 +00:00
|
|
|
unsigned BytecodeReader::ParseInstructionList(Function* F) {
|
2003-12-01 07:05:31 +00:00
|
|
|
unsigned BlockNo = 0;
|
2007-02-07 05:08:39 +00:00
|
|
|
SmallVector<unsigned, 8> Args;
|
2003-12-01 07:05:31 +00:00
|
|
|
|
2004-07-11 17:28:43 +00:00
|
|
|
while (moreInBlock()) {
|
|
|
|
if (Handler) Handler->handleBasicBlockBegin(BlockNo);
|
2003-12-01 07:05:31 +00:00
|
|
|
BasicBlock *BB;
|
|
|
|
if (ParsedBasicBlocks.size() == BlockNo)
|
|
|
|
ParsedBasicBlocks.push_back(BB = new BasicBlock());
|
|
|
|
else if (ParsedBasicBlocks[BlockNo] == 0)
|
|
|
|
BB = ParsedBasicBlocks[BlockNo] = new BasicBlock();
|
|
|
|
else
|
|
|
|
BB = ParsedBasicBlocks[BlockNo];
|
|
|
|
++BlockNo;
|
|
|
|
F->getBasicBlockList().push_back(BB);
|
|
|
|
|
|
|
|
// Read instructions into this basic block until we get to a terminator
|
2004-07-11 17:28:43 +00:00
|
|
|
while (moreInBlock() && !BB->getTerminator())
|
2004-06-29 23:29:38 +00:00
|
|
|
ParseInstruction(Args, BB);
|
2003-12-01 07:05:31 +00:00
|
|
|
|
|
|
|
if (!BB->getTerminator())
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Non-terminated basic block found!");
|
2004-07-05 00:57:50 +00:00
|
|
|
|
2004-07-11 17:28:43 +00:00
|
|
|
if (Handler) Handler->handleBasicBlockEnd(BlockNo-1);
|
2003-12-01 07:05:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return BlockNo;
|
|
|
|
}
|
|
|
|
|
2007-01-06 07:24:44 +00:00
|
|
|
/// Parse a type symbol table.
|
|
|
|
void BytecodeReader::ParseTypeSymbolTable(TypeSymbolTable *TST) {
|
|
|
|
// Type Symtab block header: [num entries]
|
|
|
|
unsigned NumEntries = read_vbr_uint();
|
|
|
|
for (unsigned i = 0; i < NumEntries; ++i) {
|
|
|
|
// Symtab entry: [type slot #][name]
|
|
|
|
unsigned slot = read_vbr_uint();
|
|
|
|
std::string Name = read_str();
|
|
|
|
const Type* T = getType(slot);
|
|
|
|
TST->insert(Name, T);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Parse a value symbol table. This works for both module level and function
|
2004-07-04 11:33:49 +00:00
|
|
|
/// level symbol tables. For function level symbol tables, the CurrentFunction
|
|
|
|
/// parameter must be non-zero and the ST parameter must correspond to
|
|
|
|
/// CurrentFunction's symbol table. For Module level symbol tables, the
|
|
|
|
/// CurrentFunction argument must be zero.
|
2007-01-06 07:24:44 +00:00
|
|
|
void BytecodeReader::ParseValueSymbolTable(Function *CurrentFunction,
|
2007-02-05 20:47:22 +00:00
|
|
|
ValueSymbolTable *VST) {
|
2007-01-06 07:24:44 +00:00
|
|
|
|
2007-02-05 20:47:22 +00:00
|
|
|
if (Handler) Handler->handleValueSymbolTableBegin(CurrentFunction,VST);
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2003-10-10 05:43:47 +00:00
|
|
|
// Allow efficient basic block lookup by number.
|
2007-02-07 05:08:39 +00:00
|
|
|
SmallVector<BasicBlock*, 32> BBMap;
|
2003-10-10 05:43:47 +00:00
|
|
|
if (CurrentFunction)
|
|
|
|
for (Function::iterator I = CurrentFunction->begin(),
|
|
|
|
E = CurrentFunction->end(); I != E; ++I)
|
|
|
|
BBMap.push_back(I);
|
|
|
|
|
2004-07-11 17:28:43 +00:00
|
|
|
while (moreInBlock()) {
|
2001-06-06 20:29:01 +00:00
|
|
|
// Symtab block header: [num entries][type id number]
|
2004-06-29 23:29:38 +00:00
|
|
|
unsigned NumEntries = read_vbr_uint();
|
2006-11-14 04:47:22 +00:00
|
|
|
unsigned Typ = read_vbr_uint();
|
2001-09-07 16:37:43 +00:00
|
|
|
|
2003-10-13 14:57:53 +00:00
|
|
|
for (unsigned i = 0; i != NumEntries; ++i) {
|
2001-06-06 20:29:01 +00:00
|
|
|
// Symtab entry: [def slot #][name]
|
2004-06-29 23:29:38 +00:00
|
|
|
unsigned slot = read_vbr_uint();
|
|
|
|
std::string Name = read_str();
|
2006-11-14 04:47:22 +00:00
|
|
|
Value *V = 0;
|
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 (Typ == LabelTySlot) {
|
2006-11-14 04:47:22 +00:00
|
|
|
if (slot < BBMap.size())
|
|
|
|
V = BBMap[slot];
|
2003-10-10 05:43:47 +00:00
|
|
|
} else {
|
2006-11-14 04:47:22 +00:00
|
|
|
V = getValue(Typ, slot, false); // Find mapping...
|
2003-10-10 05:43:47 +00:00
|
|
|
}
|
2007-02-05 20:47:22 +00:00
|
|
|
if (Handler) Handler->handleSymbolTableValue(Typ, slot, Name);
|
2006-11-14 04:47:22 +00:00
|
|
|
if (V == 0)
|
2007-02-05 20:47:22 +00:00
|
|
|
error("Failed value look-up for name '" + Name + "', type #" +
|
|
|
|
utostr(Typ) + " slot #" + utostr(slot));
|
2006-11-14 04:47:22 +00:00
|
|
|
V->setName(Name);
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
}
|
2004-06-29 23:29:38 +00:00
|
|
|
checkPastBlockEnd("Symbol Table");
|
2007-02-05 20:47:22 +00:00
|
|
|
if (Handler) Handler->handleValueSymbolTableEnd();
|
2004-07-04 11:33:49 +00:00
|
|
|
}
|
|
|
|
|
2004-07-11 17:28:43 +00:00
|
|
|
// Parse a single type. The typeid is read in first. If its a primitive type
|
|
|
|
// then nothing else needs to be read, we know how to instantiate it. If its
|
2005-04-21 21:44:41 +00:00
|
|
|
// a derived type, then additional data is read to fill out the type
|
2004-07-11 17:28:43 +00:00
|
|
|
// definition.
|
|
|
|
const Type *BytecodeReader::ParseType() {
|
2006-11-14 04:47:22 +00:00
|
|
|
unsigned PrimType = read_vbr_uint();
|
2004-06-29 23:29:38 +00:00
|
|
|
const Type *Result = 0;
|
|
|
|
if ((Result = Type::getPrimitiveType((Type::TypeID)PrimType)))
|
|
|
|
return Result;
|
2005-04-21 21:44:41 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
switch (PrimType) {
|
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: {
|
|
|
|
unsigned NumBits = read_vbr_uint();
|
|
|
|
Result = IntegerType::get(NumBits);
|
|
|
|
break;
|
|
|
|
}
|
2004-06-29 23:29:38 +00:00
|
|
|
case Type::FunctionTyID: {
|
2006-11-14 04:47:22 +00:00
|
|
|
const Type *RetType = readType();
|
2006-12-31 05:44:24 +00:00
|
|
|
unsigned RetAttr = read_vbr_uint();
|
2004-06-29 23:29:38 +00:00
|
|
|
|
|
|
|
unsigned NumParams = read_vbr_uint();
|
|
|
|
|
|
|
|
std::vector<const Type*> Params;
|
2006-12-31 05:44:24 +00:00
|
|
|
std::vector<FunctionType::ParameterAttributes> Attrs;
|
|
|
|
Attrs.push_back(FunctionType::ParameterAttributes(RetAttr));
|
|
|
|
while (NumParams--) {
|
2006-11-14 04:47:22 +00:00
|
|
|
Params.push_back(readType());
|
2006-12-31 05:44:24 +00:00
|
|
|
if (Params.back() != Type::VoidTy)
|
|
|
|
Attrs.push_back(FunctionType::ParameterAttributes(read_vbr_uint()));
|
|
|
|
}
|
2004-06-29 23:29:38 +00:00
|
|
|
|
|
|
|
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
|
|
|
|
if (isVarArg) Params.pop_back();
|
|
|
|
|
2006-12-31 05:44:24 +00:00
|
|
|
Result = FunctionType::get(RetType, Params, isVarArg, Attrs);
|
2004-06-29 23:29:38 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Type::ArrayTyID: {
|
2006-11-14 04:47:22 +00:00
|
|
|
const Type *ElementType = readType();
|
2004-06-29 23:29:38 +00:00
|
|
|
unsigned NumElements = read_vbr_uint();
|
|
|
|
Result = ArrayType::get(ElementType, NumElements);
|
|
|
|
break;
|
|
|
|
}
|
2004-08-20 06:00:58 +00:00
|
|
|
case Type::PackedTyID: {
|
2006-11-14 04:47:22 +00:00
|
|
|
const Type *ElementType = readType();
|
2004-08-20 06:00:58 +00:00
|
|
|
unsigned NumElements = read_vbr_uint();
|
|
|
|
Result = PackedType::get(ElementType, NumElements);
|
|
|
|
break;
|
|
|
|
}
|
2004-06-29 23:29:38 +00:00
|
|
|
case Type::StructTyID: {
|
|
|
|
std::vector<const Type*> Elements;
|
2006-11-14 04:47:22 +00:00
|
|
|
unsigned Typ = read_vbr_uint();
|
2004-06-29 23:29:38 +00:00
|
|
|
while (Typ) { // List is terminated by void/0 typeid
|
|
|
|
Elements.push_back(getType(Typ));
|
2006-11-14 04:47:22 +00:00
|
|
|
Typ = read_vbr_uint();
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
|
|
|
|
2006-12-08 18:06:16 +00:00
|
|
|
Result = StructType::get(Elements, false);
|
|
|
|
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
|
|
|
case Type::PackedStructTyID: {
|
2006-12-08 18:06:16 +00:00
|
|
|
std::vector<const Type*> Elements;
|
|
|
|
unsigned Typ = read_vbr_uint();
|
|
|
|
while (Typ) { // List is terminated by void/0 typeid
|
|
|
|
Elements.push_back(getType(Typ));
|
|
|
|
Typ = read_vbr_uint();
|
|
|
|
}
|
|
|
|
|
|
|
|
Result = StructType::get(Elements, true);
|
2004-06-29 23:29:38 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Type::PointerTyID: {
|
2006-11-14 04:47:22 +00:00
|
|
|
Result = PointerType::get(readType());
|
2004-06-29 23:29:38 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case Type::OpaqueTyID: {
|
|
|
|
Result = OpaqueType::get();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Don't know how to deserialize primitive type " + utostr(PrimType));
|
2004-06-29 23:29:38 +00:00
|
|
|
break;
|
|
|
|
}
|
2004-07-11 17:28:43 +00:00
|
|
|
if (Handler) Handler->handleType(Result);
|
2004-06-29 23:29:38 +00:00
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2004-08-21 20:49:23 +00:00
|
|
|
// ParseTypes - We have to use this weird code to handle recursive
|
2004-06-29 23:29:38 +00:00
|
|
|
// types. We know that recursive types will only reference the current slab of
|
|
|
|
// values in the type plane, but they can forward reference types before they
|
|
|
|
// have been read. For example, Type #0 might be '{ Ty#1 }' and Type #1 might
|
|
|
|
// be 'Ty#0*'. When reading Type #0, type number one doesn't exist. To fix
|
|
|
|
// this ugly problem, we pessimistically insert an opaque type for each type we
|
|
|
|
// are about to read. This means that forward references will resolve to
|
|
|
|
// something and when we reread the type later, we can replace the opaque type
|
|
|
|
// with a new resolved concrete type.
|
|
|
|
//
|
2004-07-11 17:28:43 +00:00
|
|
|
void BytecodeReader::ParseTypes(TypeListTy &Tab, unsigned NumEntries){
|
2004-06-29 23:29:38 +00:00
|
|
|
assert(Tab.size() == 0 && "should not have read type constants in before!");
|
|
|
|
|
|
|
|
// Insert a bunch of opaque types to be resolved later...
|
|
|
|
Tab.reserve(NumEntries);
|
|
|
|
for (unsigned i = 0; i != NumEntries; ++i)
|
|
|
|
Tab.push_back(OpaqueType::get());
|
|
|
|
|
2005-04-21 21:44:41 +00:00
|
|
|
if (Handler)
|
2004-08-21 20:49:23 +00:00
|
|
|
Handler->handleTypeList(NumEntries);
|
|
|
|
|
2005-10-03 21:26:53 +00:00
|
|
|
// If we are about to resolve types, make sure the type cache is clear.
|
|
|
|
if (NumEntries)
|
|
|
|
ModuleTypeIDCache.clear();
|
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
// Loop through reading all of the types. Forward types will make use of the
|
|
|
|
// opaque types just inserted.
|
|
|
|
//
|
|
|
|
for (unsigned i = 0; i != NumEntries; ++i) {
|
2004-07-11 17:28:43 +00:00
|
|
|
const Type* NewTy = ParseType();
|
2004-07-04 11:33:49 +00:00
|
|
|
const Type* OldTy = Tab[i].get();
|
2005-04-21 21:44:41 +00:00
|
|
|
if (NewTy == 0)
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Couldn't parse type!");
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2005-04-21 21:44:41 +00:00
|
|
|
// Don't directly push the new type on the Tab. Instead we want to replace
|
2004-06-29 23:29:38 +00:00
|
|
|
// the opaque type we previously inserted with the new concrete value. This
|
|
|
|
// approach helps with forward references to types. The refinement from the
|
|
|
|
// abstract (opaque) type to the new type causes all uses of the abstract
|
|
|
|
// type to use the concrete type (NewTy). This will also cause the opaque
|
|
|
|
// type to be deleted.
|
|
|
|
cast<DerivedType>(const_cast<Type*>(OldTy))->refineAbstractTypeTo(NewTy);
|
|
|
|
|
|
|
|
// This should have replaced the old opaque type with the new type in the
|
|
|
|
// value table... or with a preexisting type that was already in the system.
|
|
|
|
// Let's just make sure it did.
|
|
|
|
assert(Tab[i] != OldTy && "refineAbstractType didn't work!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Parse a single constant value
|
2006-01-25 23:08:15 +00:00
|
|
|
Value *BytecodeReader::ParseConstantPoolValue(unsigned TypeID) {
|
2004-06-29 23:29:38 +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:44:41 +00:00
|
|
|
//
|
2004-06-29 23:29:38 +00:00
|
|
|
// 0 if not expr; numArgs if is expr
|
|
|
|
unsigned isExprNumArgs = read_vbr_uint();
|
2004-10-16 18:18:16 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
if (isExprNumArgs) {
|
2006-11-14 04:47:22 +00:00
|
|
|
// 'undef' is encoded with 'exprnumargs' == 1.
|
|
|
|
if (isExprNumArgs == 1)
|
|
|
|
return UndefValue::get(getType(TypeID));
|
|
|
|
|
|
|
|
// Inline asm is encoded with exprnumargs == ~0U.
|
|
|
|
if (isExprNumArgs == ~0U) {
|
|
|
|
std::string AsmStr = read_str();
|
|
|
|
std::string ConstraintStr = read_str();
|
|
|
|
unsigned Flags = read_vbr_uint();
|
2006-01-25 23:08:15 +00:00
|
|
|
|
2006-11-14 04:47:22 +00:00
|
|
|
const PointerType *PTy = dyn_cast<PointerType>(getType(TypeID));
|
|
|
|
const FunctionType *FTy =
|
|
|
|
PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
|
|
|
|
|
|
|
|
if (!FTy || !InlineAsm::Verify(FTy, ConstraintStr))
|
|
|
|
error("Invalid constraints for inline asm");
|
|
|
|
if (Flags & ~1U)
|
|
|
|
error("Invalid flags for inline asm");
|
|
|
|
bool HasSideEffects = Flags & 1;
|
|
|
|
return InlineAsm::get(FTy, AsmStr, ConstraintStr, HasSideEffects);
|
2006-01-25 23:08:15 +00:00
|
|
|
}
|
2006-11-14 04:47:22 +00:00
|
|
|
|
|
|
|
--isExprNumArgs;
|
2006-01-25 23:08:15 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
// FIXME: Encoding of constant exprs could be much more compact!
|
2007-02-07 05:15:28 +00:00
|
|
|
SmallVector<Constant*, 8> ArgVec;
|
2004-06-29 23:29:38 +00:00
|
|
|
ArgVec.reserve(isExprNumArgs);
|
|
|
|
unsigned Opcode = read_vbr_uint();
|
2004-10-16 18:18:16 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
// Read the slot number and types of each of the arguments
|
|
|
|
for (unsigned i = 0; i != isExprNumArgs; ++i) {
|
|
|
|
unsigned ArgValSlot = read_vbr_uint();
|
2006-11-14 04:47:22 +00:00
|
|
|
unsigned ArgTypeSlot = read_vbr_uint();
|
2005-04-21 21:44:41 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
// Get the arg value from its slot if it exists, otherwise a placeholder
|
|
|
|
ArgVec.push_back(getConstantValue(ArgTypeSlot, ArgValSlot));
|
|
|
|
}
|
2005-04-21 21:44:41 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
// Construct a ConstantExpr of the appropriate kind
|
|
|
|
if (isExprNumArgs == 1) { // All one-operand expressions
|
2006-11-27 01:05:10 +00:00
|
|
|
if (!Instruction::isCast(Opcode))
|
2004-12-04 05:28:27 +00:00
|
|
|
error("Only cast instruction has one argument for ConstantExpr");
|
2004-07-11 17:28:43 +00:00
|
|
|
|
2006-12-11 23:20:20 +00:00
|
|
|
Constant *Result = ConstantExpr::getCast(Opcode, ArgVec[0],
|
|
|
|
getType(TypeID));
|
2007-02-07 05:08:39 +00:00
|
|
|
if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
|
|
|
|
ArgVec.size(), Result);
|
2004-06-29 23:29:38 +00:00
|
|
|
return Result;
|
|
|
|
} else if (Opcode == Instruction::GetElementPtr) { // GetElementPtr
|
2007-01-31 04:43:46 +00:00
|
|
|
Constant *Result = ConstantExpr::getGetElementPtr(ArgVec[0], &ArgVec[1],
|
|
|
|
ArgVec.size()-1);
|
2007-02-07 05:08:39 +00:00
|
|
|
if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
|
|
|
|
ArgVec.size(), Result);
|
2004-06-29 23:29:38 +00:00
|
|
|
return Result;
|
|
|
|
} else if (Opcode == Instruction::Select) {
|
2004-07-11 17:28:43 +00:00
|
|
|
if (ArgVec.size() != 3)
|
|
|
|
error("Select instruction must have three arguments.");
|
2005-04-21 21:44:41 +00:00
|
|
|
Constant* Result = ConstantExpr::getSelect(ArgVec[0], ArgVec[1],
|
2004-07-04 11:33:49 +00:00
|
|
|
ArgVec[2]);
|
2007-02-07 05:08:39 +00:00
|
|
|
if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
|
|
|
|
ArgVec.size(), Result);
|
2004-06-29 23:29:38 +00:00
|
|
|
return Result;
|
2006-01-10 19:04:39 +00:00
|
|
|
} else if (Opcode == Instruction::ExtractElement) {
|
2006-04-08 04:09:19 +00:00
|
|
|
if (ArgVec.size() != 2 ||
|
|
|
|
!ExtractElementInst::isValidOperands(ArgVec[0], ArgVec[1]))
|
|
|
|
error("Invalid extractelement constand expr arguments");
|
2006-01-10 19:04:39 +00:00
|
|
|
Constant* Result = ConstantExpr::getExtractElement(ArgVec[0], ArgVec[1]);
|
2007-02-07 05:08:39 +00:00
|
|
|
if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
|
|
|
|
ArgVec.size(), Result);
|
2006-01-10 19:04:39 +00:00
|
|
|
return Result;
|
2006-01-17 20:06:35 +00:00
|
|
|
} else if (Opcode == Instruction::InsertElement) {
|
2006-04-08 04:09:19 +00:00
|
|
|
if (ArgVec.size() != 3 ||
|
|
|
|
!InsertElementInst::isValidOperands(ArgVec[0], ArgVec[1], ArgVec[2]))
|
|
|
|
error("Invalid insertelement constand expr arguments");
|
|
|
|
|
|
|
|
Constant *Result =
|
2006-01-17 20:06:35 +00:00
|
|
|
ConstantExpr::getInsertElement(ArgVec[0], ArgVec[1], ArgVec[2]);
|
2007-02-07 05:08:39 +00:00
|
|
|
if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
|
|
|
|
ArgVec.size(), Result);
|
2006-01-17 20:06:35 +00:00
|
|
|
return Result;
|
2006-04-08 01:17:59 +00:00
|
|
|
} else if (Opcode == Instruction::ShuffleVector) {
|
|
|
|
if (ArgVec.size() != 3 ||
|
|
|
|
!ShuffleVectorInst::isValidOperands(ArgVec[0], ArgVec[1], ArgVec[2]))
|
2006-04-08 04:09:19 +00:00
|
|
|
error("Invalid shufflevector constant expr arguments.");
|
2006-04-08 01:17:59 +00:00
|
|
|
Constant *Result =
|
|
|
|
ConstantExpr::getShuffleVector(ArgVec[0], ArgVec[1], ArgVec[2]);
|
2007-02-07 05:08:39 +00:00
|
|
|
if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
|
|
|
|
ArgVec.size(), Result);
|
2006-04-08 01:17:59 +00:00
|
|
|
return Result;
|
2006-12-03 17:17:02 +00:00
|
|
|
} else if (Opcode == Instruction::ICmp) {
|
|
|
|
if (ArgVec.size() != 2)
|
2006-12-04 05:23:49 +00:00
|
|
|
error("Invalid ICmp constant expr arguments.");
|
|
|
|
unsigned predicate = read_vbr_uint();
|
|
|
|
Constant *Result = ConstantExpr::getICmp(predicate, ArgVec[0], ArgVec[1]);
|
2007-02-07 05:08:39 +00:00
|
|
|
if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
|
|
|
|
ArgVec.size(), Result);
|
2006-12-04 05:23:49 +00:00
|
|
|
return Result;
|
2006-12-03 17:17:02 +00:00
|
|
|
} else if (Opcode == Instruction::FCmp) {
|
|
|
|
if (ArgVec.size() != 2)
|
2006-12-04 05:23:49 +00:00
|
|
|
error("Invalid FCmp constant expr arguments.");
|
|
|
|
unsigned predicate = read_vbr_uint();
|
|
|
|
Constant *Result = ConstantExpr::getFCmp(predicate, ArgVec[0], ArgVec[1]);
|
2007-02-07 05:08:39 +00:00
|
|
|
if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
|
|
|
|
ArgVec.size(), Result);
|
2006-12-04 05:23:49 +00:00
|
|
|
return Result;
|
2004-06-29 23:29:38 +00:00
|
|
|
} else { // All other 2-operand expressions
|
|
|
|
Constant* Result = ConstantExpr::get(Opcode, ArgVec[0], ArgVec[1]);
|
2007-02-07 05:08:39 +00:00
|
|
|
if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
|
|
|
|
ArgVec.size(), Result);
|
2004-06-29 23:29:38 +00:00
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
}
|
2005-04-21 21:44:41 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
// Ok, not an ConstantExpr. We now know how to read the given type...
|
|
|
|
const Type *Ty = getType(TypeID);
|
2006-04-07 05:00:02 +00:00
|
|
|
Constant *Result = 0;
|
2004-06-29 23:29:38 +00:00
|
|
|
switch (Ty->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: {
|
|
|
|
const IntegerType *IT = cast<IntegerType>(Ty);
|
|
|
|
if (IT->getBitWidth() <= 32) {
|
|
|
|
uint32_t Val = read_vbr_uint();
|
2007-01-13 00:09:12 +00:00
|
|
|
if (!ConstantInt::isValueValidForType(Ty, uint64_t(Val)))
|
|
|
|
error("Integer value read is invalid for type.");
|
|
|
|
Result = ConstantInt::get(IT, Val);
|
|
|
|
if (Handler) Handler->handleConstantValue(Result);
|
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
|
|
|
} else if (IT->getBitWidth() <= 64) {
|
|
|
|
uint64_t Val = read_vbr_uint64();
|
|
|
|
if (!ConstantInt::isValueValidForType(Ty, Val))
|
|
|
|
error("Invalid constant integer read.");
|
|
|
|
Result = ConstantInt::get(IT, Val);
|
|
|
|
if (Handler) Handler->handleConstantValue(Result);
|
|
|
|
} else
|
|
|
|
assert("Integer types > 64 bits not supported");
|
2006-04-07 05:00:02 +00:00
|
|
|
break;
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
|
|
|
case Type::FloatTyID: {
|
2004-07-11 17:28:43 +00:00
|
|
|
float Val;
|
|
|
|
read_float(Val);
|
2006-04-07 05:00:02 +00:00
|
|
|
Result = ConstantFP::get(Ty, Val);
|
2004-07-04 11:33:49 +00:00
|
|
|
if (Handler) Handler->handleConstantValue(Result);
|
2006-04-07 05:00:02 +00:00
|
|
|
break;
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
case Type::DoubleTyID: {
|
|
|
|
double Val;
|
2004-07-11 17:28:43 +00:00
|
|
|
read_double(Val);
|
2006-04-07 05:00:02 +00:00
|
|
|
Result = ConstantFP::get(Ty, Val);
|
2004-07-04 11:33:49 +00:00
|
|
|
if (Handler) Handler->handleConstantValue(Result);
|
2006-04-07 05:00:02 +00:00
|
|
|
break;
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
case Type::ArrayTyID: {
|
|
|
|
const ArrayType *AT = cast<ArrayType>(Ty);
|
|
|
|
unsigned NumElements = AT->getNumElements();
|
|
|
|
unsigned TypeSlot = getTypeSlot(AT->getElementType());
|
|
|
|
std::vector<Constant*> Elements;
|
|
|
|
Elements.reserve(NumElements);
|
|
|
|
while (NumElements--) // Read all of the elements of the constant.
|
|
|
|
Elements.push_back(getConstantValue(TypeSlot,
|
|
|
|
read_vbr_uint()));
|
2006-04-07 05:00:02 +00:00
|
|
|
Result = ConstantArray::get(AT, Elements);
|
2007-02-07 05:08:39 +00:00
|
|
|
if (Handler) Handler->handleConstantArray(AT, &Elements[0], Elements.size(),
|
|
|
|
TypeSlot, Result);
|
2006-04-07 05:00:02 +00:00
|
|
|
break;
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
case Type::StructTyID: {
|
|
|
|
const StructType *ST = cast<StructType>(Ty);
|
|
|
|
|
|
|
|
std::vector<Constant *> Elements;
|
|
|
|
Elements.reserve(ST->getNumElements());
|
|
|
|
for (unsigned i = 0; i != ST->getNumElements(); ++i)
|
|
|
|
Elements.push_back(getConstantValue(ST->getElementType(i),
|
|
|
|
read_vbr_uint()));
|
|
|
|
|
2006-04-07 05:00:02 +00:00
|
|
|
Result = ConstantStruct::get(ST, Elements);
|
2007-02-07 05:08:39 +00:00
|
|
|
if (Handler) Handler->handleConstantStruct(ST, &Elements[0],Elements.size(),
|
|
|
|
Result);
|
2006-04-07 05:00:02 +00:00
|
|
|
break;
|
2005-04-21 21:44:41 +00:00
|
|
|
}
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2004-08-20 06:00:58 +00:00
|
|
|
case Type::PackedTyID: {
|
|
|
|
const PackedType *PT = cast<PackedType>(Ty);
|
|
|
|
unsigned NumElements = PT->getNumElements();
|
|
|
|
unsigned TypeSlot = getTypeSlot(PT->getElementType());
|
|
|
|
std::vector<Constant*> Elements;
|
|
|
|
Elements.reserve(NumElements);
|
|
|
|
while (NumElements--) // Read all of the elements of the constant.
|
|
|
|
Elements.push_back(getConstantValue(TypeSlot,
|
|
|
|
read_vbr_uint()));
|
2006-04-07 05:00:02 +00:00
|
|
|
Result = ConstantPacked::get(PT, Elements);
|
2007-02-07 05:08:39 +00:00
|
|
|
if (Handler) Handler->handleConstantPacked(PT, &Elements[0],Elements.size(),
|
|
|
|
TypeSlot, Result);
|
2006-04-07 05:00:02 +00:00
|
|
|
break;
|
2004-08-20 06:00:58 +00:00
|
|
|
}
|
|
|
|
|
2004-11-19 16:24:05 +00:00
|
|
|
case Type::PointerTyID: { // ConstantPointerRef value (backwards compat).
|
2004-06-29 23:29:38 +00:00
|
|
|
const PointerType *PT = cast<PointerType>(Ty);
|
|
|
|
unsigned Slot = read_vbr_uint();
|
2005-04-21 21:44:41 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
// Check to see if we have already read this global variable...
|
|
|
|
Value *Val = getValue(TypeID, Slot, false);
|
|
|
|
if (Val) {
|
2004-07-27 02:34:49 +00:00
|
|
|
GlobalValue *GV = dyn_cast<GlobalValue>(Val);
|
|
|
|
if (!GV) error("GlobalValue not in ValueTable!");
|
|
|
|
if (Handler) Handler->handleConstantPointer(PT, Slot, GV);
|
|
|
|
return GV;
|
2004-06-29 23:29:38 +00:00
|
|
|
} else {
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Forward references are not allowed here.");
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Don't know how to deserialize constant value of type '" +
|
2004-06-29 23:29:38 +00:00
|
|
|
Ty->getDescription());
|
|
|
|
break;
|
|
|
|
}
|
2006-04-07 05:00:02 +00:00
|
|
|
|
|
|
|
// Check that we didn't read a null constant if they are implicit for this
|
|
|
|
// type plane. Do not do this check for constantexprs, as they may be folded
|
|
|
|
// to a null value in a way that isn't predicted when a .bc file is initially
|
|
|
|
// produced.
|
|
|
|
assert((!isa<Constant>(Result) || !cast<Constant>(Result)->isNullValue()) ||
|
|
|
|
!hasImplicitNull(TypeID) &&
|
|
|
|
"Cannot read null values from bytecode!");
|
|
|
|
return Result;
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
|
2005-04-21 21:44:41 +00:00
|
|
|
/// Resolve references for constants. This function resolves the forward
|
|
|
|
/// referenced constants in the ConstantFwdRefs map. It uses the
|
2004-07-04 11:33:49 +00:00
|
|
|
/// replaceAllUsesWith method of Value class to substitute the placeholder
|
|
|
|
/// instance with the actual instance.
|
2004-12-09 06:19:44 +00:00
|
|
|
void BytecodeReader::ResolveReferencesToConstant(Constant *NewV, unsigned Typ,
|
|
|
|
unsigned Slot) {
|
2003-11-19 17:27:18 +00:00
|
|
|
ConstantRefsType::iterator I =
|
2004-12-09 06:19:44 +00:00
|
|
|
ConstantFwdRefs.find(std::make_pair(Typ, Slot));
|
2003-11-19 17:27:18 +00:00
|
|
|
if (I == ConstantFwdRefs.end()) return; // Never forward referenced?
|
2002-07-14 23:04:18 +00:00
|
|
|
|
2003-11-19 17:27:18 +00:00
|
|
|
Value *PH = I->second; // Get the placeholder...
|
|
|
|
PH->replaceAllUsesWith(NewV);
|
|
|
|
delete PH; // Delete the old placeholder
|
|
|
|
ConstantFwdRefs.erase(I); // Remove the map entry for it
|
2002-07-14 23:04:18 +00:00
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Parse the constant strings section.
|
2004-06-29 23:29:38 +00:00
|
|
|
void BytecodeReader::ParseStringConstants(unsigned NumEntries, ValueTable &Tab){
|
|
|
|
for (; NumEntries; --NumEntries) {
|
2006-11-14 04:47:22 +00:00
|
|
|
unsigned Typ = read_vbr_uint();
|
2004-06-29 23:29:38 +00:00
|
|
|
const Type *Ty = getType(Typ);
|
|
|
|
if (!isa<ArrayType>(Ty))
|
2004-07-09 22:21:33 +00:00
|
|
|
error("String constant data invalid!");
|
2005-04-21 21:44:41 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
const ArrayType *ATy = cast<ArrayType>(Ty);
|
2006-12-31 05:44:24 +00:00
|
|
|
if (ATy->getElementType() != Type::Int8Ty &&
|
|
|
|
ATy->getElementType() != Type::Int8Ty)
|
2004-07-09 22:21:33 +00:00
|
|
|
error("String constant data invalid!");
|
2005-04-21 21:44:41 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
// Read character data. The type tells us how long the string is.
|
2005-04-21 21:44:41 +00:00
|
|
|
char *Data = reinterpret_cast<char *>(alloca(ATy->getNumElements()));
|
2004-06-29 23:29:38 +00:00
|
|
|
read_data(Data, Data+ATy->getNumElements());
|
|
|
|
|
|
|
|
std::vector<Constant*> Elements(ATy->getNumElements());
|
2006-10-20 07:07:24 +00:00
|
|
|
const Type* ElemType = ATy->getElementType();
|
|
|
|
for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
|
|
|
|
Elements[i] = ConstantInt::get(ElemType, (unsigned char)Data[i]);
|
2004-06-29 23:29:38 +00:00
|
|
|
|
|
|
|
// Create the constant, inserting it as needed.
|
|
|
|
Constant *C = ConstantArray::get(ATy, Elements);
|
|
|
|
unsigned Slot = insertValue(C, Typ, Tab);
|
2004-12-09 06:19:44 +00:00
|
|
|
ResolveReferencesToConstant(C, Typ, Slot);
|
2004-07-04 11:33:49 +00:00
|
|
|
if (Handler) Handler->handleConstantString(cast<ConstantArray>(C));
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
2003-09-22 23:38:23 +00:00
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Parse the constant pool.
|
2005-04-21 21:44:41 +00:00
|
|
|
void BytecodeReader::ParseConstantPool(ValueTable &Tab,
|
2004-07-04 11:33:49 +00:00
|
|
|
TypeListTy &TypeTab,
|
2004-07-11 17:28:43 +00:00
|
|
|
bool isFunction) {
|
2004-07-04 11:33:49 +00:00
|
|
|
if (Handler) Handler->handleGlobalConstantsBegin();
|
|
|
|
|
|
|
|
/// In LLVM 1.3 Type does not derive from Value so the types
|
|
|
|
/// do not occupy a plane. Consequently, we read the types
|
|
|
|
/// first in the constant pool.
|
2006-11-14 04:47:22 +00:00
|
|
|
if (isFunction) {
|
2004-07-04 11:33:49 +00:00
|
|
|
unsigned NumEntries = read_vbr_uint();
|
2004-07-11 17:28:43 +00:00
|
|
|
ParseTypes(TypeTab, NumEntries);
|
2004-07-04 11:33:49 +00:00
|
|
|
}
|
|
|
|
|
2004-07-11 17:28:43 +00:00
|
|
|
while (moreInBlock()) {
|
2004-06-29 23:29:38 +00:00
|
|
|
unsigned NumEntries = read_vbr_uint();
|
2006-11-14 04:47:22 +00:00
|
|
|
unsigned Typ = read_vbr_uint();
|
|
|
|
|
|
|
|
if (Typ == Type::VoidTyID) {
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Use of Type::VoidTyID is a misnomer. It actually means
|
|
|
|
/// that the following plane is constant strings
|
2004-06-29 23:29:38 +00:00
|
|
|
assert(&Tab == &ModuleValues && "Cannot read strings in functions!");
|
|
|
|
ParseStringConstants(NumEntries, Tab);
|
|
|
|
} else {
|
|
|
|
for (unsigned i = 0; i < NumEntries; ++i) {
|
2006-01-25 23:08:15 +00:00
|
|
|
Value *V = ParseConstantPoolValue(Typ);
|
|
|
|
assert(V && "ParseConstantPoolValue returned NULL!");
|
|
|
|
unsigned Slot = insertValue(V, Typ, Tab);
|
2004-06-29 23:29:38 +00:00
|
|
|
|
|
|
|
// If we are reading a function constant table, make sure that we adjust
|
|
|
|
// the slot number to be the real global constant number.
|
|
|
|
//
|
|
|
|
if (&Tab != &ModuleValues && Typ < ModuleValues.size() &&
|
|
|
|
ModuleValues[Typ])
|
|
|
|
Slot += ModuleValues[Typ]->size();
|
2006-01-25 23:08:15 +00:00
|
|
|
if (Constant *C = dyn_cast<Constant>(V))
|
|
|
|
ResolveReferencesToConstant(C, Typ, Slot);
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-12-04 05:28:27 +00:00
|
|
|
|
|
|
|
// After we have finished parsing the constant pool, we had better not have
|
|
|
|
// any dangling references left.
|
2004-12-04 22:19:53 +00:00
|
|
|
if (!ConstantFwdRefs.empty()) {
|
|
|
|
ConstantRefsType::const_iterator I = ConstantFwdRefs.begin();
|
|
|
|
Constant* missingConst = I->second;
|
2005-04-21 21:44:41 +00:00
|
|
|
error(utostr(ConstantFwdRefs.size()) +
|
|
|
|
" unresolved constant reference exist. First one is '" +
|
|
|
|
missingConst->getName() + "' of type '" +
|
2004-12-09 06:19:44 +00:00
|
|
|
missingConst->getType()->getDescription() + "'.");
|
2004-12-04 22:19:53 +00:00
|
|
|
}
|
2004-12-04 05:28:27 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
checkPastBlockEnd("Constant Pool");
|
2004-07-04 11:33:49 +00:00
|
|
|
if (Handler) Handler->handleGlobalConstantsEnd();
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
2003-11-19 17:27:18 +00:00
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Parse the contents of a function. Note that this function can be
|
|
|
|
/// called lazily by materializeFunction
|
|
|
|
/// @see materializeFunction
|
2004-07-11 17:28:43 +00:00
|
|
|
void BytecodeReader::ParseFunctionBody(Function* F) {
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
unsigned FuncSize = BlockEnd - At;
|
2003-04-16 21:16:05 +00:00
|
|
|
GlobalValue::LinkageTypes Linkage = GlobalValue::ExternalLinkage;
|
2007-01-12 19:20:47 +00:00
|
|
|
GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;
|
2003-04-16 21:16:05 +00:00
|
|
|
|
2007-01-12 19:20:47 +00:00
|
|
|
unsigned rWord = read_vbr_uint();
|
|
|
|
unsigned LinkageID = rWord & 65535;
|
|
|
|
unsigned VisibilityID = rWord >> 16;
|
|
|
|
switch (LinkageID) {
|
2004-01-14 16:44:44 +00:00
|
|
|
case 0: Linkage = GlobalValue::ExternalLinkage; break;
|
|
|
|
case 1: Linkage = GlobalValue::WeakLinkage; break;
|
|
|
|
case 2: Linkage = GlobalValue::AppendingLinkage; break;
|
|
|
|
case 3: Linkage = GlobalValue::InternalLinkage; break;
|
|
|
|
case 4: Linkage = GlobalValue::LinkOnceLinkage; break;
|
2006-09-14 18:23:27 +00:00
|
|
|
case 5: Linkage = GlobalValue::DLLImportLinkage; break;
|
|
|
|
case 6: Linkage = GlobalValue::DLLExportLinkage; break;
|
|
|
|
case 7: Linkage = GlobalValue::ExternalWeakLinkage; break;
|
2004-06-29 23:29:38 +00:00
|
|
|
default:
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Invalid linkage type for Function.");
|
2004-06-29 23:29:38 +00:00
|
|
|
Linkage = GlobalValue::InternalLinkage;
|
|
|
|
break;
|
2003-04-16 21:16:05 +00:00
|
|
|
}
|
2007-01-12 19:20:47 +00:00
|
|
|
switch (VisibilityID) {
|
|
|
|
case 0: Visibility = GlobalValue::DefaultVisibility; break;
|
|
|
|
case 1: Visibility = GlobalValue::HiddenVisibility; break;
|
|
|
|
default:
|
|
|
|
error("Unknown visibility type: " + utostr(VisibilityID));
|
|
|
|
Visibility = GlobalValue::DefaultVisibility;
|
|
|
|
break;
|
|
|
|
}
|
2001-11-26 18:56:10 +00:00
|
|
|
|
2004-07-11 17:28:43 +00:00
|
|
|
F->setLinkage(Linkage);
|
2007-01-12 19:20:47 +00:00
|
|
|
F->setVisibility(Visibility);
|
2004-07-04 11:33:49 +00:00
|
|
|
if (Handler) Handler->handleFunctionBegin(F,FuncSize);
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2003-10-08 22:52:54 +00:00
|
|
|
// Keep track of how many basic blocks we have read in...
|
|
|
|
unsigned BlockNum = 0;
|
2004-01-18 21:08:15 +00:00
|
|
|
bool InsertedArguments = false;
|
2003-10-08 22:52:54 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
BufPtr MyEnd = BlockEnd;
|
2004-07-11 17:28:43 +00:00
|
|
|
while (At < MyEnd) {
|
2001-06-06 20:29:01 +00:00
|
|
|
unsigned Type, Size;
|
2004-06-29 23:29:38 +00:00
|
|
|
BufPtr OldAt = At;
|
|
|
|
read_block(Type, Size);
|
2001-06-06 20:29:01 +00:00
|
|
|
|
|
|
|
switch (Type) {
|
2004-07-25 18:07:36 +00:00
|
|
|
case BytecodeFormat::ConstantPoolBlockID:
|
2004-01-18 21:08:15 +00:00
|
|
|
if (!InsertedArguments) {
|
|
|
|
// Insert arguments into the value table before we parse the first basic
|
Bye, Bye Compaction Tables. The benefit compaction tables provides doesn't
outweight its computational costs. This patch removes all compaction
table handling from the bcreader and bcwriter. For the record, here's the
difference betweeen having and not having compaction tables for some tests:
Test With Without Size Chg
Olden/mst 5,602 5,598 +0.1%
viterbi 18,026 17,795 +1.3%
obsequi 162,133 166,663 -2.8%
burg 224,090 228,148 -1.8%
kimwitu++ 4,933,263 5,121,159 -3.8%
176.gcc 8,470,424 9,141,539 -7.3%
It seems that it is more beneficial to larger files, but even on the largest
test case we have (176.gcc) it only amounts ot an I/O saving of 7.3%.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33661 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-30 19:36:46 +00:00
|
|
|
// block in the function
|
2004-07-04 11:33:49 +00:00
|
|
|
insertArguments(F);
|
2004-01-18 21:08:15 +00:00
|
|
|
InsertedArguments = true;
|
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
ParseConstantPool(FunctionValues, FunctionTypes, true);
|
2001-06-06 20:29:01 +00:00
|
|
|
break;
|
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
case BytecodeFormat::InstructionListBlockID: {
|
2004-01-18 21:08:15 +00:00
|
|
|
// Insert arguments into the value table before we parse the instruction
|
Bye, Bye Compaction Tables. The benefit compaction tables provides doesn't
outweight its computational costs. This patch removes all compaction
table handling from the bcreader and bcwriter. For the record, here's the
difference betweeen having and not having compaction tables for some tests:
Test With Without Size Chg
Olden/mst 5,602 5,598 +0.1%
viterbi 18,026 17,795 +1.3%
obsequi 162,133 166,663 -2.8%
burg 224,090 228,148 -1.8%
kimwitu++ 4,933,263 5,121,159 -3.8%
176.gcc 8,470,424 9,141,539 -7.3%
It seems that it is more beneficial to larger files, but even on the largest
test case we have (176.gcc) it only amounts ot an I/O saving of 7.3%.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33661 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-30 19:36:46 +00:00
|
|
|
// list for the function
|
2004-01-18 21:08:15 +00:00
|
|
|
if (!InsertedArguments) {
|
2004-07-04 11:33:49 +00:00
|
|
|
insertArguments(F);
|
2004-01-18 21:08:15 +00:00
|
|
|
InsertedArguments = true;
|
|
|
|
}
|
|
|
|
|
2005-04-21 21:44:41 +00:00
|
|
|
if (BlockNum)
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Already parsed basic blocks!");
|
2004-06-29 23:29:38 +00:00
|
|
|
BlockNum = ParseInstructionList(F);
|
2003-12-01 07:05:31 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-01-06 07:24:44 +00:00
|
|
|
case BytecodeFormat::ValueSymbolTableBlockID:
|
|
|
|
ParseValueSymbolTable(F, &F->getValueSymbolTable());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BytecodeFormat::TypeSymbolTableBlockID:
|
|
|
|
error("Functions don't have type symbol tables");
|
2001-06-06 20:29:01 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2004-06-29 23:29:38 +00:00
|
|
|
At += Size;
|
2005-04-21 21:44:41 +00:00
|
|
|
if (OldAt > At)
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Wrapped around reading bytecode.");
|
2001-06-06 20:29:01 +00:00
|
|
|
break;
|
|
|
|
}
|
2004-06-29 23:29:38 +00:00
|
|
|
BlockEnd = MyEnd;
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
|
2003-10-08 22:52:54 +00:00
|
|
|
// Make sure there were no references to non-existant basic blocks.
|
|
|
|
if (BlockNum != ParsedBasicBlocks.size())
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Illegal basic block operand reference");
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2003-10-08 22:52:54 +00:00
|
|
|
ParsedBasicBlocks.clear();
|
|
|
|
|
2003-10-09 23:10:14 +00:00
|
|
|
// Resolve forward references. Replace any uses of a forward reference value
|
|
|
|
// with the real value.
|
2003-10-09 06:05:40 +00:00
|
|
|
while (!ForwardReferences.empty()) {
|
2004-12-09 04:51:50 +00:00
|
|
|
std::map<std::pair<unsigned,unsigned>, Value*>::iterator
|
|
|
|
I = ForwardReferences.begin();
|
|
|
|
Value *V = getValue(I->first.first, I->first.second, false);
|
2003-10-09 06:05:40 +00:00
|
|
|
Value *PlaceHolder = I->second;
|
2004-12-09 04:51:50 +00:00
|
|
|
PlaceHolder->replaceAllUsesWith(V);
|
2003-10-09 06:05:40 +00:00
|
|
|
ForwardReferences.erase(I);
|
|
|
|
delete PlaceHolder;
|
2003-10-08 21:51:46 +00:00
|
|
|
}
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2003-09-22 23:38:23 +00:00
|
|
|
// Clear out function-level types...
|
2004-06-29 23:29:38 +00:00
|
|
|
FunctionTypes.clear();
|
|
|
|
freeTable(FunctionValues);
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
if (Handler) Handler->handleFunctionEnd(F);
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// This function parses LLVM functions lazily. It obtains the type of the
|
|
|
|
/// function and records where the body of the function is in the bytecode
|
2005-04-21 21:44:41 +00:00
|
|
|
/// buffer. The caller can then use the ParseNextFunction and
|
2004-07-04 11:33:49 +00:00
|
|
|
/// ParseAllFunctionBodies to get handler events for the functions.
|
2004-06-29 23:29:38 +00:00
|
|
|
void BytecodeReader::ParseFunctionLazily() {
|
|
|
|
if (FunctionSignatureList.empty())
|
2004-07-09 22:21:33 +00:00
|
|
|
error("FunctionSignatureList empty!");
|
2004-01-18 21:08:15 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
Function *Func = FunctionSignatureList.back();
|
|
|
|
FunctionSignatureList.pop_back();
|
2004-01-18 22:35:34 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
// Save the information for future reading of the function
|
|
|
|
LazyFunctionLoadMap[Func] = LazyFunctionInfo(BlockStart, BlockEnd);
|
2004-01-18 21:08:15 +00:00
|
|
|
|
2004-11-14 21:02:55 +00:00
|
|
|
// This function has a body but it's not loaded so it appears `External'.
|
|
|
|
// Mark it as a `Ghost' instead to notify the users that it has a body.
|
|
|
|
Func->setLinkage(GlobalValue::GhostLinkage);
|
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
// Pretend we've `parsed' this function
|
|
|
|
At = BlockEnd;
|
|
|
|
}
|
2004-01-18 21:08:15 +00:00
|
|
|
|
2005-04-21 21:44:41 +00:00
|
|
|
/// The ParserFunction method lazily parses one function. Use this method to
|
|
|
|
/// casue the parser to parse a specific function in the module. Note that
|
|
|
|
/// this will remove the function from what is to be included by
|
2004-07-04 11:33:49 +00:00
|
|
|
/// ParseAllFunctionBodies.
|
|
|
|
/// @see ParseAllFunctionBodies
|
|
|
|
/// @see ParseBytecode
|
For PR797:
Final commit for this bug. This removes the last EH holdouts in LLVM
and turns off exception support by using the -fno-exceptions option. This
leads to the following reduction in library and executable sizes:
DEBUG BUILD RELEASE BUILD
before after delta before after delta
lib 162,328K 157,616K 4,712 17,864K 16,416K 1,448K
bin 571,444K 557,156K 14,288 63,296K 56,996K 6,300K
Debug Improvement: 19,000K (2.59%)
Release Improvement: 7,748K (9.55%)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29882 91177308-0d34-0410-b5e6-96231b3b80d8
2006-08-25 19:54:53 +00:00
|
|
|
bool BytecodeReader::ParseFunction(Function* Func, std::string* ErrMsg) {
|
|
|
|
|
2006-12-15 19:49:23 +00:00
|
|
|
if (setjmp(context)) {
|
|
|
|
// Set caller's error message, if requested
|
|
|
|
if (ErrMsg)
|
|
|
|
*ErrMsg = ErrorMsg;
|
|
|
|
// Indicate an error occurred
|
For PR797:
Final commit for this bug. This removes the last EH holdouts in LLVM
and turns off exception support by using the -fno-exceptions option. This
leads to the following reduction in library and executable sizes:
DEBUG BUILD RELEASE BUILD
before after delta before after delta
lib 162,328K 157,616K 4,712 17,864K 16,416K 1,448K
bin 571,444K 557,156K 14,288 63,296K 56,996K 6,300K
Debug Improvement: 19,000K (2.59%)
Release Improvement: 7,748K (9.55%)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29882 91177308-0d34-0410-b5e6-96231b3b80d8
2006-08-25 19:54:53 +00:00
|
|
|
return true;
|
2006-12-15 19:49:23 +00:00
|
|
|
}
|
For PR797:
Final commit for this bug. This removes the last EH holdouts in LLVM
and turns off exception support by using the -fno-exceptions option. This
leads to the following reduction in library and executable sizes:
DEBUG BUILD RELEASE BUILD
before after delta before after delta
lib 162,328K 157,616K 4,712 17,864K 16,416K 1,448K
bin 571,444K 557,156K 14,288 63,296K 56,996K 6,300K
Debug Improvement: 19,000K (2.59%)
Release Improvement: 7,748K (9.55%)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29882 91177308-0d34-0410-b5e6-96231b3b80d8
2006-08-25 19:54:53 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
// Find {start, end} pointers and slot in the map. If not there, we're done.
|
|
|
|
LazyFunctionMap::iterator Fi = LazyFunctionLoadMap.find(Func);
|
2004-01-18 21:08:15 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
// Make sure we found it
|
2004-07-11 17:28:43 +00:00
|
|
|
if (Fi == LazyFunctionLoadMap.end()) {
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Unrecognized function of type " + Func->getType()->getDescription());
|
For PR797:
Final commit for this bug. This removes the last EH holdouts in LLVM
and turns off exception support by using the -fno-exceptions option. This
leads to the following reduction in library and executable sizes:
DEBUG BUILD RELEASE BUILD
before after delta before after delta
lib 162,328K 157,616K 4,712 17,864K 16,416K 1,448K
bin 571,444K 557,156K 14,288 63,296K 56,996K 6,300K
Debug Improvement: 19,000K (2.59%)
Release Improvement: 7,748K (9.55%)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29882 91177308-0d34-0410-b5e6-96231b3b80d8
2006-08-25 19:54:53 +00:00
|
|
|
return true;
|
2004-01-18 21:08:15 +00:00
|
|
|
}
|
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
BlockStart = At = Fi->second.Buf;
|
|
|
|
BlockEnd = Fi->second.EndBuf;
|
2004-07-09 22:21:33 +00:00
|
|
|
assert(Fi->first == Func && "Found wrong function?");
|
2004-06-29 23:29:38 +00:00
|
|
|
|
|
|
|
LazyFunctionLoadMap.erase(Fi);
|
|
|
|
|
2004-07-11 17:28:43 +00:00
|
|
|
this->ParseFunctionBody(Func);
|
For PR797:
Final commit for this bug. This removes the last EH holdouts in LLVM
and turns off exception support by using the -fno-exceptions option. This
leads to the following reduction in library and executable sizes:
DEBUG BUILD RELEASE BUILD
before after delta before after delta
lib 162,328K 157,616K 4,712 17,864K 16,416K 1,448K
bin 571,444K 557,156K 14,288 63,296K 56,996K 6,300K
Debug Improvement: 19,000K (2.59%)
Release Improvement: 7,748K (9.55%)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29882 91177308-0d34-0410-b5e6-96231b3b80d8
2006-08-25 19:54:53 +00:00
|
|
|
return false;
|
2004-01-18 21:08:15 +00:00
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// The ParseAllFunctionBodies method parses through all the previously
|
|
|
|
/// unparsed functions in the bytecode file. If you want to completely parse
|
|
|
|
/// a bytecode file, this method should be called after Parsebytecode because
|
|
|
|
/// Parsebytecode only records the locations in the bytecode file of where
|
|
|
|
/// the function definitions are located. This function uses that information
|
|
|
|
/// to materialize the functions.
|
|
|
|
/// @see ParseBytecode
|
For PR797:
Final commit for this bug. This removes the last EH holdouts in LLVM
and turns off exception support by using the -fno-exceptions option. This
leads to the following reduction in library and executable sizes:
DEBUG BUILD RELEASE BUILD
before after delta before after delta
lib 162,328K 157,616K 4,712 17,864K 16,416K 1,448K
bin 571,444K 557,156K 14,288 63,296K 56,996K 6,300K
Debug Improvement: 19,000K (2.59%)
Release Improvement: 7,748K (9.55%)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29882 91177308-0d34-0410-b5e6-96231b3b80d8
2006-08-25 19:54:53 +00:00
|
|
|
bool BytecodeReader::ParseAllFunctionBodies(std::string* ErrMsg) {
|
2006-12-15 19:49:23 +00:00
|
|
|
if (setjmp(context)) {
|
|
|
|
// Set caller's error message, if requested
|
|
|
|
if (ErrMsg)
|
|
|
|
*ErrMsg = ErrorMsg;
|
|
|
|
// Indicate an error occurred
|
For PR797:
Final commit for this bug. This removes the last EH holdouts in LLVM
and turns off exception support by using the -fno-exceptions option. This
leads to the following reduction in library and executable sizes:
DEBUG BUILD RELEASE BUILD
before after delta before after delta
lib 162,328K 157,616K 4,712 17,864K 16,416K 1,448K
bin 571,444K 557,156K 14,288 63,296K 56,996K 6,300K
Debug Improvement: 19,000K (2.59%)
Release Improvement: 7,748K (9.55%)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29882 91177308-0d34-0410-b5e6-96231b3b80d8
2006-08-25 19:54:53 +00:00
|
|
|
return true;
|
2006-12-15 19:49:23 +00:00
|
|
|
}
|
For PR797:
Final commit for this bug. This removes the last EH holdouts in LLVM
and turns off exception support by using the -fno-exceptions option. This
leads to the following reduction in library and executable sizes:
DEBUG BUILD RELEASE BUILD
before after delta before after delta
lib 162,328K 157,616K 4,712 17,864K 16,416K 1,448K
bin 571,444K 557,156K 14,288 63,296K 56,996K 6,300K
Debug Improvement: 19,000K (2.59%)
Release Improvement: 7,748K (9.55%)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29882 91177308-0d34-0410-b5e6-96231b3b80d8
2006-08-25 19:54:53 +00:00
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
LazyFunctionMap::iterator Fi = LazyFunctionLoadMap.begin();
|
|
|
|
LazyFunctionMap::iterator Fe = LazyFunctionLoadMap.end();
|
|
|
|
|
2004-07-11 17:28:43 +00:00
|
|
|
while (Fi != Fe) {
|
2004-06-29 23:29:38 +00:00
|
|
|
Function* Func = Fi->first;
|
|
|
|
BlockStart = At = Fi->second.Buf;
|
|
|
|
BlockEnd = Fi->second.EndBuf;
|
2005-02-13 17:48:18 +00:00
|
|
|
ParseFunctionBody(Func);
|
2004-06-29 23:29:38 +00:00
|
|
|
++Fi;
|
|
|
|
}
|
2005-02-13 17:48:18 +00:00
|
|
|
LazyFunctionLoadMap.clear();
|
For PR797:
Final commit for this bug. This removes the last EH holdouts in LLVM
and turns off exception support by using the -fno-exceptions option. This
leads to the following reduction in library and executable sizes:
DEBUG BUILD RELEASE BUILD
before after delta before after delta
lib 162,328K 157,616K 4,712 17,864K 16,416K 1,448K
bin 571,444K 557,156K 14,288 63,296K 56,996K 6,300K
Debug Improvement: 19,000K (2.59%)
Release Improvement: 7,748K (9.55%)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29882 91177308-0d34-0410-b5e6-96231b3b80d8
2006-08-25 19:54:53 +00:00
|
|
|
return false;
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
2004-01-18 21:08:15 +00:00
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Parse the global type list
|
2004-06-29 23:29:38 +00:00
|
|
|
void BytecodeReader::ParseGlobalTypes() {
|
2004-07-04 11:33:49 +00:00
|
|
|
// Read the number of types
|
|
|
|
unsigned NumEntries = read_vbr_uint();
|
2004-07-11 17:28:43 +00:00
|
|
|
ParseTypes(ModuleTypes, NumEntries);
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
2004-01-18 21:08:15 +00:00
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Parse the Global info (types, global vars, constants)
|
2004-06-29 23:29:38 +00:00
|
|
|
void BytecodeReader::ParseModuleGlobalInfo() {
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
if (Handler) Handler->handleModuleGlobalsBegin();
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2005-11-12 01:33:40 +00:00
|
|
|
// SectionID - If a global has an explicit section specified, this map
|
|
|
|
// remembers the ID until we can translate it into a string.
|
|
|
|
std::map<GlobalValue*, unsigned> SectionID;
|
|
|
|
|
2001-09-10 07:58:01 +00:00
|
|
|
// Read global variables...
|
2004-06-29 23:29:38 +00:00
|
|
|
unsigned VarType = read_vbr_uint();
|
2001-09-10 07:58:01 +00:00
|
|
|
while (VarType != Type::VoidTyID) { // List is terminated by Void
|
2004-04-03 23:43:42 +00:00
|
|
|
// VarType Fields: bit0 = isConstant, bit1 = hasInitializer, bit2,3,4 =
|
|
|
|
// Linkage, bit4+ = slot#
|
|
|
|
unsigned SlotNo = VarType >> 5;
|
|
|
|
unsigned LinkageID = (VarType >> 2) & 7;
|
2007-01-12 19:20:47 +00:00
|
|
|
unsigned VisibilityID = 0;
|
2004-06-29 23:29:38 +00:00
|
|
|
bool isConstant = VarType & 1;
|
2005-11-06 08:23:17 +00:00
|
|
|
bool hasInitializer = (VarType & 2) != 0;
|
2005-11-06 07:11:04 +00:00
|
|
|
unsigned Alignment = 0;
|
2005-11-12 01:33:40 +00:00
|
|
|
unsigned GlobalSectionID = 0;
|
2005-11-06 07:11:04 +00:00
|
|
|
|
|
|
|
// An extension word is present when linkage = 3 (internal) and hasinit = 0.
|
|
|
|
if (LinkageID == 3 && !hasInitializer) {
|
|
|
|
unsigned ExtWord = read_vbr_uint();
|
|
|
|
// 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 section,
|
|
|
|
// bits 10-12 = visibility, bits 13+ = future use.
|
2005-11-06 07:11:04 +00:00
|
|
|
hasInitializer = ExtWord & 1;
|
|
|
|
LinkageID = (ExtWord >> 1) & 7;
|
|
|
|
Alignment = (1 << ((ExtWord >> 4) & 31)) >> 1;
|
2007-01-12 19:20:47 +00:00
|
|
|
VisibilityID = (ExtWord >> 10) & 7;
|
2005-11-12 01:33:40 +00:00
|
|
|
|
|
|
|
if (ExtWord & (1 << 9)) // Has a section ID.
|
|
|
|
GlobalSectionID = read_vbr_uint();
|
2005-11-06 07:11:04 +00:00
|
|
|
}
|
2003-04-16 21:16:05 +00:00
|
|
|
|
2005-11-06 08:23:17 +00:00
|
|
|
GlobalValue::LinkageTypes Linkage;
|
2004-01-14 16:44:44 +00:00
|
|
|
switch (LinkageID) {
|
|
|
|
case 0: Linkage = GlobalValue::ExternalLinkage; break;
|
|
|
|
case 1: Linkage = GlobalValue::WeakLinkage; break;
|
|
|
|
case 2: Linkage = GlobalValue::AppendingLinkage; break;
|
|
|
|
case 3: Linkage = GlobalValue::InternalLinkage; break;
|
|
|
|
case 4: Linkage = GlobalValue::LinkOnceLinkage; break;
|
2006-09-14 18:23:27 +00:00
|
|
|
case 5: Linkage = GlobalValue::DLLImportLinkage; break;
|
|
|
|
case 6: Linkage = GlobalValue::DLLExportLinkage; break;
|
|
|
|
case 7: Linkage = GlobalValue::ExternalWeakLinkage; break;
|
2005-04-21 21:44:41 +00:00
|
|
|
default:
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Unknown linkage type: " + utostr(LinkageID));
|
2004-06-29 23:29:38 +00:00
|
|
|
Linkage = GlobalValue::InternalLinkage;
|
|
|
|
break;
|
2003-04-16 21:16:05 +00:00
|
|
|
}
|
2007-01-12 19:20:47 +00:00
|
|
|
GlobalValue::VisibilityTypes Visibility;
|
|
|
|
switch (VisibilityID) {
|
|
|
|
case 0: Visibility = GlobalValue::DefaultVisibility; break;
|
|
|
|
case 1: Visibility = GlobalValue::HiddenVisibility; break;
|
|
|
|
default:
|
|
|
|
error("Unknown visibility type: " + utostr(VisibilityID));
|
|
|
|
Visibility = GlobalValue::DefaultVisibility;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2003-04-16 21:16:05 +00:00
|
|
|
const Type *Ty = getType(SlotNo);
|
2005-11-06 07:43:39 +00:00
|
|
|
if (!Ty)
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Global has no type! SlotNo=" + utostr(SlotNo));
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2005-11-06 07:43:39 +00:00
|
|
|
if (!isa<PointerType>(Ty))
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Global not a pointer type! Ty= " + Ty->getDescription());
|
2001-09-10 07:58:01 +00:00
|
|
|
|
2003-03-19 20:54:26 +00:00
|
|
|
const Type *ElTy = cast<PointerType>(Ty)->getElementType();
|
2001-09-18 04:01:05 +00:00
|
|
|
|
2001-09-10 07:58:01 +00:00
|
|
|
// Create the global variable...
|
2004-06-29 23:29:38 +00:00
|
|
|
GlobalVariable *GV = new GlobalVariable(ElTy, isConstant, Linkage,
|
2003-03-19 20:54:26 +00:00
|
|
|
0, "", TheModule);
|
2005-11-06 07:11:04 +00:00
|
|
|
GV->setAlignment(Alignment);
|
2007-01-12 19:20:47 +00:00
|
|
|
GV->setVisibility(Visibility);
|
2003-11-19 17:27:18 +00:00
|
|
|
insertValue(GV, SlotNo, ModuleValues);
|
2001-10-13 06:47:01 +00:00
|
|
|
|
2005-11-12 01:33:40 +00:00
|
|
|
if (GlobalSectionID != 0)
|
|
|
|
SectionID[GV] = GlobalSectionID;
|
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
unsigned initSlot = 0;
|
2005-04-21 21:44:41 +00:00
|
|
|
if (hasInitializer) {
|
2004-06-29 23:29:38 +00:00
|
|
|
initSlot = read_vbr_uint();
|
|
|
|
GlobalInits.push_back(std::make_pair(GV, initSlot));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Notify handler about the global value.
|
2004-10-14 01:39:18 +00:00
|
|
|
if (Handler)
|
2007-01-12 19:20:47 +00:00
|
|
|
Handler->handleGlobalVariable(ElTy, isConstant, Linkage, Visibility,
|
|
|
|
SlotNo, initSlot);
|
2004-06-29 23:29:38 +00:00
|
|
|
|
|
|
|
// Get next item
|
|
|
|
VarType = read_vbr_uint();
|
2001-09-10 07:58:01 +00:00
|
|
|
}
|
|
|
|
|
2003-03-19 20:54:26 +00:00
|
|
|
// Read the function objects for all of the functions that are coming
|
2004-10-16 18:18:16 +00:00
|
|
|
unsigned FnSignature = read_vbr_uint();
|
|
|
|
|
|
|
|
// List is terminated by VoidTy.
|
2005-11-06 07:43:39 +00:00
|
|
|
while (((FnSignature & (~0U >> 1)) >> 5) != Type::VoidTyID) {
|
|
|
|
const Type *Ty = getType((FnSignature & (~0U >> 1)) >> 5);
|
2003-10-09 20:22:47 +00:00
|
|
|
if (!isa<PointerType>(Ty) ||
|
2004-06-29 23:29:38 +00:00
|
|
|
!isa<FunctionType>(cast<PointerType>(Ty)->getElementType())) {
|
2005-04-21 21:44:41 +00:00
|
|
|
error("Function not a pointer to function type! Ty = " +
|
2004-07-11 17:28:43 +00:00
|
|
|
Ty->getDescription());
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
2002-10-23 00:51:54 +00:00
|
|
|
|
2003-03-06 17:15:19 +00:00
|
|
|
// We create functions by passing the underlying FunctionType to create...
|
2005-04-21 21:44:41 +00:00
|
|
|
const FunctionType* FTy =
|
2004-06-29 23:29:38 +00:00
|
|
|
cast<FunctionType>(cast<PointerType>(Ty)->getElementType());
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2004-11-15 21:43:03 +00:00
|
|
|
// Insert the place holder.
|
2005-11-12 01:33:40 +00:00
|
|
|
Function *Func = new Function(FTy, GlobalValue::ExternalLinkage,
|
2004-07-04 11:33:49 +00:00
|
|
|
"", TheModule);
|
2006-01-19 07:02:16 +00:00
|
|
|
|
2005-11-06 07:43:39 +00:00
|
|
|
insertValue(Func, (FnSignature & (~0U >> 1)) >> 5, ModuleValues);
|
2004-10-16 18:18:16 +00:00
|
|
|
|
|
|
|
// Flags are not used yet.
|
2004-11-15 22:38:52 +00:00
|
|
|
unsigned Flags = FnSignature & 31;
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2004-11-15 22:38:52 +00:00
|
|
|
// Save this for later so we know type of lazily instantiated functions.
|
|
|
|
// Note that known-external functions do not have FunctionInfo blocks, so we
|
|
|
|
// do not add them to the FunctionSignatureList.
|
|
|
|
if ((Flags & (1 << 4)) == 0)
|
|
|
|
FunctionSignatureList.push_back(Func);
|
2003-03-19 20:54:26 +00:00
|
|
|
|
2005-11-06 07:43:39 +00:00
|
|
|
// Get the calling convention from the low bits.
|
|
|
|
unsigned CC = Flags & 15;
|
|
|
|
unsigned Alignment = 0;
|
|
|
|
if (FnSignature & (1 << 31)) { // Has extension word?
|
|
|
|
unsigned ExtWord = read_vbr_uint();
|
|
|
|
Alignment = (1 << (ExtWord & 31)) >> 1;
|
|
|
|
CC |= ((ExtWord >> 5) & 15) << 4;
|
2005-11-12 01:33:40 +00:00
|
|
|
|
|
|
|
if (ExtWord & (1 << 10)) // Has a section ID.
|
|
|
|
SectionID[Func] = read_vbr_uint();
|
2006-09-14 18:23:27 +00:00
|
|
|
|
|
|
|
// Parse external declaration linkage
|
|
|
|
switch ((ExtWord >> 11) & 3) {
|
|
|
|
case 0: break;
|
|
|
|
case 1: Func->setLinkage(Function::DLLImportLinkage); break;
|
|
|
|
case 2: Func->setLinkage(Function::ExternalWeakLinkage); break;
|
|
|
|
default: assert(0 && "Unsupported external linkage");
|
|
|
|
}
|
2005-11-06 07:43:39 +00:00
|
|
|
}
|
|
|
|
|
2005-11-06 07:46:13 +00:00
|
|
|
Func->setCallingConv(CC-1);
|
2005-11-06 07:43:39 +00:00
|
|
|
Func->setAlignment(Alignment);
|
2005-05-06 20:42:57 +00:00
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
if (Handler) Handler->handleFunctionDeclaration(Func);
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2004-10-16 18:18:16 +00:00
|
|
|
// Get the next function signature.
|
|
|
|
FnSignature = read_vbr_uint();
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
|
2005-04-21 21:44:41 +00:00
|
|
|
// Now that the function signature list is set up, reverse it so that we can
|
2002-08-17 22:01:27 +00:00
|
|
|
// remove elements efficiently from the back of the vector.
|
|
|
|
std::reverse(FunctionSignatureList.begin(), FunctionSignatureList.end());
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2005-11-12 01:33:40 +00:00
|
|
|
/// SectionNames - This contains the list of section names encoded in the
|
|
|
|
/// moduleinfoblock. Functions and globals with an explicit section index
|
|
|
|
/// into this to get their section name.
|
|
|
|
std::vector<std::string> SectionNames;
|
|
|
|
|
2006-11-14 04:47:22 +00:00
|
|
|
// Read in the dependent library information.
|
|
|
|
unsigned num_dep_libs = read_vbr_uint();
|
|
|
|
std::string dep_lib;
|
|
|
|
while (num_dep_libs--) {
|
|
|
|
dep_lib = read_str();
|
|
|
|
TheModule->addLibrary(dep_lib);
|
2004-08-21 20:49:23 +00:00
|
|
|
if (Handler)
|
2006-11-14 04:47:22 +00:00
|
|
|
Handler->handleDependentLibrary(dep_lib);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Read target triple and place into the module.
|
|
|
|
std::string triple = read_str();
|
|
|
|
TheModule->setTargetTriple(triple);
|
|
|
|
if (Handler)
|
|
|
|
Handler->handleTargetTriple(triple);
|
|
|
|
|
2007-01-26 08:10:24 +00:00
|
|
|
// Read the data layout string and place into the module.
|
|
|
|
std::string datalayout = read_str();
|
|
|
|
TheModule->setDataLayout(datalayout);
|
|
|
|
// FIXME: Implement
|
|
|
|
// if (Handler)
|
|
|
|
// Handler->handleDataLayout(datalayout);
|
|
|
|
|
2006-11-14 04:47:22 +00:00
|
|
|
if (At != BlockEnd) {
|
|
|
|
// If the file has section info in it, read the section names now.
|
|
|
|
unsigned NumSections = read_vbr_uint();
|
|
|
|
while (NumSections--)
|
|
|
|
SectionNames.push_back(read_str());
|
2004-07-25 18:07:36 +00:00
|
|
|
}
|
2006-11-14 04:47:22 +00:00
|
|
|
|
|
|
|
// If the file has module-level inline asm, read it now.
|
|
|
|
if (At != BlockEnd)
|
|
|
|
TheModule->setModuleInlineAsm(read_str());
|
2004-07-25 18:07:36 +00:00
|
|
|
|
2005-11-12 01:33:40 +00:00
|
|
|
// If any globals are in specified sections, assign them now.
|
|
|
|
for (std::map<GlobalValue*, unsigned>::iterator I = SectionID.begin(), E =
|
|
|
|
SectionID.end(); I != E; ++I)
|
|
|
|
if (I->second) {
|
|
|
|
if (I->second > SectionID.size())
|
|
|
|
error("SectionID out of range for global!");
|
|
|
|
I->first->setSection(SectionNames[I->second-1]);
|
|
|
|
}
|
2004-07-25 18:07:36 +00:00
|
|
|
|
2001-06-06 20:29:01 +00:00
|
|
|
// This is for future proofing... in the future extra fields may be added that
|
|
|
|
// we don't understand, so we transparently ignore them.
|
|
|
|
//
|
2004-06-29 23:29:38 +00:00
|
|
|
At = BlockEnd;
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
if (Handler) Handler->handleModuleGlobalsEnd();
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Parse the version information and decode it by setting flags on the
|
|
|
|
/// Reader that enable backward compatibility of the reader.
|
2004-06-29 23:29:38 +00:00
|
|
|
void BytecodeReader::ParseVersionInfo() {
|
2007-01-26 08:10:24 +00:00
|
|
|
unsigned RevisionNum = read_vbr_uint();
|
2003-04-16 21:16:05 +00:00
|
|
|
|
2006-12-03 05:47:10 +00:00
|
|
|
// We don't provide backwards compatibility in the Reader any more. To
|
|
|
|
// upgrade, the user should use llvm-upgrade.
|
|
|
|
if (RevisionNum < 7)
|
|
|
|
error("Bytecode formats < 7 are no longer supported. Use llvm-upgrade.");
|
2003-03-06 17:55:45 +00:00
|
|
|
|
2007-01-26 08:10:24 +00:00
|
|
|
if (Handler) Handler->handleVersionInfo(RevisionNum);
|
2003-03-06 17:55:45 +00:00
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// Parse a whole module.
|
2004-06-29 23:29:38 +00:00
|
|
|
void BytecodeReader::ParseModule() {
|
2001-06-06 20:29:01 +00:00
|
|
|
unsigned Type, Size;
|
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
FunctionSignatureList.clear(); // Just in case...
|
2001-06-06 20:29:01 +00:00
|
|
|
|
|
|
|
// Read into instance variables...
|
2004-06-29 23:29:38 +00:00
|
|
|
ParseVersionInfo();
|
|
|
|
|
|
|
|
bool SeenModuleGlobalInfo = false;
|
|
|
|
bool SeenGlobalTypePlane = false;
|
|
|
|
BufPtr MyEnd = BlockEnd;
|
|
|
|
while (At < MyEnd) {
|
|
|
|
BufPtr OldAt = At;
|
|
|
|
read_block(Type, Size);
|
2001-06-06 20:29:01 +00:00
|
|
|
|
|
|
|
switch (Type) {
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
case BytecodeFormat::GlobalTypePlaneBlockID:
|
2004-07-11 17:28:43 +00:00
|
|
|
if (SeenGlobalTypePlane)
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Two GlobalTypePlane Blocks Encountered!");
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2004-08-21 20:49:23 +00:00
|
|
|
if (Size > 0)
|
|
|
|
ParseGlobalTypes();
|
2004-06-29 23:29:38 +00:00
|
|
|
SeenGlobalTypePlane = true;
|
2001-06-06 20:29:01 +00:00
|
|
|
break;
|
|
|
|
|
2005-04-21 21:44:41 +00:00
|
|
|
case BytecodeFormat::ModuleGlobalInfoBlockID:
|
2004-07-11 17:28:43 +00:00
|
|
|
if (SeenModuleGlobalInfo)
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Two ModuleGlobalInfo Blocks Encountered!");
|
2004-06-29 23:29:38 +00:00
|
|
|
ParseModuleGlobalInfo();
|
|
|
|
SeenModuleGlobalInfo = true;
|
2003-03-19 20:54:26 +00:00
|
|
|
break;
|
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
case BytecodeFormat::ConstantPoolBlockID:
|
2004-07-04 11:33:49 +00:00
|
|
|
ParseConstantPool(ModuleValues, ModuleTypes,false);
|
2001-06-06 20:29:01 +00:00
|
|
|
break;
|
|
|
|
|
2004-07-25 18:07:36 +00:00
|
|
|
case BytecodeFormat::FunctionBlockID:
|
2004-06-29 23:29:38 +00:00
|
|
|
ParseFunctionLazily();
|
2001-06-06 20:29:01 +00:00
|
|
|
break;
|
|
|
|
|
2007-01-06 07:24:44 +00:00
|
|
|
case BytecodeFormat::ValueSymbolTableBlockID:
|
|
|
|
ParseValueSymbolTable(0, &TheModule->getValueSymbolTable());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BytecodeFormat::TypeSymbolTableBlockID:
|
|
|
|
ParseTypeSymbolTable(&TheModule->getTypeSymbolTable());
|
2001-06-06 20:29:01 +00:00
|
|
|
break;
|
2004-06-29 23:29:38 +00:00
|
|
|
|
2001-06-06 20:29:01 +00:00
|
|
|
default:
|
2004-06-29 23:29:38 +00:00
|
|
|
At += Size;
|
|
|
|
if (OldAt > At) {
|
2004-07-11 17:28:43 +00:00
|
|
|
error("Unexpected Block of Type #" + utostr(Type) + " encountered!");
|
2004-06-29 23:29:38 +00:00
|
|
|
}
|
2001-06-06 20:29:01 +00:00
|
|
|
break;
|
|
|
|
}
|
2004-06-29 23:29:38 +00:00
|
|
|
BlockEnd = MyEnd;
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
|
2003-03-19 20:54:26 +00:00
|
|
|
// After the module constant pool has been read, we can safely initialize
|
|
|
|
// global variables...
|
|
|
|
while (!GlobalInits.empty()) {
|
|
|
|
GlobalVariable *GV = GlobalInits.back().first;
|
|
|
|
unsigned Slot = GlobalInits.back().second;
|
|
|
|
GlobalInits.pop_back();
|
|
|
|
|
|
|
|
// Look up the initializer value...
|
2003-11-19 17:27:18 +00:00
|
|
|
// FIXME: Preserve this type ID!
|
2004-06-29 23:29:38 +00:00
|
|
|
|
|
|
|
const llvm::PointerType* GVType = GV->getType();
|
|
|
|
unsigned TypeSlot = getTypeSlot(GVType->getElementType());
|
2004-01-15 18:45:25 +00:00
|
|
|
if (Constant *CV = getConstantValue(TypeSlot, Slot)) {
|
2005-04-21 21:44:41 +00:00
|
|
|
if (GV->hasInitializer())
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Global *already* has an initializer?!");
|
2004-07-04 11:33:49 +00:00
|
|
|
if (Handler) Handler->handleGlobalInitializer(GV,CV);
|
2004-01-15 18:45:25 +00:00
|
|
|
GV->setInitializer(CV);
|
2003-03-19 20:54:26 +00:00
|
|
|
} else
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Cannot find initializer value.");
|
2003-03-19 20:54:26 +00:00
|
|
|
}
|
|
|
|
|
2005-05-05 20:57:00 +00:00
|
|
|
if (!ConstantFwdRefs.empty())
|
|
|
|
error("Use of undefined constants in a module");
|
|
|
|
|
2004-06-29 23:29:38 +00:00
|
|
|
/// Make sure we pulled them all out. If we didn't then there's a declaration
|
|
|
|
/// but a missing body. That's not allowed.
|
2003-09-22 23:38:23 +00:00
|
|
|
if (!FunctionSignatureList.empty())
|
2004-07-09 22:21:33 +00:00
|
|
|
error("Function declared, but bytecode stream ended before definition");
|
2003-03-06 17:15:19 +00:00
|
|
|
}
|
|
|
|
|
2004-07-04 11:33:49 +00:00
|
|
|
/// This function completely parses a bytecode buffer given by the \p Buf
|
|
|
|
/// and \p Length parameters.
|
2006-09-01 20:35:17 +00:00
|
|
|
bool BytecodeReader::ParseBytecode(volatile BufPtr Buf, unsigned Length,
|
2006-08-22 16:09:19 +00:00
|
|
|
const std::string &ModuleID,
|
2007-02-07 19:49:01 +00:00
|
|
|
Decompressor_t *Decompressor,
|
2006-08-22 16:09:19 +00:00
|
|
|
std::string* ErrMsg) {
|
|
|
|
|
|
|
|
/// We handle errors by
|
|
|
|
if (setjmp(context)) {
|
|
|
|
// Cleanup after error
|
|
|
|
if (Handler) Handler->handleError(ErrorMsg);
|
2004-06-29 23:29:38 +00:00
|
|
|
freeState();
|
2003-03-06 17:15:19 +00:00
|
|
|
delete TheModule;
|
|
|
|
TheModule = 0;
|
2004-11-15 21:55:33 +00:00
|
|
|
if (decompressedBlock != 0 ) {
|
2004-11-14 21:59:21 +00:00
|
|
|
::free(decompressedBlock);
|
2004-11-15 21:55:33 +00:00
|
|
|
decompressedBlock = 0;
|
|
|
|
}
|
2006-08-22 16:09:19 +00:00
|
|
|
// Set caller's error message, if requested
|
|
|
|
if (ErrMsg)
|
|
|
|
*ErrMsg = ErrorMsg;
|
|
|
|
// Indicate an error occurred
|
|
|
|
return true;
|
2003-03-06 17:15:19 +00:00
|
|
|
}
|
2006-08-22 16:09:19 +00:00
|
|
|
|
|
|
|
RevisionNum = 0;
|
|
|
|
At = MemStart = BlockStart = Buf;
|
|
|
|
MemEnd = BlockEnd = Buf + Length;
|
|
|
|
|
|
|
|
// Create the module
|
|
|
|
TheModule = new Module(ModuleID);
|
|
|
|
|
|
|
|
if (Handler) Handler->handleStart(TheModule, Length);
|
|
|
|
|
|
|
|
// Read the four bytes of the signature.
|
|
|
|
unsigned Sig = read_uint();
|
|
|
|
|
|
|
|
// If this is a compressed file
|
|
|
|
if (Sig == ('l' | ('l' << 8) | ('v' << 16) | ('c' << 24))) {
|
|
|
|
|
|
|
|
// Invoke the decompression of the bytecode. Note that we have to skip the
|
|
|
|
// file's magic number which is not part of the compressed block. Hence,
|
|
|
|
// the Buf+4 and Length-4. The result goes into decompressedBlock, a data
|
|
|
|
// member for retention until BytecodeReader is destructed.
|
2007-02-07 19:49:01 +00:00
|
|
|
unsigned decompressedLength =
|
|
|
|
Decompressor((char*)Buf+4,Length-4,decompressedBlock, 0);
|
2006-08-22 16:09:19 +00:00
|
|
|
|
|
|
|
// We must adjust the buffer pointers used by the bytecode reader to point
|
|
|
|
// into the new decompressed block. After decompression, the
|
|
|
|
// decompressedBlock will point to a contiguous memory area that has
|
|
|
|
// the decompressed data.
|
|
|
|
At = MemStart = BlockStart = Buf = (BufPtr) decompressedBlock;
|
|
|
|
MemEnd = BlockEnd = Buf + decompressedLength;
|
|
|
|
|
|
|
|
// else if this isn't a regular (uncompressed) bytecode file, then its
|
|
|
|
// and error, generate that now.
|
|
|
|
} else if (Sig != ('l' | ('l' << 8) | ('v' << 16) | ('m' << 24))) {
|
|
|
|
error("Invalid bytecode signature: " + utohexstr(Sig));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tell the handler we're starting a module
|
|
|
|
if (Handler) Handler->handleModuleBegin(ModuleID);
|
|
|
|
|
|
|
|
// Get the module block and size and verify. This is handled specially
|
|
|
|
// because the module block/size is always written in long format. Other
|
|
|
|
// blocks are written in short format so the read_block method is used.
|
|
|
|
unsigned Type, Size;
|
|
|
|
Type = read_uint();
|
|
|
|
Size = read_uint();
|
|
|
|
if (Type != BytecodeFormat::ModuleBlockID) {
|
|
|
|
error("Expected Module Block! Type:" + utostr(Type) + ", Size:"
|
|
|
|
+ utostr(Size));
|
|
|
|
}
|
|
|
|
|
|
|
|
// It looks like the darwin ranlib program is broken, and adds trailing
|
|
|
|
// garbage to the end of some bytecode files. This hack allows the bc
|
|
|
|
// reader to ignore trailing garbage on bytecode files.
|
|
|
|
if (At + Size < MemEnd)
|
|
|
|
MemEnd = BlockEnd = At+Size;
|
|
|
|
|
|
|
|
if (At + Size != MemEnd)
|
|
|
|
error("Invalid Top Level Block Length! Type:" + utostr(Type)
|
|
|
|
+ ", Size:" + utostr(Size));
|
|
|
|
|
|
|
|
// Parse the module contents
|
|
|
|
this->ParseModule();
|
|
|
|
|
|
|
|
// Check for missing functions
|
|
|
|
if (hasFunctions())
|
|
|
|
error("Function expected, but bytecode stream ended!");
|
|
|
|
|
|
|
|
// Tell the handler we're done with the module
|
|
|
|
if (Handler)
|
|
|
|
Handler->handleModuleEnd(ModuleID);
|
|
|
|
|
|
|
|
// Tell the handler we're finished the parse
|
|
|
|
if (Handler) Handler->handleFinish();
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
2004-06-29 23:29:38 +00:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//=== Default Implementations of Handler Methods
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
BytecodeHandler::~BytecodeHandler() {}
|
|
|
|
|