xref: /aosp_15_r20/external/llvm/lib/Transforms/Utils/NameAnonFunctions.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- NameAnonFunctions.cpp - ThinLTO Summary-based Function Import ------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements naming anonymous function to make sure they can be
11*9880d681SAndroid Build Coastguard Worker // refered to by ThinLTO.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallString.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MD5.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/ModuleUtils.h"
19*9880d681SAndroid Build Coastguard Worker 
20*9880d681SAndroid Build Coastguard Worker using namespace llvm;
21*9880d681SAndroid Build Coastguard Worker 
22*9880d681SAndroid Build Coastguard Worker // Compute a "unique" hash for the module based on the name of the public
23*9880d681SAndroid Build Coastguard Worker // functions.
24*9880d681SAndroid Build Coastguard Worker class ModuleHasher {
25*9880d681SAndroid Build Coastguard Worker   Module &TheModule;
26*9880d681SAndroid Build Coastguard Worker   std::string TheHash;
27*9880d681SAndroid Build Coastguard Worker 
28*9880d681SAndroid Build Coastguard Worker public:
ModuleHasher(Module & M)29*9880d681SAndroid Build Coastguard Worker   ModuleHasher(Module &M) : TheModule(M) {}
30*9880d681SAndroid Build Coastguard Worker 
31*9880d681SAndroid Build Coastguard Worker   /// Return the lazily computed hash.
get()32*9880d681SAndroid Build Coastguard Worker   std::string &get() {
33*9880d681SAndroid Build Coastguard Worker     if (!TheHash.empty())
34*9880d681SAndroid Build Coastguard Worker       // Cache hit :)
35*9880d681SAndroid Build Coastguard Worker       return TheHash;
36*9880d681SAndroid Build Coastguard Worker 
37*9880d681SAndroid Build Coastguard Worker     MD5 Hasher;
38*9880d681SAndroid Build Coastguard Worker     for (auto &F : TheModule) {
39*9880d681SAndroid Build Coastguard Worker       if (F.isDeclaration() || F.hasLocalLinkage() || !F.hasName())
40*9880d681SAndroid Build Coastguard Worker         continue;
41*9880d681SAndroid Build Coastguard Worker       auto Name = F.getName();
42*9880d681SAndroid Build Coastguard Worker       Hasher.update(Name);
43*9880d681SAndroid Build Coastguard Worker     }
44*9880d681SAndroid Build Coastguard Worker     for (auto &GV : TheModule.globals()) {
45*9880d681SAndroid Build Coastguard Worker       if (GV.isDeclaration() || GV.hasLocalLinkage() || !GV.hasName())
46*9880d681SAndroid Build Coastguard Worker         continue;
47*9880d681SAndroid Build Coastguard Worker       auto Name = GV.getName();
48*9880d681SAndroid Build Coastguard Worker       Hasher.update(Name);
49*9880d681SAndroid Build Coastguard Worker     }
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker     // Now return the result.
52*9880d681SAndroid Build Coastguard Worker     MD5::MD5Result Hash;
53*9880d681SAndroid Build Coastguard Worker     Hasher.final(Hash);
54*9880d681SAndroid Build Coastguard Worker     SmallString<32> Result;
55*9880d681SAndroid Build Coastguard Worker     MD5::stringifyResult(Hash, Result);
56*9880d681SAndroid Build Coastguard Worker     TheHash = Result.str();
57*9880d681SAndroid Build Coastguard Worker     return TheHash;
58*9880d681SAndroid Build Coastguard Worker   }
59*9880d681SAndroid Build Coastguard Worker };
60*9880d681SAndroid Build Coastguard Worker 
61*9880d681SAndroid Build Coastguard Worker // Rename all the anon functions in the module
nameUnamedFunctions(Module & M)62*9880d681SAndroid Build Coastguard Worker bool llvm::nameUnamedFunctions(Module &M) {
63*9880d681SAndroid Build Coastguard Worker   bool Changed = false;
64*9880d681SAndroid Build Coastguard Worker   ModuleHasher ModuleHash(M);
65*9880d681SAndroid Build Coastguard Worker   int count = 0;
66*9880d681SAndroid Build Coastguard Worker   for (auto &F : M) {
67*9880d681SAndroid Build Coastguard Worker     if (F.hasName())
68*9880d681SAndroid Build Coastguard Worker       continue;
69*9880d681SAndroid Build Coastguard Worker     F.setName(Twine("anon.") + ModuleHash.get() + "." + Twine(count++));
70*9880d681SAndroid Build Coastguard Worker     Changed = true;
71*9880d681SAndroid Build Coastguard Worker   }
72*9880d681SAndroid Build Coastguard Worker   return Changed;
73*9880d681SAndroid Build Coastguard Worker }
74*9880d681SAndroid Build Coastguard Worker 
75*9880d681SAndroid Build Coastguard Worker namespace {
76*9880d681SAndroid Build Coastguard Worker 
77*9880d681SAndroid Build Coastguard Worker // Simple pass that provides a name to every anon function.
78*9880d681SAndroid Build Coastguard Worker class NameAnonFunction : public ModulePass {
79*9880d681SAndroid Build Coastguard Worker 
80*9880d681SAndroid Build Coastguard Worker public:
81*9880d681SAndroid Build Coastguard Worker   /// Pass identification, replacement for typeid
82*9880d681SAndroid Build Coastguard Worker   static char ID;
83*9880d681SAndroid Build Coastguard Worker 
84*9880d681SAndroid Build Coastguard Worker   /// Specify pass name for debug output
getPassName() const85*9880d681SAndroid Build Coastguard Worker   const char *getPassName() const override { return "Name Anon Functions"; }
86*9880d681SAndroid Build Coastguard Worker 
NameAnonFunction()87*9880d681SAndroid Build Coastguard Worker   explicit NameAnonFunction() : ModulePass(ID) {}
88*9880d681SAndroid Build Coastguard Worker 
runOnModule(Module & M)89*9880d681SAndroid Build Coastguard Worker   bool runOnModule(Module &M) override { return nameUnamedFunctions(M); }
90*9880d681SAndroid Build Coastguard Worker };
91*9880d681SAndroid Build Coastguard Worker char NameAnonFunction::ID = 0;
92*9880d681SAndroid Build Coastguard Worker 
93*9880d681SAndroid Build Coastguard Worker } // anonymous namespace
94*9880d681SAndroid Build Coastguard Worker 
95*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_BEGIN(NameAnonFunction, "name-anon-functions",
96*9880d681SAndroid Build Coastguard Worker                       "Provide a name to nameless functions", false, false)
97*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_END(NameAnonFunction, "name-anon-functions",
98*9880d681SAndroid Build Coastguard Worker                     "Provide a name to nameless functions", false, false)
99*9880d681SAndroid Build Coastguard Worker 
100*9880d681SAndroid Build Coastguard Worker namespace llvm {
createNameAnonFunctionPass()101*9880d681SAndroid Build Coastguard Worker ModulePass *createNameAnonFunctionPass() { return new NameAnonFunction(); }
102*9880d681SAndroid Build Coastguard Worker }
103