Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 3744401

Browse files
committed
[PGO] PGOFuncName in LTO optimizations
PGOFuncNames are used as the key to retrieve the Function definition from the MD5 stored in the profile. For internal linkage function, we prefix the source file name to the PGOFuncNames. LTO's internalization privatizes many global linkage symbols. This happens after value profile annotation, but those internal linkage functions should not have a source prefix. To differentiate compiler generated internal symbols from original ones, PGOFuncName meta data are created and attached to the original internal symbols in the value profile annotation step. If a symbol does not have the meta data, its original linkage must be non-internal. Also add a new map that maps PGOFuncName's MD5 value to the function definition. Differential Revision: http://reviews.llvm.org/D17895 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@264902 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 564787f commit 3744401

File tree

3 files changed

+69
-11
lines changed

3 files changed

+69
-11
lines changed

include/llvm/ProfileData/InstrProf.h

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,9 @@ inline StringRef getInstrProfFileOverriderFuncName() {
155155
inline StringRef getInstrProfNameSeparator() { return "\01"; }
156156

157157
/// Return the modified name for function \c F suitable to be
158-
/// used the key for profile lookup.
159-
std::string getPGOFuncName(const Function &F,
158+
/// used the key for profile lookup. Variable \c InLTO indicates if this
159+
/// is called in LTO optimization passes.
160+
std::string getPGOFuncName(const Function &F, bool InLTO = false,
160161
uint64_t Version = INSTR_PROF_INDEX_VERSION);
161162

162163
/// Return the modified name for a function suitable to be
@@ -302,13 +303,17 @@ class InstrProfSymtab {
302303
StringSet<> NameTab;
303304
// A map from MD5 keys to function name strings.
304305
std::vector<std::pair<uint64_t, StringRef>> MD5NameMap;
306+
// A map from MD5 keys to function define. We only populate this map
307+
// when build the Symtab from a Module.
308+
std::vector<std::pair<uint64_t, Function *>> MD5FuncMap;
305309
// A map from function runtime address to function name MD5 hash.
306310
// This map is only populated and used by raw instr profile reader.
307311
AddrHashMap AddrToMD5Map;
308312

309313
public:
310314
InstrProfSymtab()
311-
: Data(), Address(0), NameTab(), MD5NameMap(), AddrToMD5Map() {}
315+
: Data(), Address(0), NameTab(), MD5NameMap(), MD5FuncMap(),
316+
AddrToMD5Map() {}
312317

313318
/// Create InstrProfSymtab from an object file section which
314319
/// contains function PGO names. When section may contain raw
@@ -326,8 +331,9 @@ class InstrProfSymtab {
326331
inline std::error_code create(StringRef NameStrings);
327332
/// A wrapper interface to populate the PGO symtab with functions
328333
/// decls from module \c M. This interface is used by transformation
329-
/// passes such as indirect function call promotion.
330-
void create(const Module &M);
334+
/// passes such as indirect function call promotion. Variable \c InLTO
335+
/// indicates if this is called from LTO optimization passes.
336+
void create(Module &M, bool InLTO = false);
331337
/// Create InstrProfSymtab from a set of names iteratable from
332338
/// \p IterRange. This interface is used by IndexedProfReader.
333339
template <typename NameIterRange> void create(const NameIterRange &IterRange);
@@ -357,6 +363,8 @@ class InstrProfSymtab {
357363
/// Return function's PGO name from the name's md5 hash value.
358364
/// If not found, return an empty string.
359365
inline StringRef getFuncName(uint64_t FuncMD5Hash);
366+
/// Return function from the name's md5 hash. Return nullptr if not found.
367+
inline Function *getFunction(uint64_t FuncMD5Hash);
360368
/// Return the function's original assembly name by stripping off
361369
/// the prefix attached (to symbols with priviate linkage). For
362370
/// global functions, it returns the same string as getFuncName.
@@ -387,6 +395,7 @@ void InstrProfSymtab::create(const NameIterRange &IterRange) {
387395

388396
void InstrProfSymtab::finalizeSymtab() {
389397
std::sort(MD5NameMap.begin(), MD5NameMap.end(), less_first());
398+
std::sort(MD5FuncMap.begin(), MD5FuncMap.end(), less_first());
390399
std::sort(AddrToMD5Map.begin(), AddrToMD5Map.end(), less_first());
391400
AddrToMD5Map.erase(std::unique(AddrToMD5Map.begin(), AddrToMD5Map.end()),
392401
AddrToMD5Map.end());
@@ -402,6 +411,16 @@ StringRef InstrProfSymtab::getFuncName(uint64_t FuncMD5Hash) {
402411
return StringRef();
403412
}
404413

414+
Function* InstrProfSymtab::getFunction(uint64_t FuncMD5Hash) {
415+
auto Result =
416+
std::lower_bound(MD5FuncMap.begin(), MD5FuncMap.end(), FuncMD5Hash,
417+
[](const std::pair<uint64_t, Function*> &LHS,
418+
uint64_t RHS) { return LHS.first < RHS; });
419+
if (Result != MD5FuncMap.end() && Result->first == FuncMD5Hash)
420+
return Result->second;
421+
return nullptr;
422+
}
423+
405424
// See also getPGOFuncName implementation. These two need to be
406425
// matched.
407426
StringRef InstrProfSymtab::getOrigFuncName(uint64_t FuncMD5Hash) {

lib/ProfileData/InstrProf.cpp

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,32 @@ std::string getPGOFuncName(StringRef RawFuncName,
8383
return GlobalValue::getGlobalIdentifier(RawFuncName, Linkage, FileName);
8484
}
8585

86-
std::string getPGOFuncName(const Function &F, uint64_t Version) {
87-
return getPGOFuncName(F.getName(), F.getLinkage(), F.getParent()->getName(),
88-
Version);
86+
// Return the PGOFuncName. This function has some special handling when called
87+
// in LTO optimization. The following only applies when calling in LTO passes
88+
// (when \c InLTO is true): LTO's internalization privatizes many global linkage
89+
// symbols. This happens after value profile annotation, but those internal
90+
// linkage functions should not have a source prefix.
91+
// To differentiate compiler generated internal symbols from original ones,
92+
// PGOFuncName meta data are created and attached to the original internal
93+
// symbols in the value profile annotation step
94+
// (PGOUseFunc::annotateIndirectCallSites). If a symbol does not have the meta
95+
// data, its original linkage must be non-internal.
96+
std::string getPGOFuncName(const Function &F, bool InLTO, uint64_t Version) {
97+
if (!InLTO)
98+
return getPGOFuncName(F.getName(), F.getLinkage(), F.getParent()->getName(),
99+
Version);
100+
101+
// InLTO mode. First check if these is a meta data.
102+
MDNode *MD = F.getMetadata("PGOFuncName");
103+
if (MD != nullptr) {
104+
StringRef S = cast<MDString>(MD->getOperand(0))->getString();
105+
return S.str();
106+
}
107+
108+
// If there is no meta data, the function must be a global before the value
109+
// profile annotation pass. Its current linkage may be internal if it is
110+
// internalized in LTO mode.
111+
return getPGOFuncName (F.getName(), GlobalValue::ExternalLinkage, "");
89112
}
90113

91114
StringRef getFuncNameWithoutPrefix(StringRef PGOFuncName, StringRef FileName) {
@@ -149,9 +172,16 @@ GlobalVariable *createPGOFuncNameVar(Function &F, StringRef PGOFuncName) {
149172
return createPGOFuncNameVar(*F.getParent(), F.getLinkage(), PGOFuncName);
150173
}
151174

152-
void InstrProfSymtab::create(const Module &M) {
153-
for (const Function &F : M)
154-
addFuncName(getPGOFuncName(F));
175+
void InstrProfSymtab::create(Module &M, bool InLTO) {
176+
for (Function &F : M) {
177+
// Function may not have a name: like using asm("") to overwrite the name.
178+
// Ignore in this case.
179+
if (!F.hasName())
180+
continue;
181+
const std::string &PGOFuncName = getPGOFuncName(F, InLTO);
182+
addFuncName(PGOFuncName);
183+
MD5FuncMap.push_back(std::make_pair(Function::getGUID(PGOFuncName), &F));
184+
}
155185

156186
finalizeSymtab();
157187
}

lib/Transforms/Instrumentation/PGOInstrumentation.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,15 @@ void PGOUseFunc::annotateIndirectCallSites() {
750750
if (DisableValueProfiling)
751751
return;
752752

753+
// Write out the PGOFuncName if this is different from it's raw name.
754+
// This should only apply to internal linkage functions only.
755+
const std::string &FuncName = getPGOFuncName(F);
756+
if (FuncName != F.getName()) {
757+
LLVMContext &C = F.getContext();
758+
MDNode *N = MDNode::get(C, MDString::get(C, FuncName.c_str()));
759+
F.setMetadata("PGOFuncName", N);
760+
}
761+
753762
unsigned IndirectCallSiteIndex = 0;
754763
PGOIndirectCallSiteVisitor ICV;
755764
ICV.visit(F);

0 commit comments

Comments
 (0)