diff options
Diffstat (limited to 'llvm/tools/llvm-profdata/llvm-profdata.cpp')
-rw-r--r-- | llvm/tools/llvm-profdata/llvm-profdata.cpp | 103 |
1 files changed, 94 insertions, 9 deletions
diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp index de34f39..df7b43a2 100644 --- a/llvm/tools/llvm-profdata/llvm-profdata.cpp +++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp @@ -31,6 +31,7 @@ #include "llvm/Support/Format.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/InitLLVM.h" +#include "llvm/Support/MD5.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/ThreadPool.h" @@ -42,6 +43,10 @@ using namespace llvm; +// We use this string to indicate that there are +// multiple static functions map to the same name. +const std::string DuplicateNameStr = "----"; + enum ProfileFormat { PF_None = 0, PF_Text, @@ -480,7 +485,7 @@ InstrProfileEntry::InstrProfileEntry(InstrProfRecord *Record) { NumEdgeCounters = CntNum; } -/// Either set all the counters in the instr profile entry \p IFE to -1 +// Either set all the counters in the instr profile entry \p IFE to -1 /// in order to drop the profile or scale up the counters in \p IFP to /// be above hot threshold. We use the ratio of zero counters in the /// profile of a function to decide the profile is helpful or harmful @@ -541,7 +546,73 @@ adjustInstrProfile(std::unique_ptr<WriterContext> &WC, unsigned InstrProfColdThreshold) { // Function to its entry in instr profile. StringMap<InstrProfileEntry> InstrProfileMap; + StringMap<StringRef> StaticFuncMap; InstrProfSummaryBuilder IPBuilder(ProfileSummaryBuilder::DefaultCutoffs); + + auto checkSampleProfileHasFUnique = [&Reader]() { + for (const auto &PD : Reader->getProfiles()) { + auto &FContext = PD.first; + if (FContext.toString().find(FunctionSamples::UniqSuffix) != + std::string::npos) { + return true; + } + } + return false; + }; + + bool SampleProfileHasFUnique = checkSampleProfileHasFUnique(); + + auto buildStaticFuncMap = [&StaticFuncMap, + SampleProfileHasFUnique](const StringRef Name) { + std::string Prefixes[] = {".cpp:", "cc:", ".c:", ".hpp:", ".h:"}; + size_t PrefixPos = StringRef::npos; + for (auto &Prefix : Prefixes) { + PrefixPos = Name.find_insensitive(Prefix); + if (PrefixPos == StringRef::npos) + continue; + PrefixPos += Prefix.size(); + break; + } + + if (PrefixPos == StringRef::npos) { + return; + } + + StringRef NewName = Name.drop_front(PrefixPos); + StringRef FName = Name.substr(0, PrefixPos - 1); + if (NewName.size() == 0) { + return; + } + + // This name should have a static linkage. + size_t PostfixPos = NewName.find(FunctionSamples::UniqSuffix); + bool ProfileHasFUnique = (PostfixPos != StringRef::npos); + + // If sample profile and instrumented profile do not agree on symbol + // uniqification. + if (SampleProfileHasFUnique != ProfileHasFUnique) { + // If instrumented profile uses -funique-internal-linakge-symbols, + // we need to trim the name. + if (ProfileHasFUnique) { + NewName = NewName.substr(0, PostfixPos); + } else { + // If sample profile uses -funique-internal-linakge-symbols, + // we build the map. + std::string NStr = + NewName.str() + getUniqueInternalLinkagePostfix(FName); + NewName = StringRef(NStr); + StaticFuncMap[NewName] = Name; + return; + } + } + + if (StaticFuncMap.find(NewName) == StaticFuncMap.end()) { + StaticFuncMap[NewName] = Name; + } else { + StaticFuncMap[NewName] = DuplicateNameStr; + } + }; + for (auto &PD : WC->Writer.getProfileData()) { // Populate IPBuilder. for (const auto &PDV : PD.getValue()) { @@ -555,7 +626,9 @@ adjustInstrProfile(std::unique_ptr<WriterContext> &WC, // Initialize InstrProfileMap. InstrProfRecord *R = &PD.getValue().begin()->second; - InstrProfileMap[PD.getKey()] = InstrProfileEntry(R); + StringRef FullName = PD.getKey(); + InstrProfileMap[FullName] = InstrProfileEntry(R); + buildStaticFuncMap(FullName); } ProfileSummary InstrPS = *IPBuilder.getSummary(); @@ -583,16 +656,28 @@ adjustInstrProfile(std::unique_ptr<WriterContext> &WC, // Find hot/warm functions in sample profile which is cold in instr profile // and adjust the profiles of those functions in the instr profile. for (const auto &PD : Reader->getProfiles()) { - auto &FContext = PD.first; const sampleprof::FunctionSamples &FS = PD.second; + if (FS.getMaxCountInside() <= ColdSampleThreshold) + continue; + auto &FContext = PD.first; auto It = InstrProfileMap.find(FContext.toString()); - if (FS.getMaxCountInside() > ColdSampleThreshold && - It != InstrProfileMap.end() && - It->second.MaxCount <= ColdInstrThreshold && - It->second.NumEdgeCounters >= SupplMinSizeThreshold) { - updateInstrProfileEntry(It->second, HotInstrThreshold, - ZeroCounterThreshold); + if (It == InstrProfileMap.end()) { + auto NewName = StaticFuncMap.find(FContext.toString()); + if (NewName != StaticFuncMap.end()) { + It = InstrProfileMap.find(NewName->second.str()); + if (NewName->second == DuplicateNameStr) { + WithColor::warning() + << "Static function " << FContext.toString() + << " has multiple promoted names, cannot adjust profile.\n"; + } + } } + if (It == InstrProfileMap.end() || + It->second.MaxCount > ColdInstrThreshold || + It->second.NumEdgeCounters < SupplMinSizeThreshold) + continue; + updateInstrProfileEntry(It->second, HotInstrThreshold, + ZeroCounterThreshold); } } |