diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp b/llvm/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp new file mode 100644 index 0000000000000..5b58548e54dc1 --- /dev/null +++ b/llvm/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp @@ -0,0 +1,97 @@ +//===- 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/Module.h" +#include "llvm/InitializePasses.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); + std::string ModuleNameHash = (Twine(".") + Twine(Str)).str(); + bool Changed = false; + + // Append the module hash to all internal linkage functions. + for (auto &F : M) { + if (F.hasInternalLinkage()) { + F.setName(F.getName() + ModuleNameHash); + 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 |