summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-05-09 23:14:58 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-05-09 23:14:58 +0000
commit18d66b3c136a821b8aadabcd666f578da97a545b (patch)
tree8a76a917ad1f6b94c9c9d5121572e81e83769e17 /test
parent2e8e44123a1af21beacf1190fc9f9c8104088c5f (diff)
InstrProf: Test the functions in the runtime
Check that the profile runtime works as expected. This tests the functions that are meant to be available to advanced users. In particular, check that the `atexit()` hook can be disabled by defining a custom `__llvm_profile_runtime` variable, that the libc dependencies are optional, and that the various functions for writing out files work for basic cases. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@208460 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/profile/instrprof-reset-counters.c19
-rw-r--r--test/profile/instrprof-set-filename.c14
-rw-r--r--test/profile/instrprof-without-libc.c61
-rw-r--r--test/profile/instrprof-write-file-atexit-explicitly.c17
-rw-r--r--test/profile/instrprof-write-file-only.c30
-rw-r--r--test/profile/instrprof-write-file.c34
6 files changed, 175 insertions, 0 deletions
diff --git a/test/profile/instrprof-reset-counters.c b/test/profile/instrprof-reset-counters.c
new file mode 100644
index 000000000..c92732baf
--- /dev/null
+++ b/test/profile/instrprof-reset-counters.c
@@ -0,0 +1,19 @@
+// RUN: %clang_profgen -o %t -O3 %s
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
+// RUN: llvm-profdata merge -o %t.profdata %t.profraw
+// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s
+
+void __llvm_profile_reset_counters(void);
+void foo(int);
+int main(void) {
+ foo(0);
+ __llvm_profile_reset_counters();
+ foo(1);
+ return 0;
+}
+void foo(int N) {
+ // CHECK-LABEL: define void @foo(
+ // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[FOO:[0-9]+]]
+ if (N) {}
+}
+// CHECK: ![[FOO]] = metadata !{metadata !"branch_weights", i32 2, i32 1}
diff --git a/test/profile/instrprof-set-filename.c b/test/profile/instrprof-set-filename.c
new file mode 100644
index 000000000..51de14f61
--- /dev/null
+++ b/test/profile/instrprof-set-filename.c
@@ -0,0 +1,14 @@
+// RUN: %clang_profgen -o %t -O3 %s
+// RUN: %run %t %t.profraw
+// RUN: llvm-profdata merge -o %t.profdata %t.profraw
+// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s
+
+void __llvm_profile_set_filename(const char *);
+int main(int argc, const char *argv[]) {
+ // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof !1
+ if (argc < 2)
+ return 1;
+ __llvm_profile_set_filename(argv[1]);
+ return 0;
+}
+// CHECK: !1 = metadata !{metadata !"branch_weights", i32 1, i32 2}
diff --git a/test/profile/instrprof-without-libc.c b/test/profile/instrprof-without-libc.c
new file mode 100644
index 000000000..3657af24a
--- /dev/null
+++ b/test/profile/instrprof-without-libc.c
@@ -0,0 +1,61 @@
+// RUN: %clang_profgen -DCHECK_SYMBOLS -O3 -o %t.symbols %s
+// RUN: llvm-nm %t.symbols | FileCheck %s --check-prefix=CHECK-SYMBOLS
+// RUN: %clang_profgen -O3 -o %t %s
+// RUN: %run %t %t.profraw
+// RUN: llvm-profdata merge -o %t.profdata %t.profraw
+// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifndef CHECK_SYMBOLS
+#include <stdio.h>
+#endif
+
+int __llvm_profile_runtime = 0;
+uint64_t __llvm_profile_get_size_for_buffer(void);
+int __llvm_profile_write_buffer(char *);
+int write_buffer(uint64_t, const char *);
+int main(int argc, const char *argv[]) {
+ // CHECK-LABEL: define i32 @main(
+ // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof !1
+ if (argc < 2)
+ return 1;
+
+ const uint64_t MaxSize = 10000;
+ static char Buffer[MaxSize];
+
+ uint64_t Size = __llvm_profile_get_size_for_buffer();
+ if (Size > MaxSize)
+ return 1;
+ int Write = __llvm_profile_write_buffer(Buffer);
+ if (__llvm_profile_write_buffer(Buffer))
+ return Write;
+
+#ifdef CHECK_SYMBOLS
+ // Don't write it out. Since we're checking the symbols, we don't have libc
+ // available.
+ return 0;
+#else
+ // Actually write it out so we can FileCheck the output.
+ FILE *File = fopen(argv[1], "w");
+ if (!File)
+ return 1;
+ if (fwrite(Buffer, 1, Size, File) != Size)
+ return 1;
+ return fclose(File);
+#endif
+}
+// CHECK: !1 = metadata !{metadata !"branch_weights", i32 1, i32 2}
+
+// CHECK-SYMBOLS-NOT: GLOBAL
+// CHECK-SYMBOLS-NOT: ___cxx_global_var_init
+// CHECK-SYMBOLS-NOT: ___llvm_profile_register_write_file_atexit
+// CHECK-SYMBOLS-NOT: ___llvm_profile_set_filename
+// CHECK-SYMBOLS-NOT: ___llvm_profile_write_file
+// CHECK-SYMBOLS-NOT: _fdopen
+// CHECK-SYMBOLS-NOT: _fopen
+// CHECK-SYMBOLS-NOT: _fwrite
+// CHECK-SYMBOLS-NOT: _getenv
+// CHECK-SYMBOLS-NOT: _malloc
+// CHECK-SYMBOLS-NOT: _open
diff --git a/test/profile/instrprof-write-file-atexit-explicitly.c b/test/profile/instrprof-write-file-atexit-explicitly.c
new file mode 100644
index 000000000..931a48b24
--- /dev/null
+++ b/test/profile/instrprof-write-file-atexit-explicitly.c
@@ -0,0 +1,17 @@
+// RUN: %clang_profgen -o %t -O3 %s
+// RUN: %run %t %t.profraw
+// RUN: llvm-profdata merge -o %t.profdata %t.profraw
+// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s
+
+int __llvm_profile_runtime = 0;
+int __llvm_profile_register_write_file_atexit(void);
+void __llvm_profile_set_filename(const char *);
+int main(int argc, const char *argv[]) {
+ __llvm_profile_register_write_file_atexit();
+ // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof !1
+ if (argc < 2)
+ return 1;
+ __llvm_profile_set_filename(argv[1]);
+ return 0;
+}
+// CHECK: !1 = metadata !{metadata !"branch_weights", i32 1, i32 2}
diff --git a/test/profile/instrprof-write-file-only.c b/test/profile/instrprof-write-file-only.c
new file mode 100644
index 000000000..b9a1be4c0
--- /dev/null
+++ b/test/profile/instrprof-write-file-only.c
@@ -0,0 +1,30 @@
+// RUN: %clang_profgen -o %t -O3 %s
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
+// RUN: llvm-profdata merge -o %t.profdata %t.profraw
+// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s
+
+int __llvm_profile_runtime = 0;
+int __llvm_profile_write_file(void);
+void __llvm_profile_set_filename(const char *);
+int foo(int);
+int main(int argc, const char *argv[]) {
+ // CHECK-LABEL: define i32 @main
+ // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof !1
+ if (argc > 1)
+ return 1;
+
+ // Write out the profile.
+ __llvm_profile_write_file();
+
+ // Change the profile.
+ return foo(0);
+}
+int foo(int X) {
+ // There should be no profiling information for @foo, since it was called
+ // after the profile was written (and the atexit was supressed by defining
+ // profile_runtime).
+ // CHECK-LABEL: define i32 @foo
+ // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{[^,]+$}}
+ return X <= 0 ? -X : X;
+}
+// CHECK: !1 = metadata !{metadata !"branch_weights", i32 1, i32 2}
diff --git a/test/profile/instrprof-write-file.c b/test/profile/instrprof-write-file.c
new file mode 100644
index 000000000..f5c2958e5
--- /dev/null
+++ b/test/profile/instrprof-write-file.c
@@ -0,0 +1,34 @@
+// RUN: %clang_profgen -o %t -O3 %s
+// RUN: env LLVM_PROFILE_FILE=%t1.profraw %run %t %t2.profraw
+// RUN: llvm-profdata merge -o %t1.profdata %t1.profraw
+// RUN: %clang_profuse=%t1.profdata -o - -S -emit-llvm %s | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK
+// RUN: llvm-profdata merge -o %t2.profdata %t2.profraw
+// RUN: %clang_profuse=%t2.profdata -o - -S -emit-llvm %s | FileCheck %s --check-prefix=CHECK2 --check-prefix=CHECK
+
+int __llvm_profile_write_file(void);
+void __llvm_profile_set_filename(const char *);
+int foo(int);
+int main(int argc, const char *argv[]) {
+ // CHECK-LABEL: define i32 @main
+ // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof !1
+ if (argc < 2)
+ return 1;
+
+ // Write out the profile.
+ __llvm_profile_write_file();
+
+ // Change the profile.
+ int Ret = foo(0);
+
+ // It'll write out again at exit; change the filename so we get two files.
+ __llvm_profile_set_filename(argv[1]);
+ return Ret;
+}
+int foo(int X) {
+ // CHECK-LABEL: define i32 @foo
+ // CHECK1: br i1 %{{.*}}, label %{{.*}}, label %{{[^,]+$}}
+ // CHECK2: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof !2
+ return X <= 0 ? -X : X;
+}
+// CHECK: !1 = metadata !{metadata !"branch_weights", i32 1, i32 2}
+// CHECK2: !2 = metadata !{metadata !"branch_weights", i32 2, i32 1}