aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-profdata/llvm-profdata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-profdata/llvm-profdata.cpp')
-rw-r--r--llvm/tools/llvm-profdata/llvm-profdata.cpp103
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);
}
}