llvm.org GIT mirror llvm / cbdb39c
[PGO] Remove redundant counter copies for avail_extern functions. Differential Revision: http://reviews.llvm.org/D17654 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@262157 91177308-0d34-0410-b5e6-96231b3b80d8 Xinliang David Li 4 years ago
2 changed file(s) with 42 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
285285 return F->hasAddressTaken();
286286 }
287287
288 static inline Comdat *getOrCreateProfileComdat(Module &M,
288 static inline bool needsComdatForCounter(Function &F, Module &M) {
289
290 if (F.hasComdat())
291 return true;
292
293 Triple TT(M.getTargetTriple());
294 if (!TT.isOSBinFormatELF())
295 return false;
296
297 // See createPGOFuncNameVar for more details. To avoid link errors, profile
298 // counters for function with available_externally linkage needs to be changed
299 // to linkonce linkage. On ELF based systems, this leads to weak symbols to be
300 // created. Without using comdat, duplicate entries won't be removed by the
301 // linker leading to increased data segement size and raw profile size. Even
302 // worse, since the referenced counter from profile per-function data object
303 // will be resolved to the common strong definition, the profile counts for
304 // available_externally functions will end up being duplicated in raw profile
305 // data. This can result in distorted profile as the counts of those dups
306 // will be accumulated by the profile merger.
307 GlobalValue::LinkageTypes Linkage = F.getLinkage();
308 if (Linkage != GlobalValue::ExternalWeakLinkage &&
309 Linkage != GlobalValue::AvailableExternallyLinkage)
310 return false;
311
312 return true;
313 }
314
315 static inline Comdat *getOrCreateProfileComdat(Module &M, Function &F,
289316 InstrProfIncrementInst *Inc) {
317 if (!needsComdatForCounter(F, M))
318 return nullptr;
319
290320 // COFF format requires a COMDAT section to have a key symbol with the same
291321 // name. The linker targeting COFF also requires that the COMDAT
292322 // a section is associated to must precede the associating section. For this
314344 // linking.
315345 Function *Fn = Inc->getParent()->getParent();
316346 Comdat *ProfileVarsComdat = nullptr;
317 if (Fn->hasComdat())
318 ProfileVarsComdat = getOrCreateProfileComdat(*M, Inc);
347 ProfileVarsComdat = getOrCreateProfileComdat(*M, *Fn, Inc);
319348
320349 uint64_t NumCounters = Inc->getNumCounters()->getZExtValue();
321350 LLVMContext &Ctx = M->getContext();
66 @__profn_foo_weak = weak hidden constant [8 x i8] c"foo_weak"
77 @"__profn_linkage.ll:foo_internal" = internal constant [23 x i8] c"linkage.ll:foo_internal"
88 @__profn_foo_inline = linkonce_odr hidden constant [10 x i8] c"foo_inline"
9 @__profn_foo_extern = linkonce_odr hidden constant [10 x i8] c"foo_extern"
910
1011 ; COMMON: @__profc_foo = hidden global
1112 ; COMMON: @__profd_foo = hidden global
3536 ret void
3637 }
3738
39 ; LINUX: @__profc_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_cnts", comdat($__profv_foo_extern), align 8
40 ; LINUX: @__profd_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_data", comdat($__profv_foo_extern), align 8
41 ; OTHER: @__profc_foo_extern = linkonce_odr hidden global
42 ; OTHER: @__profd_foo_extern = linkonce_odr hidden global
43 define available_externally void @foo_extern() {
44 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)
45 ret void
46 }
47
3848 declare void @llvm.instrprof.increment(i8*, i64, i32, i32)
3949
4050 ; OTHER: @__llvm_profile_runtime = external global i32