forked from OSchip/llvm-project
Bitcode: Prepare to move bitcode readers to free functions.
Make initStream() a free function, and change BitcodeReaderBase ctor to take a BitstreamCursor. llvm-svn: 286622
This commit is contained in:
parent
4f734f254e
commit
c0032b7178
|
@ -228,15 +228,54 @@ private:
|
|||
Metadata *resolveTypeRefArray(Metadata *MaybeTuple);
|
||||
};
|
||||
|
||||
Error error(const Twine &Message) {
|
||||
return make_error<StringError>(
|
||||
Message, make_error_code(BitcodeError::CorruptedBitcode));
|
||||
}
|
||||
|
||||
/// Helper to read the header common to all bitcode files.
|
||||
bool hasValidBitcodeHeader(BitstreamCursor &Stream) {
|
||||
// Sniff for the signature.
|
||||
if (!Stream.canSkipToPos(4) ||
|
||||
Stream.Read(8) != 'B' ||
|
||||
Stream.Read(8) != 'C' ||
|
||||
Stream.Read(4) != 0x0 ||
|
||||
Stream.Read(4) != 0xC ||
|
||||
Stream.Read(4) != 0xE ||
|
||||
Stream.Read(4) != 0xD)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Expected<BitstreamCursor> initStream(MemoryBufferRef Buffer) {
|
||||
const unsigned char *BufPtr = (const unsigned char *)Buffer.getBufferStart();
|
||||
const unsigned char *BufEnd = BufPtr + Buffer.getBufferSize();
|
||||
|
||||
if (Buffer.getBufferSize() & 3)
|
||||
return error("Invalid bitcode signature");
|
||||
|
||||
// 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");
|
||||
|
||||
BitstreamCursor Stream(ArrayRef<uint8_t>(BufPtr, BufEnd));
|
||||
if (!hasValidBitcodeHeader(Stream))
|
||||
return error("Invalid bitcode signature");
|
||||
|
||||
return std::move(Stream);
|
||||
}
|
||||
|
||||
class BitcodeReaderBase {
|
||||
protected:
|
||||
BitcodeReaderBase(MemoryBufferRef Buffer) : Buffer(Buffer) {}
|
||||
BitcodeReaderBase(BitstreamCursor Stream) : Stream(std::move(Stream)) {
|
||||
this->Stream.setBlockInfo(&BlockInfo);
|
||||
}
|
||||
|
||||
MemoryBufferRef Buffer;
|
||||
BitstreamBlockInfo BlockInfo;
|
||||
BitstreamCursor Stream;
|
||||
|
||||
Error initStream();
|
||||
bool readBlockInfo();
|
||||
|
||||
// Contains an arbitrary and optional string identifying the bitcode producer
|
||||
|
@ -250,27 +289,7 @@ Error BitcodeReaderBase::error(const Twine &Message) {
|
|||
if (!ProducerIdentification.empty())
|
||||
FullMsg += " (Producer: '" + ProducerIdentification + "' Reader: 'LLVM " +
|
||||
LLVM_VERSION_STRING "')";
|
||||
return make_error<StringError>(
|
||||
FullMsg, make_error_code(BitcodeError::CorruptedBitcode));
|
||||
}
|
||||
|
||||
Error BitcodeReaderBase::initStream() {
|
||||
const unsigned char *BufPtr = (const unsigned char*)Buffer.getBufferStart();
|
||||
const unsigned char *BufEnd = BufPtr+Buffer.getBufferSize();
|
||||
|
||||
if (Buffer.getBufferSize() & 3)
|
||||
return error("Invalid bitcode signature");
|
||||
|
||||
// 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");
|
||||
|
||||
Stream = BitstreamCursor(ArrayRef<uint8_t>(BufPtr, BufEnd));
|
||||
Stream.setBlockInfo(&BlockInfo);
|
||||
|
||||
return Error::success();
|
||||
return ::error(FullMsg);
|
||||
}
|
||||
|
||||
class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
|
||||
|
@ -366,7 +385,7 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
|
|||
std::vector<std::string> BundleTags;
|
||||
|
||||
public:
|
||||
BitcodeReader(MemoryBufferRef Buffer, LLVMContext &Context);
|
||||
BitcodeReader(BitstreamCursor Stream, LLVMContext &Context);
|
||||
|
||||
Error materializeForwardReferencedFunctions();
|
||||
|
||||
|
@ -579,21 +598,21 @@ class ModuleSummaryIndexBitcodeReader : public BitcodeReaderBase {
|
|||
|
||||
public:
|
||||
ModuleSummaryIndexBitcodeReader(
|
||||
MemoryBufferRef Buffer, bool CheckGlobalValSummaryPresenceOnly = false);
|
||||
BitstreamCursor Stream, bool CheckGlobalValSummaryPresenceOnly = false);
|
||||
|
||||
/// Check if the parser has encountered a summary section.
|
||||
bool foundGlobalValSummary() { return SeenGlobalValSummary; }
|
||||
|
||||
/// \brief Main interface to parsing a bitcode buffer.
|
||||
/// \returns true if an error occurred.
|
||||
Error parseSummaryIndexInto(ModuleSummaryIndex *I);
|
||||
Error parseSummaryIndexInto(ModuleSummaryIndex *I, StringRef ModulePath);
|
||||
|
||||
private:
|
||||
Error parseModule();
|
||||
Error parseModule(StringRef ModulePath);
|
||||
Error parseValueSymbolTable(
|
||||
uint64_t Offset,
|
||||
DenseMap<unsigned, GlobalValue::LinkageTypes> &ValueIdToLinkageMap);
|
||||
Error parseEntireSummary();
|
||||
Error parseEntireSummary(StringRef ModulePath);
|
||||
Error parseModuleStringTable();
|
||||
std::pair<GlobalValue::GUID, GlobalValue::GUID>
|
||||
|
||||
|
@ -647,8 +666,8 @@ expectedToErrorOrAndEmitErrors(const DiagnosticHandlerFunction &DiagHandler,
|
|||
|
||||
} // end anonymous namespace
|
||||
|
||||
BitcodeReader::BitcodeReader(MemoryBufferRef Buffer, LLVMContext &Context)
|
||||
: BitcodeReaderBase(Buffer), Context(Context), ValueList(Context),
|
||||
BitcodeReader::BitcodeReader(BitstreamCursor Stream, LLVMContext &Context)
|
||||
: BitcodeReaderBase(std::move(Stream)), Context(Context), ValueList(Context),
|
||||
MetadataList(Context) {}
|
||||
|
||||
Error BitcodeReader::materializeForwardReferencedFunctions() {
|
||||
|
@ -4222,30 +4241,9 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
|
|||
}
|
||||
}
|
||||
|
||||
/// Helper to read the header common to all bitcode files.
|
||||
static bool hasValidBitcodeHeader(BitstreamCursor &Stream) {
|
||||
// Sniff for the signature.
|
||||
if (!Stream.canSkipToPos(4) ||
|
||||
Stream.Read(8) != 'B' ||
|
||||
Stream.Read(8) != 'C' ||
|
||||
Stream.Read(4) != 0x0 ||
|
||||
Stream.Read(4) != 0xC ||
|
||||
Stream.Read(4) != 0xE ||
|
||||
Stream.Read(4) != 0xD)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata) {
|
||||
TheModule = M;
|
||||
|
||||
if (Error Err = initStream())
|
||||
return Err;
|
||||
|
||||
// Sniff for the signature.
|
||||
if (!hasValidBitcodeHeader(Stream))
|
||||
return error("Invalid bitcode signature");
|
||||
|
||||
// We expect a number of well-defined blocks, though we don't necessarily
|
||||
// need to understand them all.
|
||||
while (true) {
|
||||
|
@ -4314,13 +4312,6 @@ Expected<std::string> BitcodeReader::parseModuleTriple() {
|
|||
}
|
||||
|
||||
Expected<std::string> BitcodeReader::parseTriple() {
|
||||
if (Error Err = initStream())
|
||||
return std::move(Err);
|
||||
|
||||
// Sniff for the signature.
|
||||
if (!hasValidBitcodeHeader(Stream))
|
||||
return error("Invalid bitcode signature");
|
||||
|
||||
// We expect a number of well-defined blocks, though we don't necessarily
|
||||
// need to understand them all.
|
||||
while (true) {
|
||||
|
@ -4349,13 +4340,6 @@ Expected<std::string> BitcodeReader::parseTriple() {
|
|||
}
|
||||
|
||||
Expected<std::string> BitcodeReader::parseIdentificationBlock() {
|
||||
if (Error Err = initStream())
|
||||
return std::move(Err);
|
||||
|
||||
// Sniff for the signature.
|
||||
if (!hasValidBitcodeHeader(Stream))
|
||||
return error("Invalid bitcode signature");
|
||||
|
||||
// We expect a number of well-defined blocks, though we don't necessarily
|
||||
// need to understand them all.
|
||||
while (true) {
|
||||
|
@ -4405,13 +4389,6 @@ Error BitcodeReader::parseGlobalObjectAttachment(GlobalObject &GO,
|
|||
}
|
||||
|
||||
Expected<bool> BitcodeReader::hasObjCCategory() {
|
||||
if (Error Err = initStream())
|
||||
return std::move(Err);
|
||||
|
||||
// Sniff for the signature.
|
||||
if (!hasValidBitcodeHeader(Stream))
|
||||
return error("Invalid bitcode signature");
|
||||
|
||||
// We expect a number of well-defined blocks, though we don't necessarily
|
||||
// need to understand them all.
|
||||
while (true) {
|
||||
|
@ -5981,8 +5958,8 @@ std::vector<StructType *> BitcodeReader::getIdentifiedStructTypes() const {
|
|||
}
|
||||
|
||||
ModuleSummaryIndexBitcodeReader::ModuleSummaryIndexBitcodeReader(
|
||||
MemoryBufferRef Buffer, bool CheckGlobalValSummaryPresenceOnly)
|
||||
: BitcodeReaderBase(Buffer),
|
||||
BitstreamCursor Cursor, bool CheckGlobalValSummaryPresenceOnly)
|
||||
: BitcodeReaderBase(std::move(Cursor)),
|
||||
CheckGlobalValSummaryPresenceOnly(CheckGlobalValSummaryPresenceOnly) {}
|
||||
|
||||
std::pair<GlobalValue::GUID, GlobalValue::GUID>
|
||||
|
@ -6094,7 +6071,7 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable(
|
|||
// Parse just the blocks needed for building the index out of the module.
|
||||
// At the end of this routine the module Index is populated with a map
|
||||
// from global value id to GlobalValueSummary objects.
|
||||
Error ModuleSummaryIndexBitcodeReader::parseModule() {
|
||||
Error ModuleSummaryIndexBitcodeReader::parseModule(StringRef ModulePath) {
|
||||
if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
|
||||
return error("Invalid record");
|
||||
|
||||
|
@ -6155,7 +6132,7 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() {
|
|||
SeenValueSymbolTable = true;
|
||||
}
|
||||
SeenGlobalValSummary = true;
|
||||
if (Error Err = parseEntireSummary())
|
||||
if (Error Err = parseEntireSummary(ModulePath))
|
||||
return Err;
|
||||
break;
|
||||
case bitc::MODULE_STRTAB_BLOCK_ID:
|
||||
|
@ -6187,7 +6164,7 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() {
|
|||
break;
|
||||
if (TheIndex->modulePaths().empty())
|
||||
// We always seed the index with the module.
|
||||
TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0);
|
||||
TheIndex->addModulePath(ModulePath, 0);
|
||||
if (TheIndex->modulePaths().size() != 1)
|
||||
return error("Don't expect multiple modules defined?");
|
||||
auto &Hash = TheIndex->modulePaths().begin()->second.second;
|
||||
|
@ -6246,7 +6223,8 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() {
|
|||
|
||||
// Eagerly parse the entire summary block. This populates the GlobalValueSummary
|
||||
// objects in the index.
|
||||
Error ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
|
||||
Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
|
||||
StringRef ModulePath) {
|
||||
if (Stream.EnterSubBlock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID))
|
||||
return error("Invalid record");
|
||||
SmallVector<uint64_t, 64> Record;
|
||||
|
@ -6326,8 +6304,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
|
|||
// string table section in the per-module index, we create a single
|
||||
// module path string table entry with an empty (0) ID to take
|
||||
// ownership.
|
||||
FS->setModulePath(
|
||||
TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0)->first());
|
||||
FS->setModulePath(TheIndex->addModulePath(ModulePath, 0)->first());
|
||||
static int RefListStartIndex = 4;
|
||||
int CallGraphEdgeStartIndex = RefListStartIndex + NumRefs;
|
||||
assert(Record.size() >= RefListStartIndex + NumRefs &&
|
||||
|
@ -6365,8 +6342,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
|
|||
// string table section in the per-module index, we create a single
|
||||
// module path string table entry with an empty (0) ID to take
|
||||
// ownership.
|
||||
AS->setModulePath(
|
||||
TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0)->first());
|
||||
AS->setModulePath(TheIndex->addModulePath(ModulePath, 0)->first());
|
||||
|
||||
GlobalValue::GUID AliaseeGUID = getGUIDFromValueId(AliaseeID).first;
|
||||
auto *AliaseeSummary = TheIndex->getGlobalValueSummary(AliaseeGUID);
|
||||
|
@ -6386,8 +6362,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
|
|||
auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
|
||||
std::unique_ptr<GlobalVarSummary> FS =
|
||||
llvm::make_unique<GlobalVarSummary>(Flags);
|
||||
FS->setModulePath(
|
||||
TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0)->first());
|
||||
FS->setModulePath(TheIndex->addModulePath(ModulePath, 0)->first());
|
||||
for (unsigned I = 2, E = Record.size(); I != E; ++I) {
|
||||
unsigned RefValueId = Record[I];
|
||||
GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId).first;
|
||||
|
@ -6577,17 +6552,10 @@ Error ModuleSummaryIndexBitcodeReader::parseModuleStringTable() {
|
|||
}
|
||||
|
||||
// Parse the function info index from the bitcode streamer into the given index.
|
||||
Error
|
||||
ModuleSummaryIndexBitcodeReader::parseSummaryIndexInto(ModuleSummaryIndex *I) {
|
||||
Error ModuleSummaryIndexBitcodeReader::parseSummaryIndexInto(
|
||||
ModuleSummaryIndex *I, StringRef ModulePath) {
|
||||
TheIndex = I;
|
||||
|
||||
if (Error Err = initStream())
|
||||
return Err;
|
||||
|
||||
// Sniff for the signature.
|
||||
if (!hasValidBitcodeHeader(Stream))
|
||||
return error("Invalid bitcode signature");
|
||||
|
||||
// We expect a number of well-defined blocks, though we don't necessarily
|
||||
// need to understand them all.
|
||||
while (true) {
|
||||
|
@ -6605,7 +6573,7 @@ ModuleSummaryIndexBitcodeReader::parseSummaryIndexInto(ModuleSummaryIndex *I) {
|
|||
// If we see a MODULE_BLOCK, parse it to find the blocks needed for
|
||||
// building the function summary index.
|
||||
if (Entry.ID == bitc::MODULE_BLOCK_ID)
|
||||
return parseModule();
|
||||
return parseModule(ModulePath);
|
||||
|
||||
if (Stream.SkipBlock())
|
||||
return error("Invalid record");
|
||||
|
@ -6655,7 +6623,11 @@ static ErrorOr<std::unique_ptr<Module>>
|
|||
getLazyBitcodeModuleImpl(MemoryBufferRef Buffer, LLVMContext &Context,
|
||||
bool MaterializeAll,
|
||||
bool ShouldLazyLoadMetadata = false) {
|
||||
BitcodeReader *R = new BitcodeReader(Buffer, Context);
|
||||
Expected<BitstreamCursor> StreamOrErr = initStream(Buffer);
|
||||
if (!StreamOrErr)
|
||||
return errorToErrorCodeAndEmitErrors(Context, StreamOrErr.takeError());
|
||||
|
||||
BitcodeReader *R = new BitcodeReader(std::move(*StreamOrErr), Context);
|
||||
|
||||
std::unique_ptr<Module> M =
|
||||
llvm::make_unique<Module>(Buffer.getBufferIdentifier(), Context);
|
||||
|
@ -6703,7 +6675,12 @@ ErrorOr<std::unique_ptr<Module>> llvm::parseBitcodeFile(MemoryBufferRef Buffer,
|
|||
|
||||
std::string llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer,
|
||||
LLVMContext &Context) {
|
||||
BitcodeReader R(Buffer, Context);
|
||||
ErrorOr<BitstreamCursor> StreamOrErr =
|
||||
expectedToErrorOrAndEmitErrors(Context, initStream(Buffer));
|
||||
if (!StreamOrErr)
|
||||
return "";
|
||||
|
||||
BitcodeReader R(std::move(*StreamOrErr), Context);
|
||||
ErrorOr<std::string> Triple =
|
||||
expectedToErrorOrAndEmitErrors(Context, R.parseTriple());
|
||||
if (Triple.getError())
|
||||
|
@ -6713,7 +6690,12 @@ std::string llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer,
|
|||
|
||||
bool llvm::isBitcodeContainingObjCCategory(MemoryBufferRef Buffer,
|
||||
LLVMContext &Context) {
|
||||
BitcodeReader R(Buffer, Context);
|
||||
ErrorOr<BitstreamCursor> StreamOrErr =
|
||||
expectedToErrorOrAndEmitErrors(Context, initStream(Buffer));
|
||||
if (!StreamOrErr)
|
||||
return false;
|
||||
|
||||
BitcodeReader R(std::move(*StreamOrErr), Context);
|
||||
ErrorOr<bool> hasObjCCategory =
|
||||
expectedToErrorOrAndEmitErrors(Context, R.hasObjCCategory());
|
||||
if (hasObjCCategory.getError())
|
||||
|
@ -6723,7 +6705,12 @@ bool llvm::isBitcodeContainingObjCCategory(MemoryBufferRef Buffer,
|
|||
|
||||
std::string llvm::getBitcodeProducerString(MemoryBufferRef Buffer,
|
||||
LLVMContext &Context) {
|
||||
BitcodeReader R(Buffer, Context);
|
||||
ErrorOr<BitstreamCursor> StreamOrErr =
|
||||
expectedToErrorOrAndEmitErrors(Context, initStream(Buffer));
|
||||
if (!StreamOrErr)
|
||||
return "";
|
||||
|
||||
BitcodeReader R(std::move(*StreamOrErr), Context);
|
||||
ErrorOr<std::string> ProducerString =
|
||||
expectedToErrorOrAndEmitErrors(Context, R.parseIdentificationBlock());
|
||||
if (ProducerString.getError())
|
||||
|
@ -6735,12 +6722,18 @@ std::string llvm::getBitcodeProducerString(MemoryBufferRef Buffer,
|
|||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> llvm::getModuleSummaryIndex(
|
||||
MemoryBufferRef Buffer,
|
||||
const DiagnosticHandlerFunction &DiagnosticHandler) {
|
||||
ModuleSummaryIndexBitcodeReader R(Buffer);
|
||||
Expected<BitstreamCursor> StreamOrErr = initStream(Buffer);
|
||||
if (!StreamOrErr)
|
||||
return errorToErrorCodeAndEmitErrors(DiagnosticHandler,
|
||||
StreamOrErr.takeError());
|
||||
|
||||
ModuleSummaryIndexBitcodeReader R(std::move(*StreamOrErr));
|
||||
|
||||
auto Index = llvm::make_unique<ModuleSummaryIndex>();
|
||||
|
||||
if (std::error_code EC = errorToErrorCodeAndEmitErrors(
|
||||
DiagnosticHandler, R.parseSummaryIndexInto(Index.get())))
|
||||
DiagnosticHandler,
|
||||
R.parseSummaryIndexInto(Index.get(), Buffer.getBufferIdentifier())))
|
||||
return EC;
|
||||
|
||||
return std::move(Index);
|
||||
|
@ -6750,10 +6743,15 @@ ErrorOr<std::unique_ptr<ModuleSummaryIndex>> llvm::getModuleSummaryIndex(
|
|||
bool llvm::hasGlobalValueSummary(
|
||||
MemoryBufferRef Buffer,
|
||||
const DiagnosticHandlerFunction &DiagnosticHandler) {
|
||||
ModuleSummaryIndexBitcodeReader R(Buffer, true);
|
||||
ErrorOr<BitstreamCursor> StreamOrErr = expectedToErrorOrAndEmitErrors(
|
||||
DiagnosticHandler, initStream(Buffer));
|
||||
if (!StreamOrErr)
|
||||
return false;
|
||||
|
||||
if (errorToErrorCodeAndEmitErrors(DiagnosticHandler,
|
||||
R.parseSummaryIndexInto(nullptr)))
|
||||
ModuleSummaryIndexBitcodeReader R(std::move(*StreamOrErr), true);
|
||||
if (errorToErrorCodeAndEmitErrors(
|
||||
DiagnosticHandler,
|
||||
R.parseSummaryIndexInto(nullptr, Buffer.getBufferIdentifier())))
|
||||
return false;
|
||||
|
||||
return R.foundGlobalValSummary();
|
||||
|
|
Loading…
Reference in New Issue