LLVM  9.0.0svn
NameAnonGlobals.cpp
Go to the documentation of this file.
1 //===- NameAnonGlobals.cpp - ThinLTO Support: Name Unnamed Globals --------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements naming anonymous globals to make sure they can be
10 // referred to by ThinLTO.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/Support/MD5.h"
20 
21 using namespace llvm;
22 
23 namespace {
24 // Compute a "unique" hash for the module based on the name of the public
25 // globals.
26 class ModuleHasher {
27  Module &TheModule;
28  std::string TheHash;
29 
30 public:
31  ModuleHasher(Module &M) : TheModule(M) {}
32 
33  /// Return the lazily computed hash.
34  std::string &get() {
35  if (!TheHash.empty())
36  // Cache hit :)
37  return TheHash;
38 
39  MD5 Hasher;
40  for (auto &F : TheModule) {
41  if (F.isDeclaration() || F.hasLocalLinkage() || !F.hasName())
42  continue;
43  auto Name = F.getName();
44  Hasher.update(Name);
45  }
46  for (auto &GV : TheModule.globals()) {
47  if (GV.isDeclaration() || GV.hasLocalLinkage() || !GV.hasName())
48  continue;
49  auto Name = GV.getName();
50  Hasher.update(Name);
51  }
52 
53  // Now return the result.
54  MD5::MD5Result Hash;
55  Hasher.final(Hash);
57  MD5::stringifyResult(Hash, Result);
58  TheHash = Result.str();
59  return TheHash;
60  }
61 };
62 } // end anonymous namespace
63 
64 // Rename all the anon globals in the module
66  bool Changed = false;
67  ModuleHasher ModuleHash(M);
68  int count = 0;
69  auto RenameIfNeed = [&](GlobalValue &GV) {
70  if (GV.hasName())
71  return;
72  GV.setName(Twine("anon.") + ModuleHash.get() + "." + Twine(count++));
73  Changed = true;
74  };
75  for (auto &GO : M.global_objects())
76  RenameIfNeed(GO);
77  for (auto &GA : M.aliases())
78  RenameIfNeed(GA);
79 
80  return Changed;
81 }
82 
83 namespace {
84 
85 // Legacy pass that provides a name to every anon globals.
86 class NameAnonGlobalLegacyPass : public ModulePass {
87 
88 public:
89  /// Pass identification, replacement for typeid
90  static char ID;
91 
92  /// Specify pass name for debug output
93  StringRef getPassName() const override { return "Name Anon Globals"; }
94 
95  explicit NameAnonGlobalLegacyPass() : ModulePass(ID) {}
96 
97  bool runOnModule(Module &M) override { return nameUnamedGlobals(M); }
98 };
100 
101 } // anonymous namespace
102 
104  ModuleAnalysisManager &AM) {
105  if (!nameUnamedGlobals(M))
106  return PreservedAnalyses::all();
107 
108  return PreservedAnalyses::none();
109 }
110 
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)
115 
116 namespace llvm {
118  return new NameAnonGlobalLegacyPass();
119 }
120 }
ModulePass * createNameAnonGlobalPass()
===------------------------------------------------------------------—===//
This class represents lattice values for constants.
Definition: AllocatorList.h:23
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
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
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:662
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
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:266
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:1251
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:156
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:153
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:159
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.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:224
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:48
A container for analyses that lazily runs them and caches their results.
iterator_range< alias_iterator > aliases()
Definition: Module.h:627