diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:52:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:52:19 +0000 |
commit | 5c909fa013fc285f010a95e8d387e0ef3412da9c (patch) | |
tree | 1059d068ad281f4776ff44cd414574f99a460023 /test/profile | |
parent | f31bcc68c72371a2bf63aead9f3373a1ff2053b6 (diff) | |
download | src-5c909fa013fc285f010a95e8d387e0ef3412da9c.tar.gz src-5c909fa013fc285f010a95e8d387e0ef3412da9c.zip |
Vendor import of compiler-rt trunk r256633:vendor/compiler-rt/compiler-rt-trunk-r256633
Notes
Notes:
svn path=/vendor/compiler-rt/dist/; revision=292925
svn path=/vendor/compiler-rt/compiler-rt-trunk-r256633/; revision=292926; tag=vendor/compiler-rt/compiler-rt-trunk-r256633
Diffstat (limited to 'test/profile')
-rw-r--r-- | test/profile/Inputs/instrprof-shared-lib.c | 9 | ||||
-rw-r--r-- | test/profile/Inputs/instrprof-shared-main.c | 13 | ||||
-rw-r--r-- | test/profile/instrprof-bufferio.c | 128 | ||||
-rw-r--r-- | test/profile/instrprof-error.c | 12 | ||||
-rw-r--r-- | test/profile/instrprof-shared.test | 75 | ||||
-rw-r--r-- | test/profile/instrprof-value-prof-2.c | 135 | ||||
-rw-r--r-- | test/profile/instrprof-value-prof.c | 253 | ||||
-rw-r--r-- | test/profile/instrprof-without-libc.c | 6 |
8 files changed, 631 insertions, 0 deletions
diff --git a/test/profile/Inputs/instrprof-shared-lib.c b/test/profile/Inputs/instrprof-shared-lib.c new file mode 100644 index 000000000000..d22b0a54a017 --- /dev/null +++ b/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/test/profile/Inputs/instrprof-shared-main.c b/test/profile/Inputs/instrprof-shared-main.c new file mode 100644 index 000000000000..60da3b42c63f --- /dev/null +++ b/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/test/profile/instrprof-bufferio.c b/test/profile/instrprof-bufferio.c new file mode 100644 index 000000000000..eed548fd0da2 --- /dev/null +++ b/test/profile/instrprof-bufferio.c @@ -0,0 +1,128 @@ +// RUN: %clang_profgen -O3 -o %t %s +// RUN: %run %t %t.out.1 %t.out.2 %t.out.3 %t.out.4 +// RUN: cat %t.out.1 | FileCheck %s +// RUN: diff %t.out.1 %t.out.2 +// RUN: diff %t.out.2 %t.out.3 +// RUN: diff %t.out.3 %t.out.4 + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +typedef struct ProfBufferIO ProfBufferIO; +ProfBufferIO *llvmCreateBufferIOInternal(FILE *File, uint32_t DefaultBufferSz); +void llvmDeleteBufferIO(ProfBufferIO *BufferIO); + +int llvmBufferIOWrite(ProfBufferIO *BufferIO, const char *Data, uint32_t Size); +int llvmBufferIOFlush(ProfBufferIO *BufferIO); + +int __llvm_profile_runtime = 0; + +const char *SmallData = "ABC\n"; +const char *MediumData = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n"; +char LargeData[10 * 1024]; +int main(int argc, const char *argv[]) { + ProfBufferIO *BufferIO; + FILE *File[4]; + uint32_t IOBufferSize[4] = {8, 128, 8 * 1024, 11 * 1024}; + int I, J; + if (argc < 5) + return 1; + + for (I = 0; I < 10 * 1024 - 2; I++) + LargeData[I] = 'A'; + + LargeData[I++] = '\n'; + LargeData[I++] = '\0'; + + for (J = 0; J < 4; J++) { + File[J] = fopen(argv[1 + J], "w"); + if (!File[J]) + return 1; + + BufferIO = llvmCreateBufferIOInternal(File[J], IOBufferSize[J]); + + llvmBufferIOWrite(BufferIO, "Short Strings:\n", strlen("Short Strings:\n")); + for (I = 0; I < 1024; I++) { + llvmBufferIOWrite(BufferIO, SmallData, strlen(SmallData)); + } + llvmBufferIOWrite(BufferIO, "Long Strings:\n", strlen("Long Strings:\n")); + for (I = 0; I < 1024; I++) { + llvmBufferIOWrite(BufferIO, MediumData, strlen(MediumData)); + } + llvmBufferIOWrite(BufferIO, "Extra Long Strings:\n", + strlen("Extra Long Strings:\n")); + for (I = 0; I < 10; I++) { + llvmBufferIOWrite(BufferIO, LargeData, strlen(LargeData)); + } + llvmBufferIOWrite(BufferIO, "Mixed Strings:\n", strlen("Mixed Strings:\n")); + for (I = 0; I < 1024; I++) { + llvmBufferIOWrite(BufferIO, MediumData, strlen(MediumData)); + llvmBufferIOWrite(BufferIO, SmallData, strlen(SmallData)); + } + llvmBufferIOWrite(BufferIO, "Endings:\n", strlen("Endings:\n")); + llvmBufferIOWrite(BufferIO, "END\n", strlen("END\n")); + llvmBufferIOWrite(BufferIO, "ENDEND\n", strlen("ENDEND\n")); + llvmBufferIOWrite(BufferIO, "ENDENDEND\n", strlen("ENDENDEND\n")); + llvmBufferIOWrite(BufferIO, "ENDENDENDEND\n", strlen("ENDENDENDEND\n")); + llvmBufferIOFlush(BufferIO); + + llvmDeleteBufferIO(BufferIO); + + fclose(File[J]); + } + return 0; +} + +// CHECK-LABEL: Short Strings: +// CHECK: ABC +// CHECK-NEXT: ABC +// CHECK-NEXT: ABC +// CHECK-NEXT: ABC +// CHECK-NEXT: ABC +// CHECK-NEXT: ABC +// CHECK-NEXT: ABC +// CHECK-NEXT: ABC +// CHECK-NEXT: ABC +// CHECK-NEXT: ABC +// CHECK-NEXT: ABC +// CHECK-NEXT: ABC +// CHECK-NEXT: ABC +// CHECK-NEXT: ABC +// CHECK-LABEL: Long Strings: +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-LABEL: Mixed Strings: +// CHECK: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABC +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABC +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABC +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABC +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABC +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABC +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABC +// CHECK-NEXT: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +// CHECK-NEXT: ABC +// CHECK-LABEL: Endings: +// CHECK: END +// CHECK-NEXT: ENDEND +// CHECK-NEXT: ENDENDEND +// CHECK-NEXT: ENDENDENDEND diff --git a/test/profile/instrprof-error.c b/test/profile/instrprof-error.c new file mode 100644 index 000000000000..4386d5321878 --- /dev/null +++ b/test/profile/instrprof-error.c @@ -0,0 +1,12 @@ +// RUN: %clang_profgen -o %t -O3 %s +// RUN: touch %t.profraw +// RUN: chmod -w %t.profraw +// RUN: LLVM_PROFILE_FILE=%t.profraw LLVM_PROFILE_VERBOSE_ERRORS=1 %run %t 1 2>&1 | FileCheck %s +// RUN: chmod +w %t.profraw + +int main(int argc, const char *argv[]) { + if (argc < 2) + return 1; + return 0; +} +// CHECK: LLVM Profile: Failed to write file diff --git a/test/profile/instrprof-shared.test b/test/profile/instrprof-shared.test new file mode 100644 index 000000000000..851578b0f2c0 --- /dev/null +++ b/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 + diff --git a/test/profile/instrprof-value-prof-2.c b/test/profile/instrprof-value-prof-2.c new file mode 100644 index 000000000000..989353e1f53e --- /dev/null +++ b/test/profile/instrprof-value-prof-2.c @@ -0,0 +1,135 @@ +// RUN: %clang_profgen -O2 -o %t %s +// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t +// RUN: llvm-profdata merge -o %t.profdata %t.profraw +// RUN: llvm-profdata show --all-functions -ic-targets %t.profdata | FileCheck %s + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +typedef struct __llvm_profile_data __llvm_profile_data; +const __llvm_profile_data *__llvm_profile_begin_data(void); +const __llvm_profile_data *__llvm_profile_end_data(void); +void __llvm_profile_set_num_value_sites(__llvm_profile_data *Data, + uint32_t ValueKind, + uint16_t NumValueSites); +__llvm_profile_data * +__llvm_profile_iterate_data(const __llvm_profile_data *Data); +void *__llvm_get_function_addr(const __llvm_profile_data *Data); +void __llvm_profile_instrument_target(uint64_t TargetValue, void *Data, + uint32_t CounterIndex); +void callee1() {} +void callee2() {} + +void caller_without_value_site1() {} +void caller_with_value_site_never_called1() {} +void caller_with_vp1() {} +void caller_with_value_site_never_called2() {} +void caller_without_value_site2() {} +void caller_with_vp2() {} + +int main(int argc, const char *argv[]) { + unsigned S, NS = 10, V; + const __llvm_profile_data *Data, *DataEnd; + + Data = __llvm_profile_begin_data(); + DataEnd = __llvm_profile_end_data(); + for (; Data < DataEnd; Data = __llvm_profile_iterate_data(Data)) { + void *func = __llvm_get_function_addr(Data); + if (func == caller_without_value_site1 || + func == caller_without_value_site2 || + func == callee1 || func == callee2 || func == main) + continue; + + __llvm_profile_set_num_value_sites((__llvm_profile_data *)Data, + 0 /*IPVK_IndirectCallTarget */, 10); + + if (func == caller_with_value_site_never_called1 || + func == caller_with_value_site_never_called2) + continue; + for (S = 0; S < NS; S++) { + unsigned C; + for (C = 0; C < S + 1; C++) { + __llvm_profile_instrument_target((uint64_t)&callee1, (void *)Data, S); + if (C % 2 == 0) + __llvm_profile_instrument_target((uint64_t)&callee2, (void *)Data, S); + } + } + } +} + +// CHECK-LABEL: caller_with_value_site_never_called2: +// CHECK-NEXT: Hash: 0x0000000000000000 +// CHECK-NEXT: Counters: +// CHECK-NEXT: Function count +// CHECK-NEXT: Indirect Call Site Count: 10 +// CHECK-NEXT: Indirect Target Results: +// CHECK-LABEL: caller_with_vp2: +// CHECK-NEXT: Hash: 0x0000000000000000 +// CHECK-NEXT: Counters: +// CHECK-NEXT: Function count: +// CHECK-NEXT: Indirect Call Site Count: 10 +// CHECK-NEXT: Indirect Target Results: +// CHECK-NEXT: [ 0, callee1, 1 ] +// CHECK-NEXT: [ 0, callee2, 1 ] +// CHECK-NEXT: [ 1, callee1, 2 ] +// CHECK-NEXT: [ 1, callee2, 1 ] +// CHECK-NEXT: [ 2, callee1, 3 ] +// CHECK-NEXT: [ 2, callee2, 2 ] +// CHECK-NEXT: [ 3, callee1, 4 ] +// CHECK-NEXT: [ 3, callee2, 2 ] +// CHECK-NEXT: [ 4, callee1, 5 ] +// CHECK-NEXT: [ 4, callee2, 3 ] +// CHECK-NEXT: [ 5, callee1, 6 ] +// CHECK-NEXT: [ 5, callee2, 3 ] +// CHECK-NEXT: [ 6, callee1, 7 ] +// CHECK-NEXT: [ 6, callee2, 4 ] +// CHECK-NEXT: [ 7, callee1, 8 ] +// CHECK-NEXT: [ 7, callee2, 4 ] +// CHECK-NEXT: [ 8, callee1, 9 ] +// CHECK-NEXT: [ 8, callee2, 5 ] +// CHECK-NEXT: [ 9, callee1, 10 ] +// CHECK-NEXT: [ 9, callee2, 5 ] +// CHECK-LABEL: caller_with_vp1: +// CHECK-NEXT: Hash: 0x0000000000000000 +// CHECK-NEXT: Counters: +// CHECK-NEXT: Function count +// CHECK-NEXT: Indirect Call Site Count: 10 +// CHECK-NEXT: Indirect Target Results: +// CHECK-NEXT: [ 0, callee1, 1 ] +// CHECK-NEXT: [ 0, callee2, 1 ] +// CHECK-NEXT: [ 1, callee1, 2 ] +// CHECK-NEXT: [ 1, callee2, 1 ] +// CHECK-NEXT: [ 2, callee1, 3 ] +// CHECK-NEXT: [ 2, callee2, 2 ] +// CHECK-NEXT: [ 3, callee1, 4 ] +// CHECK-NEXT: [ 3, callee2, 2 ] +// CHECK-NEXT: [ 4, callee1, 5 ] +// CHECK-NEXT: [ 4, callee2, 3 ] +// CHECK-NEXT: [ 5, callee1, 6 ] +// CHECK-NEXT: [ 5, callee2, 3 ] +// CHECK-NEXT: [ 6, callee1, 7 ] +// CHECK-NEXT: [ 6, callee2, 4 ] +// CHECK-NEXT: [ 7, callee1, 8 ] +// CHECK-NEXT: [ 7, callee2, 4 ] +// CHECK-NEXT: [ 8, callee1, 9 ] +// CHECK-NEXT: [ 8, callee2, 5 ] +// CHECK-NEXT: [ 9, callee1, 10 ] +// CHECK-NEXT: [ 9, callee2, 5 ] +// CHECK-LABEL: caller_with_value_site_never_called1: +// CHECK-NEXT: Hash: 0x0000000000000000 +// CHECK-NEXT: Counters: +// CHECK-NEXT: Function count: +// CHECK-NEXT: Indirect Call Site Count: 10 +// CHECK-NEXT: Indirect Target Results: +// CHECK-LABEL: caller_without_value_site2: +// CHECK-NEXT: Hash: 0x0000000000000000 +// CHECK-NEXT: Counters: +// CHECK-NEXT: Function count: +// CHECK-NEXT: Indirect Call Site Count: 0 +// CHECK-NEXT: Indirect Target Results: +// CHECK-LABEL: caller_without_value_site1: +// CHECK-NEXT: Hash: 0x0000000000000000 +// CHECK-NEXT: Counters: +// CHECK-NEXT: Function count: +// CHECK-NEXT: Indirect Call Site Count: 0 +// CHECK-NEXT: Indirect Target Results: diff --git a/test/profile/instrprof-value-prof.c b/test/profile/instrprof-value-prof.c new file mode 100644 index 000000000000..3ccecbe75593 --- /dev/null +++ b/test/profile/instrprof-value-prof.c @@ -0,0 +1,253 @@ +// RUN: %clang_profgen -O2 -o %t %s +// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t 1 +// RUN: env LLVM_PROFILE_FILE=%t-2.profraw %run %t +// RUN: llvm-profdata merge -o %t.profdata %t.profraw +// RUN: llvm-profdata merge -o %t-2.profdata %t-2.profraw +// RUN: llvm-profdata merge -o %t-merged.profdata %t.profraw %t-2.profdata +// RUN: llvm-profdata show --all-functions -ic-targets %t-2.profdata | FileCheck %s -check-prefix=NO-VALUE +// RUN: llvm-profdata show --all-functions -ic-targets %t.profdata | FileCheck %s +// value profile merging current do sorting based on target values -- this will destroy the order of the target +// in the list leading to comparison problem. For now just check a small subset of output. +// RUN: llvm-profdata show --all-functions -ic-targets %t-merged.profdata | FileCheck %s -check-prefix=MERGE +// +// RUN: env LLVM_PROFILE_FILE=%t-3.profraw LLVM_VP_BUFFER_SIZE=1 %run %t 1 +// RUN: env LLVM_PROFILE_FILE=%t-4.profraw LLVM_VP_BUFFER_SIZE=8 %run %t 1 +// RUN: env LLVM_PROFILE_FILE=%t-5.profraw LLVM_VP_BUFFER_SIZE=128 %run %t 1 +// RUN: env LLVM_PROFILE_FILE=%t-6.profraw LLVM_VP_BUFFER_SIZE=1024 %run %t 1 +// RUN: env LLVM_PROFILE_FILE=%t-7.profraw LLVM_VP_BUFFER_SIZE=102400 %run %t 1 +// RUN: llvm-profdata merge -o %t-3.profdata %t-3.profraw +// RUN: llvm-profdata merge -o %t-4.profdata %t-4.profraw +// RUN: llvm-profdata merge -o %t-5.profdata %t-5.profraw +// RUN: llvm-profdata merge -o %t-6.profdata %t-6.profraw +// RUN: llvm-profdata merge -o %t-7.profdata %t-7.profraw +// RUN: llvm-profdata show --all-functions -ic-targets %t-3.profdata | FileCheck %s +// RUN: llvm-profdata show --all-functions -ic-targets %t-4.profdata | FileCheck %s +// RUN: llvm-profdata show --all-functions -ic-targets %t-5.profdata | FileCheck %s +// RUN: llvm-profdata show --all-functions -ic-targets %t-6.profdata | FileCheck %s +// RUN: llvm-profdata show --all-functions -ic-targets %t-7.profdata | FileCheck %s + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +typedef struct __llvm_profile_data __llvm_profile_data; +const __llvm_profile_data *__llvm_profile_begin_data(void); +const __llvm_profile_data *__llvm_profile_end_data(void); +void __llvm_profile_set_num_value_sites(__llvm_profile_data *Data, + uint32_t ValueKind, + uint16_t NumValueSites); +__llvm_profile_data * +__llvm_profile_iterate_data(const __llvm_profile_data *Data); +void *__llvm_get_function_addr(const __llvm_profile_data *Data); +void __llvm_profile_instrument_target(uint64_t TargetValue, void *Data, + uint32_t CounterIndex); + +#define DEF_FUNC(x) \ + void x() {} +#define DEF_2_FUNCS(x) DEF_FUNC(x##_1) DEF_FUNC(x##_2) +#define DEF_4_FUNCS(x) DEF_2_FUNCS(x##_1) DEF_2_FUNCS(x##_2) +#define DEF_8_FUNCS(x) DEF_4_FUNCS(x##_1) DEF_4_FUNCS(x##_2) +#define DEF_16_FUNCS(x) DEF_8_FUNCS(x##_1) DEF_8_FUNCS(x##_2) +#define DEF_32_FUNCS(x) DEF_16_FUNCS(x##_1) DEF_16_FUNCS(x##_2) +#define DEF_64_FUNCS(x) DEF_32_FUNCS(x##_1) DEF_32_FUNCS(x##_2) +#define DEF_128_FUNCS(x) DEF_64_FUNCS(x##_1) DEF_64_FUNCS(x##_2) + +#define FUNC_ADDR(x) &x, +#define FUNC_2_ADDRS(x) FUNC_ADDR(x##_1) FUNC_ADDR(x##_2) +#define FUNC_4_ADDRS(x) FUNC_2_ADDRS(x##_1) FUNC_2_ADDRS(x##_2) +#define FUNC_8_ADDRS(x) FUNC_4_ADDRS(x##_1) FUNC_4_ADDRS(x##_2) +#define FUNC_16_ADDRS(x) FUNC_8_ADDRS(x##_1) FUNC_8_ADDRS(x##_2) +#define FUNC_32_ADDRS(x) FUNC_16_ADDRS(x##_1) FUNC_16_ADDRS(x##_2) +#define FUNC_64_ADDRS(x) FUNC_32_ADDRS(x##_1) FUNC_32_ADDRS(x##_2) +#define FUNC_128_ADDRS(x) FUNC_64_ADDRS(x##_1) FUNC_64_ADDRS(x##_2) + +DEF_8_FUNCS(callee) +DEF_128_FUNCS(caller) + +void *CallerAddrs[] = {FUNC_128_ADDRS(caller)}; +void *CalleeAddrs[] = {FUNC_8_ADDRS(callee)}; +typedef struct CallerInfo { + void *CallerAddr; + uint32_t NS; /* Number value sites. */ +} CallerInfo; + +CallerInfo CallerInfos[128]; + +int cmpaddr(const void *p1, const void *p2) { + CallerInfo *addr1 = (CallerInfo *)p1; + CallerInfo *addr2 = (CallerInfo *)p2; + return (intptr_t)addr2->CallerAddr - (intptr_t)addr1->CallerAddr; +} + +int main(int argc, const char *argv[]) { + unsigned S, NS = 0, I, V, doInstrument = 1; + const __llvm_profile_data *Data, *DataEnd; + + if (argc < 2) + doInstrument = 0; + + for (I = 0; I < 128; I++) { + CallerInfos[I].CallerAddr = CallerAddrs[I]; + CallerInfos[I].NS = I; + } + qsort(CallerInfos, sizeof(CallerInfos) / sizeof(CallerInfo), sizeof(CallerInfo), + cmpaddr); + + /* We will synthesis value profile data for 128 callers functions. + * The number of * value sites. The number values for each value site + * ranges from 0 to 8. */ + + Data = __llvm_profile_begin_data(); + DataEnd = __llvm_profile_end_data(); + + for (; Data < DataEnd; Data = __llvm_profile_iterate_data(Data)) { + void *func = __llvm_get_function_addr(Data); + CallerInfo Key, *Res; + Key.CallerAddr = func; + Res = (CallerInfo *) bsearch(&Key, CallerInfos, sizeof(CallerInfos) / sizeof(CallerInfo), + sizeof(CallerInfo), cmpaddr); + if (Res) { + NS = Res->NS; + __llvm_profile_set_num_value_sites((__llvm_profile_data *)Data, + 0 /*IPVK_IndirectCallTarget */, NS); + if (!doInstrument) { + continue; + } + for (S = 0; S < NS; S++) { + for (V = 0; V < S % 8; V++) { + unsigned C; + for (C = 0; C < V + 1; C++) + __llvm_profile_instrument_target((uint64_t)CalleeAddrs[V], + (void *)Data, S); + } + } + } + } +} + +// NO-VALUE: Indirect Call Site Count: 127 +// NO-VALUE-NEXT: Indirect Target Results: +// MERGE-LABEL: caller_1_1_1_1_2_2_1: +// MERGE: Indirect Call Site Count: 6 +// MERGE: Indirect Target Results: +// MERGE: [ 1, callee_1_1_1, 1 ] +// MERGE: [ 2, callee_1_1_1, 1 ] +// MERGE: [ 2, callee_1_1_2, 2 ] +// MERGE: [ 3, callee_1_1_1, 1 ] +// MERGE: [ 3, callee_1_1_2, 2 ] +// MERGE: [ 3, callee_1_2_1, 3 ] +// MERGE: [ 4, callee_1_1_1, 1 ] +// MERGE: [ 4, callee_1_1_2, 2 ] +// MERGE: [ 4, callee_1_2_1, 3 ] +// MERGE: [ 4, callee_1_2_2, 4 ] +// MERGE: [ 5, callee_1_1_1, 1 ] +// MERGE: [ 5, callee_1_1_2, 2 ] +// MERGE: [ 5, callee_1_2_1, 3 ] +// MERGE: [ 5, callee_1_2_2, 4 ] +// MERGE: [ 5, callee_2_1_1, 5 ] +// MERGE-LABEL: caller_2_2_2_2_2_2_2: +// MERGE: Indirect Call Site Count: 127 +// MERGE-NEXT: Indirect Target Results: +// MERGE-NEXT: [ 1, callee_1_1_1, 1 ] +// MERGE: [ 2, callee_1_1_1, 1 ] +// MERGE: [ 2, callee_1_1_2, 2 ] +// MERGE: [ 3, callee_1_1_1, 1 ] +// MERGE: [ 3, callee_1_1_2, 2 ] +// MERGE: [ 3, callee_1_2_1, 3 ] +// CHECK-LABEL: caller_1_1_1_1_2_2_1: +// CHECK: Indirect Call Site Count: 6 +// CHECK-NEXT: Indirect Target Results: +// CHECK-NEXT: [ 1, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 2, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 2, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 3, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 3, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 3, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 4, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 4, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 4, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 4, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 5, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 5, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 5, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 5, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 5, callee_2_1_1, 5 ] +// CHECK-LABEL: caller_2_2_2_2_2_2_2: +// CHECK: Indirect Call Site Count: 127 +// CHECK-NEXT: Indirect Target Results: +// CHECK-NEXT: [ 1, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 2, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 2, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 3, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 3, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 3, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 4, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 4, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 4, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 4, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 5, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 5, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 5, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 5, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 5, callee_2_1_1, 5 ] +// CHECK-NEXT: [ 6, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 6, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 6, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 6, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 6, callee_2_1_1, 5 ] +// CHECK-NEXT: [ 6, callee_2_1_2, 6 ] +// CHECK-NEXT: [ 7, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 7, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 7, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 7, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 7, callee_2_1_1, 5 ] +// CHECK-NEXT: [ 7, callee_2_1_2, 6 ] +// CHECK-NEXT: [ 7, callee_2_2_1, 7 ] +// CHECK-NEXT: [ 9, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 10, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 10, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 11, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 11, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 11, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 12, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 12, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 12, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 12, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 13, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 13, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 13, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 13, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 13, callee_2_1_1, 5 ] +// CHECK-NEXT: [ 14, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 14, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 14, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 14, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 14, callee_2_1_1, 5 ] +// CHECK-NEXT: [ 14, callee_2_1_2, 6 ] +// CHECK-NEXT: [ 15, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 15, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 15, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 15, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 15, callee_2_1_1, 5 ] +// CHECK-NEXT: [ 15, callee_2_1_2, 6 ] +// CHECK-NEXT: [ 15, callee_2_2_1, 7 ] +// CHECK-NEXT: [ 17, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 18, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 18, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 19, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 19, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 19, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 20, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 20, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 20, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 20, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 21, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 21, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 21, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 21, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 21, callee_2_1_1, 5 ] +// CHECK-NEXT: [ 22, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 22, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 22, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 22, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 22, callee_2_1_1, 5 ] + diff --git a/test/profile/instrprof-without-libc.c b/test/profile/instrprof-without-libc.c index fc6c9b25b3ba..eb0a76ded39f 100644 --- a/test/profile/instrprof-without-libc.c +++ b/test/profile/instrprof-without-libc.c @@ -56,5 +56,11 @@ int main(int argc, const char *argv[]) { // CHECK-SYMBOLS-NOT: _fopen // CHECK-SYMBOLS-NOT: _fwrite // CHECK-SYMBOLS-NOT: _getenv +// CHECK-SYMBOLS-NOT: getenv // CHECK-SYMBOLS-NOT: _malloc +// CHECK-SYMBOLS-NOT: malloc +// CHECK-SYMBOLS-NOT: _calloc +// CHECK-SYMBOLS-NOT: calloc +// CHECK-SYMBOLS-NOT: _free +// CHECK-SYMBOLS-NOT: free // CHECK-SYMBOLS-NOT: _open |