1 | /* |
2 | RUN: rm -fr %t.profdir |
3 | RUN: %clang_profgen=%t.profdir/default_%m.profraw -o %t -O2 %s |
4 | RUN: %run %t 2>&1 | FileCheck %s --check-prefix=NO_EXIT_WRITE |
5 | RUN: llvm-profdata merge -o %t.profdata %t.profdir |
6 | RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s --check-prefix=PROF |
7 | |
8 | NO_EXIT_WRITE: Profile data not written to file: already written |
9 | */ |
10 | |
11 | int __llvm_profile_dump(void); |
12 | void __llvm_profile_reset_counters(void); |
13 | int foo(int); |
14 | int bar(int); |
15 | int skip(int); |
16 | |
17 | int main(int argc, const char *argv[]) { |
18 | int Ret = foo(0); /* region 1 */ |
19 | __llvm_profile_dump(); |
20 | |
21 | /* not profiled -- cleared later. */ |
22 | skip(0); /* skipped region */ |
23 | |
24 | __llvm_profile_reset_counters(); |
25 | Ret += bar(0); /* region 2 */ |
26 | __llvm_profile_dump(); |
27 | |
28 | skip(1); |
29 | |
30 | __llvm_profile_reset_counters(); |
31 | /* foo's profile will be merged. */ |
32 | foo(1); /* region 3 */ |
33 | __llvm_profile_dump(); |
34 | |
35 | return Ret; |
36 | } |
37 | |
38 | __attribute__((noinline)) int foo(int X) { |
39 | /* PROF: define {{.*}} @foo({{.*}}!prof ![[ENT:[0-9]+]] |
40 | PROF: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]] |
41 | */ |
42 | return X <= 0 ? -X : X; |
43 | } |
44 | |
45 | __attribute__((noinline)) int skip(int X) { |
46 | /* PROF: define {{.*}} @skip( |
47 | PROF: br i1 %{{.*}}, label %{{.*}}, label %{{[^,]+$}} |
48 | */ |
49 | return X <= 0 ? -X : X; |
50 | } |
51 | |
52 | __attribute__((noinline)) int bar(int X) { |
53 | /* PROF-LABEL: define {{.*}} @bar( |
54 | PROF: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD2:[0-9]+]] |
55 | */ |
56 | return X <= 0 ? -X : X; |
57 | } |
58 | |
59 | /* |
60 | PROF: ![[ENT]] = !{!"function_entry_count", i64 2} |
61 | PROF: ![[PD1]] = !{!"branch_weights", i32 2, i32 2} |
62 | */ |
63 | |