mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-29 14:20:29 +00:00
Add a pass to name anonymous/nameless function
Summary: For correct handling of alias to nameless function, we need to be able to refer them through a GUID in the summary. Here we name them using a hash of the non-private global names in the module. Reviewers: tejohnson Subscribers: joker.eph, llvm-commits Differential Revision: http://reviews.llvm.org/D18883 From: Mehdi Amini <mehdi.amini@apple.com> llvm-svn: 266132
This commit is contained in:
parent
03a2cdacee
commit
6875fa5607
@ -221,6 +221,7 @@ void initializeMergedLoadStoreMotionPass(PassRegistry &);
|
||||
void initializeMetaRenamerPass(PassRegistry&);
|
||||
void initializeMergeFunctionsPass(PassRegistry&);
|
||||
void initializeModuleDebugInfoPrinterPass(PassRegistry&);
|
||||
void initializeNameAnonFunctionPass(PassRegistry &);
|
||||
void initializeNaryReassociatePass(PassRegistry&);
|
||||
void initializeNoAAPass(PassRegistry&);
|
||||
void initializeObjCARCAAWrapperPassPass(PassRegistry&);
|
||||
|
@ -503,6 +503,9 @@ FunctionPass *createLoopVersioningPass();
|
||||
//
|
||||
FunctionPass *createLoopDataPrefetchPass();
|
||||
|
||||
///===---------------------------------------------------------------------===//
|
||||
ModulePass *createNameAnonFunctionPass();
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -61,6 +61,11 @@ std::pair<Function *, Function *> createSanitizerCtorAndInitFunctions(
|
||||
Module &M, StringRef CtorName, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
|
||||
StringRef VersionCheckName = StringRef());
|
||||
|
||||
/// Rename all the anon functions in the module using a hash computed from
|
||||
/// the list of public globals in the module.
|
||||
bool nameUnamedFunctions(Module &M);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
|
||||
|
@ -247,6 +247,8 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
|
||||
if (PrepareForThinLTO) {
|
||||
MPM.add(createAggressiveDCEPass()); // Delete dead instructions
|
||||
addInstructionCombiningPass(MPM); // Combine silly seq's
|
||||
// Rename anon function to export them
|
||||
MPM.add(createNameAnonFunctionPass());
|
||||
return;
|
||||
}
|
||||
// Rotate Loop - disable header duplication at -Oz
|
||||
|
@ -31,6 +31,7 @@ add_llvm_library(LLVMTransformUtils
|
||||
MemorySSA.cpp
|
||||
MetaRenamer.cpp
|
||||
ModuleUtils.cpp
|
||||
NameAnonFunctions.cpp
|
||||
PromoteMemoryToRegister.cpp
|
||||
SSAUpdater.cpp
|
||||
SanitizerStats.cpp
|
||||
|
102
lib/Transforms/Utils/NameAnonFunctions.cpp
Normal file
102
lib/Transforms/Utils/NameAnonFunctions.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
//===- NameAnonFunctions.cpp - ThinLTO Summary-based Function Import ------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements naming anonymous function to make sure they can be
|
||||
// refered to by ThinLTO.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/MD5.h"
|
||||
#include "llvm/Transforms/Utils/ModuleUtils.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
// Compute a "unique" hash for the module based on the name of the public
|
||||
// functions.
|
||||
class ModuleHasher {
|
||||
Module &TheModule;
|
||||
std::string TheHash;
|
||||
|
||||
public:
|
||||
ModuleHasher(Module &M) : TheModule(M) {}
|
||||
|
||||
/// Return the lazily computed hash.
|
||||
std::string &get() {
|
||||
if (!TheHash.empty())
|
||||
// Cache hit :)
|
||||
return TheHash;
|
||||
|
||||
MD5 Hasher;
|
||||
for (auto &F : TheModule) {
|
||||
if (F.isDeclaration() || F.hasLocalLinkage() || !F.hasName())
|
||||
continue;
|
||||
auto Name = F.getName();
|
||||
Hasher.update(Name);
|
||||
}
|
||||
for (auto &GV : TheModule.globals()) {
|
||||
if (GV.isDeclaration() || GV.hasLocalLinkage() || !GV.hasName())
|
||||
continue;
|
||||
auto Name = GV.getName();
|
||||
Hasher.update(Name);
|
||||
}
|
||||
|
||||
// Now return the result.
|
||||
MD5::MD5Result Hash;
|
||||
Hasher.final(Hash);
|
||||
SmallString<32> Result;
|
||||
MD5::stringifyResult(Hash, Result);
|
||||
TheHash = Result.str();
|
||||
return TheHash;
|
||||
}
|
||||
};
|
||||
|
||||
// Rename all the anon functions in the module
|
||||
bool llvm::nameUnamedFunctions(Module &M) {
|
||||
bool Changed = false;
|
||||
ModuleHasher ModuleHash(M);
|
||||
int count = 0;
|
||||
for (auto &F : M) {
|
||||
if (F.hasName())
|
||||
continue;
|
||||
F.setName(Twine("anon.") + ModuleHash.get() + "." + Twine(count++));
|
||||
Changed = true;
|
||||
}
|
||||
return Changed;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Simple pass that provides a name to every anon function.
|
||||
class NameAnonFunction : public ModulePass {
|
||||
|
||||
public:
|
||||
/// Pass identification, replacement for typeid
|
||||
static char ID;
|
||||
|
||||
/// Specify pass name for debug output
|
||||
const char *getPassName() const override { return "Name Anon Functions"; }
|
||||
|
||||
explicit NameAnonFunction() : ModulePass(ID) {}
|
||||
|
||||
bool runOnModule(Module &M) override { return nameUnamedFunctions(M); }
|
||||
};
|
||||
char NameAnonFunction::ID = 0;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
INITIALIZE_PASS_BEGIN(NameAnonFunction, "name-anon-functions",
|
||||
"Provide a name to nameless functions", false, false)
|
||||
INITIALIZE_PASS_END(NameAnonFunction, "name-anon-functions",
|
||||
"Provide a name to nameless functions", false, false)
|
||||
|
||||
namespace llvm {
|
||||
Pass *createNameAnonFunctionPass() { return new NameAnonFunction(); }
|
||||
}
|
@ -28,6 +28,7 @@ void llvm::initializeTransformUtils(PassRegistry &Registry) {
|
||||
initializeLoopSimplifyPass(Registry);
|
||||
initializeLowerInvokePass(Registry);
|
||||
initializeLowerSwitchPass(Registry);
|
||||
initializeNameAnonFunctionPass(Registry);
|
||||
initializePromotePassPass(Registry);
|
||||
initializeUnifyFunctionExitNodesPass(Registry);
|
||||
initializeInstSimplifierPass(Registry);
|
||||
|
27
test/Transforms/NameAnonFunctions/rename.ll
Normal file
27
test/Transforms/NameAnonFunctions/rename.ll
Normal file
@ -0,0 +1,27 @@
|
||||
; RUN: opt -S -name-anon-functions < %s | FileCheck %s
|
||||
|
||||
|
||||
; foo contribute to the unique hash for the module
|
||||
define void @foo() {
|
||||
ret void
|
||||
}
|
||||
|
||||
; bar is internal, and does not contribute to the unique hash for the module
|
||||
define internal void @bar() {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: define void @anon.acbd18db4cc2f85cedef654fccc4a4d8.0()
|
||||
; CHECK: define void @anon.acbd18db4cc2f85cedef654fccc4a4d8.1()
|
||||
; CHECK: define void @anon.acbd18db4cc2f85cedef654fccc4a4d8.2()
|
||||
|
||||
define void @0() {
|
||||
ret void
|
||||
}
|
||||
define void @1() {
|
||||
ret void
|
||||
}
|
||||
define void @2() {
|
||||
ret void
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user