diff options
author | Teresa Johnson <tejohnson@google.com> | 2016-02-10 18:57:54 +0000 |
---|---|---|
committer | Teresa Johnson <tejohnson@google.com> | 2016-02-10 18:57:54 +0000 |
commit | 0919a84071e55190643eb6e833a51755692b0d29 (patch) | |
tree | defa683bb416a4a6ee5cb54564e29d96d99dd143 /llvm/lib/Bitcode/Reader/BitcodeReader.cpp | |
parent | ad7b6f5aeaaf9c8fbaad65f1e3a9e21ddb76d048 (diff) | |
download | llvm-0919a84071e55190643eb6e833a51755692b0d29.zip llvm-0919a84071e55190643eb6e833a51755692b0d29.tar.gz llvm-0919a84071e55190643eb6e833a51755692b0d29.tar.bz2 |
[ThinLTO] Use MD5 hash in function index.
Summary:
This patch uses the lower 64-bits of the MD5 hash of a function name as
a GUID in the function index, instead of storing function names. Any
local functions are first given a global name by prepending the original
source file name. This is the same naming scheme and GUID used by PGO in
the indexed profile format.
This change has a couple of benefits. The primary benefit is size
reduction in the combined index file, for example 483.xalancbmk's
combined index file was reduced by around 70%. It should also result in
memory savings for the index file in memory, as the in-memory map is
also indexed by the hash instead of the string.
Second, this enables integration with indirect call promotion, since the
indirect call profile targets are recorded using the same global naming
convention and hash. This will enable the function importer to easily
locate function summaries for indirect call profile targets to enable
their import and subsequent promotion.
The original source file name is recorded in the bitcode in a new
module-level record for use in the ThinLTO backend pipeline.
Reviewers: davidxl, joker.eph
Subscribers: llvm-commits, joker.eph
Differential Revision: http://reviews.llvm.org/D17028
llvm-svn: 260408
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 36eff13..8183a37 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -458,6 +458,9 @@ class FunctionIndexBitcodeReader { /// summary records. DenseMap<uint64_t, StringRef> ModuleIdMap; + /// Original source file name recorded in a bitcode record. + std::string SourceFileName; + public: std::error_code error(BitcodeError E, const Twine &Message); std::error_code error(BitcodeError E); @@ -3697,6 +3700,13 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit, assert(MetadataList.size() == 0); MetadataList.resize(NumModuleMDs); break; + /// MODULE_CODE_SOURCE_FILENAME: [namechar x N] + case bitc::MODULE_CODE_SOURCE_FILENAME: + SmallString<128> ValueName; + if (convertToString(Record, 0, ValueName)) + return error("Invalid record"); + TheModule->setSourceFileName(ValueName); + break; } Record.clear(); } @@ -5454,24 +5464,31 @@ std::error_code FunctionIndexBitcodeReader::parseValueSymbolTable() { return error("Invalid record"); unsigned ValueID = Record[0]; uint64_t FuncOffset = Record[1]; - std::unique_ptr<FunctionInfo> FuncInfo = - llvm::make_unique<FunctionInfo>(FuncOffset); - if (foundFuncSummary() && !IsLazy) { + assert(!IsLazy && "Lazy summary read only supported for combined index"); + // Gracefully handle bitcode without a function summary section, + // which will simply not populate the index. + if (foundFuncSummary()) { DenseMap<uint64_t, std::unique_ptr<FunctionSummary>>::iterator SMI = SummaryMap.find(ValueID); assert(SMI != SummaryMap.end() && "Summary info not found"); + std::unique_ptr<FunctionInfo> FuncInfo = + llvm::make_unique<FunctionInfo>(FuncOffset); FuncInfo->setFunctionSummary(std::move(SMI->second)); + assert(!SourceFileName.empty()); + TheIndex->addFunctionInfo( + Function::getGlobalIdentifier( + ValueName, FuncInfo->functionSummary()->getFunctionLinkage(), + SourceFileName), + std::move(FuncInfo)); } - TheIndex->addFunctionInfo(ValueName, std::move(FuncInfo)); ValueName.clear(); break; } case bitc::VST_CODE_COMBINED_FNENTRY: { - // VST_CODE_FNENTRY: [offset, namechar x N] - if (convertToString(Record, 1, ValueName)) - return error("Invalid record"); + // VST_CODE_COMBINED_FNENTRY: [offset, funcguid] uint64_t FuncSummaryOffset = Record[0]; + uint64_t FuncGUID = Record[1]; std::unique_ptr<FunctionInfo> FuncInfo = llvm::make_unique<FunctionInfo>(FuncSummaryOffset); if (foundFuncSummary() && !IsLazy) { @@ -5480,7 +5497,7 @@ std::error_code FunctionIndexBitcodeReader::parseValueSymbolTable() { assert(SMI != SummaryMap.end() && "Summary info not found"); FuncInfo->setFunctionSummary(std::move(SMI->second)); } - TheIndex->addFunctionInfo(ValueName, std::move(FuncInfo)); + TheIndex->addFunctionInfo(FuncGUID, std::move(FuncInfo)); ValueName.clear(); break; @@ -5499,6 +5516,8 @@ std::error_code FunctionIndexBitcodeReader::parseModule() { if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) return error("Invalid record"); + SmallVector<uint64_t, 64> Record; + // Read the function index for this module. while (1) { BitstreamEntry Entry = Stream.advance(); @@ -5551,7 +5570,24 @@ std::error_code FunctionIndexBitcodeReader::parseModule() { continue; case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); + // Once we find the single record of interest, skip the rest. + if (!SourceFileName.empty()) + Stream.skipRecord(Entry.ID); + else { + Record.clear(); + auto BitCode = Stream.readRecord(Entry.ID, Record); + switch (BitCode) { + default: + break; // Default behavior, ignore unknown content. + /// MODULE_CODE_SOURCE_FILENAME: [namechar x N] + case bitc::MODULE_CODE_SOURCE_FILENAME: + SmallString<128> ValueName; + if (convertToString(Record, 0, ValueName)) + return error("Invalid record"); + SourceFileName = ValueName.c_str(); + break; + } + } continue; } } |