mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[PGO] Use linkonce_odr linkage for __profd_ variables in comdat groups
This fixes relocations against __profd_ symbols in discarded sections, which is PR41380. In general, instrumentation happens very early, and optimization and inlining happens afterwards. The counters for a function are calculated early, and after inlining, counters for an inlined function may be widely referenced by other functions. For C++ inline functions of all kinds (linkonce_odr & available_externally mainly), instr profiling wants to deduplicate these __profc_ and __profd_ globals. Otherwise the binary would be quite large. I made __profd_ and __profc_ comdat in r355044, but I chose to make __profd_ internal. At the time, I was only dealing with coverage, and in that case, none of the instrumentation needs to reference __profd_. However, if you use PGO, then instrumentation passes add calls to __llvm_profile_instrument_range which reference __profd_ globals. The solution is to make these globals externally visible by using linkonce_odr linkage for data as was done for counters. This is safe because PGO adds a CFG hash to the names of the data and counter globals, so if different TUs have different globals, they will get different data and counter arrays. Reviewers: xur, hans Differential Revision: https://reviews.llvm.org/D67579 llvm-svn: 372020
This commit is contained in:
parent
315cdcecbb
commit
f30ad55559
@ -740,9 +740,8 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
|
||||
PD = It->second;
|
||||
}
|
||||
|
||||
// Match the linkage and visibility of the name global, except on COFF, where
|
||||
// the linkage must be local and consequentially the visibility must be
|
||||
// default.
|
||||
// Match the linkage and visibility of the name global. COFF supports using
|
||||
// comdats with internal symbols, so do that if we can.
|
||||
Function *Fn = Inc->getParent()->getParent();
|
||||
GlobalValue::LinkageTypes Linkage = NamePtr->getLinkage();
|
||||
GlobalValue::VisibilityTypes Visibility = NamePtr->getVisibility();
|
||||
@ -759,15 +758,16 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
|
||||
// of the parent function, that will result in relocations against discarded
|
||||
// sections.
|
||||
Comdat *Cmdt = nullptr;
|
||||
GlobalValue::LinkageTypes CounterLinkage = Linkage;
|
||||
if (needsComdatForCounter(*Fn, *M)) {
|
||||
StringRef CmdtPrefix = getInstrProfComdatPrefix();
|
||||
if (TT.isOSBinFormatCOFF()) {
|
||||
// For COFF, the comdat group name must be the name of a symbol in the
|
||||
// group. Use the counter variable name, and upgrade its linkage to
|
||||
// something externally visible, like linkonce_odr.
|
||||
// something externally visible, like linkonce_odr. Use hidden visibility
|
||||
// to imply that this is dso local.
|
||||
CmdtPrefix = getInstrProfCountersVarPrefix();
|
||||
CounterLinkage = GlobalValue::LinkOnceODRLinkage;
|
||||
Linkage = GlobalValue::LinkOnceODRLinkage;
|
||||
Visibility = GlobalValue::HiddenVisibility;
|
||||
}
|
||||
Cmdt = M->getOrInsertComdat(getVarName(Inc, CmdtPrefix));
|
||||
}
|
||||
@ -786,7 +786,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
|
||||
getInstrProfSectionName(IPSK_cnts, TT.getObjectFormat()));
|
||||
CounterPtr->setAlignment(8);
|
||||
CounterPtr->setComdat(Cmdt);
|
||||
CounterPtr->setLinkage(CounterLinkage);
|
||||
CounterPtr->setLinkage(Linkage);
|
||||
|
||||
auto *Int8PtrTy = Type::getInt8PtrTy(Ctx);
|
||||
// Allocate statically the array of pointers to value profile nodes for
|
||||
@ -841,6 +841,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
|
||||
Data->setSection(getInstrProfSectionName(IPSK_data, TT.getObjectFormat()));
|
||||
Data->setAlignment(INSTR_PROF_DATA_ALIGNMENT);
|
||||
Data->setComdat(Cmdt);
|
||||
Data->setLinkage(Linkage);
|
||||
|
||||
PD.RegionCounters = CounterPtr;
|
||||
PD.DataVar = Data;
|
||||
|
@ -20,8 +20,8 @@ $_Z3barIvEvv = comdat any
|
||||
|
||||
|
||||
; COFF-NOT: __profn__Z3barIvEvv
|
||||
; COFF: @__profc__Z3barIvEvv = linkonce_odr dso_local global [1 x i64] zeroinitializer, section "{{.*}}prfc$M", comdat, align 8
|
||||
; COFF: @__profd__Z3barIvEvv = internal global { i64, i64, i64*, i8*, i8*, i32, [2 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8*{{.*}}, i8* null, i32 1, [2 x i16] zeroinitializer }, section "{{.*}}prfd{{.*}}", comdat($__profc__Z3barIvEvv), align 8
|
||||
; COFF: @__profc__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}prfc$M", comdat, align 8
|
||||
; COFF: @__profd__Z3barIvEvv = linkonce_odr hidden global { i64, i64, i64*, i8*, i8*, i32, [2 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8*{{.*}}, i8* null, i32 1, [2 x i16] zeroinitializer }, section "{{.*}}prfd{{.*}}", comdat($__profc__Z3barIvEvv), align 8
|
||||
|
||||
|
||||
declare void @llvm.instrprof.increment(i8*, i64, i32, i32) #1
|
||||
|
@ -17,8 +17,8 @@ $foo_inline = comdat any
|
||||
|
||||
; ELF: @__profc_foo_inline = linkonce_odr hidden global{{.*}}, section "__llvm_prf_cnts", comdat($__profv_foo_inline), align 8
|
||||
; ELF: @__profd_foo_inline = linkonce_odr hidden global{{.*}}, section "__llvm_prf_data", comdat($__profv_foo_inline), align 8
|
||||
; COFF: @__profc_foo_inline = linkonce_odr dso_local global{{.*}}, section ".lprfc$M", comdat, align 8
|
||||
; COFF: @__profd_foo_inline = internal global{{.*}}, section ".lprfd$M", comdat($__profc_foo_inline), align 8
|
||||
; COFF: @__profc_foo_inline = linkonce_odr hidden global{{.*}}, section ".lprfc$M", comdat, align 8
|
||||
; COFF: @__profd_foo_inline = linkonce_odr hidden global{{.*}}, section ".lprfd$M", comdat($__profc_foo_inline), align 8
|
||||
define weak_odr void @foo_inline() comdat {
|
||||
call void @llvm.instrprof.increment(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @__profn_foo_inline, i32 0, i32 0), i64 0, i32 1, i32 0)
|
||||
ret void
|
||||
@ -30,8 +30,8 @@ $foo_extern = comdat any
|
||||
|
||||
; ELF: @__profc_foo_extern = linkonce_odr hidden global{{.*}}, section "__llvm_prf_cnts", comdat($__profv_foo_extern)
|
||||
; ELF: @__profd_foo_extern = linkonce_odr hidden global{{.*}}, section "__llvm_prf_data", comdat($__profv_foo_extern)
|
||||
; COFF: @__profc_foo_extern = linkonce_odr dso_local global{{.*}}, section ".lprfc$M", comdat, align 8
|
||||
; COFF: @__profd_foo_extern = internal global{{.*}}, section ".lprfd$M", comdat($__profc_foo_extern), align 8
|
||||
; COFF: @__profc_foo_extern = linkonce_odr hidden global{{.*}}, section ".lprfc$M", comdat, align 8
|
||||
; COFF: @__profd_foo_extern = linkonce_odr hidden global{{.*}}, section ".lprfd$M", comdat($__profc_foo_extern), align 8
|
||||
define available_externally void @foo_extern() {
|
||||
call void @llvm.instrprof.increment(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @__profn_foo_extern, i32 0, i32 0), i64 0, i32 1, i32 0)
|
||||
ret void
|
||||
|
@ -57,8 +57,8 @@ define linkonce_odr void @foo_inline() {
|
||||
; LINUX: @__profd_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_data", comdat($__profv_foo_extern), align 8
|
||||
; MACHO: @__profc_foo_extern = linkonce_odr hidden global
|
||||
; MACHO: @__profd_foo_extern = linkonce_odr hidden global
|
||||
; COFF: @__profc_foo_extern = linkonce_odr dso_local global {{.*}}section ".lprfc$M", comdat, align 8
|
||||
; COFF: @__profd_foo_extern = internal global {{.*}}section ".lprfd$M", comdat($__profc_foo_extern), align 8
|
||||
; COFF: @__profc_foo_extern = linkonce_odr hidden global {{.*}}section ".lprfc$M", comdat, align 8
|
||||
; COFF: @__profd_foo_extern = linkonce_odr hidden global {{.*}}section ".lprfd$M", comdat($__profc_foo_extern), align 8
|
||||
define available_externally void @foo_extern() {
|
||||
call void @llvm.instrprof.increment(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @__profn_foo_extern, i32 0, i32 0), i64 0, i32 1, i32 0)
|
||||
ret void
|
||||
|
Loading…
x
Reference in New Issue
Block a user