diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1148,7 +1148,8 @@ PassInstrumentationCallbacks PIC; StandardInstrumentations SI(CodeGenOpts.DebugPassManager); SI.registerCallbacks(PIC); - PassBuilder PB(CodeGenOpts.DebugPassManager, TM.get(), PTO, PGOOpt, &PIC); + PassBuilder PB(CodeGenOpts.DebugPassManager, TM.get(), PTO, PGOOpt, &PIC, + CodeGenOpts.UniqueInternalLinkageNames); // Attempt to load pass plugins and register their callbacks with PB. for (auto &PluginFN : CodeGenOpts.PassPlugins) { @@ -1325,11 +1326,6 @@ MPM = PB.buildPerModuleDefaultPipeline(Level); } - // Add UniqueInternalLinkageNames Pass which renames internal linkage - // symbols with unique names. - if (CodeGenOpts.UniqueInternalLinkageNames) - MPM.addPass(UniqueInternalLinkageNamesPass()); - if (!CodeGenOpts.MemoryProfileOutput.empty()) { MPM.addPass(createModuleToFunctionPassAdaptor(MemProfilerPass())); MPM.addPass(ModuleMemProfilerPass()); diff --git a/clang/test/CodeGen/unique-internal-linkage-names.cpp b/clang/test/CodeGen/unique-internal-linkage-names.cpp --- a/clang/test/CodeGen/unique-internal-linkage-names.cpp +++ b/clang/test/CodeGen/unique-internal-linkage-names.cpp @@ -5,6 +5,7 @@ // RUN: %clang_cc1 -triple x86_64 -x c++ -O1 -S -emit-llvm -funique-internal-linkage-names -o - < %s | FileCheck %s --check-prefix=UNIQUEO1 // RUN: %clang_cc1 -triple x86_64 -x c++ -O0 -S -emit-llvm -fexperimental-new-pass-manager -funique-internal-linkage-names -o - < %s | FileCheck %s --check-prefix=UNIQUE // RUN: %clang_cc1 -triple x86_64 -x c++ -O1 -S -emit-llvm -fexperimental-new-pass-manager -funique-internal-linkage-names -o - < %s | FileCheck %s --check-prefix=UNIQUEO1 +// RUN: %clang_cc1 -triple x86_64 -x c++ -O2 -S -emit-llvm -fexperimental-new-pass-manager -funique-internal-linkage-names -debug-info-kind=limited -mllvm -unqiue-debug-profile-names=true -o - < %s | FileCheck %s --check-prefix=UNIQUEDEBUG static int glob; static int foo() { @@ -65,3 +66,6 @@ // UNIQUEO1: define weak_odr i32 ()* @_ZL4mverv.resolver() // UNIQUEO1: define internal i32 @_ZL4mverv.__uniq.{{[0-9a-f]+}}() // UNIQUEO1: define internal i32 @_ZL4mverv.sse4.2.__uniq.{{[0-9a-f]+}} +// UNIQUEDEBUG: define internal i32 @_ZL3foov.__uniq.{{[0-9a-f]+}}() [[ATTR:#[0-9]+]] !dbg ![[#DBG:]] +// UNIQUEDEBUG: attributes [[ATTR]] = { {{.*}} "sample-profile-suffix-elision-policy"="selected" {{.*}} } +// UNIQUEDEBUG: ![[#DBG]] = distinct !DISubprogram(name: "foo", linkageName: "_ZL3foov.__uniq.{{[0-9a-f]+}}" diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -2053,6 +2053,8 @@ return getNumOperands() > 10 ? getOperandAs(10) : nullptr; } + void replaceRawLinkageName(MDString *LinkageName); + /// Check if this subprogram describes the given function. /// /// FIXME: Should this be looking through bitcasts? diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -137,6 +137,7 @@ /// construction. class PassBuilder { bool DebugLogging; + bool UniqueLinkageNames; TargetMachine *TM; PipelineTuningOptions PTO; Optional PGOOpt; @@ -281,7 +282,8 @@ explicit PassBuilder(bool DebugLogging = false, TargetMachine *TM = nullptr, PipelineTuningOptions PTO = PipelineTuningOptions(), Optional PGOOpt = None, - PassInstrumentationCallbacks *PIC = nullptr); + PassInstrumentationCallbacks *PIC = nullptr, + bool UniqueLinkageNames = false); /// Cross register the analysis managers through their proxies. /// diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -877,6 +877,10 @@ return F->getSubprogram() == this; } +void DISubprogram::replaceRawLinkageName(MDString *LinkageName) { + replaceOperandWith(3, LinkageName); +} + DILexicalBlock *DILexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope, Metadata *File, unsigned Line, unsigned Column, StorageType Storage, diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -434,8 +434,10 @@ PassBuilder::PassBuilder(bool DebugLogging, TargetMachine *TM, PipelineTuningOptions PTO, Optional PGOOpt, - PassInstrumentationCallbacks *PIC) - : DebugLogging(DebugLogging), TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC) { + PassInstrumentationCallbacks *PIC, + bool UniqueLinkageNames) + : DebugLogging(DebugLogging), UniqueLinkageNames(UniqueLinkageNames), + TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC) { if (TM) TM->registerPassBuilderCallbacks(*this, DebugLogging); if (PIC && shouldPopulateClassToPassNames()) { @@ -1001,6 +1003,11 @@ ThinLTOPhase Phase) { ModulePassManager MPM(DebugLogging); + // Add UniqueInternalLinkageNames Pass which renames internal linkage + // symbols with unique names. + if (UniqueLinkageNames) + MPM.addPass(UniqueInternalLinkageNamesPass()); + // Place pseudo probe instrumentation as the first pass of the pipeline to // minimize the impact of optimization changes. if (PGOOpt && PGOOpt->PseudoProbeForProfiling && @@ -1764,6 +1771,11 @@ ModulePassManager MPM(DebugLogging); + // Add UniqueInternalLinkageNames Pass which renames internal linkage + // symbols with unique names. + if (UniqueLinkageNames) + MPM.addPass(UniqueInternalLinkageNamesPass()); + if (PGOOpt && (PGOOpt->Action == PGOOptions::IRInstr || PGOOpt->Action == PGOOptions::IRUse)) addPGOInstrPassesForO0( diff --git a/llvm/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp b/llvm/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp --- a/llvm/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp +++ b/llvm/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp @@ -13,13 +13,20 @@ #include "llvm/Transforms/Utils/UniqueInternalLinkageNames.h" #include "llvm/ADT/SmallString.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/MDBuilder.h" #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/MD5.h" #include "llvm/Transforms/Utils/ModuleUtils.h" using namespace llvm; +static cl::opt UniqueDebugAndProfileNames( + "unqiue-debug-profile-names", cl::init(false), cl::Hidden, + cl::desc("Uniqueify debug and profile symbol Names")); + static bool uniqueifyInternalLinkageNames(Module &M) { llvm::MD5 Md5; Md5.update(M.getSourceFileName()); @@ -31,11 +38,19 @@ // this symbol is of internal linkage type. std::string ModuleNameHash = (Twine(".__uniq.") + Twine(Str)).str(); bool Changed = false; + MDBuilder MDB(M.getContext()); // Append the module hash to all internal linkage functions. for (auto &F : M) { if (F.hasInternalLinkage()) { F.setName(F.getName() + ModuleNameHash); + if (UniqueDebugAndProfileNames) { + F.addFnAttr("sample-profile-suffix-elision-policy", "selected"); + if (DISubprogram *SP = F.getSubprogram()) { + auto Name = MDB.createString(F.getName()); + SP->replaceRawLinkageName(Name); + } + } Changed = true; } }