forked from OSchip/llvm-project
[PGO] Remove redundant counter copies for avail_extern functions.
Differential Revision: http://reviews.llvm.org/D17654 llvm-svn: 262157
This commit is contained in:
parent
6993abff14
commit
985ff20a9c
|
@ -286,8 +286,38 @@ static inline bool shouldRecordFunctionAddr(Function *F) {
|
|||
return F->hasAddressTaken();
|
||||
}
|
||||
|
||||
static inline Comdat *getOrCreateProfileComdat(Module &M,
|
||||
static inline bool needsComdatForCounter(Function &F, Module &M) {
|
||||
|
||||
if (F.hasComdat())
|
||||
return true;
|
||||
|
||||
Triple TT(M.getTargetTriple());
|
||||
if (!TT.isOSBinFormatELF())
|
||||
return false;
|
||||
|
||||
// See createPGOFuncNameVar for more details. To avoid link errors, profile
|
||||
// counters for function with available_externally linkage needs to be changed
|
||||
// to linkonce linkage. On ELF based systems, this leads to weak symbols to be
|
||||
// created. Without using comdat, duplicate entries won't be removed by the
|
||||
// linker leading to increased data segement size and raw profile size. Even
|
||||
// worse, since the referenced counter from profile per-function data object
|
||||
// will be resolved to the common strong definition, the profile counts for
|
||||
// available_externally functions will end up being duplicated in raw profile
|
||||
// data. This can result in distorted profile as the counts of those dups
|
||||
// will be accumulated by the profile merger.
|
||||
GlobalValue::LinkageTypes Linkage = F.getLinkage();
|
||||
if (Linkage != GlobalValue::ExternalWeakLinkage &&
|
||||
Linkage != GlobalValue::AvailableExternallyLinkage)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline Comdat *getOrCreateProfileComdat(Module &M, Function &F,
|
||||
InstrProfIncrementInst *Inc) {
|
||||
if (!needsComdatForCounter(F, M))
|
||||
return nullptr;
|
||||
|
||||
// COFF format requires a COMDAT section to have a key symbol with the same
|
||||
// name. The linker targeting COFF also requires that the COMDAT
|
||||
// a section is associated to must precede the associating section. For this
|
||||
|
@ -315,8 +345,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
|
|||
// linking.
|
||||
Function *Fn = Inc->getParent()->getParent();
|
||||
Comdat *ProfileVarsComdat = nullptr;
|
||||
if (Fn->hasComdat())
|
||||
ProfileVarsComdat = getOrCreateProfileComdat(*M, Inc);
|
||||
ProfileVarsComdat = getOrCreateProfileComdat(*M, *Fn, Inc);
|
||||
|
||||
uint64_t NumCounters = Inc->getNumCounters()->getZExtValue();
|
||||
LLVMContext &Ctx = M->getContext();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
@__profn_foo_weak = weak hidden constant [8 x i8] c"foo_weak"
|
||||
@"__profn_linkage.ll:foo_internal" = internal constant [23 x i8] c"linkage.ll:foo_internal"
|
||||
@__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"
|
||||
|
||||
; COMMON: @__profc_foo = hidden global
|
||||
; COMMON: @__profd_foo = hidden global
|
||||
|
@ -36,6 +37,15 @@ define linkonce_odr void @foo_inline() {
|
|||
ret void
|
||||
}
|
||||
|
||||
; LINUX: @__profc_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_cnts", comdat($__profv_foo_extern), align 8
|
||||
; LINUX: @__profd_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_data", comdat($__profv_foo_extern), align 8
|
||||
; OTHER: @__profc_foo_extern = linkonce_odr hidden global
|
||||
; OTHER: @__profd_foo_extern = linkonce_odr hidden global
|
||||
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
|
||||
}
|
||||
|
||||
declare void @llvm.instrprof.increment(i8*, i64, i32, i32)
|
||||
|
||||
; OTHER: @__llvm_profile_runtime = external global i32
|
||||
|
|
Loading…
Reference in New Issue