You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
3.0 KiB

//===- UniqueInternalLinkageNames.cpp - Unique Internal Linkage Sym Names -===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements unique naming of internal linkage symbols with option
// -funique-internal-linkage-symbols.
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/UniqueInternalLinkageNames.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/MD5.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
using namespace llvm;
static bool uniqueifyInternalLinkageNames(Module &M) {
llvm::MD5 Md5;
Md5.update(M.getSourceFileName());
llvm::MD5::MD5Result R;
Md5.final(R);
SmallString<32> Str;
llvm::MD5::stringifyResult(R, Str);
// Prepend "__uniq" before the hash for tools like profilers to understand that
// this symbol is of internal linkage type.
std::string ModuleNameHash = (Twine(".__uniq.") + Twine(Str)).str();
bool Changed = false;
// Append the module hash to all internal linkage functions.
for (auto &F : M) {
if (F.hasInternalLinkage()) {
F.setName(F.getName() + ModuleNameHash);
Changed = true;
}
}
// Append the module hash to all internal linkage globals.
for (auto &GV : M.globals()) {
if (GV.hasInternalLinkage()) {
GV.setName(GV.getName() + ModuleNameHash);
Changed = true;
}
}
return Changed;
}
namespace {
// Legacy pass that provides a name to every anon globals.
class UniqueInternalLinkageNamesLegacyPass : public ModulePass {
public:
/// Pass identification, replacement for typeid
static char ID;
/// Specify pass name for debug output
StringRef getPassName() const override {
return "Unique Internal Linkage Names";
}
explicit UniqueInternalLinkageNamesLegacyPass() : ModulePass(ID) {
initializeUniqueInternalLinkageNamesLegacyPassPass(
*PassRegistry::getPassRegistry());
}
bool runOnModule(Module &M) override {
return uniqueifyInternalLinkageNames(M);
}
};
char UniqueInternalLinkageNamesLegacyPass::ID = 0;
} // anonymous namespace
PreservedAnalyses
UniqueInternalLinkageNamesPass::run(Module &M, ModuleAnalysisManager &AM) {
if (!uniqueifyInternalLinkageNames(M))
return PreservedAnalyses::all();
return PreservedAnalyses::none();
}
INITIALIZE_PASS_BEGIN(UniqueInternalLinkageNamesLegacyPass,
"unique-internal-linkage-names",
"Uniqueify internal linkage names", false, false)
INITIALIZE_PASS_END(UniqueInternalLinkageNamesLegacyPass,
"unique-internal-linkage-names",
"Uniqueify Internal linkage names", false, false)
namespace llvm {
ModulePass *createUniqueInternalLinkageNamesPass() {
return new UniqueInternalLinkageNamesLegacyPass();
}
} // namespace llvm