[InstrProfiling] If no value profiling, make data variable private and (for Windows) use one comdat

`__profd_*` variables are referenced by code only when value profiling is
enabled. If disabled (e.g. default -fprofile-instr-generate), the symbols just
waste space on ELF/Mach-O. We change the comdat symbol from `__profd_*` to
`__profc_*` because an internal symbol does not provide deduplication features
on COFF. The choice doesn't matter on ELF.

(In -DLLVM_BUILD_INSTRUMENTED_COVERAGE=on build, there is now no `__profd_*` symbols.)

On Windows this enables further optimization. We are no longer affected by the
link.exe limitation: an external symbol in IMAGE_COMDAT_SELECT_ASSOCIATIVE can
cause duplicate definition error.
https://lists.llvm.org/pipermail/llvm-dev/2021-May/150758.html
We can thus use llvm.compiler.used instead of llvm.used like ELF (D97585).
This avoids many `/INCLUDE:` directives in `.drectve`.

Here is rnk's measurement for Chrome:
```
This reduced object file size of base_unittests.exe, compiled with coverage, optimizations, and gmlt debug info by 10%:

#BEFORE

$ find . -iname '*.obj' | xargs du -b | awk '{ sum += $1 } END { print sum}'
1047758867

$ du -cksh base_unittests.exe
82M     base_unittests.exe
82M     total

# AFTER

$ find . -iname '*.obj' | xargs du -b | awk '{ sum += $1 } END { print sum}'
937886499

$ du -cksh base_unittests.exe
78M     base_unittests.exe
78M     total
```

The change is NFC for Mach-O.

Reviewed By: davidxl, rnk

Differential Revision: https://reviews.llvm.org/D103372
This commit is contained in:
Fangrui Song 2021-06-04 13:27:56 -07:00
parent ca68f3bc48
commit 9e51d1f348
7 changed files with 87 additions and 56 deletions

View File

