diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/ProfileData/InstrProf.cpp | 42 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp | 9 | 
2 files changed, 45 insertions, 6 deletions
| diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp index 8514b44777e..fa15170ef6c 100644 --- a/llvm/lib/ProfileData/InstrProf.cpp +++ b/llvm/lib/ProfileData/InstrProf.cpp @@ -83,9 +83,32 @@ std::string getPGOFuncName(StringRef RawFuncName,    return GlobalValue::getGlobalIdentifier(RawFuncName, Linkage, FileName);  } -std::string getPGOFuncName(const Function &F, uint64_t Version) { -  return getPGOFuncName(F.getName(), F.getLinkage(), F.getParent()->getName(), -                        Version); +// Return the PGOFuncName. This function has some special handling when called +// in LTO optimization. The following only applies when calling in LTO passes +// (when \c InLTO is true): 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 +// (PGOUseFunc::annotateIndirectCallSites). If a symbol does not have the meta +// data, its original linkage must be non-internal. +std::string getPGOFuncName(const Function &F, bool InLTO, uint64_t Version) { +  if (!InLTO) +    return getPGOFuncName(F.getName(), F.getLinkage(), F.getParent()->getName(), +                          Version); + +  // InLTO mode. First check if these is a meta data. +  MDNode *MD = F.getMetadata("PGOFuncName"); +  if (MD != nullptr) { +    StringRef S = cast<MDString>(MD->getOperand(0))->getString(); +    return S.str(); +  } + +  // If there is no meta data, the function must be a global before the value +  // profile annotation pass. Its current linkage may be internal if it is +  // internalized in LTO mode. +  return getPGOFuncName (F.getName(), GlobalValue::ExternalLinkage, "");  }  StringRef getFuncNameWithoutPrefix(StringRef PGOFuncName, StringRef FileName) { @@ -149,9 +172,16 @@ GlobalVariable *createPGOFuncNameVar(Function &F, StringRef PGOFuncName) {    return createPGOFuncNameVar(*F.getParent(), F.getLinkage(), PGOFuncName);  } -void InstrProfSymtab::create(const Module &M) { -  for (const Function &F : M) -    addFuncName(getPGOFuncName(F)); +void InstrProfSymtab::create(Module &M, bool InLTO) { +  for (Function &F : M) { +    // Function may not have a name: like using asm("") to overwrite the name. +    // Ignore in this case. +    if (!F.hasName()) +      continue; +    const std::string &PGOFuncName = getPGOFuncName(F, InLTO); +    addFuncName(PGOFuncName); +    MD5FuncMap.push_back(std::make_pair(Function::getGUID(PGOFuncName), &F)); +  }    finalizeSymtab();  } diff --git a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp index 23947137c67..c8f6bb2b709 100644 --- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp @@ -750,6 +750,15 @@ void PGOUseFunc::annotateIndirectCallSites() {    if (DisableValueProfiling)      return; +  // Write out the PGOFuncName if this is different from it's raw name. +  // This should only apply to internal linkage functions only. +  const std::string &FuncName = getPGOFuncName(F); +  if (FuncName != F.getName()) { +    LLVMContext &C = F.getContext(); +    MDNode *N = MDNode::get(C, MDString::get(C, FuncName.c_str())); +    F.setMetadata("PGOFuncName", N); +  } +    unsigned IndirectCallSiteIndex = 0;    PGOIndirectCallSiteVisitor ICV;    ICV.visit(F); | 

