Add a module Hash in the bitcode and the combined index, implementing a kind of "build-id"

This is intended to be used for ThinLTO incremental build.

Differential Revision: http://reviews.llvm.org/D18213

From: Mehdi Amini <mehdi.amini@apple.com>
llvm-svn: 265095
This commit is contained in:
Mehdi Amini
2016-04-01 01:30:06 +00:00
parent 3689ae14eb
commit 4c2ed3337d
11 changed files with 232 additions and 38 deletions

View File

@@ -5632,11 +5632,7 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseModule() {
}
continue;
case BitstreamEntry::Record:
// Once we find the last record of interest, skip the rest.
if (VSTOffset > 0)
Stream.skipRecord(Entry.ID);
else {
case BitstreamEntry::Record: {
Record.clear();
auto BitCode = Stream.readRecord(Entry.ID, Record);
switch (BitCode) {
@@ -5650,6 +5646,25 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseModule() {
SourceFileName = ValueName.c_str();
break;
}
/// MODULE_CODE_HASH: [5*i32]
case bitc::MODULE_CODE_HASH: {
if (Record.size() != 5)
return error("Invalid hash length " + Twine(Record.size()).str());
if (!TheIndex)
break;
if (TheIndex->modulePaths().empty())
// Does not have any summary emitted.
break;
if (TheIndex->modulePaths().size() != 1)
return error("Don't expect multiple modules defined?");
auto &Hash = TheIndex->modulePaths().begin()->second.second;
int Pos = 0;
for (auto &Val : Record) {
assert(!(Val >> 32) && "Unexpected high bits set");
Hash[Pos++] = Val;
}
break;
}
/// MODULE_CODE_VSTOFFSET: [offset]
case bitc::MODULE_CODE_VSTOFFSET:
if (Record.size() < 1)
@@ -5761,7 +5776,7 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
// module path string table entry with an empty (0) ID to take
// ownership.
FS->setModulePath(
TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0));
TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0)->first());
static int RefListStartIndex = 4;
int CallGraphEdgeStartIndex = RefListStartIndex + NumRefs;
assert(Record.size() >= RefListStartIndex + NumRefs &&
@@ -5799,7 +5814,7 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
std::unique_ptr<GlobalVarSummary> FS =
llvm::make_unique<GlobalVarSummary>(getDecodedLinkage(RawLinkage));
FS->setModulePath(
TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0));
TheIndex->addModulePath(Buffer->getBufferIdentifier(), 0)->first());
for (unsigned I = 2, E = Record.size(); I != E; ++I) {
unsigned RefValueId = Record[I];
uint64_t RefGUID = getGUIDFromValueId(RefValueId);
@@ -5887,6 +5902,7 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseModuleStringTable() {
SmallVector<uint64_t, 64> Record;
SmallString<128> ModulePath;
ModulePathStringTableTy::iterator LastSeenModulePath;
while (1) {
BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
@@ -5907,14 +5923,32 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseModuleStringTable() {
break;
case bitc::MST_CODE_ENTRY: {
// MST_ENTRY: [modid, namechar x N]
uint64_t ModuleId = Record[0];
if (convertToString(Record, 1, ModulePath))
return error("Invalid record");
uint64_t ModuleId = Record[0];
StringRef ModulePathInMap = TheIndex->addModulePath(ModulePath, ModuleId);
ModuleIdMap[ModuleId] = ModulePathInMap;
LastSeenModulePath = TheIndex->addModulePath(ModulePath, ModuleId);
ModuleIdMap[ModuleId] = LastSeenModulePath->first();
ModulePath.clear();
break;
}
/// MST_CODE_HASH: [5*i32]
case bitc::MST_CODE_HASH: {
if (Record.size() != 5)
return error("Invalid hash length " + Twine(Record.size()).str());
if (LastSeenModulePath == TheIndex->modulePaths().end())
return error("Invalid hash that does not follow a module path");
int Pos = 0;
for (auto &Val : Record) {
assert(!(Val >> 32) && "Unexpected high bits set");
LastSeenModulePath->second.second[Pos++] = Val;
}
// Reset LastSeenModulePath to avoid overriding the hash unexpectedly.
LastSeenModulePath = TheIndex->modulePaths().end();
break;
}
}
}
llvm_unreachable("Exit infinite loop");