[compiler-rt] r253098 - [PGO] Ensure profile section symbols are created (linux)

Xinliang David Li via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 13 14:33:07 PST 2015


Author: davidxl
Date: Fri Nov 13 16:33:07 2015
New Revision: 253098

URL: http://llvm.org/viewvc/llvm-project?rev=253098&view=rev
Log:
[PGO] Ensure profile section symbols are created (linux)

- This is to handle a corner case where profile lib is linked
  in but non of the modules are instrumented (On linux, since
  we avoided the overhead to emit runtime hook use functions so
  this is the side effect of that size optimization).
- Added a profile runtime test case to cover all scenarios of
  shared library builds. 

Differential Revision: http://reviews.llvm.org/D14468


Added:
    compiler-rt/trunk/test/profile/Inputs/instrprof-shared-lib.c
    compiler-rt/trunk/test/profile/Inputs/instrprof-shared-main.c
    compiler-rt/trunk/test/profile/instrprof-shared.test
Modified:
    compiler-rt/trunk/lib/profile/CMakeLists.txt
    compiler-rt/trunk/lib/profile/InstrProfilingBuffer.c
    compiler-rt/trunk/lib/profile/InstrProfilingFile.c
    compiler-rt/trunk/lib/profile/InstrProfilingPlatformLinux.c

Modified: compiler-rt/trunk/lib/profile/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/CMakeLists.txt?rev=253098&r1=253097&r2=253098&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/profile/CMakeLists.txt Fri Nov 13 16:33:07 2015
@@ -11,6 +11,15 @@ set(PROFILE_SOURCES
   InstrProfilingRuntime.cc
   InstrProfilingUtil.c)
 
