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