From 68745a557e9454c0f54011b9eea139f04b699b69 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 1 Sep 2021 14:46:51 -0700 Subject: [PATCH] [InstrProfiling] Use llvm.compiler.used if applicable for Mach-O Similar to D97585. D25456 used `S_ATTR_LIVE_SUPPORT` to ensure the data variable will be retained or discarded as a unit with the counter variable, so llvm.compiler.used is sufficient. It allows ld to dead strip unneeded profc and profd variables. Reviewed By: vsk Differential Revision: https://reviews.llvm.org/D105445 --- .../test/profile/Darwin/coverage-linkage.cpp | 46 ++++++++++++++++++++++ compiler-rt/test/profile/Darwin/lit.local.cfg.py | 9 +++++ .../Transforms/Instrumentation/InstrProfiling.cpp | 12 +++--- .../Instrumentation/InstrProfiling/profiling.ll | 2 +- 4 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 compiler-rt/test/profile/Darwin/coverage-linkage.cpp create mode 100644 compiler-rt/test/profile/Darwin/lit.local.cfg.py diff --git a/compiler-rt/test/profile/Darwin/coverage-linkage.cpp b/compiler-rt/test/profile/Darwin/coverage-linkage.cpp new file mode 100644 index 0000000..062717b --- /dev/null +++ b/compiler-rt/test/profile/Darwin/coverage-linkage.cpp @@ -0,0 +1,46 @@ +/// Test instrumentation can handle various linkages. +// RUN: %clang_profgen -fcoverage-mapping %s -o %t +// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t +// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s + +// RUN: %clang_profgen -fcoverage-mapping -Wl,-dead_strip %s -o %t +// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t +// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s + +// CHECK: {{.*}}external{{.*}}: +// CHECK-NEXT: Hash: +// CHECK-NEXT: Counters: 1 +// CHECK-NEXT: Function count: 1 +// CHECK: {{.*}}weak{{.*}}: +// CHECK-NEXT: Hash: +// CHECK-NEXT: Counters: 1 +// CHECK-NEXT: Function count: 1 +// CHECK: main: +// CHECK-NEXT: Hash: +// CHECK-NEXT: Counters: 1 +// CHECK-NEXT: Function count: 1 +// CHECK: {{.*}}internal{{.*}}: +// CHECK-NEXT: Hash: +// CHECK-NEXT: Counters: 1 +// CHECK-NEXT: Function count: 1 +// CHECK: {{.*}}linkonce_odr{{.*}}: +// CHECK-NEXT: Hash: +// CHECK-NEXT: Counters: 1 +// CHECK-NEXT: Function count: 1 + +#include + +void discarded0() {} +__attribute__((weak)) void discarded1() {} + +void external() { puts("external"); } +__attribute__((weak)) void weak() { puts("weak"); } +static void internal() { puts("internal"); } +__attribute__((noinline)) inline void linkonce_odr() { puts("linkonce_odr"); } + +int main() { + internal(); + external(); + weak(); + linkonce_odr(); +} diff --git a/compiler-rt/test/profile/Darwin/lit.local.cfg.py b/compiler-rt/test/profile/Darwin/lit.local.cfg.py new file mode 100644 index 0000000..a85dfcd2 --- /dev/null +++ b/compiler-rt/test/profile/Darwin/lit.local.cfg.py @@ -0,0 +1,9 @@ +def getRoot(config): + if not config.parent: + return config + return getRoot(config.parent) + +root = getRoot(config) + +if root.host_os not in ['Darwin']: + config.unsupported = True diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp index a335824..83b35fa 100644 --- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -1178,12 +1178,12 @@ void InstrProfiling::emitUses() { // GlobalOpt/ConstantMerge) may not discard associated sections as a unit, so // we conservatively retain all unconditionally in the compiler. // - // On ELF, the linker can guarantee the associated sections will be retained - // or discarded as a unit, so llvm.compiler.used is sufficient. Similarly on - // COFF, if prof data is not referenced by code we use one comdat and ensure - // this GC property as well. Otherwise, we have to conservatively make all of - // the sections retained by the linker. - if (TT.isOSBinFormatELF() || + // On ELF and Mach-O, the linker can guarantee the associated sections will be + // retained or discarded as a unit, so llvm.compiler.used is sufficient. + // Similarly on COFF, if prof data is not referenced by code we use one comdat + // and ensure this GC property as well. Otherwise, we have to conservatively + // make all of the sections retained by the linker. + if (TT.isOSBinFormatELF() || TT.isOSBinFormatMachO() || (TT.isOSBinFormatCOFF() && !profDataReferencedByCode(*M))) appendToCompilerUsed(*M, CompilerUsedVars); else diff --git a/llvm/test/Instrumentation/InstrProfiling/profiling.ll b/llvm/test/Instrumentation/InstrProfiling/profiling.ll index f85a945..f5c0c56 100644 --- a/llvm/test/Instrumentation/InstrProfiling/profiling.ll +++ b/llvm/test/Instrumentation/InstrProfiling/profiling.ll @@ -82,7 +82,7 @@ declare void @llvm.instrprof.increment(i8*, i64, i32, i32) ; ELF: @llvm.compiler.used = appending global {{.*}} @__profd_foo {{.*}} ; ELF_GENERIC: @llvm.compiler.used = appending global {{.*}} @__llvm_profile_runtime {{.*}} @__profd_foo {{.*}} -; MACHO: @llvm.used = appending global {{.*}} @__llvm_profile_runtime_user {{.*}} @__profd_foo {{.*}} +; MACHO: @llvm.compiler.used = appending global {{.*}} @__llvm_profile_runtime_user {{.*}} @__profd_foo {{.*}} ; COFF: @llvm.compiler.used = appending global {{.*}} @__llvm_profile_runtime_user {{.*}} @__profd_foo {{.*}} ; MACHO: define linkonce_odr hidden i32 @__llvm_profile_runtime_user() {{.*}} { -- 2.7.4