+if(UNIX)
+ set(EXTRA_FLAGS
+     -fPIC
+     -Wno-pedantic)
+else()
+ set(EXTRA_FLAGS
+     -fPIC)
+endif()
+
 if(APPLE)
   add_compiler_rt_runtime(clang_rt.profile
     STATIC
@@ -22,7 +31,7 @@ else()
   add_compiler_rt_runtime(clang_rt.profile
     STATIC
     ARCHS ${PROFILE_SUPPORTED_ARCH}
-    CFLAGS -fPIC
+    CFLAGS ${EXTRA_FLAGS}
     SOURCES ${PROFILE_SOURCES}
     PARENT_TARGET profile)
 endif()

Modified: compiler-rt/trunk/lib/profile/InstrProfilingBuffer.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingBuffer.c?rev=253098&r1=253097&r2=253098&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingBuffer.c (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingBuffer.c Fri Nov 13 16:33:07 2015
@@ -79,6 +79,10 @@ int __llvm_profile_write_buffer_internal
 
   /* Create the header. */
   __llvm_profile_header Header;
+
+  if (!DataSize)
+    return 0;
+
   Header.Magic = __llvm_profile_get_magic();
   Header.Version = __llvm_profile_get_version();
   Header.DataSize = DataSize;

Modified: compiler-rt/trunk/lib/profile/InstrProfilingFile.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingFile.c?rev=253098&r1=253097&r2=253098&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingFile.c (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingFile.c Fri Nov 13 16:33:07 2015
@@ -36,6 +36,10 @@ static int writeFile(FILE *File) {
 
   /* Create the header. */
   __llvm_profile_header Header;
+
+  if (!DataSize)
+    return 0;
+
   Header.Magic = __llvm_profile_get_magic();
   Header.Version = __llvm_profile_get_version();
   Header.DataSize = DataSize;

Modified: compiler-rt/trunk/lib/profile/InstrProfilingPlatformLinux.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingPlatformLinux.c?rev=253098&r1=253097&r2=253098&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingPlatformLinux.c (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingPlatformLinux.c Fri Nov 13 16:33:07 2015
@@ -21,6 +21,13 @@ extern uint64_t __stop___llvm_prf_cnts _
 extern char __start___llvm_prf_names __attribute__((visibility("hidden")));
 extern char __stop___llvm_prf_names __attribute__((visibility("hidden")));
 
+/* Add dummy data to ensure the section is always created. */
+__llvm_profile_data __llvm_prof_sect_data[0]
+    __attribute__((section("__llvm_prf_data")));
+uint64_t __llvm_prof_cnts_sect_data[0]
+    __attribute__((section("__llvm_prf_cnts")));
+char __llvm_prof_nms_sect_data[0] __attribute__((section("__llvm_prf_names")));
+
 __attribute__((visibility("hidden"))) const __llvm_profile_data *
 __llvm_profile_begin_data(void) {
   return &__start___llvm_prf_data;

Added: compiler-rt/trunk/test/profile/Inputs/instrprof-shared-lib.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/profile/Inputs/instrprof-shared-lib.c?rev=253098&view=auto
==============================================================================
--- compiler-rt/trunk/test/profile/Inputs/instrprof-shared-lib.c (added)
+++ compiler-rt/trunk/test/profile/Inputs/instrprof-shared-lib.c Fri Nov 13 16:33:07 2015
@@ -0,0 +1,9 @@
+int g1 = 0;
+int g2 = 1;
+
+void foo(int n) {
+  if (n % 5 == 0)
+    g1++;
+  else
+    g2++;
+}

Added: compiler-rt/trunk/test/profile/Inputs/instrprof-shared-main.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/profile/Inputs/instrprof-shared-main.c?rev=253098&view=auto
==============================================================================
--- compiler-rt/trunk/test/profile/Inputs/instrprof-shared-main.c (added)
+++ compiler-rt/trunk/test/profile/Inputs/instrprof-shared-main.c Fri Nov 13 16:33:07 2015
@@ -0,0 +1,13 @@
+extern int g1, g2;
+extern void foo(int n);
+
+int main() {
+  int i, j;
+  for (i = 0; i < 1000; i++)
+    for (j = 0; j < 1000; j++)
+      foo(i * j);
+
+  if (g2 - g1 == 280001)
+    return 0;
+  return 1;
+}

Added: compiler-rt/trunk/test/profile/instrprof-shared.test
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/profile/instrprof-shared.test?rev=253098&view=auto
==============================================================================
--- compiler-rt/trunk/test/profile/instrprof-shared.test (added)
+++ compiler-rt/trunk/test/profile/instrprof-shared.test Fri Nov 13 16:33:07 2015
@@ -0,0 +1,75 @@
+"""
+This test produces three shared libraries:
+
+1. libt-instr.so is instrumented
+2. libt-no-instr1.so is not instrumented
+3. libt-no-instr2.so is compiled with instrumentation enabled, but the object file is built
+   with instrumentation turned off.
+
+After the libraries are built, the main program is then built with/without instrumentation and linked
+against 3 libraries above.
+
+The test is to verify that programs linked against these shared objects with and without instrumentation
+enabled behave as expected.
+"""
+
+RUN: mkdir -p %t.d
+RUN: %clang_profgen -o %t.d/libt-instr.so -fPIC -shared %S/Inputs/instrprof-shared-lib.c
+RUN: %clang -o %t.d/libt-no-instr1.so -fPIC -shared %S/Inputs/instrprof-shared-lib.c
+RUN: %clang -c -o %t.d/instrprof-shared-lib-no-instr2.o -fPIC  %S/Inputs/instrprof-shared-lib.c
+RUN: %clang_profgen -o %t.d/libt-no-instr2.so -fPIC -shared %t.d/instrprof-shared-lib-no-instr2.o
+
+RUN: %clang_profgen -o %t-instr-instr -L%t.d -rpath %t.d -lt-instr  %S/Inputs/instrprof-shared-main.c
+RUN: %clang_profgen -o %t-instr-no-instr1 -L%t.d -rpath %t.d -lt-no-instr1  %S/Inputs/instrprof-shared-main.c
+RUN: %clang_profgen -o %t-instr-no-instr2 -L%t.d -rpath %t.d -lt-no-instr2  %S/Inputs/instrprof-shared-main.c
+RUN: %clang -o %t-no-instr1-instr -L%t.d -rpath %t.d -lt-instr  %S/Inputs/instrprof-shared-main.c
+RUN: %clang -o %t-no-instr1-no-instr1 -L%t.d -rpath %t.d -lt-no-instr1  %S/Inputs/instrprof-shared-main.c
+RUN: %clang -o %t-no-instr1-no-instr2 -L%t.d -rpath %t.d -lt-no-instr2  %S/Inputs/instrprof-shared-main.c
+RUN: %clang -c -o %t.d/instrprof-shared-main-no-instr2.o  %S/Inputs/instrprof-shared-main.c
+RUN: %clang -o %t-no-instr2-instr -L%t.d -rpath %t.d -lt-instr  %t.d/instrprof-shared-main-no-instr2.o
+RUN: %clang -o %t-no-instr2-no-instr1 -L%t.d -rpath %t.d -lt-no-instr1  %t.d/instrprof-shared-main-no-instr2.o
+RUN: %clang -o %t-no-instr2-no-instr2 -L%t.d -rpath %t.d -lt-no-instr2  %t.d/instrprof-shared-main-no-instr2.o
+
+RUN: env LLVM_PROFILE_FILE=%t-instr-instr.profraw %run %t-instr-instr
+RUN: env LLVM_PROFILE_FILE=%t-instr-no-instr1.profraw %run %t-instr-no-instr1
+RUN: env LLVM_PROFILE_FILE=%t-instr-no-instr2.profraw %run %t-instr-no-instr2
+RUN: env LLVM_PROFILE_FILE=%t-no-instr1-instr.profraw %run %t-no-instr1-instr
+RUN: env LLVM_PROFILE_FILE=%t-no-instr2-instr.profraw %run %t-no-instr2-instr
+RUN: env LLVM_PROFILE_FILE=%t-no-instr1-no-instr1.profraw %run %t-no-instr1-no-instr1
+RUN: env LLVM_PROFILE_FILE=%t-no-instr1-no-instr2.profraw %run %t-no-instr1-no-instr2
+RUN: env LLVM_PROFILE_FILE=%t-no-instr2-no-instr1.profraw %run %t-no-instr2-no-instr1
+RUN: env LLVM_PROFILE_FILE=%t-no-instr2-no-instr2.profraw %run %t-no-instr2-no-instr2
+
+RUN: llvm-profdata merge -o %t-instr-instr.profdata %t-instr-instr.profraw
+RUN: llvm-profdata merge -o %t-instr-no-instr1.profdata %t-instr-no-instr1.profraw
+RUN: llvm-profdata merge -o %t-instr-no-instr2.profdata %t-instr-no-instr2.profraw
+RUN: llvm-profdata merge -o %t-no-instr1-instr.profdata %t-no-instr1-instr.profraw
+RUN: llvm-profdata merge -o %t-no-instr2-instr.profdata %t-no-instr2-instr.profraw
+
+RUN: not llvm-profdata merge -o %t-no-instr1-no-instr1.profdata %t-no-instr1-no-instr1.profraw 2>&1 | FileCheck %s --check-prefix=MISSING-FILE
+RUN: not llvm-profdata merge -o %t-no-instr2-no-instr1.profdata %t-no-instr2-no-instr1.profraw 2>&1 | FileCheck %s --check-prefix=MISSING-FILE
+MISSING-FILE: profraw
+
+RUN: llvm-profdata show -counts --function main %t-instr-instr.profdata | grep -v 'Total\|Maximum' > %t-main-1
+RUN: llvm-profdata show -counts --function main %t-instr-no-instr1.profdata | grep -v 'Total\|Maximum' > %t-main-2
+RUN: llvm-profdata show -counts --function main %t-instr-no-instr2.profdata | grep -v 'Total\|Maximum' > %t-main-3
+RUN: llvm-profdata show -counts --function foo %t-instr-instr.profdata | grep -v 'Total\|Maximum' > %t-foo-1
+RUN: llvm-profdata show -counts --function foo %t-no-instr1-instr.profdata | grep -v 'Total\|Maximum' > %t-foo-2
+RUN: llvm-profdata show -counts --function foo %t-no-instr2-instr.profdata | grep -v 'Total\|Maximum'  > %t-foo-3
+
+RUN: %clang_profuse=%t-instr-instr.profdata -o %t-main-instr-instr.ll -S -emit-llvm %S/Inputs/instrprof-shared-main.c
+RUN: %clang_profuse=%t-instr-no-instr1.profdata -o %t-main-instr-no-instr1.ll -S -emit-llvm %S/Inputs/instrprof-shared-main.c
+RUN: %clang_profuse=%t-instr-no-instr2.profdata -o %t-main-instr-no-instr2.ll -S -emit-llvm %S/Inputs/instrprof-shared-main.c
+RUN: %clang_profuse=%t-instr-instr.profdata -o %t-lib-instr-instr.ll -S -emit-llvm %S/Inputs/instrprof-shared-lib.c
+RUN: %clang_profuse=%t-no-instr1-instr.profdata -o %t-lib-no-instr1-instr.ll -S -emit-llvm %S/Inputs/instrprof-shared-lib.c
+RUN: %clang_profuse=%t-no-instr2-instr.profdata -o %t-lib-no-instr2-instr.ll -S -emit-llvm %S/Inputs/instrprof-shared-lib.c
+RUN: %clang_profuse=%t-instr-instr.profdata -o %t-lib-instr-instr.ll -S -emit-llvm %S/Inputs/instrprof-shared-lib.c
+
+RUN: diff %t-main-instr-no-instr1.ll %t-main-instr-no-instr2.ll
+RUN: diff %t-lib-no-instr1-instr.ll %t-lib-no-instr2-instr.ll
+
+RUN: diff %t-main-1 %t-main-2
+RUN: diff %t-main-1 %t-main-3
+RUN: diff %t-foo-1 %t-foo-2
+RUN: diff %t-foo-1 %t-foo-3
+




More information about the llvm-commits mailing list