1 //===- NameAnonGlobals.cpp - ThinLTO Support: Name Unnamed Globals --------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements naming anonymous globals to make sure they can be
10 // referred to by ThinLTO.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Transforms/Utils/NameAnonGlobals.h"
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/Support/MD5.h"
19 #include "llvm/Transforms/Utils/ModuleUtils.h"
24 // Compute a "unique" hash for the module based on the name of the public
31 ModuleHasher(Module
&M
) : TheModule(M
) {}
33 /// Return the lazily computed hash.
40 for (auto &F
: TheModule
) {
41 if (F
.isDeclaration() || F
.hasLocalLinkage() || !F
.hasName())
43 auto Name
= F
.getName();
46 for (auto &GV
: TheModule
.globals()) {
47 if (GV
.isDeclaration() || GV
.hasLocalLinkage() || !GV
.hasName())
49 auto Name
= GV
.getName();
53 // Now return the result.
56 SmallString
<32> Result
;
57 MD5::stringifyResult(Hash
, Result
);
58 TheHash
= Result
.str();
62 } // end anonymous namespace
64 // Rename all the anon globals in the module
65 bool llvm::nameUnamedGlobals(Module
&M
) {
67 ModuleHasher
ModuleHash(M
);
69 auto RenameIfNeed
= [&](GlobalValue
&GV
) {
72 GV
.setName(Twine("anon.") + ModuleHash
.get() + "." + Twine(count
++));
75 for (auto &GO
: M
.global_objects())
77 for (auto &GA
: M
.aliases())
85 // Legacy pass that provides a name to every anon globals.
86 class NameAnonGlobalLegacyPass
: public ModulePass
{
89 /// Pass identification, replacement for typeid
92 /// Specify pass name for debug output
93 StringRef
getPassName() const override
{ return "Name Anon Globals"; }
95 explicit NameAnonGlobalLegacyPass() : ModulePass(ID
) {}
97 bool runOnModule(Module
&M
) override
{ return nameUnamedGlobals(M
); }
99 char NameAnonGlobalLegacyPass::ID
= 0;
101 } // anonymous namespace
103 PreservedAnalyses
NameAnonGlobalPass::run(Module
&M
,
104 ModuleAnalysisManager
&AM
) {
105 if (!nameUnamedGlobals(M
))
106 return PreservedAnalyses::all();
108 return PreservedAnalyses::none();
111 INITIALIZE_PASS_BEGIN(NameAnonGlobalLegacyPass
, "name-anon-globals",
112 "Provide a name to nameless globals", false, false)
113 INITIALIZE_PASS_END(NameAnonGlobalLegacyPass
, "name-anon-globals",
114 "Provide a name to nameless globals", false, false)
117 ModulePass
*createNameAnonGlobalPass() {
118 return new NameAnonGlobalLegacyPass();