[InstrProfiling] Use llvm.compiler.used if applicable for Mach-O
authorFangrui Song <i@maskray.me>
Wed, 1 Sep 2021 21:46:51 +0000 (14:46 -0700)
committerFangrui Song <i@maskray.me>
Wed, 1 Sep 2021 21:46:51 +0000 (14:46 -0700)
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

compiler-rt/test/profile/Darwin/coverage-linkage.cpp [new file with mode: 0644]
compiler-rt/test/profile/Darwin/lit.local.cfg.py [new file with mode: 0644]
llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
llvm/test/Instrumentation/InstrProfiling/profiling.ll

diff --git a/compiler-rt/test/profile/Darwin/coverage-linkage.cpp b/compiler-rt/test/profile/Darwin/coverage-linkage.cpp
new file mode 100644 (file)
index 0000000..062717b
--- /dev/null
@@ -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 <stdio.h>
+
+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 (file)
index 0000000..a85dfcd
--- /dev/null
@@ -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
index a335824..83b35fa 100644 (file)
@@ -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
index f85a945..f5c0c56 100644 (file)
@@ -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() {{.*}} {