LLVM  8.0.1
NameAnonGlobals.cpp
Go to the documentation of this file.
1 //===- NameAnonGlobals.cpp - ThinLTO Support: Name Unnamed Globals --------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements naming anonymous globals to make sure they can be
11 // referred to by ThinLTO.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/Support/MD5.h"
21 
22 using namespace llvm;
23 
24 namespace {
25 // Compute a "unique" hash for the module based on the name of the public
26 // globals.
27 class ModuleHasher {
28  Module &TheModule;
29  std::string TheHash;
30 
31 public:
32  ModuleHasher(Module &M) : TheModule(M) {}
33 
34  /// Return the lazily computed hash.
35  std::string &get() {
36  if (!TheHash.empty())
37  // Cache hit :)
38  return TheHash;
39 
40  MD5 Hasher;
41  for (auto &F : TheModule) {
42  if (F.isDeclaration() || F.hasLocalLinkage() || !F.hasName())
43  continue;
44  auto Name = F.getName();
45  Hasher.update(Name);
46  }
47  for (auto &GV : TheModule.globals()) {
48  if (GV.isDeclaration() || GV.hasLocalLinkage() || !GV.hasName())
49  continue;
50  auto Name = GV.getName();
51  Hasher.update(Name);
52  }
53 
54  // Now return the result.
55  MD5::MD5Result Hash;
56  Hasher.final(Hash);
58  MD5::stringifyResult(Hash, Result);
59  TheHash = Result.str();
60  return TheHash;
61  }
62 };
63 } // end anonymous namespace
64 
65 // Rename all the anon globals in the module
67  bool Changed = false;
68  ModuleHasher ModuleHash(M);
69  int count = 0;
70  auto RenameIfNeed = [&](GlobalValue &GV) {
71  if (GV.hasName())
72  return;
73  GV.setName(Twine("anon.") + ModuleHash.get() + "." + Twine(count++));
74  Changed = true;
75  };
76  for (auto &GO : M.global_objects())
77  RenameIfNeed(GO);
78  for (auto &GA : M.aliases())
79  RenameIfNeed(GA);
80 
81  return Changed;
82 }
83 
84 namespace {
85 
86 // Legacy pass that provides a name to every anon globals.
87 class NameAnonGlobalLegacyPass : public ModulePass {
88 
89 public:
90  /// Pass identification, replacement for typeid
91  static char ID;
92 
93  /// Specify pass name for debug output
94  StringRef getPassName() const override { return "Name Anon Globals"; }
95 
96  explicit NameAnonGlobalLegacyPass() : ModulePass(ID) {}
97 
98  bool runOnModule(Module &M) override { return nameUnamedGlobals(M); }
99 };
101 
102 } // anonymous namespace
103 
105  ModuleAnalysisManager &AM) {
106  if (!nameUnamedGlobals(M))
107  return PreservedAnalyses::all();
108 
109  return PreservedAnalyses::none();
110 }
111 
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)
116 
117 namespace llvm {
119  return new NameAnonGlobalLegacyPass();
120 }
121 }
ModulePass * createNameAnonGlobalPass()
===------------------------------------------------------------------—===//
This class represents lattice values for constants.
Definition: AllocatorList.h:24
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
static void stringifyResult(MD5Result &Result, SmallString< 32 > &Str)
Translates the bytes in Res to a hex string that is deposited into Str.
Definition: MD5.cpp:272
F(f)
INITIALIZE_PASS_BEGIN(NameAnonGlobalLegacyPass, "name-anon-globals", "Provide a name to nameless globals", false, false) INITIALIZE_PASS_END(NameAnonGlobalLegacyPass
bool nameUnamedGlobals(Module &M)
Rename all the anon globals in the module using a hash computed from the list of public globals in th...
iterator_range< global_object_iterator > global_objects()
Definition: Module.h:659
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
Definition: MD5.cpp:189
std::array< uint32_t, 5 > ModuleHash
160 bits SHA1
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:267
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(adl_begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition: STLExtras.h:1252
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:157
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:154
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:160
name anon globals
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
Module.h This file contains the declarations for the Module class.
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:214
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:225
Definition: MD5.h:41
static const char * name
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
Definition: MD5.cpp:234
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
A container for analyses that lazily runs them and caches their results.
iterator_range< alias_iterator > aliases()
Definition: Module.h:624