mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[InstrProfiling] Use !associated metadata for counters, data and values
C identifier name input sections such as __llvm_prf_* are GC roots so they cannot be discarded. In LLD, the SHF_LINK_ORDER flag overrides the C identifier name semantics. The !associated metadata may be attached to a global object declaration with a single argument that references another global object, and it gets lowered to SHF_LINK_ORDER flag. When a function symbol is discarded by the linker, setting up !associated metadata allows linker to discard counters, data and values associated with that function symbol. Note that !associated metadata is only supported by ELF, it does not have any effect on non-ELF targets. Differential Revision: https://reviews.llvm.org/D76802
This commit is contained in:
parent
01a807c55f
commit
0778936d8e
@ -132,6 +132,9 @@ struct InstrProfOptions {
|
||||
// Use BFI to guide register promotion
|
||||
bool UseBFIInPromotion = false;
|
||||
|
||||
// Use !associated metadata to enable linker GC
|
||||
bool CounterLinkOrder = false;
|
||||
|
||||
// Name of the profile file to use as output
|
||||
std::string InstrProfileOutput;
|
||||
|
||||
|
@ -83,6 +83,9 @@ private:
|
||||
/// Returns true if profile counter update register promotion is enabled.
|
||||
bool isCounterPromotionEnabled() const;
|
||||
|
||||
/// Returns true if the use of !associated metadata is enabled.
|
||||
bool isCounterLinkOrderEnabled() const;
|
||||
|
||||
/// Count the number of instrumented value sites for the function.
|
||||
void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins);
|
||||
|
||||
|
@ -69,6 +69,11 @@ cl::opt<bool> RuntimeCounterRelocation(
|
||||
cl::desc("Enable relocating counters at runtime."),
|
||||
cl::init(false));
|
||||
|
||||
cl::opt<bool> CounterLinkOrder(
|
||||
"counter-link-order",
|
||||
cl::desc("Set counter associated metadata to enable garbage collection at link time."),
|
||||
cl::init(false));
|
||||
|
||||
cl::opt<bool> ValueProfileStaticAlloc(
|
||||
"vp-static-alloc",
|
||||
cl::desc("Do static counter allocation for value profiler"),
|
||||
@ -479,6 +484,13 @@ bool InstrProfiling::isCounterPromotionEnabled() const {
|
||||
return Options.DoCounterPromotion;
|
||||
}
|
||||
|
||||
bool InstrProfiling::isCounterLinkOrderEnabled() const {
|
||||
if (CounterLinkOrder.getNumOccurrences() > 0)
|
||||
return CounterLinkOrder;
|
||||
|
||||
return Options.CounterLinkOrder;
|
||||
}
|
||||
|
||||
void InstrProfiling::promoteCounterLoadStores(Function *F) {
|
||||
if (!isCounterPromotionEnabled())
|
||||
return;
|
||||
@ -850,6 +862,12 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
|
||||
CounterPtr->setAlignment(Align(8));
|
||||
MaybeSetComdat(CounterPtr);
|
||||
CounterPtr->setLinkage(Linkage);
|
||||
// We need a self-link for the counter variable because the ELF section name
|
||||
// (that is __llvm_prf_cnts) is a C identifier and considered a GC root in the
|
||||
// absence of the SHF_LINK_ORDER flag.
|
||||
if (isCounterLinkOrderEnabled())
|
||||
CounterPtr->setMetadata(LLVMContext::MD_associated,
|
||||
MDNode::get(Ctx, ValueAsMetadata::get(Fn)));
|
||||
|
||||
auto *Int8PtrTy = Type::getInt8PtrTy(Ctx);
|
||||
// Allocate statically the array of pointers to value profile nodes for
|
||||
@ -871,6 +889,10 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
|
||||
getInstrProfSectionName(IPSK_vals, TT.getObjectFormat()));
|
||||
ValuesVar->setAlignment(Align(8));
|
||||
MaybeSetComdat(ValuesVar);
|
||||
if (isCounterLinkOrderEnabled())
|
||||
ValuesVar->setMetadata(
|
||||
LLVMContext::MD_associated,
|
||||
MDNode::get(Ctx, ValueAsMetadata::get(CounterPtr)));
|
||||
ValuesPtrExpr =
|
||||
ConstantExpr::getBitCast(ValuesVar, Type::getInt8PtrTy(Ctx));
|
||||
}
|
||||
@ -905,6 +927,9 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
|
||||
Data->setAlignment(Align(INSTR_PROF_DATA_ALIGNMENT));
|
||||
MaybeSetComdat(Data);
|
||||
Data->setLinkage(Linkage);
|
||||
if (isCounterLinkOrderEnabled())
|
||||
Data->setMetadata(LLVMContext::MD_associated,
|
||||
MDNode::get(Ctx, ValueAsMetadata::get(CounterPtr)));
|
||||
|
||||
PD.RegionCounters = CounterPtr;
|
||||
PD.DataVar = Data;
|
||||
|
@ -11,6 +11,7 @@
|
||||
; RUN: opt < %s -mtriple=mips64-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC-SEXT
|
||||
; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -vp-static-alloc=false -instrprof -S | FileCheck %s --check-prefix=DYN
|
||||
; RUN: opt < %s -mtriple=x86_64-unknown-linux -instrprof -vp-static-alloc=false -S | FileCheck %s --check-prefix=DYN
|
||||
; RUN: opt < %s -mtriple=x86_64-unknown-linux -instrprof -counter-link-order -vp-static-alloc=true -S | FileCheck %s --check-prefix=METADATA
|
||||
|
||||
|
||||
@__profn_foo = private constant [3 x i8] c"foo"
|
||||
@ -57,3 +58,12 @@ attributes #0 = { nounwind }
|
||||
; STATIC: declare void @__llvm_profile_instrument_target(i64, i8*, i32)
|
||||
; STATIC-EXT: declare void @__llvm_profile_instrument_target(i64, i8*, i32 zeroext)
|
||||
; STATIC-SEXT: declare void @__llvm_profile_instrument_target(i64, i8*, i32 signext)
|
||||
|
||||
; METADATA: @__profc_foo = private global [1 x i64] zeroinitializer, section "{{[^"]+}}", align 8, !associated !0
|
||||
; METADATA: @__profvp_foo = private global [1 x i64] zeroinitializer, section "{{[^"]+}}", align 8, !associated !1
|
||||
; METADATA: @__profc_bar = private global [1 x i64] zeroinitializer, section "{{[^"]+}}", comdat($__profd_bar), align 8, !associated !2
|
||||
; METADATA: @__profvp_bar = private global [1 x i64] zeroinitializer, section "{{[^"]+}}", comdat($__profd_bar), align 8, !associated !3
|
||||
; METADATA: !0 = !{i32 (i32 ()*)* @foo}
|
||||
; METADATA: !1 = !{[1 x i64]* @__profc_foo}
|
||||
; METADATA: !2 = !{i32 (i32 ()*)* @bar}
|
||||
; METADATA: !3 = !{[1 x i64]* @__profc_bar}
|
||||
|
@ -8,6 +8,8 @@
|
||||
; RUN: opt < %s -mtriple=x86_64-unknown-linux -passes=instrprof -S | FileCheck %s --check-prefixes=POSIX,LINUX
|
||||
; RUN: opt < %s -mtriple=x86_64-unknown-fuchsia -passes=instrprof -S | FileCheck %s --check-prefixes=POSIX,LINUX
|
||||
; RUN: opt < %s -mtriple=x86_64-pc-win32-coff -passes=instrprof -S | FileCheck %s --check-prefixes=COFF
|
||||
; RUN: opt < %s -mtriple=x86_64-unknown-linux -instrprof -counter-link-order -S | FileCheck %s --check-prefixes=LINUX,POSIX,METADATA
|
||||
; RUN: opt < %s -mtriple=x86_64-unknown-linux -passes=instrprof -counter-link-order -S | FileCheck %s --check-prefixes=LINUX,POSIX,METADATA
|
||||
|
||||
; MACHO: @__llvm_profile_runtime = external global i32
|
||||
; LINUX-NOT: @__llvm_profile_runtime = external global i32
|
||||
@ -19,7 +21,9 @@
|
||||
@__profn_foo_extern = linkonce_odr hidden constant [10 x i8] c"foo_extern"
|
||||
|
||||
; POSIX: @__profc_foo = hidden global
|
||||
; METADATA-SAME: !associated !0
|
||||
; POSIX: @__profd_foo = hidden global
|
||||
; METADATA-SAME: !associated !1
|
||||
; COFF: @__profc_foo = internal global
|
||||
; COFF-NOT: comdat
|
||||
; COFF: @__profd_foo = internal global
|
||||
@ -29,7 +33,9 @@ define void @foo() {
|
||||
}
|
||||
|
||||
; POSIX: @__profc_foo_weak = weak hidden global
|
||||
; METADATA: !associated !2
|
||||
; POSIX: @__profd_foo_weak = weak hidden global
|
||||
; METADATA: !associated !3
|
||||
; COFF: @__profc_foo_weak = internal global
|
||||
; COFF: @__profd_foo_weak = internal global
|
||||
define weak void @foo_weak() {
|
||||
@ -38,7 +44,9 @@ define weak void @foo_weak() {
|
||||
}
|
||||
|
||||
; POSIX: @"__profc_linkage.ll:foo_internal" = internal global
|
||||
; METADATA-SAME: !associated !4
|
||||
; POSIX: @"__profd_linkage.ll:foo_internal" = internal global
|
||||
; METADATA-SAME: !associated !5
|
||||
; COFF: @"__profc_linkage.ll:foo_internal" = internal global
|
||||
; COFF: @"__profd_linkage.ll:foo_internal" = internal global
|
||||
define internal void @foo_internal() {
|
||||
@ -47,7 +55,9 @@ define internal void @foo_internal() {
|
||||
}
|
||||
|
||||
; POSIX: @__profc_foo_inline = linkonce_odr hidden global
|
||||
; METADATA-SAME: !associated !6
|
||||
; POSIX: @__profd_foo_inline = linkonce_odr hidden global
|
||||
; METADATA-SAME: !associated !7
|
||||
; COFF: @__profc_foo_inline = internal global{{.*}} section ".lprfc$M", align 8
|
||||
; COFF: @__profd_foo_inline = internal global{{.*}} section ".lprfd$M", align 8
|
||||
define linkonce_odr void @foo_inline() {
|
||||
@ -56,7 +66,9 @@ define linkonce_odr void @foo_inline() {
|
||||
}
|
||||
|
||||
; LINUX: @__profc_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_cnts", comdat($__profd_foo_extern), align 8
|
||||
; METADATA-SAME: !associated !8
|
||||
; LINUX: @__profd_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_data", comdat, align 8
|
||||
; METADATA-SAME: !associated !9
|
||||
; MACHO: @__profc_foo_extern = linkonce_odr hidden global
|
||||
; MACHO: @__profd_foo_extern = linkonce_odr hidden global
|
||||
; COFF: @__profc_foo_extern = linkonce_odr hidden global {{.*}}section ".lprfc$M", comdat, align 8
|
||||
@ -75,3 +87,14 @@ declare void @llvm.instrprof.increment(i8*, i64, i32, i32)
|
||||
; COFF: define linkonce_odr hidden i32 @__llvm_profile_runtime_user() {{.*}} comdat {
|
||||
; LINUX-NOT: define linkonce_odr hidden i32 @__llvm_profile_runtime_user() {{.*}} {
|
||||
; LINUX-NOT: %[[REG:.*]] = load i32, i32* @__llvm_profile_runtime
|
||||
|
||||
; METADATA: !0 = !{void ()* @foo}
|
||||
; METADATA: !1 = !{[1 x i64]* @__profc_foo}
|
||||
; METADATA: !2 = !{void ()* @foo_weak}
|
||||
; METADATA: !3 = !{[1 x i64]* @__profc_foo_weak}
|
||||
; METADATA: !4 = !{void ()* @foo_internal}
|
||||
; METADATA: !5 = !{[1 x i64]* @"__profc_linkage.ll:foo_internal"}
|
||||
; METADATA: !6 = !{void ()* @foo_inline}
|
||||
; METADATA: !7 = !{[1 x i64]* @__profc_foo_inline}
|
||||
; METADATA: !8 = !{void ()* @foo_extern}
|
||||
; METADATA: !9 = !{[1 x i64]* @__profc_foo_extern}
|
||||
|
12
test/Transforms/PGOProfile/associated.ll
Normal file
12
test/Transforms/PGOProfile/associated.ll
Normal file
@ -0,0 +1,12 @@
|
||||
; RUN: opt < %s -pgo-instr-gen -instrprof -counter-link-order -S | FileCheck %s
|
||||
; RUN: opt < %s -passes=pgo-instr-gen,instrprof -counter-link-order -S | FileCheck %s
|
||||
|
||||
; CHECK: @__profc_foo = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", align 8, !associated !0
|
||||
; CHECK: @__profd_foo = private global {{.*}}, section "__llvm_prf_data", align 8, !associated !1
|
||||
|
||||
define void @foo() {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: !0 = !{void ()* @foo}
|
||||
; CHECK: !1 = !{[1 x i64]* @__profc_foo}
|
@ -60,7 +60,7 @@ bb12: ; preds = %bb9
|
||||
; ATOMIC_PROMO: atomicrmw add {{.*}} @__profc_foo{{.*}}0), i64 %[[LIVEOUT1]] seq_cst
|
||||
; ATOMIC_PROMO-NEXT: atomicrmw add {{.*}} @__profc_foo{{.*}}1), i64 %[[LIVEOUT2]] seq_cst
|
||||
; ATOMIC_PROMO-NEXT: atomicrmw add {{.*}} @__profc_foo{{.*}}2), i64 %[[LIVEOUT3]] seq_cst
|
||||
; PROMO-NOT: @__profc_foo
|
||||
; PROMO-NOT: @__profc_foo{{.*}})
|
||||
|
||||
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ bb15_0: ; preds = %bb11
|
||||
; PROMO-NEXT: %pgocount{{.*}} = load {{.*}} @__profc_foo{{.*}} 4)
|
||||
; PROMO-NEXT: add
|
||||
; PROMO-NEXT: store {{.*}}@__profc_foo{{.*}}4)
|
||||
; PROMO-NOT: @__profc_foo
|
||||
; PROMO-NOT: @__profc_foo{{.*}})
|
||||
|
||||
|
||||
bb15: ; preds = %bb14, %bb4
|
||||
|
Loading…
Reference in New Issue
Block a user