aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ProfileData/InstrProfReader.cpp
diff options
context:
space:
mode:
authorXinliang David Li <davidxl@google.com>2015-12-20 06:22:13 +0000
committerXinliang David Li <davidxl@google.com>2015-12-20 06:22:13 +0000
commita716cc5c33cb22b84c8f91c94e1682c6c8245cc2 (patch)
tree43977a99dc295b1ba2dda5ff76434ae0b74a0e22 /llvm/lib/ProfileData/InstrProfReader.cpp
parent5c24da5d8e1c27f06598576c51b8d7e2784e2f17 (diff)
downloadllvm-a716cc5c33cb22b84c8f91c94e1682c6c8245cc2.zip
llvm-a716cc5c33cb22b84c8f91c94e1682c6c8245cc2.tar.gz
llvm-a716cc5c33cb22b84c8f91c94e1682c6c8245cc2.tar.bz2
[PGO] Improve Indexed Profile Reader efficiency
With the support of value profiling added, the Indexed prof reader gets less efficient. The prof reader initialization used to be just reading the file header, but with VP support added, initialization needs to walk through all profile keys of ondisk hash table resulting in very poor locality and large memory increase (keys are stored together with the profile data in the mapped profile buffer). Even worse, when the reader is used by the compiler (not llvm-profdata too), the penalty becomes very high as compilation of each single module requires touching profile data buffer for the whole program. In this patch, the icall target values (MD5hash) are no longer eargerly converted back to name strings when the data is read into memory. New interface is added to to profile reader so that InstrProfSymtab can be lazily created for Indexed profile reader on-demand. Creating of the symtab is intended to be used by llvm-profdata tool for symbolic dumping of VP data. It can be used with compiler (for legacy out of tree uses) too but not recommended due to compile time and memory reasons mentioned above. Some other cleanups are also included: Function Addr to md5 map is now consolated into InstrProfSymtab. InstrProfStringtab is no longer used and eliminated. llvm-svn: 256114
Diffstat (limited to 'llvm/lib/ProfileData/InstrProfReader.cpp')
-rw-r--r--llvm/lib/ProfileData/InstrProfReader.cpp84
1 files changed, 50 insertions, 34 deletions
diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp
index aca4354..5e83456 100644
--- a/llvm/lib/ProfileData/InstrProfReader.cpp
+++ b/llvm/lib/ProfileData/InstrProfReader.cpp
@@ -109,6 +109,11 @@ bool TextInstrProfReader::hasFormat(const MemoryBuffer &Buffer) {
[](char c) { return ::isprint(c) || ::isspace(c); });
}
+std::error_code TextInstrProfReader::readHeader() {
+ Symtab.reset(new InstrProfSymtab());
+ return success();
+}
+
std::error_code
TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) {
@@ -126,6 +131,7 @@ TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) {
if (Line.is_at_end())
return success();
+
uint32_t NumValueKinds;
if (Line->getAsInteger(10, NumValueKinds)) {
// No value profile data
@@ -152,12 +158,13 @@ TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) {
CHECK_LINE_END(Line);
std::pair<StringRef, StringRef> VD = Line->split(':');
uint64_t TakenCount, Value;
- READ_NUM(VD.second, TakenCount);
- if (VK == IPVK_IndirectCallTarget)
- Value = (uint64_t)StringTable.insertString(VD.first);
- else {
+ if (VK == IPVK_IndirectCallTarget) {
+ Symtab->addFuncName(VD.first);
+ Value = IndexedInstrProf::ComputeHash(VD.first);
+ } else {
READ_NUM(VD.first, Value);
}
+ READ_NUM(VD.second, TakenCount);
CurrentValues.push_back({Value, TakenCount});
Line++;
}
@@ -176,11 +183,14 @@ std::error_code TextInstrProfReader::readNextRecord(InstrProfRecord &Record) {
while (!Line.is_at_end() && (Line->empty() || Line->startswith("#")))
++Line;
// If we hit EOF while looking for a name, we're done.
- if (Line.is_at_end())
+ if (Line.is_at_end()) {
+ Symtab->finalizeSymtab();
return error(instrprof_error::eof);
+ }
// Read the function name.
Record.Name = *Line++;
+ Symtab->addFuncName(Record.Name);
// Read the function hash.
if (Line.is_at_end())
@@ -213,6 +223,9 @@ std::error_code TextInstrProfReader::readNextRecord(InstrProfRecord &Record) {
if (std::error_code EC = readValueProfileData(Record))
return EC;
+ // This is needed to avoid two pass parsing because llvm-profdata
+ // does dumping while reading.
+ Symtab->finalizeSymtab();
return success();
}
@@ -266,8 +279,21 @@ RawInstrProfReader<IntPtrT>::readNextHeader(const char *CurrentPos) {
}
template <class IntPtrT>
-std::error_code RawInstrProfReader<IntPtrT>::readHeader(
- const RawInstrProf::Header &Header) {
+void RawInstrProfReader<IntPtrT>::createSymtab(InstrProfSymtab &Symtab) {
+ for (const RawInstrProf::ProfileData<IntPtrT> *I = Data; I != DataEnd; ++I) {
+ StringRef FunctionName(getName(I->NamePtr), swap(I->NameSize));
+ Symtab.addFuncName(FunctionName);
+ const IntPtrT FPtr = swap(I->FunctionPointer);
+ if (!FPtr)
+ continue;
+ Symtab.mapAddress(FPtr, IndexedInstrProf::ComputeHash(FunctionName));
+ }
+ Symtab.finalizeSymtab();
+}
+
+template <class IntPtrT>
+std::error_code
+RawInstrProfReader<IntPtrT>::readHeader(const RawInstrProf::Header &Header) {
if (swap(Header.Version) != RawInstrProf::Version)
return error(instrprof_error::unsupported_version);
@@ -297,23 +323,12 @@ std::error_code RawInstrProfReader<IntPtrT>::readHeader(
DataEnd = Data + DataSize;
CountersStart = reinterpret_cast<const uint64_t *>(Start + CountersOffset);
NamesStart = Start + NamesOffset;
- ValueDataStart = reinterpret_cast<const uint8_t*>(Start + ValueDataOffset);
+ ValueDataStart = reinterpret_cast<const uint8_t *>(Start + ValueDataOffset);
ProfileEnd = Start + ProfileSize;
- FunctionPtrToNameMap.clear();
- for (const RawInstrProf::ProfileData<IntPtrT> *I = Data; I != DataEnd; ++I) {
- const IntPtrT FPtr = swap(I->FunctionPointer);
- if (!FPtr)
- continue;
- StringRef FunctionName(getName(I->NamePtr), swap(I->NameSize));
- const char* NameEntryPtr = StringTable.insertString(FunctionName);
- FunctionPtrToNameMap.push_back(std::pair<const IntPtrT, const char*>
- (FPtr, NameEntryPtr));
- }
- std::sort(FunctionPtrToNameMap.begin(), FunctionPtrToNameMap.end(), less_first());
- FunctionPtrToNameMap.erase(std::unique(FunctionPtrToNameMap.begin(),
- FunctionPtrToNameMap.end()),
- FunctionPtrToNameMap.end());
+ std::unique_ptr<InstrProfSymtab> NewSymtab = make_unique<InstrProfSymtab>();
+ createSymtab(*NewSymtab.get());
+ Symtab = std::move(NewSymtab);
return success();
}
@@ -383,7 +398,7 @@ RawInstrProfReader<IntPtrT>::readValueProfilingData(InstrProfRecord &Record) {
if (VDataPtrOrErr.getError())
return VDataPtrOrErr.getError();
- VDataPtrOrErr.get()->deserializeTo(Record, &FunctionPtrToNameMap);
+ VDataPtrOrErr.get()->deserializeTo(Record, &Symtab->getAddrHashMap());
CurValueDataSize = VDataPtrOrErr.get()->getSize();
return success();
}
@@ -437,7 +452,7 @@ bool InstrProfLookupTrait::readValueProfilingData(
if (VDataPtrOrErr.getError())
return false;
- VDataPtrOrErr.get()->deserializeTo(DataBuffer.back(), &HashKeys);
+ VDataPtrOrErr.get()->deserializeTo(DataBuffer.back(), nullptr);
D += VDataPtrOrErr.get()->TotalSize;
return true;
@@ -525,16 +540,6 @@ InstrProfReaderIndex<HashTableImpl>::InstrProfReaderIndex(
HashTable.reset(HashTableImpl::Create(
Buckets, Payload, Base,
typename HashTableImpl::InfoType(HashType, Version)));
- // Form the map of hash values to const char* keys in profiling data.
- std::vector<std::pair<uint64_t, const char *>> HashKeys;
- for (auto Key : HashTable->keys()) {
- const char *KeyTableRef = StringTable.insertString(Key);
- HashKeys.push_back(std::make_pair(ComputeHash(HashType, Key), KeyTableRef));
- }
- std::sort(HashKeys.begin(), HashKeys.end(), less_first());
- HashKeys.erase(std::unique(HashKeys.begin(), HashKeys.end()), HashKeys.end());
- // Set the hash key map for the InstrLookupTrait
- HashTable->getInfoObj().setHashKeys(std::move(HashKeys));
RecordIterator = HashTable->data_begin();
}
@@ -590,6 +595,17 @@ std::error_code IndexedInstrProfReader::readHeader() {
return success();
}
+InstrProfSymtab &IndexedInstrProfReader::getSymtab() {
+ if (Symtab.get())
+ return *Symtab.get();
+
+ std::unique_ptr<InstrProfSymtab> NewSymtab = make_unique<InstrProfSymtab>();
+ Index->populateSymtab(*NewSymtab.get());
+
+ Symtab = std::move(NewSymtab);
+ return *Symtab.get();
+}
+
ErrorOr<InstrProfRecord>
IndexedInstrProfReader::getInstrProfRecord(StringRef FuncName,
uint64_t FuncHash) {