@ -748,8 +748,8 @@ static std::string getVarName(InstrProfIncrementInst *Inc, StringRef Prefix) {
return (Prefix + Name + "." + Twine(FuncHash)).str(); return (Prefix + Name + "." + Twine(FuncHash)).str();
} }
static uint64_t getIntModuleFlagOrZero(Module *M, StringRef Flag) { static uint64_t getIntModuleFlagOrZero(const Module &M, StringRef Flag) {
auto *MD = dyn_cast_or_null<ConstantAsMetadata>(M->getModuleFlag(Flag)); auto *MD = dyn_cast_or_null<ConstantAsMetadata>(M.getModuleFlag(Flag));
if (!MD) if (!MD)
return 0; return 0;
@ -758,15 +758,23 @@ static uint64_t getIntModuleFlagOrZero(Module *M, StringRef Flag) {
return cast<ConstantInt>(MD->getValue())->getZExtValue(); return cast<ConstantInt>(MD->getValue())->getZExtValue();
} }
static bool enablesValueProfiling(const Module &M) {
return isIRPGOFlagSet(&M) ||
getIntModuleFlagOrZero(M, "EnableValueProfiling") != 0;
}
// Conservatively returns true if data variables may be referenced by code.
static bool profDataReferencedByCode(const Module &M) {
return enablesValueProfiling(M);
}
static inline bool shouldRecordFunctionAddr(Function *F) { static inline bool shouldRecordFunctionAddr(Function *F) {
// Only record function addresses if IR PGO is enabled or if clang value // Only record function addresses if IR PGO is enabled or if clang value
// profiling is enabled. Recording function addresses greatly increases object // profiling is enabled. Recording function addresses greatly increases object
// file size, because it prevents the inliner from deleting functions that // file size, because it prevents the inliner from deleting functions that
// have been inlined everywhere. // have been inlined everywhere.
if (!isIRPGOFlagSet(F->getParent()) && if (!profDataReferencedByCode(*F->getParent()))
getIntModuleFlagOrZero(F->getParent(), "EnableValueProfiling") == 0) {
return false; return false;
}
// Check the linkage // Check the linkage
bool HasAvailableExternallyLinkage = F->hasAvailableExternallyLinkage(); bool HasAvailableExternallyLinkage = F->hasAvailableExternallyLinkage();
@ -834,21 +842,25 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
// of the parent function, that will result in relocations against discarded // of the parent function, that will result in relocations against discarded
// sections. // sections.
// //
// For COFF, put the counters, data, and values each into their own // If the data variable is referenced by code, counters and data have to be
// comdats. We can't use a group because the Visual C++ linker will // in different comdats for COFF because the Visual C++ linker will report
// report duplicate symbol errors if there are multiple external symbols // duplicate symbol errors if there are multiple external symbols with the
// with the same name marked IMAGE_COMDAT_SELECT_ASSOCIATIVE. // same name marked IMAGE_COMDAT_SELECT_ASSOCIATIVE.
// //
// For ELF, when not using COMDAT, put counters, data and values into a // 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 // noduplicates COMDAT which is lowered to a zero-flag section group. This
// allows -z start-stop-gc to discard the entire group when the function is // allows -z start-stop-gc to discard the entire group when the function is
// discarded. // discarded.
bool DataReferencedByCode = profDataReferencedByCode(*M);
bool NeedComdat = needsComdatForCounter(*Fn, *M); bool NeedComdat = needsComdatForCounter(*Fn, *M);
std::string CntsVarName = getVarName(Inc, getInstrProfCountersVarPrefix());
std::string DataVarName = getVarName(Inc, getInstrProfDataVarPrefix()); std::string DataVarName = getVarName(Inc, getInstrProfDataVarPrefix());
auto MaybeSetComdat = [=](GlobalVariable *GV) { auto MaybeSetComdat = [&](GlobalVariable *GV) {
bool UseComdat = (NeedComdat || TT.isOSBinFormatELF()); bool UseComdat = (NeedComdat || TT.isOSBinFormatELF());
if (UseComdat) { if (UseComdat) {
auto GroupName = TT.isOSBinFormatCOFF() ? GV->getName() : DataVarName; StringRef GroupName = TT.isOSBinFormatCOFF() && DataReferencedByCode
? GV->getName()
: CntsVarName;
Comdat *C = M->getOrInsertComdat(GroupName); Comdat *C = M->getOrInsertComdat(GroupName);
if (!NeedComdat) if (!NeedComdat)
C->setSelectionKind(Comdat::NoDuplicates); C->setSelectionKind(Comdat::NoDuplicates);
@ -863,8 +875,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
// Create the counters variable. // Create the counters variable.
auto *CounterPtr = auto *CounterPtr =
new GlobalVariable(*M, CounterTy, false, Linkage, new GlobalVariable(*M, CounterTy, false, Linkage,
Constant::getNullValue(CounterTy), Constant::getNullValue(CounterTy), CntsVarName);
getVarName(Inc, getInstrProfCountersVarPrefix()));
CounterPtr->setVisibility(Visibility); CounterPtr->setVisibility(Visibility);
CounterPtr->setSection( CounterPtr->setSection(
getInstrProfSectionName(IPSK_cnts, TT.getObjectFormat())); getInstrProfSectionName(IPSK_cnts, TT.getObjectFormat()));
@ -918,6 +929,13 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
#define INSTR_PROF_DATA(Type, LLVMType, Name, Init) Init, #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) Init,
#include "llvm/ProfileData/InstrProfData.inc" #include "llvm/ProfileData/InstrProfData.inc"
}; };
// If code never references data variables (the symbol is unneeded), and
// linker GC cannot discard data variables while the text section is retained,
// data variables can be private. This optimization applies on COFF and ELF.
if (!DataReferencedByCode && !TT.isOSBinFormatMachO()) {
Linkage = GlobalValue::PrivateLinkage;
Visibility = GlobalValue::DefaultVisibility;
}
auto *Data = auto *Data =
new GlobalVariable(*M, DataTy, false, Linkage, new GlobalVariable(*M, DataTy, false, Linkage,
ConstantStruct::get(DataTy, DataVals), DataVarName); ConstantStruct::get(DataTy, DataVals), DataVarName);
@ -1109,9 +1127,12 @@ void InstrProfiling::emitUses() {
// we conservatively retain all unconditionally in the compiler. // we conservatively retain all unconditionally in the compiler.
// //
// On ELF, the linker can guarantee the associated sections will be retained // On ELF, the linker can guarantee the associated sections will be retained
// or discarded as a unit, so llvm.compiler.used is sufficient. Otherwise, // or discarded as a unit, so llvm.compiler.used is sufficient. Similarly on
// conservatively make all of them retained by the linker. // COFF, if prof data is not referenced by code we use one comdat and ensure
if (TT.isOSBinFormatELF()) // this GC property as well. Otherwise, we have to conservatively make all of
// the sections retained by the linker.
if (TT.isOSBinFormatELF() ||
(TT.isOSBinFormatCOFF() && !profDataReferencedByCode(*M)))
appendToCompilerUsed(*M, CompilerUsedVars); appendToCompilerUsed(*M, CompilerUsedVars);
else else
appendToUsed(*M, CompilerUsedVars); appendToUsed(*M, CompilerUsedVars);

View File

@ -22,26 +22,36 @@ $foo_extern = comdat any
@__profn_foo_inline = linkonce_odr hidden constant [10 x i8] c"foo_inline" @__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" @__profn_foo_extern = linkonce_odr hidden constant [10 x i8] c"foo_extern"
; ELF: @__profc_foo_inline = linkonce_odr hidden global {{.*}}, section "__llvm_prf_cnts", comdat($__profd_foo_inline), align 8 ;; When value profiling is disabled, __profd_ variables are not referenced by
; ELF: @__profd_foo_inline = linkonce_odr hidden global {{.*}}, section "__llvm_prf_data", comdat, align 8 ;; code. We can use private linkage. When enabled, __profd_ needs to be
; COFF: @__profc_foo_inline = linkonce_odr hidden global {{.*}}, section ".lprfc$M", comdat, align 8 ;; non-local which requires separate comdat on COFF due to a link.exe limitation.
; COFF: @__profd_foo_inline = linkonce_odr hidden global {{.*}}, section ".lprfd$M", comdat, align 8
; ELF: @__profc_foo_inline = linkonce_odr hidden global {{.*}}, section "__llvm_prf_cnts", comdat, align 8
; ELF0: @__profd_foo_inline = private global {{.*}}, section "__llvm_prf_data", comdat($__profc_foo_inline), align 8
; ELF1: @__profd_foo_inline = linkonce_odr hidden global {{.*}}, section "__llvm_prf_data", comdat($__profc_foo_inline), align 8
; COFF0: @__profc_foo_inline = linkonce_odr hidden global {{.*}}, section ".lprfc$M", comdat, align 8
; COFF0: @__profd_foo_inline = private global {{.*}}, section ".lprfd$M", comdat($__profc_foo_inline), align 8
; COFF1: @__profc_foo_inline = linkonce_odr hidden global {{.*}}, section ".lprfc$M", comdat, align 8
; COFF1: @__profd_foo_inline = linkonce_odr hidden global {{.*}}, section ".lprfd$M", comdat, align 8
define weak_odr void @foo_inline() comdat { 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) 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 ret void
} }
; ELF: @__profc_foo_extern = linkonce_odr hidden global{{.*}}, section "__llvm_prf_cnts", comdat($__profd_foo_extern), align 8 ; ELF: @__profc_foo_extern = linkonce_odr hidden global{{.*}}, section "__llvm_prf_cnts", comdat, align 8
; ELF: @__profd_foo_extern = linkonce_odr hidden global{{.*}}, section "__llvm_prf_data", comdat, align 8 ; ELF0: @__profd_foo_extern = private global{{.*}}, section "__llvm_prf_data", comdat($__profc_foo_extern), align 8
; ELF1: @__profd_foo_extern = linkonce_odr hidden global{{.*}}, section "__llvm_prf_data", comdat($__profc_foo_extern), align 8
; COFF: @__profc_foo_extern = linkonce_odr hidden global{{.*}}, section ".lprfc$M", comdat, 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, align 8 ; COFF0: @__profd_foo_extern = private global{{.*}}, section ".lprfd$M", comdat($__profc_foo_extern), align 8
; COFF1: @__profd_foo_extern = linkonce_odr hidden global{{.*}}, section ".lprfd$M", comdat, align 8
define available_externally void @foo_extern() { 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) 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 ret void
} }
; ELF: @llvm.compiler.used = appending global {{.*}} @__profd_foo_inline {{.*}} @__profd_foo_extern ; ELF: @llvm.compiler.used = appending global {{.*}} @__profd_foo_inline {{.*}} @__profd_foo_extern
; COFF: @llvm.used = appending global {{.*}} @__llvm_profile_runtime_user {{.*}} @__profd_foo_inline {{.*}} @__profd_foo_extern ; COFF0: @llvm.compiler.used = appending global {{.*}} @__llvm_profile_runtime_user {{.*}} @__profd_foo_inline {{.*}} @__profd_foo_extern
; COFF1: @llvm.used = appending global {{.*}} @__llvm_profile_runtime_user {{.*}} @__profd_foo_inline {{.*}} @__profd_foo_extern
;--- disable.ll ;--- disable.ll
!llvm.module.flags = !{!0} !llvm.module.flags = !{!0}

View File

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

View File

@ -12,11 +12,11 @@
; MACHO: @__llvm_profile_runtime = external global i32 ; MACHO: @__llvm_profile_runtime = external global i32
; ELF-NOT: @__llvm_profile_runtime = external global i32 ; ELF-NOT: @__llvm_profile_runtime = external global i32
; ELF: $__profd_foo = comdat noduplicates ; ELF: $__profc_foo = comdat noduplicates
; ELF: $__profd_foo_weak = comdat noduplicates ; ELF: $__profc_foo_weak = comdat noduplicates
; ELF: $"__profd_linkage.ll:foo_internal" = comdat noduplicates ; ELF: $"__profc_linkage.ll:foo_internal" = comdat noduplicates
; ELF: $__profd_foo_inline = comdat noduplicates ; ELF: $__profc_foo_inline = comdat noduplicates
; ELF: $__profd_foo_extern = comdat any ; ELF: $__profc_foo_extern = comdat any
@__profn_foo = private constant [3 x i8] c"foo" @__profn_foo = private constant [3 x i8] c"foo"
@__profn_foo_weak = weak hidden constant [8 x i8] c"foo_weak" @__profn_foo_weak = weak hidden constant [8 x i8] c"foo_weak"
@ -24,8 +24,8 @@
@__profn_foo_inline = linkonce_odr hidden constant [10 x i8] c"foo_inline" @__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" @__profn_foo_extern = linkonce_odr hidden constant [10 x i8] c"foo_extern"
; ELF: @__profc_foo = private global {{.*}} section "__llvm_prf_cnts", comdat($__profd_foo), align 8 ; ELF: @__profc_foo = private global {{.*}} section "__llvm_prf_cnts", comdat
; ELF: @__profd_foo = private global {{.*}} section "__llvm_prf_data", comdat, align 8 ; ELF: @__profd_foo = private global {{.*}} section "__llvm_prf_data", comdat($__profc_foo)
; MACHO: @__profc_foo = private global ; MACHO: @__profc_foo = private global
; MACHO: @__profd_foo = private global ; MACHO: @__profd_foo = private global
; COFF: @__profc_foo = private global ; COFF: @__profc_foo = private global
@ -36,19 +36,19 @@ define void @foo() {
ret void ret void
} }
; ELF: @__profc_foo_weak = weak hidden global {{.*}} section "__llvm_prf_cnts", comdat($__profd_foo_weak), align 8 ; ELF: @__profc_foo_weak = weak hidden global{{.*}}section "__llvm_prf_cnts", comdat, align 8
; ELF: @__profd_foo_weak = weak hidden global {{.*}} section "__llvm_prf_data", comdat, align 8 ; ELF: @__profd_foo_weak = private global{{.*}}section "__llvm_prf_data", comdat($__profc_foo_weak)
; MACHO: @__profc_foo_weak = weak hidden global ; MACHO: @__profc_foo_weak = weak hidden global
; MACHO: @__profd_foo_weak = weak hidden global ; MACHO: @__profd_foo_weak = weak hidden global
; COFF: @__profc_foo_weak = weak hidden global ; COFF: @__profc_foo_weak = weak hidden global
; COFF: @__profd_foo_weak = weak hidden global ; COFF: @__profd_foo_weak = private global
define weak void @foo_weak() { define weak void @foo_weak() {
call void @llvm.instrprof.increment(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @__profn_foo_weak, i32 0, i32 0), i64 0, i32 1, i32 0) call void @llvm.instrprof.increment(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @__profn_foo_weak, i32 0, i32 0), i64 0, i32 1, i32 0)
ret void ret void
} }
; ELF: @"__profc_linkage.ll:foo_internal" = private global {{.*}} section "__llvm_prf_cnts", comdat($"__profd_linkage.ll:foo_internal"), align 8 ; ELF: @"__profc_linkage.ll:foo_internal" = private global{{.*}}section "__llvm_prf_cnts", comdat, align 8
; ELF: @"__profd_linkage.ll:foo_internal" = private global {{.*}} section "__llvm_prf_data", comdat, align 8 ; ELF: @"__profd_linkage.ll:foo_internal" = private global{{.*}}section "__llvm_prf_data", comdat($"__profc_linkage.ll:foo_internal"), align 8
; MACHO: @"__profc_linkage.ll:foo_internal" = private global ; MACHO: @"__profc_linkage.ll:foo_internal" = private global
; MACHO: @"__profd_linkage.ll:foo_internal" = private global ; MACHO: @"__profd_linkage.ll:foo_internal" = private global
; COFF: @"__profc_linkage.ll:foo_internal" = private global ; COFF: @"__profc_linkage.ll:foo_internal" = private global
@ -58,23 +58,23 @@ define internal void @foo_internal() {
ret void ret void
} }
; ELF: @__profc_foo_inline = linkonce_odr hidden global {{.*}} section "__llvm_prf_cnts", comdat($__profd_foo_inline), align 8 ; ELF: @__profc_foo_inline = linkonce_odr hidden global{{.*}}section "__llvm_prf_cnts", comdat, align 8
; ELF: @__profd_foo_inline = linkonce_odr hidden global {{.*}} section "__llvm_prf_data", comdat, align 8 ; ELF: @__profd_foo_inline = private global{{.*}}section "__llvm_prf_data", comdat($__profc_foo_inline), align 8
; MACHO: @__profc_foo_inline = linkonce_odr hidden global ; MACHO: @__profc_foo_inline = linkonce_odr hidden global
; MACHO: @__profd_foo_inline = linkonce_odr hidden global ; MACHO: @__profd_foo_inline = linkonce_odr hidden global
; COFF: @__profc_foo_inline = linkonce_odr hidden global{{.*}} section ".lprfc$M", align 8 ; COFF: @__profc_foo_inline = linkonce_odr hidden global{{.*}} section ".lprfc$M", align 8
; COFF: @__profd_foo_inline = linkonce_odr hidden global{{.*}} section ".lprfd$M", align 8 ; COFF: @__profd_foo_inline = private global{{.*}} section ".lprfd$M", align 8
define linkonce_odr void @foo_inline() { define linkonce_odr void @foo_inline() {
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) 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 ret void
} }
; ELF: @__profc_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_cnts", comdat($__profd_foo_extern), align 8 ; ELF: @__profc_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_cnts", comdat, align 8
; ELF: @__profd_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_data", comdat, align 8 ; ELF: @__profd_foo_extern = private global {{.*}}section "__llvm_prf_data", comdat($__profc_foo_extern), align 8
; MACHO: @__profc_foo_extern = linkonce_odr hidden global ; MACHO: @__profc_foo_extern = linkonce_odr hidden global
; MACHO: @__profd_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 ; 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, align 8 ; COFF: @__profd_foo_extern = private global {{.*}}section ".lprfd$M", comdat($__profc_foo_extern), align 8
define available_externally void @foo_extern() { 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) 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 ret void

