summaryrefslogtreecommitdiff
path: root/llvm/lib/ProfileData/InstrProfReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ProfileData/InstrProfReader.cpp')
-rw-r--r--llvm/lib/ProfileData/InstrProfReader.cpp38
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>