89 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements naming anonymous globals to make sure they can be10// referred to by ThinLTO.11//12//===----------------------------------------------------------------------===//13 14#include "llvm/Transforms/Utils/NameAnonGlobals.h"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 20using namespace llvm;21 22namespace {23// Compute a "unique" hash for the module based on the name of the public24// globals.25class ModuleHasher {26 Module &TheModule;27 std::string TheHash;28 29public:30 ModuleHasher(Module &M) : TheModule(M) {}31 32 /// Return the lazily computed hash.33 std::string &get() {34 if (!TheHash.empty())35 // Cache hit :)36 return TheHash;37 38 MD5 Hasher;39 for (auto &F : TheModule) {40 if (F.isDeclaration() || F.hasLocalLinkage() || !F.hasName())41 continue;42 auto Name = F.getName();43 Hasher.update(Name);44 }45 for (auto &GV : TheModule.globals()) {46 if (GV.isDeclaration() || GV.hasLocalLinkage() || !GV.hasName())47 continue;48 auto Name = GV.getName();49 Hasher.update(Name);50 }51 52 // Now return the result.53 MD5::MD5Result Hash;54 Hasher.final(Hash);55 SmallString<32> Result;56 MD5::stringifyResult(Hash, Result);57 TheHash = std::string(Result);58 return TheHash;59 }60};61} // end anonymous namespace62 63// Rename all the anon globals in the module64bool llvm::nameUnamedGlobals(Module &M) {65 bool Changed = false;66 ModuleHasher ModuleHash(M);67 int count = 0;68 auto RenameIfNeed = [&](GlobalValue &GV) {69 if (GV.hasName())70 return;71 GV.setName(Twine("anon.") + ModuleHash.get() + "." + Twine(count++));72 Changed = true;73 };74 for (auto &GO : M.global_objects())75 RenameIfNeed(GO);76 for (auto &GA : M.aliases())77 RenameIfNeed(GA);78 79 return Changed;80}81 82PreservedAnalyses NameAnonGlobalPass::run(Module &M,83 ModuleAnalysisManager &AM) {84 if (!nameUnamedGlobals(M))85 return PreservedAnalyses::all();86 87 return PreservedAnalyses::none();88}89