summaryrefslogtreecommitdiffstats
path: root/compiler-rt
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt')
-rw-r--r--compiler-rt/lib/profile/CMakeLists.txt11
-rw-r--r--compiler-rt/lib/profile/InstrProfilingBuffer.c4
-rw-r--r--compiler-rt/lib/profile/InstrProfilingFile.c4
-rw-r--r--compiler-rt/lib/profile/InstrProfilingPlatformLinux.c7
-rw-r--r--compiler-rt/test/profile/Inputs/instrprof-shared-lib.c9
-rw-r--r--compiler-rt/test/profile/Inputs/instrprof-shared-main.c13
-rw-r--r--compiler-rt/test/profile/instrprof-shared.test75
7 files changed, 122 insertions, 1 deletions
diff --git a/compiler-rt/lib/profile/CMakeLists.txt b/compiler-rt/lib/profile/CMakeLists.txt
index 6b37b39b4ff..9c518afff58 100644
--- a/compiler-rt/lib/profile/CMakeLists.txt
+++ b/compiler-rt/lib/profile/CMakeLists.txt
@@ -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()
diff --git a/compiler-rt/lib/profile/InstrProfilingBuffer.c b/compiler-rt/lib/profile/InstrProfilingBuffer.c
index e587932da0a..620c1755baa 100644
--- a/compiler-rt/lib/profile/InstrProfilingBuffer.c
+++ b/compiler-rt/lib/profile/InstrProfilingBuffer.c
@@ -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;
diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c
index 6af835e484a..318648e446b 100644
--- a/compiler-rt/lib/profile/InstrProfilingFile.c
+++ b/compiler-rt/lib/profile/InstrProfilingFile.c
@@ -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;
diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
index 7a74e0e45fb..282d6b4a9e0 100644
--- a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
+++ b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
@@ -21,6 +21,13 @@ extern uint64_t __stop___llvm_prf_cnts __attribute__((visibility("hidden")));
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;
diff --git a/compiler-rt/test/profile/Inputs/instrprof-shared-lib.c b/compiler-rt/test/profile/Inputs/instrprof-shared-lib.c
new file mode 100644
index 00000000000..d22b0a54a01
--- /dev/null
+++ b/compiler-rt/test/profile/Inputs/instrprof-shared-lib.c
@@ -0,0 +1,9 @@
+int g1 = 0;
+int g2 = 1;
+
+void foo(int n) {
+ if (n % 5 == 0)
+ g1++;
+ else
+ g2++;
+}
diff --git a/compiler-rt/test/profile/Inputs/instrprof-shared-main.c b/compiler-rt/test/profile/Inputs/instrprof-shared-main.c
new file mode 100644
index 00000000000..60da3b42c63
--- /dev/null
+++ b/compiler-rt/test/profile/Inputs/instrprof-shared-main.c
@@ -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;
+}
diff --git a/compiler-rt/test/profile/instrprof-shared.test b/compiler-rt/test/profile/instrprof-shared.test
new file mode 100644
index 00000000000..851578b0f2c
--- /dev/null
+++ b/compiler-rt/test/profile/instrprof-shared.test
@@ -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
+
OpenPOWER on IntegriCloud