aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Bitcode
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bitcode')
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp351
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.h35
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp180
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.cpp4
4 files changed, 376 insertions, 194 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index d584015..e399040 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -22,11 +22,19 @@
#include "llvm/AutoUpgrade.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataStream.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/OperandTraits.h"
using namespace llvm;
+void BitcodeReader::materializeForwardReferencedFunctions() {
+ while (!BlockAddrFwdRefs.empty()) {
+ Function *F = BlockAddrFwdRefs.begin()->first;
+ F->Materialize();
+ }
+}
+
void BitcodeReader::FreeState() {
if (BufferOwned)
delete Buffer;
@@ -394,7 +402,7 @@ Type *BitcodeReader::getTypeByID(unsigned ID) {
// The type table size is always specified correctly.
if (ID >= TypeList.size())
return 0;
-
+
if (Type *Ty = TypeList[ID])
return Ty;
@@ -454,8 +462,8 @@ bool BitcodeReader::ParseAttributeBlock() {
// If Function attributes are using index 0 then transfer them
// to index ~0. Index 0 is used for return value attributes but used to be
// used for function attributes.
- Attributes RetAttribute = Attribute::None;
- Attributes FnAttribute = Attribute::None;
+ Attributes RetAttribute;
+ Attributes FnAttribute;
for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
// FIXME: remove in LLVM 3.0
// The alignment is stored as a 16-bit raw value from bits 31--16.
@@ -465,23 +473,24 @@ bool BitcodeReader::ParseAttributeBlock() {
if (Alignment && !isPowerOf2_32(Alignment))
return Error("Alignment is not a power of two.");
- Attributes ReconstitutedAttr = Record[i+1] & 0xffff;
+ Attributes ReconstitutedAttr(Record[i+1] & 0xffff);
if (Alignment)
ReconstitutedAttr |= Attribute::constructAlignmentFromInt(Alignment);
- ReconstitutedAttr |= (Record[i+1] & (0xffffull << 32)) >> 11;
- Record[i+1] = ReconstitutedAttr;
+ ReconstitutedAttr |=
+ Attributes((Record[i+1] & (0xffffull << 32)) >> 11);
+ Record[i+1] = ReconstitutedAttr.Raw();
if (Record[i] == 0)
- RetAttribute = Record[i+1];
+ RetAttribute = ReconstitutedAttr;
else if (Record[i] == ~0U)
- FnAttribute = Record[i+1];
+ FnAttribute = ReconstitutedAttr;
}
- unsigned OldRetAttrs = (Attribute::NoUnwind|Attribute::NoReturn|
+ Attributes OldRetAttrs = (Attribute::NoUnwind|Attribute::NoReturn|
Attribute::ReadOnly|Attribute::ReadNone);
if (FnAttribute == Attribute::None && RetAttribute != Attribute::None &&
- (RetAttribute & OldRetAttrs) != 0) {
+ (RetAttribute & OldRetAttrs)) {
if (FnAttribute == Attribute::None) { // add a slot so they get added.
Record.push_back(~0U);
Record.push_back(0);
@@ -498,8 +507,9 @@ bool BitcodeReader::ParseAttributeBlock() {
} else if (Record[i] == ~0U) {
if (FnAttribute != Attribute::None)
Attrs.push_back(AttributeWithIndex::get(~0U, FnAttribute));
- } else if (Record[i+1] != Attribute::None)
- Attrs.push_back(AttributeWithIndex::get(Record[i], Record[i+1]));
+ } else if (Attributes(Record[i+1]) != Attribute::None)
+ Attrs.push_back(AttributeWithIndex::get(Record[i],
+ Attributes(Record[i+1])));
}
MAttributes.push_back(AttrListPtr::get(Attrs.begin(), Attrs.end()));
@@ -513,7 +523,7 @@ bool BitcodeReader::ParseAttributeBlock() {
bool BitcodeReader::ParseTypeTable() {
if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW))
return Error("Malformed block record");
-
+
return ParseTypeTableBody();
}
@@ -525,7 +535,7 @@ bool BitcodeReader::ParseTypeTableBody() {
unsigned NumRecords = 0;
SmallString<64> TypeName;
-
+
// Read all the records for this type table.
while (1) {
unsigned Code = Stream.ReadCode();
@@ -565,6 +575,9 @@ bool BitcodeReader::ParseTypeTableBody() {
case bitc::TYPE_CODE_VOID: // VOID
ResultTy = Type::getVoidTy(Context);
break;
+ case bitc::TYPE_CODE_HALF: // HALF
+ ResultTy = Type::getHalfTy(Context);
+ break;
case bitc::TYPE_CODE_FLOAT: // FLOAT
ResultTy = Type::getFloatTy(Context);
break;
@@ -612,7 +625,7 @@ bool BitcodeReader::ParseTypeTableBody() {
// FUNCTION: [vararg, attrid, retty, paramty x N]
if (Record.size() < 3)
return Error("Invalid FUNCTION type record");
- std::vector<Type*> ArgTys;
+ SmallVector<Type*, 8> ArgTys;
for (unsigned i = 3, e = Record.size(); i != e; ++i) {
if (Type *T = getTypeByID(Record[i]))
ArgTys.push_back(T);
@@ -631,7 +644,7 @@ bool BitcodeReader::ParseTypeTableBody() {
// FUNCTION: [vararg, retty, paramty x N]
if (Record.size() < 2)
return Error("Invalid FUNCTION type record");
- std::vector<Type*> ArgTys;
+ SmallVector<Type*, 8> ArgTys;
for (unsigned i = 2, e = Record.size(); i != e; ++i) {
if (Type *T = getTypeByID(Record[i]))
ArgTys.push_back(T);
@@ -649,7 +662,7 @@ bool BitcodeReader::ParseTypeTableBody() {
case bitc::TYPE_CODE_STRUCT_ANON: { // STRUCT: [ispacked, eltty x N]
if (Record.size() < 1)
return Error("Invalid STRUCT type record");
- std::vector<Type*> EltTys;
+ SmallVector<Type*, 8> EltTys;
for (unsigned i = 1, e = Record.size(); i != e; ++i) {
if (Type *T = getTypeByID(Record[i]))
EltTys.push_back(T);
@@ -1032,7 +1045,9 @@ bool BitcodeReader::ParseConstants() {
case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval]
if (Record.empty())
return Error("Invalid FLOAT record");
- if (CurTy->isFloatTy())
+ if (CurTy->isHalfTy())
+ V = ConstantFP::get(Context, APFloat(APInt(16, (uint16_t)Record[0])));
+ else if (CurTy->isFloatTy())
V = ConstantFP::get(Context, APFloat(APInt(32, (uint32_t)Record[0])));
else if (CurTy->isDoubleTy())
V = ConstantFP::get(Context, APFloat(APInt(64, Record[0])));
@@ -1056,7 +1071,7 @@ bool BitcodeReader::ParseConstants() {
return Error("Invalid CST_AGGREGATE record");
unsigned Size = Record.size();
- std::vector<Constant*> Elts;
+ SmallVector<Constant*, 16> Elts;
if (StructType *STy = dyn_cast<StructType>(CurTy)) {
for (unsigned i = 0; i != Size; ++i)
@@ -1078,35 +1093,78 @@ bool BitcodeReader::ParseConstants() {
}
break;
}
- case bitc::CST_CODE_STRING: { // STRING: [values]
+ case bitc::CST_CODE_STRING: // STRING: [values]
+ case bitc::CST_CODE_CSTRING: { // CSTRING: [values]
if (Record.empty())
- return Error("Invalid CST_AGGREGATE record");
-
- ArrayType *ATy = cast<ArrayType>(CurTy);
- Type *EltTy = ATy->getElementType();
+ return Error("Invalid CST_STRING record");
unsigned Size = Record.size();
- std::vector<Constant*> Elts;
+ SmallString<16> Elts;
for (unsigned i = 0; i != Size; ++i)
- Elts.push_back(ConstantInt::get(EltTy, Record[i]));
- V = ConstantArray::get(ATy, Elts);
+ Elts.push_back(Record[i]);
+ V = ConstantDataArray::getString(Context, Elts,
+ BitCode == bitc::CST_CODE_CSTRING);
break;
}
- case bitc::CST_CODE_CSTRING: { // CSTRING: [values]
+ case bitc::CST_CODE_DATA: {// DATA: [n x value]
if (Record.empty())
- return Error("Invalid CST_AGGREGATE record");
-
- ArrayType *ATy = cast<ArrayType>(CurTy);
- Type *EltTy = ATy->getElementType();
-
+ return Error("Invalid CST_DATA record");
+
+ Type *EltTy = cast<SequentialType>(CurTy)->getElementType();
unsigned Size = Record.size();
- std::vector<Constant*> Elts;
- for (unsigned i = 0; i != Size; ++i)
- Elts.push_back(ConstantInt::get(EltTy, Record[i]));
- Elts.push_back(Constant::getNullValue(EltTy));
- V = ConstantArray::get(ATy, Elts);
+
+ if (EltTy->isIntegerTy(8)) {
+ SmallVector<uint8_t, 16> Elts(Record.begin(), Record.end());
+ if (isa<VectorType>(CurTy))
+ V = ConstantDataVector::get(Context, Elts);
+ else
+ V = ConstantDataArray::get(Context, Elts);
+ } else if (EltTy->isIntegerTy(16)) {
+ SmallVector<uint16_t, 16> Elts(Record.begin(), Record.end());
+ if (isa<VectorType>(CurTy))
+ V = ConstantDataVector::get(Context, Elts);
+ else
+ V = ConstantDataArray::get(Context, Elts);
+ } else if (EltTy->isIntegerTy(32)) {
+ SmallVector<uint32_t, 16> Elts(Record.begin(), Record.end());
+ if (isa<VectorType>(CurTy))
+ V = ConstantDataVector::get(Context, Elts);
+ else
+ V = ConstantDataArray::get(Context, Elts);
+ } else if (EltTy->isIntegerTy(64)) {
+ SmallVector<uint64_t, 16> Elts(Record.begin(), Record.end());
+ if (isa<VectorType>(CurTy))
+ V = ConstantDataVector::get(Context, Elts);
+ else
+ V = ConstantDataArray::get(Context, Elts);
+ } else if (EltTy->isFloatTy()) {
+ SmallVector<float, 16> Elts;
+ for (unsigned i = 0; i != Size; ++i) {
+ union { uint32_t I; float F; };
+ I = Record[i];
+ Elts.push_back(F);
+ }
+ if (isa<VectorType>(CurTy))
+ V = ConstantDataVector::get(Context, Elts);
+ else
+ V = ConstantDataArray::get(Context, Elts);
+ } else if (EltTy->isDoubleTy()) {
+ SmallVector<double, 16> Elts;
+ for (unsigned i = 0; i != Size; ++i) {
+ union { uint64_t I; double F; };
+ I = Record[i];
+ Elts.push_back(F);
+ }
+ if (isa<VectorType>(CurTy))
+ V = ConstantDataVector::get(Context, Elts);
+ else
+ V = ConstantDataArray::get(Context, Elts);
+ } else {
+ return Error("Unknown element type in CE_DATA");
+ }
break;
}
+
case bitc::CST_CODE_CE_BINOP: { // CE_BINOP: [opcode, opval, opval]
if (Record.size() < 3) return Error("Invalid CE_BINOP record");
int Opc = GetDecodedBinaryOpcode(Record[0], CurTy);
@@ -1352,8 +1410,36 @@ bool BitcodeReader::RememberAndSkipFunctionBody() {
return false;
}
-bool BitcodeReader::ParseModule() {
- if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
+bool BitcodeReader::GlobalCleanup() {
+ // Patch the initializers for globals and aliases up.
+ ResolveGlobalAndAliasInits();
+ if (!GlobalInits.empty() || !AliasInits.empty())
+ return Error("Malformed global initializer set");
+
+ // Look for intrinsic functions which need to be upgraded at some point
+ for (Module::iterator FI = TheModule->begin(), FE = TheModule->end();
+ FI != FE; ++FI) {
+ Function *NewFn;
+ if (UpgradeIntrinsicFunction(FI, NewFn))
+ UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn));
+ }
+
+ // Look for global variables which need to be renamed.
+ for (Module::global_iterator
+ GI = TheModule->global_begin(), GE = TheModule->global_end();
+ GI != GE; ++GI)
+ UpgradeGlobalVariable(GI);
+ // Force deallocation of memory for these vectors to favor the client that
+ // want lazy deserialization.
+ std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits);
+ std::vector<std::pair<GlobalAlias*, unsigned> >().swap(AliasInits);
+ return false;
+}
+
+bool BitcodeReader::ParseModule(bool Resume) {
+ if (Resume)
+ Stream.JumpToBit(NextUnreadBit);
+ else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
return Error("Malformed block record");
SmallVector<uint64_t, 64> Record;
@@ -1367,33 +1453,7 @@ bool BitcodeReader::ParseModule() {
if (Stream.ReadBlockEnd())
return Error("Error at end of module block");
- // Patch the initializers for globals and aliases up.
- ResolveGlobalAndAliasInits();
- if (!GlobalInits.empty() || !AliasInits.empty())
- return Error("Malformed global initializer set");
- if (!FunctionsWithBodies.empty())
- return Error("Too few function bodies found");
-
- // Look for intrinsic functions which need to be upgraded at some point
- for (Module::iterator FI = TheModule->begin(), FE = TheModule->end();
- FI != FE; ++FI) {
- Function* NewFn;
- if (UpgradeIntrinsicFunction(FI, NewFn))
- UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn));
- }
-
- // Look for global variables which need to be renamed.
- for (Module::global_iterator
- GI = TheModule->global_begin(), GE = TheModule->global_end();
- GI != GE; ++GI)
- UpgradeGlobalVariable(GI);
-
- // Force deallocation of memory for these vectors to favor the client that
- // want lazy deserialization.
- std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits);
- std::vector<std::pair<GlobalAlias*, unsigned> >().swap(AliasInits);
- std::vector<Function*>().swap(FunctionsWithBodies);
- return false;
+ return GlobalCleanup();
}
if (Code == bitc::ENTER_SUBBLOCK) {
@@ -1417,6 +1477,7 @@ bool BitcodeReader::ParseModule() {
case bitc::VALUE_SYMTAB_BLOCK_ID:
if (ParseValueSymbolTable())
return true;
+ SeenValueSymbolTable = true;
break;
case bitc::CONSTANTS_BLOCK_ID:
if (ParseConstants() || ResolveGlobalAndAliasInits())
@@ -1429,13 +1490,25 @@ bool BitcodeReader::ParseModule() {
case bitc::FUNCTION_BLOCK_ID:
// If this is the first function body we've seen, reverse the
// FunctionsWithBodies list.
- if (!HasReversedFunctionsWithBodies) {
+ if (!SeenFirstFunctionBody) {
std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end());
- HasReversedFunctionsWithBodies = true;
+ if (GlobalCleanup())
+ return true;
+ SeenFirstFunctionBody = true;
}
if (RememberAndSkipFunctionBody())
return true;
+ // For streaming bitcode, suspend parsing when we reach the function
+ // bodies. Subsequent materialization calls will resume it when
+ // necessary. For streaming, the function bodies must be at the end of
+ // the bitcode. If the bitcode file is old, the symbol table will be
+ // at the end instead and will not have been seen yet. In this case,
+ // just finish the parse now.
+ if (LazyStreamer && SeenValueSymbolTable) {
+ NextUnreadBit = Stream.GetCurrentBitNo();
+ return false;
+ }
break;
case bitc::USELIST_BLOCK_ID:
if (ParseUseLists())
@@ -1594,8 +1667,10 @@ bool BitcodeReader::ParseModule() {
// If this is a function with a body, remember the prototype we are
// creating now, so that we can match up the body with them later.
- if (!isProto)
+ if (!isProto) {
FunctionsWithBodies.push_back(Func);
+ if (LazyStreamer) DeferredFunctionInfo[Func] = 0;
+ }
break;
}
// ALIAS: [alias type, aliasee val#, linkage]
@@ -1634,24 +1709,7 @@ bool BitcodeReader::ParseModule() {
bool BitcodeReader::ParseBitcodeInto(Module *M) {
TheModule = 0;
- unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
- unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
-
- if (Buffer->getBufferSize() & 3) {
- if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd))
- return Error("Invalid bitcode signature");
- else
- return Error("Bitcode stream should be a multiple of 4 bytes in length");
- }
-
- // If we have a wrapper header, parse it and ignore the non-bc file contents.
- // The magic number is 0x0B17C0DE stored in little endian.
- if (isBitcodeWrapper(BufPtr, BufEnd))
- if (SkipBitcodeWrapperHeader(BufPtr, BufEnd))
- return Error("Invalid bitcode wrapper header");
-
- StreamFile.init(BufPtr, BufEnd);
- Stream.init(StreamFile);
+ if (InitStream()) return true;
// Sniff for the signature.
if (Stream.Read(8) != 'B' ||
@@ -1693,8 +1751,9 @@ bool BitcodeReader::ParseBitcodeInto(Module *M) {
if (TheModule)
return Error("Multiple MODULE_BLOCKs in same stream");
TheModule = M;
- if (ParseModule())
+ if (ParseModule(false))
return true;
+ if (LazyStreamer) return false;
break;
default:
if (Stream.SkipBlock())
@@ -1762,20 +1821,7 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) {
}
bool BitcodeReader::ParseTriple(std::string &Triple) {
- if (Buffer->getBufferSize() & 3)
- return Error("Bitcode stream should be a multiple of 4 bytes in length");
-
- unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
- unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
-
- // If we have a wrapper header, parse it and ignore the non-bc file contents.
- // The magic number is 0x0B17C0DE stored in little endian.
- if (isBitcodeWrapper(BufPtr, BufEnd))
- if (SkipBitcodeWrapperHeader(BufPtr, BufEnd))
- return Error("Invalid bitcode wrapper header");
-
- StreamFile.init(BufPtr, BufEnd);
- Stream.init(StreamFile);
+ if (InitStream()) return true;
// Sniff for the signature.
if (Stream.Read(8) != 'B' ||
@@ -2327,10 +2373,6 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
InstructionList.push_back(I);
break;
}
- case bitc::FUNC_CODE_INST_UNWIND: // UNWIND
- I = new UnwindInst(Context);
- InstructionList.push_back(I);
- break;
case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE
I = new UnreachableInst(Context);
InstructionList.push_back(I);
@@ -2655,6 +2697,19 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
return false;
}
+/// FindFunctionInStream - Find the function body in the bitcode stream
+bool BitcodeReader::FindFunctionInStream(Function *F,
+ DenseMap<Function*, uint64_t>::iterator DeferredFunctionInfoIterator) {
+ while (DeferredFunctionInfoIterator->second == 0) {
+ if (Stream.AtEndOfStream())
+ return Error("Could not find Function in stream");
+ // ParseModule will parse the next body in the stream and set its
+ // position in the DeferredFunctionInfo map.
+ if (ParseModule(true)) return true;
+ }
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// GVMaterializer implementation
//===----------------------------------------------------------------------===//
@@ -2675,6 +2730,10 @@ bool BitcodeReader::Materialize(GlobalValue *GV, std::string *ErrInfo) {
DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F);
assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!");
+ // If its position is recorded as 0, its body is somewhere in the stream
+ // but we haven't seen it yet.
+ if (DFII->second == 0)
+ if (LazyStreamer && FindFunctionInStream(F, DFII)) return true;
// Move the bit stream to the saved position of the deferred function body.
Stream.JumpToBit(DFII->second);
@@ -2730,6 +2789,12 @@ bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) {
Materialize(F, ErrInfo))
return true;
+ // At this point, if there are any function bodies, the current bit is
+ // pointing to the END_BLOCK record after them. Now make sure the rest
+ // of the bits in the module have been read.
+ if (NextUnreadBit)
+ ParseModule(true);
+
// Upgrade any intrinsic calls that slipped through (should not happen!) and
// delete the old functions to clean up. We can't do this unless the entire
// module is materialized because there could always be another function body
@@ -2752,6 +2817,57 @@ bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) {
return false;
}
+bool BitcodeReader::InitStream() {
+ if (LazyStreamer) return InitLazyStream();
+ return InitStreamFromBuffer();
+}
+
+bool BitcodeReader::InitStreamFromBuffer() {
+ const unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
+ const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
+
+ if (Buffer->getBufferSize() & 3) {
+ if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd))
+ return Error("Invalid bitcode signature");
+ else
+ return Error("Bitcode stream should be a multiple of 4 bytes in length");
+ }
+
+ // If we have a wrapper header, parse it and ignore the non-bc file contents.
+ // The magic number is 0x0B17C0DE stored in little endian.
+ if (isBitcodeWrapper(BufPtr, BufEnd))
+ if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true))
+ return Error("Invalid bitcode wrapper header");
+
+ StreamFile.reset(new BitstreamReader(BufPtr, BufEnd));
+ Stream.init(*StreamFile);
+
+ return false;
+}
+
+bool BitcodeReader::InitLazyStream() {
+ // Check and strip off the bitcode wrapper; BitstreamReader expects never to
+ // see it.
+ StreamingMemoryObject *Bytes = new StreamingMemoryObject(LazyStreamer);
+ StreamFile.reset(new BitstreamReader(Bytes));
+ Stream.init(*StreamFile);
+
+ unsigned char buf[16];
+ if (Bytes->readBytes(0, 16, buf, NULL) == -1)
+ return Error("Bitcode stream must be at least 16 bytes in length");
+
+ if (!isBitcode(buf, buf + 16))
+ return Error("Invalid bitcode signature");
+
+ if (isBitcodeWrapper(buf, buf + 4)) {
+ const unsigned char *bitcodeStart = buf;
+ const unsigned char *bitcodeEnd = buf + 16;
+ SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false);
+ Bytes->dropLeadingBytes(bitcodeStart - buf);
+ Bytes->setKnownObjectSize(bitcodeEnd - bitcodeStart);
+ }
+ return false;
+}
//===----------------------------------------------------------------------===//
// External interface
@@ -2774,6 +2890,27 @@ Module *llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
}
// Have the BitcodeReader dtor delete 'Buffer'.
R->setBufferOwned(true);
+
+ R->materializeForwardReferencedFunctions();
+
+ return M;
+}
+
+
+Module *llvm::getStreamedBitcodeModule(const std::string &name,
+ DataStreamer *streamer,
+ LLVMContext &Context,
+ std::string *ErrMsg) {
+ Module *M = new Module(name, Context);
+ BitcodeReader *R = new BitcodeReader(streamer, Context);
+ M->setMaterializer(R);
+ if (R->ParseBitcodeInto(M)) {
+ if (ErrMsg)
+ *ErrMsg = R->getErrorString();
+ delete M; // Also deletes R.
+ return 0;
+ }
+ R->setBufferOwned(false); // no buffer to delete
return M;
}
diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h
index 978b15b..e7c4e94 100644
--- a/lib/Bitcode/Reader/BitcodeReader.h
+++ b/lib/Bitcode/Reader/BitcodeReader.h
@@ -126,8 +126,11 @@ class BitcodeReader : public GVMaterializer {
Module *TheModule;
MemoryBuffer *Buffer;
bool BufferOwned;
- BitstreamReader StreamFile;
+ OwningPtr<BitstreamReader> StreamFile;
BitstreamCursor Stream;
+ DataStreamer *LazyStreamer;
+ uint64_t NextUnreadBit;
+ bool SeenValueSymbolTable;
const char *ErrorString;
@@ -161,9 +164,10 @@ class BitcodeReader : public GVMaterializer {
// Map the bitcode's custom MDKind ID to the Module's MDKind ID.
DenseMap<unsigned, unsigned> MDKindMap;
- // After the module header has been read, the FunctionsWithBodies list is
- // reversed. This keeps track of whether we've done this yet.
- bool HasReversedFunctionsWithBodies;
+ // Several operations happen after the module header has been read, but
+ // before function bodies are processed. This keeps track of whether
+ // we've done this yet.
+ bool SeenFirstFunctionBody;
/// DeferredFunctionInfo - When function bodies are initially scanned, this
/// map contains info about where to find deferred function body in the
@@ -178,13 +182,22 @@ class BitcodeReader : public GVMaterializer {
public:
explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C)
: Context(C), TheModule(0), Buffer(buffer), BufferOwned(false),
- ErrorString(0), ValueList(C), MDValueList(C) {
- HasReversedFunctionsWithBodies = false;
+ LazyStreamer(0), NextUnreadBit(0), SeenValueSymbolTable(false),
+ ErrorString(0), ValueList(C), MDValueList(C),
+ SeenFirstFunctionBody(false) {
+ }
+ explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C)
+ : Context(C), TheModule(0), Buffer(0), BufferOwned(false),
+ LazyStreamer(streamer), NextUnreadBit(0), SeenValueSymbolTable(false),
+ ErrorString(0), ValueList(C), MDValueList(C),
+ SeenFirstFunctionBody(false) {
}
~BitcodeReader() {
FreeState();
}
-
+
+ void materializeForwardReferencedFunctions();
+
void FreeState();
/// setBufferOwned - If this is true, the reader will destroy the MemoryBuffer
@@ -256,7 +269,7 @@ private:
}
- bool ParseModule();
+ bool ParseModule(bool Resume);
bool ParseAttributeBlock();
bool ParseTypeTable();
bool ParseTypeTableBody();
@@ -265,11 +278,17 @@ private:
bool ParseConstants();
bool RememberAndSkipFunctionBody();
bool ParseFunctionBody(Function *F);
+ bool GlobalCleanup();
bool ResolveGlobalAndAliasInits();
bool ParseMetadata();
bool ParseMetadataAttachment();
bool ParseModuleTriple(std::string &Triple);
bool ParseUseLists();
+ bool InitStream();
+ bool InitStreamFromBuffer();
+ bool InitLazyStream();
+ bool FindFunctionInStream(Function *F,
+ DenseMap<Function*, uint64_t>::iterator DeferredFunctionInfoIterator);
};
} // End llvm namespace
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index d980163..9376990 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -126,7 +126,6 @@ static unsigned GetEncodedRMWOperation(AtomicRMWInst::BinOp Op) {
static unsigned GetEncodedOrdering(AtomicOrdering Ordering) {
switch (Ordering) {
- default: llvm_unreachable("Unknown atomic ordering");
case NotAtomic: return bitc::ORDERING_NOTATOMIC;
case Unordered: return bitc::ORDERING_UNORDERED;
case Monotonic: return bitc::ORDERING_MONOTONIC;
@@ -135,14 +134,15 @@ static unsigned GetEncodedOrdering(AtomicOrdering Ordering) {
case AcquireRelease: return bitc::ORDERING_ACQREL;
case SequentiallyConsistent: return bitc::ORDERING_SEQCST;
}
+ llvm_unreachable("Invalid ordering");
}
static unsigned GetEncodedSynchScope(SynchronizationScope SynchScope) {
switch (SynchScope) {
- default: llvm_unreachable("Unknown synchronization scope");
case SingleThread: return bitc::SYNCHSCOPE_SINGLETHREAD;
case CrossThread: return bitc::SYNCHSCOPE_CROSSTHREAD;
}
+ llvm_unreachable("Invalid synch scope");
}
static void WriteStringRecord(unsigned Code, StringRef Str,
@@ -179,10 +179,11 @@ static void WriteAttributeTable(const ValueEnumerator &VE,
// Store the alignment in the bitcode as a 16-bit raw value instead of a
// 5-bit log2 encoded value. Shift the bits above the alignment up by
// 11 bits.
- uint64_t FauxAttr = PAWI.Attrs & 0xffff;
+ uint64_t FauxAttr = PAWI.Attrs.Raw() & 0xffff;
if (PAWI.Attrs & Attribute::Alignment)
- FauxAttr |= (1ull<<16)<<(((PAWI.Attrs & Attribute::Alignment)-1) >> 16);
- FauxAttr |= (PAWI.Attrs & (0x3FFull << 21)) << 11;
+ FauxAttr |= (1ull<<16)<<
+ (((PAWI.Attrs & Attribute::Alignment).Raw()-1) >> 16);
+ FauxAttr |= (PAWI.Attrs.Raw() & (0x3FFull << 21)) << 11;
Record.push_back(FauxAttr);
}
@@ -266,6 +267,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
switch (T->getTypeID()) {
default: llvm_unreachable("Unknown type!");
case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break;
+ case Type::HalfTyID: Code = bitc::TYPE_CODE_HALF; break;
case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break;
case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break;
case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break;
@@ -356,7 +358,6 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
static unsigned getEncodedLinkage(const GlobalValue *GV) {
switch (GV->getLinkage()) {
- default: llvm_unreachable("Invalid linkage!");
case GlobalValue::ExternalLinkage: return 0;
case GlobalValue::WeakAnyLinkage: return 1;
case GlobalValue::AppendingLinkage: return 2;
@@ -374,15 +375,16 @@ static unsigned getEncodedLinkage(const GlobalValue *GV) {
case GlobalValue::LinkerPrivateWeakLinkage: return 14;
case GlobalValue::LinkerPrivateWeakDefAutoLinkage: return 15;
}
+ llvm_unreachable("Invalid linkage");
}
static unsigned getEncodedVisibility(const GlobalValue *GV) {
switch (GV->getVisibility()) {
- default: llvm_unreachable("Invalid visibility!");
case GlobalValue::DefaultVisibility: return 0;
case GlobalValue::HiddenVisibility: return 1;
case GlobalValue::ProtectedVisibility: return 2;
}
+ llvm_unreachable("Invalid visibility");
}
// Emit top-level description of module, including target triple, inline asm,
@@ -826,7 +828,7 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
Code = bitc::CST_CODE_FLOAT;
Type *Ty = CFP->getType();
- if (Ty->isFloatTy() || Ty->isDoubleTy()) {
+ if (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy()) {
Record.push_back(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
} else if (Ty->isX86_FP80Ty()) {
// api needed to prevent premature destruction
@@ -843,34 +845,56 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
} else {
assert (0 && "Unknown FP type!");
}
- } else if (isa<ConstantArray>(C) && cast<ConstantArray>(C)->isString()) {
- const ConstantArray *CA = cast<ConstantArray>(C);
+ } else if (isa<ConstantDataSequential>(C) &&
+ cast<ConstantDataSequential>(C)->isString()) {
+ const ConstantDataSequential *Str = cast<ConstantDataSequential>(C);
// Emit constant strings specially.
- unsigned NumOps = CA->getNumOperands();
+ unsigned NumElts = Str->getNumElements();
// If this is a null-terminated string, use the denser CSTRING encoding.
- if (CA->getOperand(NumOps-1)->isNullValue()) {
+ if (Str->isCString()) {
Code = bitc::CST_CODE_CSTRING;
- --NumOps; // Don't encode the null, which isn't allowed by char6.
+ --NumElts; // Don't encode the null, which isn't allowed by char6.
} else {
Code = bitc::CST_CODE_STRING;
AbbrevToUse = String8Abbrev;
}
bool isCStr7 = Code == bitc::CST_CODE_CSTRING;
bool isCStrChar6 = Code == bitc::CST_CODE_CSTRING;
- for (unsigned i = 0; i != NumOps; ++i) {
- unsigned char V = cast<ConstantInt>(CA->getOperand(i))->getZExtValue();
+ for (unsigned i = 0; i != NumElts; ++i) {
+ unsigned char V = Str->getElementAsInteger(i);
Record.push_back(V);
isCStr7 &= (V & 128) == 0;
if (isCStrChar6)
isCStrChar6 = BitCodeAbbrevOp::isChar6(V);
}
-
+
if (isCStrChar6)
AbbrevToUse = CString6Abbrev;
else if (isCStr7)
AbbrevToUse = CString7Abbrev;
- } else if (isa<ConstantArray>(C) || isa<ConstantStruct>(V) ||
- isa<ConstantVector>(V)) {
+ } else if (const ConstantDataSequential *CDS =
+ dyn_cast<ConstantDataSequential>(C)) {
+ Code = bitc::CST_CODE_DATA;
+ Type *EltTy = CDS->getType()->getElementType();
+ if (isa<IntegerType>(EltTy)) {
+ for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i)
+ Record.push_back(CDS->getElementAsInteger(i));
+ } else if (EltTy->isFloatTy()) {
+ for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
+ union { float F; uint32_t I; };
+ F = CDS->getElementAsFloat(i);
+ Record.push_back(I);
+ }
+ } else {
+ assert(EltTy->isDoubleTy() && "Unknown ConstantData element type");
+ for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
+ union { double F; uint64_t I; };
+ F = CDS->getElementAsDouble(i);
+ Record.push_back(I);
+ }
+ }
+ } else if (isa<ConstantArray>(C) || isa<ConstantStruct>(C) ||
+ isa<ConstantVector>(C)) {
Code = bitc::CST_CODE_AGGREGATE;
for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
Record.push_back(VE.getValueID(C->getOperand(i)));
@@ -1112,10 +1136,17 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
}
break;
case Instruction::Switch:
- Code = bitc::FUNC_CODE_INST_SWITCH;
- Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
- for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
- Vals.push_back(VE.getValueID(I.getOperand(i)));
+ {
+ Code = bitc::FUNC_CODE_INST_SWITCH;
+ SwitchInst &SI = cast<SwitchInst>(I);
+ Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
+ Vals.push_back(VE.getValueID(SI.getCondition()));
+ Vals.push_back(VE.getValueID(SI.getDefaultDest()));
+ for (unsigned i = 0, e = SI.getNumCases(); i != e; ++i) {
+ Vals.push_back(VE.getValueID(SI.getCaseValue(i)));
+ Vals.push_back(VE.getValueID(SI.getCaseSuccessor(i)));
+ }
+ }
break;
case Instruction::IndirectBr:
Code = bitc::FUNC_CODE_INST_INDIRECTBR;
@@ -1153,9 +1184,6 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
Code = bitc::FUNC_CODE_INST_RESUME;
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
break;
- case Instruction::Unwind:
- Code = bitc::FUNC_CODE_INST_UNWIND;
- break;
case Instruction::Unreachable:
Code = bitc::FUNC_CODE_INST_UNREACHABLE;
AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV;
@@ -1710,11 +1738,6 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) {
// Emit metadata.
WriteModuleMetadata(M, VE, Stream);
- // Emit function bodies.
- for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F)
- if (!F->isDeclaration())
- WriteFunction(*F, VE, Stream);
-
// Emit metadata.
WriteModuleMetadataStore(M, Stream);
@@ -1725,6 +1748,11 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) {
if (EnablePreserveUseListOrdering)
WriteModuleUseLists(M, VE, Stream);
+ // Emit function bodies.
+ for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F)
+ if (!F->isDeclaration())
+ WriteFunction(*F, VE, Stream);
+
Stream.ExitBlock();
}
@@ -1746,7 +1774,17 @@ enum {
DarwinBCHeaderSize = 5*4
};
-static void EmitDarwinBCHeader(BitstreamWriter &Stream, const Triple &TT) {
+static void WriteInt32ToBuffer(uint32_t Value, SmallVectorImpl<char> &Buffer,
+ uint32_t &Position) {
+ Buffer[Position + 0] = (unsigned char) (Value >> 0);
+ Buffer[Position + 1] = (unsigned char) (Value >> 8);
+ Buffer[Position + 2] = (unsigned char) (Value >> 16);
+ Buffer[Position + 3] = (unsigned char) (Value >> 24);
+ Position += 4;
+}
+
+static void EmitDarwinBCHeaderAndTrailer(SmallVectorImpl<char> &Buffer,
+ const Triple &TT) {
unsigned CPUType = ~0U;
// Match x86_64-*, i[3-9]86-*, powerpc-*, powerpc64-*, arm-*, thumb-*,
@@ -1773,63 +1811,55 @@ static void EmitDarwinBCHeader(BitstreamWriter &Stream, const Triple &TT) {
CPUType = DARWIN_CPU_TYPE_ARM;
// Traditional Bitcode starts after header.
+ assert(Buffer.size() >= DarwinBCHeaderSize &&
+ "Expected header size to be reserved");
unsigned BCOffset = DarwinBCHeaderSize;
+ unsigned BCSize = Buffer.size()-DarwinBCHeaderSize;
- Stream.Emit(0x0B17C0DE, 32);
- Stream.Emit(0 , 32); // Version.
- Stream.Emit(BCOffset , 32);
- Stream.Emit(0 , 32); // Filled in later.
- Stream.Emit(CPUType , 32);
-}
-
-/// EmitDarwinBCTrailer - Emit the darwin epilog after the bitcode file and
-/// finalize the header.
-static void EmitDarwinBCTrailer(BitstreamWriter &Stream, unsigned BufferSize) {
- // Update the size field in the header.
- Stream.BackpatchWord(DarwinBCSizeFieldOffset, BufferSize-DarwinBCHeaderSize);
+ // Write the magic and version.
+ unsigned Position = 0;
+ WriteInt32ToBuffer(0x0B17C0DE , Buffer, Position);
+ WriteInt32ToBuffer(0 , Buffer, Position); // Version.
+ WriteInt32ToBuffer(BCOffset , Buffer, Position);
+ WriteInt32ToBuffer(BCSize , Buffer, Position);
+ WriteInt32ToBuffer(CPUType , Buffer, Position);
// If the file is not a multiple of 16 bytes, insert dummy padding.
- while (BufferSize & 15) {
- Stream.Emit(0, 8);
- ++BufferSize;
- }
+ while (Buffer.size() & 15)
+ Buffer.push_back(0);
}
-
/// WriteBitcodeToFile - Write the specified module to the specified output
/// stream.
void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out) {
- std::vector<unsigned char> Buffer;
- BitstreamWriter Stream(Buffer);
-
+ SmallVector<char, 1024> Buffer;
Buffer.reserve(256*1024);
- WriteBitcodeToStream( M, Stream );
-
- // Write the generated bitstream to "Out".
- Out.write((char*)&Buffer.front(), Buffer.size());
-}
-
-/// WriteBitcodeToStream - Write the specified module to the specified output
-/// stream.
-void llvm::WriteBitcodeToStream(const Module *M, BitstreamWriter &Stream) {
- // If this is darwin or another generic macho target, emit a file header and
- // trailer if needed.
+ // If this is darwin or another generic macho target, reserve space for the
+ // header.
Triple TT(M->getTargetTriple());
if (TT.isOSDarwin())
- EmitDarwinBCHeader(Stream, TT);
-
- // Emit the file header.
- Stream.Emit((unsigned)'B', 8);
- Stream.Emit((unsigned)'C', 8);
- Stream.Emit(0x0, 4);
- Stream.Emit(0xC, 4);
- Stream.Emit(0xE, 4);
- Stream.Emit(0xD, 4);
-
- // Emit the module.
- WriteModule(M, Stream);
+ Buffer.insert(Buffer.begin(), DarwinBCHeaderSize, 0);
+
+ // Emit the module into the buffer.
+ {
+ BitstreamWriter Stream(Buffer);
+
+ // Emit the file header.
+ Stream.Emit((unsigned)'B', 8);
+ Stream.Emit((unsigned)'C', 8);
+ Stream.Emit(0x0, 4);
+ Stream.Emit(0xC, 4);
+ Stream.Emit(0xE, 4);
+ Stream.Emit(0xD, 4);
+
+ // Emit the module.
+ WriteModule(M, Stream);
+ }
if (TT.isOSDarwin())
- EmitDarwinBCTrailer(Stream, Stream.getBuffer().size());
+ EmitDarwinBCHeaderAndTrailer(Buffer, TT);
+
+ // Write the generated bitstream to "Out".
+ Out.write((char*)&Buffer.front(), Buffer.size());
}
diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp
index 1c4d670..1ed9004 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -321,10 +321,6 @@ void ValueEnumerator::EnumerateValue(const Value *V) {
if (const Constant *C = dyn_cast<Constant>(V)) {
if (isa<GlobalValue>(C)) {
// Initializers for globals are handled explicitly elsewhere.
- } else if (isa<ConstantArray>(C) && cast<ConstantArray>(C)->isString()) {
- // Do not enumerate the initializers for an array of simple characters.
- // The initializers just pollute the value table, and we emit the strings
- // specially.
} else if (C->getNumOperands()) {
// If a constant has operands, enumerate them. This makes sure that if a
// constant has uses (for example an array of const ints), that they are