1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[InstrProfiling] Use ELF section groups for counters, data and values

__start_/__stop_ references retain C identifier name sections such as
__llvm_prf_*. Putting these into a section group disables this logic.

The ELF section group semantics ensures that group members are retained
or discarded as a unit. When a function symbol is discarded, this allows
allows linker to discard counters, data and values associated with that
function symbol as well.

Note that `noduplicates` COMDAT is lowered to zero-flag section group in
ELF. We only set this for functions that aren't already in a COMDAT and
for those that don't have available_externally linkage since we already
use regular COMDAT groups for those.

Differential Revision: https://reviews.llvm.org/D96757
This commit is contained in:
Petr Hosek 2019-07-13 14:02:07 -07:00
parent c5bcd963eb
commit 6b7b1199a8
6 changed files with 51 additions and 28 deletions

View File

@ -830,9 +830,18 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
}
std::string DataVarName = getVarName(Inc, getInstrProfDataVarPrefix());
auto MaybeSetComdat = [=](GlobalVariable *GV) {
if (NeedComdat)
GV->setComdat(M->getOrInsertComdat(TT.isOSBinFormatCOFF() ? GV->getName()
: DataVarName));
// For ELF, when not using COMDAT, put counters, data and values into
// a noduplicates COMDAT which is lowered to a zero-flag section group.
// This allows linker GC to discard the entire group when the function
// is discarded.
bool UseComdat = (NeedComdat || TT.isOSBinFormatELF());
if (UseComdat) {
auto GroupName = TT.isOSBinFormatCOFF() ? GV->getName() : DataVarName;
Comdat *C = M->getOrInsertComdat(GroupName);
if (!NeedComdat)
C->setSelectionKind(Comdat::NoDuplicates);
GV->setComdat(C);
}
};
uint64_t NumCounters = Inc->getNumCounters()->getZExtValue();

View File

@ -43,8 +43,8 @@ declare void @llvm.instrprof.value.profile(i8*, i64, i64, i32, i32) #0
attributes #0 = { nounwind }
; STATIC: @__profvp_foo = private global [1 x i64] zeroinitializer, section "{{[^"]+}}", align 8
; STATIC: @__profvp_bar = private global [1 x i64] zeroinitializer, section "{{[^"]+}}", comdat($__profd_bar), align 8
; STATIC: @__profvp_foo = private global [1 x i64] zeroinitializer, section "{{[^"]+}}"
; STATIC: @__profvp_bar = private global [1 x i64] zeroinitializer, section "{{[^"]+}}", comdat($__profd_bar)
; STATIC: @__llvm_prf_vnodes
; DYN-NOT: @__profvp_foo

View File

