1 | // RUN: %clang_profgen -mllvm -enable-value-profiling -O2 -o %t %s |
2 | // RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t |
3 | // RUN: llvm-profdata merge -o %t.profdata %t.profraw |
4 | // RUN: llvm-profdata show --all-functions -ic-targets %t.profdata > %t.out |
5 | // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-1 < %t.out |
6 | // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-2 < %t.out |
7 | // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-3 < %t.out |
8 | // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-4 < %t.out |
9 | // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-5 < %t.out |
10 | // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-6 < %t.out |
11 | |
12 | #include <stdint.h> |
13 | #include <stdio.h> |
14 | #include <stdlib.h> |
15 | typedef struct __llvm_profile_data __llvm_profile_data; |
16 | const __llvm_profile_data *__llvm_profile_begin_data(void); |
17 | const __llvm_profile_data *__llvm_profile_end_data(void); |
18 | void __llvm_profile_set_num_value_sites(__llvm_profile_data *Data, |
19 | uint32_t ValueKind, |
20 | uint16_t NumValueSites); |
21 | __llvm_profile_data * |
22 | __llvm_profile_iterate_data(const __llvm_profile_data *Data); |
23 | void *__llvm_get_function_addr(const __llvm_profile_data *Data); |
24 | void __llvm_profile_instrument_target(uint64_t TargetValue, void *Data, |
25 | uint32_t CounterIndex); |
26 | void callee1() {} |
27 | void callee2() {} |
28 | |
29 | void caller_without_value_site1() {} |
30 | void caller_with_value_site_never_called1() {} |
31 | void caller_with_vp1() {} |
32 | void caller_with_value_site_never_called2() {} |
33 | void caller_without_value_site2() {} |
34 | void caller_with_vp2() {} |
35 | |
36 | void (*callee1Ptr)(); |
37 | void (*callee2Ptr)(); |
38 | |
39 | void __attribute__ ((noinline)) setFunctionPointers () { |
40 | callee1Ptr = callee1; |
41 | callee2Ptr = callee2; |
42 | } |
43 | |
44 | int main(int argc, const char *argv[]) { |
45 | unsigned S, NS = 10, V; |
46 | const __llvm_profile_data *Data, *DataEnd; |
47 | |
48 | setFunctionPointers(); |
49 | Data = __llvm_profile_begin_data(); |
50 | DataEnd = __llvm_profile_end_data(); |
51 | for (; Data < DataEnd; Data = __llvm_profile_iterate_data(Data)) { |
52 | void *func = __llvm_get_function_addr(Data); |
53 | if (func == caller_without_value_site1 || |
54 | func == caller_without_value_site2 || |
55 | func == callee1 || func == callee2 || func == main) |
56 | continue; |
57 | |
58 | __llvm_profile_set_num_value_sites(Data: (__llvm_profile_data *)Data, |
59 | ValueKind: 0 /*IPVK_IndirectCallTarget */, NumValueSites: 10); |
60 | |
61 | if (func == caller_with_value_site_never_called1 || |
62 | func == caller_with_value_site_never_called2) |
63 | continue; |
64 | for (S = 0; S < NS; S++) { |
65 | unsigned C; |
66 | for (C = 0; C < S + 1; C++) { |
67 | __llvm_profile_instrument_target(TargetValue: (uint64_t)callee1Ptr, Data: (void *)Data, CounterIndex: S); |
68 | if (C % 2 == 0) |
69 | __llvm_profile_instrument_target(TargetValue: (uint64_t)callee2Ptr, Data: (void *)Data, CounterIndex: S); |
70 | } |
71 | } |
72 | } |
73 | } |
74 | |
75 | // CHECK: Counters: |
76 | // CHECK-1-LABEL: caller_with_value_site_never_called2: |
77 | // CHECK-1-NEXT: Hash: 0x0000000000000000 |
78 | // CHECK-1-NEXT: Counters: |
79 | // CHECK-1-NEXT: Function count |
80 | // CHECK-1-NEXT: Indirect Call Site Count: 10 |
81 | // CHECK-1-NEXT: Indirect Target Results: |
82 | // CHECK-2-LABEL: caller_with_vp2: |
83 | // CHECK-2-NEXT: Hash: 0x0000000000000000 |
84 | // CHECK-2-NEXT: Counters: |
85 | // CHECK-2-NEXT: Function count: |
86 | // CHECK-2-NEXT: Indirect Call Site Count: 10 |
87 | // CHECK-2-NEXT: Indirect Target Results: |
88 | // CHECK-2-NEXT: [ 0, callee1, 1 ] |
89 | // CHECK-2-NEXT: [ 0, callee2, 1 ] |
90 | // CHECK-2-NEXT: [ 1, callee1, 2 ] |
91 | // CHECK-2-NEXT: [ 1, callee2, 1 ] |
92 | // CHECK-2-NEXT: [ 2, callee1, 3 ] |
93 | // CHECK-2-NEXT: [ 2, callee2, 2 ] |
94 | // CHECK-2-NEXT: [ 3, callee1, 4 ] |
95 | // CHECK-2-NEXT: [ 3, callee2, 2 ] |
96 | // CHECK-2-NEXT: [ 4, callee1, 5 ] |
97 | // CHECK-2-NEXT: [ 4, callee2, 3 ] |
98 | // CHECK-2-NEXT: [ 5, callee1, 6 ] |
99 | // CHECK-2-NEXT: [ 5, callee2, 3 ] |
100 | // CHECK-2-NEXT: [ 6, callee1, 7 ] |
101 | // CHECK-2-NEXT: [ 6, callee2, 4 ] |
102 | // CHECK-2-NEXT: [ 7, callee1, 8 ] |
103 | // CHECK-2-NEXT: [ 7, callee2, 4 ] |
104 | // CHECK-2-NEXT: [ 8, callee1, 9 ] |
105 | // CHECK-2-NEXT: [ 8, callee2, 5 ] |
106 | // CHECK-2-NEXT: [ 9, callee1, 10 ] |
107 | // CHECK-2-NEXT: [ 9, callee2, 5 ] |
108 | // CHECK-3-LABEL: caller_with_vp1: |
109 | // CHECK-3-NEXT: Hash: 0x0000000000000000 |
110 | // CHECK-3-NEXT: Counters: |
111 | // CHECK-3-NEXT: Function count |
112 | // CHECK-3-NEXT: Indirect Call Site Count: 10 |
113 | // CHECK-3-NEXT: Indirect Target Results: |
114 | // CHECK-3-NEXT: [ 0, callee1, 1 ] |
115 | // CHECK-3-NEXT: [ 0, callee2, 1 ] |
116 | // CHECK-3-NEXT: [ 1, callee1, 2 ] |
117 | // CHECK-3-NEXT: [ 1, callee2, 1 ] |
118 | // CHECK-3-NEXT: [ 2, callee1, 3 ] |
119 | // CHECK-3-NEXT: [ 2, callee2, 2 ] |
120 | // CHECK-3-NEXT: [ 3, callee1, 4 ] |
121 | // CHECK-3-NEXT: [ 3, callee2, 2 ] |
122 | // CHECK-3-NEXT: [ 4, callee1, 5 ] |
123 | // CHECK-3-NEXT: [ 4, callee2, 3 ] |
124 | // CHECK-3-NEXT: [ 5, callee1, 6 ] |
125 | // CHECK-3-NEXT: [ 5, callee2, 3 ] |
126 | // CHECK-3-NEXT: [ 6, callee1, 7 ] |
127 | // CHECK-3-NEXT: [ 6, callee2, 4 ] |
128 | // CHECK-3-NEXT: [ 7, callee1, 8 ] |
129 | // CHECK-3-NEXT: [ 7, callee2, 4 ] |
130 | // CHECK-3-NEXT: [ 8, callee1, 9 ] |
131 | // CHECK-3-NEXT: [ 8, callee2, 5 ] |
132 | // CHECK-3-NEXT: [ 9, callee1, 10 ] |
133 | // CHECK-3-NEXT: [ 9, callee2, 5 ] |
134 | // CHECK-4-LABEL: caller_with_value_site_never_called1: |
135 | // CHECK-4-NEXT: Hash: 0x0000000000000000 |
136 | // CHECK-4-NEXT: Counters: |
137 | // CHECK-4-NEXT: Function count: |
138 | // CHECK-4-NEXT: Indirect Call Site Count: 10 |
139 | // CHECK-4-NEXT: Indirect Target Results: |
140 | // CHECK-5-LABEL: caller_without_value_site2: |
141 | // CHECK-5-NEXT: Hash: 0x0000000000000000 |
142 | // CHECK-5-NEXT: Counters: |
143 | // CHECK-5-NEXT: Function count: |
144 | // CHECK-5-NEXT: Indirect Call Site Count: 0 |
145 | // CHECK-5-NEXT: Indirect Target Results: |
146 | // CHECK-6-LABEL: caller_without_value_site1: |
147 | // CHECK-6-NEXT: Hash: 0x0000000000000000 |
148 | // CHECK-6-NEXT: Counters: |
149 | // CHECK-6-NEXT: Function count: |
150 | // CHECK-6-NEXT: Indirect Call Site Count: 0 |
151 | // CHECK-6-NEXT: Indirect Target Results: |
152 | |