diff options
Diffstat (limited to 'llvm/lib/ProfileData/InstrProfReader.cpp')
| -rw-r--r-- | llvm/lib/ProfileData/InstrProfReader.cpp | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp index ee8989979a26..23804ce604c4 100644 --- a/llvm/lib/ProfileData/InstrProfReader.cpp +++ b/llvm/lib/ProfileData/InstrProfReader.cpp @@ -1026,20 +1026,50 @@ InstrProfSymtab &IndexedInstrProfReader::getSymtab() { return *Symtab; } -Expected<InstrProfRecord> -IndexedInstrProfReader::getInstrProfRecord(StringRef FuncName, - uint64_t FuncHash) { +Expected<InstrProfRecord> IndexedInstrProfReader::getInstrProfRecord( + StringRef FuncName, uint64_t FuncHash, uint64_t *MismatchedFuncSum) { ArrayRef<NamedInstrProfRecord> Data; + uint64_t FuncSum = 0; Error Err = Remapper->getRecords(FuncName, Data); if (Err) return std::move(Err); // Found it. Look for counters with the right hash. + + // A flag to indicate if the records are from the same type + // of profile (i.e cs vs nocs). + bool CSBitMatch = false; + auto getFuncSum = [](const std::vector<uint64_t> &Counts) { + uint64_t ValueSum = 0; + for (unsigned I = 0, S = Counts.size(); I < S; I++) { + uint64_t CountValue = Counts[I]; + if (CountValue == (uint64_t)-1) + continue; + // Handle overflow -- if that happens, return max. + if (std::numeric_limits<uint64_t>::max() - CountValue <= ValueSum) + return std::numeric_limits<uint64_t>::max(); + ValueSum += CountValue; + } + return ValueSum; + }; + for (const NamedInstrProfRecord &I : Data) { // Check for a match and fill the vector if there is one. if (I.Hash == FuncHash) return std::move(I); + if (NamedInstrProfRecord::hasCSFlagInHash(I.Hash) == + NamedInstrProfRecord::hasCSFlagInHash(FuncHash)) { + CSBitMatch = true; + if (MismatchedFuncSum == nullptr) + continue; + FuncSum = std::max(FuncSum, getFuncSum(I.Counts)); + } + } + if (CSBitMatch) { + if (MismatchedFuncSum != nullptr) + *MismatchedFuncSum = FuncSum; + return error(instrprof_error::hash_mismatch); } - return error(instrprof_error::hash_mismatch); + return error(instrprof_error::unknown_function); } Expected<memprof::MemProfRecord> |