View File

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

View File

@ -17,8 +17,8 @@
@__profn_baz = private constant [3 x i8] c"baz" @__profn_baz = private constant [3 x i8] c"baz"
; CHECK-NOT: __profn_baz ; CHECK-NOT: __profn_baz
; ELF: @__profc_foo = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat($__profd_foo), align 8 ; ELF: @__profc_foo = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8
; ELF: @__profd_foo = private {{.*}}, section "__llvm_prf_data", comdat, align 8 ; ELF: @__profd_foo = private {{.*}}, section "__llvm_prf_data", comdat($__profc_foo), align 8
; MACHO: @__profc_foo = private global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 ; MACHO: @__profc_foo = private global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
; MACHO: @__profd_foo = private {{.*}}, section "__DATA,__llvm_prf_data,regular,live_support", align 8 ; MACHO: @__profd_foo = private {{.*}}, section "__DATA,__llvm_prf_data,regular,live_support", align 8
; WIN: @__profc_foo = private global [1 x i64] zeroinitializer, section ".lprfc$M", align 8 ; WIN: @__profc_foo = private global [1 x i64] zeroinitializer, section ".lprfc$M", align 8
@ -28,8 +28,8 @@ define void @foo() {
ret void ret void
} }
; ELF: @__profc_bar = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat($__profd_bar), align 8 ; ELF: @__profc_bar = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8
; ELF: @__profd_bar = private {{.*}}, section "__llvm_prf_data", comdat, align 8 ; ELF: @__profd_bar = private {{.*}}, section "__llvm_prf_data", comdat($__profc_bar), align 8
; MACHO: @__profc_bar = private global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 ; MACHO: @__profc_bar = private global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
; MACHO: @__profd_bar = private {{.*}}, section "__DATA,__llvm_prf_data,regular,live_support", align 8 ; MACHO: @__profd_bar = private {{.*}}, section "__DATA,__llvm_prf_data,regular,live_support", align 8
; WIN: @__profc_bar = private global [1 x i64] zeroinitializer, section ".lprfc$M", align 8 ; WIN: @__profc_bar = private global [1 x i64] zeroinitializer, section ".lprfc$M", align 8
@ -39,8 +39,8 @@ define void @bar() {
ret void ret void
} }
; ELF: @__profc_baz = private global [3 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat($__profd_baz), align 8 ; ELF: @__profc_baz = private global [3 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8
; ELF: @__profd_baz = private {{.*}}, section "__llvm_prf_data", comdat, align 8 ; ELF: @__profd_baz = private {{.*}}, section "__llvm_prf_data", comdat($__profc_baz), align 8
; MACHO: @__profc_baz = private global [3 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 ; MACHO: @__profc_baz = private global [3 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
; MACHO: @__profd_baz = private {{.*}}, section "__DATA,__llvm_prf_data,regular,live_support", align 8 ; MACHO: @__profd_baz = private {{.*}}, section "__DATA,__llvm_prf_data,regular,live_support", align 8
; WIN: @__profc_baz = private global [3 x i64] zeroinitializer, section ".lprfc$M", align 8 ; WIN: @__profc_baz = private global [3 x i64] zeroinitializer, section ".lprfc$M", align 8
@ -56,7 +56,7 @@ declare void @llvm.instrprof.increment(i8*, i64, i32, i32)
; ELF: @llvm.compiler.used = appending global {{.*}} @__llvm_profile_runtime_user {{.*}} @__profd_foo {{.*}} @__profd_bar {{.*}} @__profd_baz ; ELF: @llvm.compiler.used = appending global {{.*}} @__llvm_profile_runtime_user {{.*}} @__profd_foo {{.*}} @__profd_bar {{.*}} @__profd_baz
; MACHO: @llvm.used = appending global {{.*}} @__llvm_profile_runtime_user {{.*}} @__profd_foo {{.*}} @__profd_bar {{.*}} @__profd_baz ; MACHO: @llvm.used = appending global {{.*}} @__llvm_profile_runtime_user {{.*}} @__profd_foo {{.*}} @__profd_bar {{.*}} @__profd_baz
; WIN: @llvm.used = appending global {{.*}} @__llvm_profile_runtime_user {{.*}} @__profd_foo {{.*}} @__profd_bar {{.*}} @__profd_baz ; WIN: @llvm.compiler.used = appending global {{.*}} @__llvm_profile_runtime_user {{.*}} @__profd_foo {{.*}} @__profd_bar {{.*}} @__profd_baz
; ELF_GENERIC: define internal void @__llvm_profile_register_functions() unnamed_addr { ; ELF_GENERIC: define internal void @__llvm_profile_register_functions() unnamed_addr {
; ELF_GENERIC-NEXT: call void @__llvm_profile_register_function(i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [2 x i16] }* @__profd_foo to i8*)) ; ELF_GENERIC-NEXT: call void @__llvm_profile_register_function(i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [2 x i16] }* @__profd_foo to i8*))

View File

@ -7,16 +7,16 @@ $foo = comdat any
; CHECK: $foo = comdat any ; CHECK: $foo = comdat any
; CHECK: $__llvm_profile_raw_version = comdat any ; CHECK: $__llvm_profile_raw_version = comdat any
; CHECK: $__profd__stdin__foo.[[FOO_HASH:[0-9]+]] = comdat any ; CHECK: $__profc__stdin__foo.[[#FOO_HASH:]] = comdat any
@bar = global i32 ()* @foo, align 8 @bar = global i32 ()* @foo, align 8
; CHECK: @__llvm_profile_raw_version = constant i64 {{[0-9]+}}, comdat ; CHECK: @__llvm_profile_raw_version = constant i64 {{[0-9]+}}, comdat
; CHECK-NOT: __profn__stdin__foo ; CHECK-NOT: __profn__stdin__foo
; CHECK: @__profc__stdin__foo.[[FOO_HASH]] = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat($__profd__stdin__foo.[[FOO_HASH]]), align 8 ; CHECK: @__profc__stdin__foo.[[#FOO_HASH]] = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8
; CHECK: @__profd__stdin__foo.[[FOO_HASH]] = private global { i64, i64, i64*, i8*, i8*, i32, [2 x i16] } { i64 -5640069336071256030, i64 [[FOO_HASH]], i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__stdin__foo.[[FOO_HASH]], i32 0, i32 0), i8* null ; CHECK: @__profd__stdin__foo.[[#FOO_HASH]] = private global { i64, i64, i64*, i8*, i8*, i32, [2 x i16] } { i64 -5640069336071256030, i64 [[#FOO_HASH]], i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__stdin__foo.[[#FOO_HASH]], i32 0, i32 0), i8* null
; CHECK-NOT: bitcast (i32 ()* @foo to i8*) ; CHECK-NOT: bitcast (i32 ()* @foo to i8*)
; CHECK-SAME: , i8* null, i32 1, [2 x i16] zeroinitializer }, section "__llvm_prf_data", comdat, align 8 ; CHECK-SAME: , i8* null, i32 1, [2 x i16] zeroinitializer }, section "__llvm_prf_data", comdat($__profc__stdin__foo.[[#FOO_HASH]]), align 8
; CHECK: @__llvm_prf_nm ; CHECK: @__llvm_prf_nm
; CHECK: @llvm.compiler.used ; CHECK: @llvm.compiler.used