diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h --- a/llvm/include/llvm/IR/Metadata.h +++ b/llvm/include/llvm/IR/Metadata.h @@ -56,6 +56,9 @@ /// promoted for the instruction and shouldn't be promoted again. const uint64_t NOMORE_ICP_MAGICNUM = -1; +/// Special metadata node name for llvm statistic. +constexpr const char *LLVMStatsMetadataName = "llvm.stats"; + /// Root of the metadata hierarchy. /// /// This is a root class for typeless data in the IR. @@ -303,7 +306,7 @@ /// Replace all uses of this with \c MD, which is allowed to be null. void replaceAllUsesWith(Metadata *MD); /// Replace all uses of the constant with Undef in debug info metadata - static void SalvageDebugInfo(const Constant &C); + static void SalvageDebugInfo(const Constant &C); /// Returns the list of all DIArgList users of this. SmallVector getAllArgListUsers(); diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -367,7 +367,7 @@ } } - if (NamedMDNode *LLVMStats = M.getNamedMetadata("llvm.stats")) { + if (NamedMDNode *LLVMStats = M.getNamedMetadata(LLVMStatsMetadataName)) { // Emit the metadata for llvm statistics into .llvm_stats section, which is // formatted as a list of key/value pair, the value is base64 encoded. auto *S = C.getObjectFileInfo()->getLLVMStatsSection(); diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp --- a/llvm/lib/Linker/IRMover.cpp +++ b/llvm/lib/Linker/IRMover.cpp @@ -1244,6 +1244,11 @@ DstM.getModuleIdentifier() + "' is not\n"); continue; } + // The stats are computed per module and will all be merged in the binary. + // Importing the metadata will cause duplication of the stats. + if (IsPerformingImport && NMD.getName() == LLVMStatsMetadataName) + continue; + NamedMDNode *DestNMD = DstM.getOrInsertNamedMetadata(NMD.getName()); // Add Src elements into Dest node. for (const MDNode *Op : NMD.operands()) diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp --- a/llvm/lib/Transforms/IPO/SampleProfile.cpp +++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp @@ -2188,7 +2188,7 @@ ProfStatsVec.emplace_back("TotalCallsiteSamples", TotalCallsiteSamples); auto *MD = MDB.createLLVMStats(ProfStatsVec); - auto *NMD = M.getOrInsertNamedMetadata("llvm.stats"); + auto *NMD = M.getOrInsertNamedMetadata(LLVMStatsMetadataName); NMD->addOperand(MD); } } diff --git a/llvm/test/ThinLTO/X86/Inputs/llvm-stats-import.ll b/llvm/test/ThinLTO/X86/Inputs/llvm-stats-import.ll new file mode 100644 --- /dev/null +++ b/llvm/test/ThinLTO/X86/Inputs/llvm-stats-import.ll @@ -0,0 +1,12 @@ +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @foo() { +entry: + ret void +} + +attributes #0 = { inaccessiblememonly nounwind willreturn } + +!llvm.stats = !{!0} +!0 = !{!"foo", i64 456} diff --git a/llvm/test/ThinLTO/X86/llvm-stats-import.ll b/llvm/test/ThinLTO/X86/llvm-stats-import.ll new file mode 100644 --- /dev/null +++ b/llvm/test/ThinLTO/X86/llvm-stats-import.ll @@ -0,0 +1,28 @@ +; RUN: opt -module-summary %s -o %t1.bc +; RUN: opt -module-summary %p/Inputs/llvm-stats-import.ll -o %t2.bc +; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc %t2.bc + +; RUN: llvm-lto -thinlto-action=import %t1.bc -thinlto-index=%t.index.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=CHECK-MAIN +; RUN: llvm-lto -thinlto-action=import %t2.bc -thinlto-index=%t.index.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=CHECK-FOO + +; CHECK-MAIN: !0 = !{!"main", i64 123} +; CHECK-MAIN-NOT: !{!"foo", i64 456} + +; CHECK-FOO: !0 = !{!"foo", i64 456} +; CHECK-FOO-NOT: !{!"main", i64 123} + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define i32 @main() { +entry: + call void (...) @foo() + ret i32 0 +} + +declare void @foo(...) + +attributes #0 = { inaccessiblememonly nounwind willreturn } + +!llvm.stats = !{!0} +!0 = !{!"main", i64 123}