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