1 //===- NameAnonGlobals.cpp - ThinLTO Support: Name Unnamed Globals --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements naming anonymous globals to make sure they can be
11 // referred to by ThinLTO.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/Transforms/Utils/NameAnonGlobals.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/Support/MD5.h"
20 #include "llvm/Transforms/Utils/ModuleUtils.h"
25 // Compute a "unique" hash for the module based on the name of the public
32 ModuleHasher(Module
&M
) : TheModule(M
) {}
34 /// Return the lazily computed hash.
41 for (auto &F
: TheModule
) {
42 if (F
.isDeclaration() || F
.hasLocalLinkage() || !F
.hasName())
44 auto Name
= F
.getName();
47 for (auto &GV
: TheModule
.globals()) {
48 if (GV
.isDeclaration() || GV
.hasLocalLinkage() || !GV
.hasName())
50 auto Name
= GV
.getName();
54 // Now return the result.
57 SmallString
<32> Result
;
58 MD5::stringifyResult(Hash
, Result
);
59 TheHash
= Result
.str();
63 } // end anonymous namespace
65 // Rename all the anon globals in the module
66 bool llvm::nameUnamedGlobals(Module
&M
) {
68 ModuleHasher
ModuleHash(M
);
70 auto RenameIfNeed
= [&](GlobalValue
&GV
) {
73 GV
.setName(Twine("anon.") + ModuleHash
.get() + "." + Twine(count
++));
76 for (auto &GO
: M
.global_objects())
78 for (auto &GA
: M
.aliases())
86 // Legacy pass that provides a name to every anon globals.
87 class NameAnonGlobalLegacyPass
: public ModulePass
{
90 /// Pass identification, replacement for typeid
93 /// Specify pass name for debug output
94 StringRef
getPassName() const override
{ return "Name Anon Globals"; }
96 explicit NameAnonGlobalLegacyPass() : ModulePass(ID
) {}
98 bool runOnModule(Module
&M
) override
{ return nameUnamedGlobals(M
); }
100 char NameAnonGlobalLegacyPass::ID
= 0;
102 } // anonymous namespace
104 PreservedAnalyses
NameAnonGlobalPass::run(Module
&M
,
105 ModuleAnalysisManager
&AM
) {
106 if (!nameUnamedGlobals(M
))
107 return PreservedAnalyses::all();
109 return PreservedAnalyses::none();
112 INITIALIZE_PASS_BEGIN(NameAnonGlobalLegacyPass
, "name-anon-globals",
113 "Provide a name to nameless globals", false, false)
114 INITIALIZE_PASS_END(NameAnonGlobalLegacyPass
, "name-anon-globals",
115 "Provide a name to nameless globals", false, false)
118 ModulePass
*createNameAnonGlobalPass() {
119 return new NameAnonGlobalLegacyPass();