Index: include/llvm/IR/Function.h =================================================================== --- include/llvm/IR/Function.h +++ include/llvm/IR/Function.h @@ -639,6 +639,14 @@ /// to \a DISubprogram. DISubprogram *getSubprogram() const; + /// Return the modified name for a function suitable to be + /// used as the key for a global lookup (e.g. profile or ThinLTO). + /// The function's original name is \c FuncName and has linkage of type + /// \c Linkage. The function is defined in module \c FileName. + static std::string getGlobalIdentifier(StringRef FuncName, + GlobalValue::LinkageTypes Linkage, + StringRef FileName); + private: void allocHungoffUselist(); template void setHungoffOperand(Constant *C); Index: include/llvm/ProfileData/InstrProf.h =================================================================== --- include/llvm/ProfileData/InstrProf.h +++ include/llvm/ProfileData/InstrProf.h @@ -615,21 +615,10 @@ Last = MD5 }; -static inline uint64_t MD5Hash(StringRef Str) { - MD5 Hash; - Hash.update(Str); - llvm::MD5::MD5Result Result; - Hash.final(Result); - // Return the least significant 8 bytes. Our MD5 implementation returns the - // result in little endian, so we may need to swap bytes. - using namespace llvm::support; - return endian::read(Result); -} - inline uint64_t ComputeHash(HashT Type, StringRef K) { switch (Type) { case HashT::MD5: - return IndexedInstrProf::MD5Hash(K); + return MD5Hash(K); } llvm_unreachable("Unhandled hash type"); } Index: include/llvm/Support/MD5.h =================================================================== --- include/llvm/Support/MD5.h +++ include/llvm/Support/MD5.h @@ -31,6 +31,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/Endian.h" namespace llvm { @@ -65,6 +66,18 @@ const uint8_t *body(ArrayRef Data); }; +/// Helper to compute and return a 64-bit MD5 Hash of a given string. +static inline uint64_t MD5Hash(StringRef Str) { + MD5 Hash; + Hash.update(Str); + llvm::MD5::MD5Result Result; + Hash.final(Result); + // Return the least significant 8 bytes. Our MD5 implementation returns the + // result in little endian, so we may need to swap bytes. + using namespace llvm::support; + return endian::read(Result); +} + } #endif Index: lib/IR/Function.cpp =================================================================== --- lib/IR/Function.cpp +++ lib/IR/Function.cpp @@ -997,3 +997,27 @@ } return None; } + +std::string Function::getGlobalIdentifier(StringRef FuncName, + GlobalValue::LinkageTypes Linkage, + StringRef FileName) { + + // Function names may be prefixed with a binary '1' to indicate + // that the backend should not modify the symbols due to any platform + // naming convention. Do not include that '1' in the PGO profile name. + if (FuncName[0] == '\1') + FuncName = FuncName.substr(1); + + std::string NewFuncName = FuncName; + if (llvm::GlobalValue::isLocalLinkage(Linkage)) { + // For local symbols, prepend the main file name to distinguish them. + // Do not include the full path in the file name since there's no guarantee + // that it will stay the same, e.g., if the files are checked out from + // version control in different locations. + if (FileName.empty()) + NewFuncName = NewFuncName.insert(0, ":"); + else + NewFuncName = NewFuncName.insert(0, FileName.str() + ":"); + } + return NewFuncName; +} Index: lib/ProfileData/InstrProf.cpp =================================================================== --- lib/ProfileData/InstrProf.cpp +++ lib/ProfileData/InstrProf.cpp @@ -80,25 +80,7 @@ GlobalValue::LinkageTypes Linkage, StringRef FileName, uint64_t Version LLVM_ATTRIBUTE_UNUSED) { - - // Function names may be prefixed with a binary '1' to indicate - // that the backend should not modify the symbols due to any platform - // naming convention. Do not include that '1' in the PGO profile name. - if (RawFuncName[0] == '\1') - RawFuncName = RawFuncName.substr(1); - - std::string FuncName = RawFuncName; - if (llvm::GlobalValue::isLocalLinkage(Linkage)) { - // For local symbols, prepend the main file name to distinguish them. - // Do not include the full path in the file name since there's no guarantee - // that it will stay the same, e.g., if the files are checked out from - // version control in different locations. - if (FileName.empty()) - FuncName = FuncName.insert(0, ":"); - else - FuncName = FuncName.insert(0, FileName.str() + ":"); - } - return FuncName; + return Function::getGlobalIdentifier(RawFuncName, Linkage, FileName); } std::string getPGOFuncName(const Function &F, uint64_t Version) {