[](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) {
if (Line.is_at_end())
return success();
+
uint32_t NumValueKinds;
if (Line->getAsInteger(10, NumValueKinds)) {
// No value profile data
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++;
}
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())
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();
}
}
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);
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();
}
if (VDataPtrOrErr.getError())
return VDataPtrOrErr.getError();
- VDataPtrOrErr.get()->deserializeTo(Record, &FunctionPtrToNameMap);
+ VDataPtrOrErr.get()->deserializeTo(Record, &Symtab->getAddrHashMap());
CurValueDataSize = VDataPtrOrErr.get()->getSize();
return success();
}
if (VDataPtrOrErr.getError())
return false;
- VDataPtrOrErr.get()->deserializeTo(DataBuffer.back(), &HashKeys);
+ VDataPtrOrErr.get()->deserializeTo(DataBuffer.back(), nullptr);
D += VDataPtrOrErr.get()->TotalSize;
return true;
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();
}
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) {