@ -1,16 +1,22 @@
;; Check that runtime symbols get appropriate linkage.
; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -instrprof -S | FileCheck %s --check-prefixes=POSIX,MACHO
; RUN: opt < %s -mtriple=x86_64-unknown-linux -instrprof -S | FileCheck %s --check-prefixes=POSIX,LINUX
; RUN: opt < %s -mtriple=x86_64-unknown-fuchsia -instrprof -S | FileCheck %s --check-prefixes=POSIX,LINUX
; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -instrprof -S | FileCheck %s --check-prefixes=MACHO
; RUN: opt < %s -mtriple=x86_64-unknown-linux -instrprof -S | FileCheck %s --check-prefixes=ELF
; RUN: opt < %s -mtriple=x86_64-unknown-fuchsia -instrprof -S | FileCheck %s --check-prefixes=ELF
; RUN: opt < %s -mtriple=x86_64-pc-win32-coff -instrprof -S | FileCheck %s --check-prefixes=COFF
; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -passes=instrprof -S | FileCheck %s --check-prefixes=POSIX,MACHO
; 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-apple-macosx10.10.0 -passes=instrprof -S | FileCheck %s --check-prefixes=MACHO
; RUN: opt < %s -mtriple=x86_64-unknown-linux -passes=instrprof -S | FileCheck %s --check-prefixes=ELF
; RUN: opt < %s -mtriple=x86_64-unknown-fuchsia -passes=instrprof -S | FileCheck %s --check-prefixes=ELF
; RUN: opt < %s -mtriple=x86_64-pc-win32-coff -passes=instrprof -S | FileCheck %s --check-prefixes=COFF
; MACHO: @__llvm_profile_runtime = external global i32
; LINUX-NOT: @__llvm_profile_runtime = external global i32
; ELF-NOT: @__llvm_profile_runtime = external global i32
; ELF: $__profd_foo = comdat noduplicates
; ELF: $__profd_foo_weak = comdat noduplicates
; ELF: $"__profd_linkage.ll:foo_internal" = comdat noduplicates
; ELF: $__profd_foo_inline = comdat noduplicates
; ELF: $__profd_foo_extern = comdat any
@__profn_foo = hidden constant [3 x i8] c"foo"
@__profn_foo_weak = weak hidden constant [8 x i8] c"foo_weak"
@ -18,8 +24,10 @@
@__profn_foo_inline = linkonce_odr hidden constant [10 x i8] c"foo_inline"
@__profn_foo_extern = linkonce_odr hidden constant [10 x i8] c"foo_extern"
; POSIX: @__profc_foo = hidden global
; POSIX: @__profd_foo = hidden global
; ELF: @__profc_foo = hidden global{{.*}}section "__llvm_prf_cnts", comdat($__profd_foo)
; ELF: @__profd_foo = hidden global{{.*}}section "__llvm_prf_data", comdat
; MACHO: @__profc_foo = hidden global
; MACHO: @__profd_foo = hidden global
; COFF: @__profc_foo = internal global
; COFF-NOT: comdat
; COFF: @__profd_foo = internal global
@ -28,8 +36,10 @@ define void @foo() {
ret void
}
; POSIX: @__profc_foo_weak = weak hidden global
; POSIX: @__profd_foo_weak = weak hidden global
; ELF: @__profc_foo_weak = weak hidden global{{.*}}section "__llvm_prf_cnts", comdat($__profd_foo_weak)
; ELF: @__profd_foo_weak = weak hidden global{{.*}}section "__llvm_prf_data", comdat
; MACHO: @__profc_foo_weak = weak hidden global
; MACHO: @__profd_foo_weak = weak hidden global
; COFF: @__profc_foo_weak = internal global
; COFF: @__profd_foo_weak = internal global
define weak void @foo_weak() {
@ -37,8 +47,10 @@ define weak void @foo_weak() {
ret void
}
; POSIX: @"__profc_linkage.ll:foo_internal" = internal global
; POSIX: @"__profd_linkage.ll:foo_internal" = internal global
; ELF: @"__profc_linkage.ll:foo_internal" = internal global{{.*}}section "__llvm_prf_cnts", comdat($"__profd_linkage.ll:foo_internal")
; ELF: @"__profd_linkage.ll:foo_internal" = internal global{{.*}}section "__llvm_prf_data", comdat
; MACHO: @"__profc_linkage.ll:foo_internal" = internal global
; MACHO: @"__profd_linkage.ll:foo_internal" = internal global
; COFF: @"__profc_linkage.ll:foo_internal" = internal global
; COFF: @"__profd_linkage.ll:foo_internal" = internal global
define internal void @foo_internal() {
@ -46,8 +58,10 @@ define internal void @foo_internal() {
ret void
}
; POSIX: @__profc_foo_inline = linkonce_odr hidden global
; POSIX: @__profd_foo_inline = linkonce_odr hidden global
; ELF: @__profc_foo_inline = linkonce_odr hidden global{{.*}}section "__llvm_prf_cnts", comdat($__profd_foo_inline)
; ELF: @__profd_foo_inline = linkonce_odr hidden global{{.*}}section "__llvm_prf_data", comdat
; MACHO: @__profc_foo_inline = linkonce_odr hidden global
; MACHO: @__profd_foo_inline = linkonce_odr hidden global
; 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() {
@ -55,8 +69,8 @@ define linkonce_odr void @foo_inline() {
ret void
}
; LINUX: @__profc_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_cnts", comdat($__profd_foo_extern), align 8
; LINUX: @__profd_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_data", comdat, align 8
; ELF: @__profc_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_cnts", comdat($__profd_foo_extern), align 8
; ELF: @__profd_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_data", comdat, align 8
; 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
@ -73,5 +87,5 @@ declare void @llvm.instrprof.increment(i8*, i64, i32, i32)
; MACHO: ret i32 %[[REG]]
; MACHO: }
; 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
; ELF-NOT: define linkonce_odr hidden i32 @__llvm_profile_runtime_user() {{.*}} {
; ELF-NOT: %[[REG:.*]] = load i32, i32* @__llvm_profile_runtime

View File

@ -19,11 +19,11 @@
; WINDOWS-NOT: __profn_foo
; MACHO: @__profc_foo = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
; ELF: @__profc_foo = hidden global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", align 8
; ELF: @__profc_foo = hidden global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat($__profd_foo), align 8
; WINDOWS: @__profc_foo = internal global [1 x i64] zeroinitializer, section ".lprfc$M", align 8
; MACHO: @__profd_foo = hidden {{.*}}, section "__DATA,__llvm_prf_data,regular,live_support", align 8
; ELF: @__profd_foo = hidden {{.*}}, section "__llvm_prf_data", align 8
; ELF: @__profd_foo = hidden {{.*}}, section "__llvm_prf_data", comdat, align 8
; WINDOWS: @__profd_foo = internal global {{.*}}, section ".lprfd$M", align 8
; ELF: @__llvm_prf_nm = private constant [{{.*}} x i8] c"{{.*}}", section "{{.*}}__llvm_prf_names", align 1

View File

@ -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{{.*}})
}

View File

@ -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