diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp new file mode 100644 index 000000000000..c57cec6be676 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp @@ -0,0 +1,118 @@ +//===- UniqueInternalLinkageNames.cpp - Unique Internal Linkage Sym Names -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements unique naming of internal linkage symbols with option +// -funique-internal-linkage-symbols. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Utils/UniqueInternalLinkageNames.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/MDBuilder.h" +#include "llvm/IR/Module.h" +#include "llvm/InitializePasses.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/MD5.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" + +using namespace llvm; + +static bool uniqueifyInternalLinkageNames(Module &M) { + llvm::MD5 Md5; + Md5.update(M.getSourceFileName()); + llvm::MD5::MD5Result R; + Md5.final(R); + SmallString<32> Str; + llvm::MD5::stringifyResult(R, Str); + // Convert MD5hash to Decimal. Demangler suffixes can either contain numbers + // or characters but not both. + APInt IntHash = APInt(128, Str.str(), 16); + // Prepend "__uniq" before the hash for tools like profilers to understand that + // this symbol is of internal linkage type. + std::string ModuleNameHash = (Twine(".__uniq.") + Twine(IntHash.toString(10, false))).str(); + bool Changed = false; + MDBuilder MDB(M.getContext()); + + // Append the module hash to all internal linkage functions. + for (auto &F : M) { + if (F.hasInternalLinkage()) { + F.setName(F.getName() + ModuleNameHash); + F.addFnAttr("sample-profile-suffix-elision-policy", "selected"); + // Replace linkage names in the debug metadata. + if (DISubprogram *SP = F.getSubprogram()) { + if (SP->getRawLinkageName()) { + auto *Name = MDB.createString(F.getName()); + SP->replaceRawLinkageName(Name); + if (DISubprogram *SPDecl = SP->getDeclaration()) { + if (SPDecl->getRawLinkageName()) + SPDecl->replaceRawLinkageName(Name); + } + } + } + Changed = true; + } + } + + // Append the module hash to all internal linkage globals. + for (auto &GV : M.globals()) { + if (GV.hasInternalLinkage()) { + GV.setName(GV.getName() + ModuleNameHash); + Changed = true; + } + } + return Changed; +} + +namespace { + +// Legacy pass that provides a name to every anon globals. +class UniqueInternalLinkageNamesLegacyPass : public ModulePass { + +public: + /// Pass identification, replacement for typeid + static char ID; + + /// Specify pass name for debug output + StringRef getPassName() const override { + return "Unique Internal Linkage Names"; + } + + explicit UniqueInternalLinkageNamesLegacyPass() : ModulePass(ID) { + initializeUniqueInternalLinkageNamesLegacyPassPass( + *PassRegistry::getPassRegistry()); + } + + bool runOnModule(Module &M) override { + return uniqueifyInternalLinkageNames(M); + } +}; + +char UniqueInternalLinkageNamesLegacyPass::ID = 0; +} // anonymous namespace + +PreservedAnalyses +UniqueInternalLinkageNamesPass::run(Module &M, ModuleAnalysisManager &AM) { + if (!uniqueifyInternalLinkageNames(M)) + return PreservedAnalyses::all(); + + return PreservedAnalyses::none(); +} + +INITIALIZE_PASS_BEGIN(UniqueInternalLinkageNamesLegacyPass, + "unique-internal-linkage-names", + "Uniqueify internal linkage names", false, false) +INITIALIZE_PASS_END(UniqueInternalLinkageNamesLegacyPass, + "unique-internal-linkage-names", + "Uniqueify Internal linkage names", false, false) + +namespace llvm { +ModulePass *createUniqueInternalLinkageNamesPass() { + return new UniqueInternalLinkageNamesLegacyPass(); +} +} // namespace llvm |