1// RUN: %clang_profgen -mllvm -enable-value-profiling -mllvm -vp-static-alloc=false -O2 -o %t %s
2// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
3// RUN: env LLVM_PROFILE_FILE=%t-2.profraw %run %t DO_NOT_INSTRUMENT
4// RUN: llvm-profdata merge -o %t.profdata %t.profraw
5// RUN: llvm-profdata merge -o %t-2.profdata %t-2.profraw
6// RUN: llvm-profdata merge -o %t-merged.profdata %t.profraw %t-2.profdata
7// RUN: llvm-profdata show --all-functions -ic-targets %t-2.profdata | FileCheck %s -check-prefix=NO-VALUE
8// RUN: llvm-profdata show --all-functions -ic-targets %t.profdata | FileCheck %s
9// RUN: llvm-profdata show --all-functions -ic-targets %t-merged.profdata | FileCheck %s
10//
11// RUN: env LLVM_PROFILE_FILE=%t-3.profraw LLVM_VP_BUFFER_SIZE=1 %run %t
12// RUN: env LLVM_PROFILE_FILE=%t-4.profraw LLVM_VP_BUFFER_SIZE=8 %run %t
13// RUN: env LLVM_PROFILE_FILE=%t-5.profraw LLVM_VP_BUFFER_SIZE=128 %run %t
14// RUN: env LLVM_PROFILE_FILE=%t-6.profraw LLVM_VP_BUFFER_SIZE=1024 %run %t
15// RUN: env LLVM_PROFILE_FILE=%t-7.profraw LLVM_VP_BUFFER_SIZE=102400 %run %t
16// RUN: llvm-profdata merge -o %t-3.profdata %t-3.profraw
17// RUN: llvm-profdata merge -o %t-4.profdata %t-4.profraw
18// RUN: llvm-profdata merge -o %t-5.profdata %t-5.profraw
19// RUN: llvm-profdata merge -o %t-6.profdata %t-6.profraw
20// RUN: llvm-profdata merge -o %t-7.profdata %t-7.profraw
21// RUN: llvm-profdata show --all-functions -ic-targets %t-3.profdata | FileCheck %s
22// RUN: llvm-profdata show --all-functions -ic-targets %t-4.profdata | FileCheck %s
23// RUN: llvm-profdata show --all-functions -ic-targets %t-5.profdata | FileCheck %s
24// RUN: llvm-profdata show --all-functions -ic-targets %t-6.profdata | FileCheck %s
25// RUN: llvm-profdata show --all-functions -ic-targets %t-7.profdata | FileCheck %s
26
27#include <stdint.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31typedef struct __llvm_profile_data __llvm_profile_data;
32const __llvm_profile_data *__llvm_profile_begin_data(void);
33const __llvm_profile_data *__llvm_profile_end_data(void);
34void __llvm_profile_set_num_value_sites(__llvm_profile_data *Data,
35 uint32_t ValueKind,
36 uint16_t NumValueSites);
37__llvm_profile_data *
38__llvm_profile_iterate_data(const __llvm_profile_data *Data);
39void *__llvm_get_function_addr(const __llvm_profile_data *Data);
40void __llvm_profile_instrument_target(uint64_t TargetValue, void *Data,
41 uint32_t CounterIndex);
42
43#define DEF_FUNC(x) \
44 void x() {}
45#define DEF_2_FUNCS(x) DEF_FUNC(x##_1) DEF_FUNC(x##_2)
46#define DEF_4_FUNCS(x) DEF_2_FUNCS(x##_1) DEF_2_FUNCS(x##_2)
47#define DEF_8_FUNCS(x) DEF_4_FUNCS(x##_1) DEF_4_FUNCS(x##_2)
48#define DEF_16_FUNCS(x) DEF_8_FUNCS(x##_1) DEF_8_FUNCS(x##_2)
49#define DEF_32_FUNCS(x) DEF_16_FUNCS(x##_1) DEF_16_FUNCS(x##_2)
50#define DEF_64_FUNCS(x) DEF_32_FUNCS(x##_1) DEF_32_FUNCS(x##_2)
51#define DEF_128_FUNCS(x) DEF_64_FUNCS(x##_1) DEF_64_FUNCS(x##_2)
52
53#define FUNC_ADDR(x) &x,
54#define FUNC_2_ADDRS(x) FUNC_ADDR(x##_1) FUNC_ADDR(x##_2)
55#define FUNC_4_ADDRS(x) FUNC_2_ADDRS(x##_1) FUNC_2_ADDRS(x##_2)
56#define FUNC_8_ADDRS(x) FUNC_4_ADDRS(x##_1) FUNC_4_ADDRS(x##_2)
57#define FUNC_16_ADDRS(x) FUNC_8_ADDRS(x##_1) FUNC_8_ADDRS(x##_2)
58#define FUNC_32_ADDRS(x) FUNC_16_ADDRS(x##_1) FUNC_16_ADDRS(x##_2)
59#define FUNC_64_ADDRS(x) FUNC_32_ADDRS(x##_1) FUNC_32_ADDRS(x##_2)
60#define FUNC_128_ADDRS(x) FUNC_64_ADDRS(x##_1) FUNC_64_ADDRS(x##_2)
61
62DEF_8_FUNCS(callee)
63DEF_128_FUNCS(caller)
64
65void *CallerAddrs[] = {FUNC_128_ADDRS(caller)};
66void *CalleeAddrs[] = {FUNC_8_ADDRS(callee)};
67typedef struct CallerInfo {
68 void *CallerAddr;
69 uint32_t NS; /* Number value sites. */
70} CallerInfo;
71
72CallerInfo CallerInfos[128];
73
74int cmpaddr(const void *p1, const void *p2) {
75 CallerInfo *addr1 = (CallerInfo *)p1;
76 CallerInfo *addr2 = (CallerInfo *)p2;
77 return (intptr_t)addr2->CallerAddr - (intptr_t)addr1->CallerAddr;
78}
79
80int main(int argc, const char *argv[]) {
81 unsigned S, NS = 0, I, V, doInstrument = 1;
82 const __llvm_profile_data *Data, *DataEnd;
83
84 if (argc >= 2 && !strcmp(s1: argv[1], s2: "DO_NOT_INSTRUMENT"))
85 doInstrument = 0;
86
87 for (I = 0; I < 128; I++) {
88 CallerInfos[I].CallerAddr = CallerAddrs[I];
89 CallerInfos[I].NS = I;
90 }
91 qsort(base: CallerInfos, nmemb: sizeof(CallerInfos) / sizeof(CallerInfo), size: sizeof(CallerInfo),
92 compar: cmpaddr);
93
94 /* We will synthesis value profile data for 128 callers functions declared.
95 * The number of value sites for each caller function is recorded in
96 * the NS field of the CallerInfo object. For each value site, the number of
97 * callee values is determined by the site index (modulo 8). The frequency
98 * of each callee target synthesized is equal to V + 1, in which V is the
99 * index of the target value for the callsite. */
100
101 Data = __llvm_profile_begin_data();
102 DataEnd = __llvm_profile_end_data();
103
104 for (; Data < DataEnd; Data = __llvm_profile_iterate_data(Data)) {
105 void *func = __llvm_get_function_addr(Data);
106 CallerInfo Key, *Res;
107 Key.CallerAddr = func;
108 Res = (CallerInfo *) bsearch(key: &Key, base: CallerInfos, nmemb: sizeof(CallerInfos) / sizeof(CallerInfo),
109 size: sizeof(CallerInfo), compar: cmpaddr);
110 if (Res) {
111 NS = Res->NS;
112 __llvm_profile_set_num_value_sites(Data: (__llvm_profile_data *)Data,
113 ValueKind: 0 /*IPVK_IndirectCallTarget */, NumValueSites: NS);
114 if (!doInstrument) {
115 continue;
116 }
117 for (S = 0; S < NS; S++) {
118 for (V = 0; V < S % 8; V++) {
119 unsigned C;
120 for (C = 0; C < V + 1; C++)
121 __llvm_profile_instrument_target(TargetValue: (uint64_t)CalleeAddrs[V],
122 Data: (void *)Data, CounterIndex: S);
123 }
124 }
125 }
126 }
127}
128
129// NO-VALUE: Indirect Call Site Count: 127
130// NO-VALUE-NEXT: Indirect Target Results:
131// CHECK-LABEL: caller_1_1_1_1_2_2_1:
132// CHECK: Indirect Call Site Count: 6
133// CHECK-NEXT: Indirect Target Results:
134// CHECK-NEXT: [ 1, callee_1_1_1, 1 ]
135// CHECK-NEXT: [ 2, callee_1_1_2, 2 ]
136// CHECK-NEXT: [ 2, callee_1_1_1, 1 ]
137// CHECK-NEXT: [ 3, callee_1_2_1, 3 ]
138// CHECK-NEXT: [ 3, callee_1_1_2, 2 ]
139// CHECK-NEXT: [ 3, callee_1_1_1, 1 ]
140// CHECK-NEXT: [ 4, callee_1_2_2, 4 ]
141// CHECK-NEXT: [ 4, callee_1_2_1, 3 ]
142// CHECK-NEXT: [ 4, callee_1_1_2, 2 ]
143// CHECK-NEXT: [ 4, callee_1_1_1, 1 ]
144// CHECK-NEXT: [ 5, callee_2_1_1, 5 ]
145// CHECK-NEXT: [ 5, callee_1_2_2, 4 ]
146// CHECK-NEXT: [ 5, callee_1_2_1, 3 ]
147// CHECK-NEXT: [ 5, callee_1_1_2, 2 ]
148// CHECK-NEXT: [ 5, callee_1_1_1, 1 ]
149// CHECK-LABEL: caller_2_2_2_2_2_2_2:
150// CHECK: Indirect Call Site Count: 127
151// CHECK-NEXT: Indirect Target Results:
152// CHECK-NEXT: [ 1, callee_1_1_1, 1 ]
153// CHECK-NEXT: [ 2, callee_1_1_2, 2 ]
154// CHECK-NEXT: [ 2, callee_1_1_1, 1 ]
155// CHECK-NEXT: [ 3, callee_1_2_1, 3 ]
156// CHECK-NEXT: [ 3, callee_1_1_2, 2 ]
157// CHECK-NEXT: [ 3, callee_1_1_1, 1 ]
158// CHECK-NEXT: [ 4, callee_1_2_2, 4 ]
159// CHECK-NEXT: [ 4, callee_1_2_1, 3 ]
160// CHECK-NEXT: [ 4, callee_1_1_2, 2 ]
161// CHECK-NEXT: [ 4, callee_1_1_1, 1 ]
162// CHECK-NEXT: [ 5, callee_2_1_1, 5 ]
163// CHECK-NEXT: [ 5, callee_1_2_2, 4 ]
164// CHECK-NEXT: [ 5, callee_1_2_1, 3 ]
165// CHECK-NEXT: [ 5, callee_1_1_2, 2 ]
166// CHECK-NEXT: [ 5, callee_1_1_1, 1 ]
167// CHECK-NEXT: [ 6, callee_2_1_2, 6 ]
168// CHECK-NEXT: [ 6, callee_2_1_1, 5 ]
169// CHECK-NEXT: [ 6, callee_1_2_2, 4 ]
170// CHECK-NEXT: [ 6, callee_1_2_1, 3 ]
171// CHECK-NEXT: [ 6, callee_1_1_2, 2 ]
172// CHECK-NEXT: [ 6, callee_1_1_1, 1 ]
173// CHECK-NEXT: [ 7, callee_2_2_1, 7 ]
174// CHECK-NEXT: [ 7, callee_2_1_2, 6 ]
175// CHECK-NEXT: [ 7, callee_2_1_1, 5 ]
176// CHECK-NEXT: [ 7, callee_1_2_2, 4 ]
177// CHECK-NEXT: [ 7, callee_1_2_1, 3 ]
178// CHECK-NEXT: [ 7, callee_1_1_2, 2 ]
179// CHECK-NEXT: [ 7, callee_1_1_1, 1 ]
180// CHECK-NEXT: [ 9, callee_1_1_1, 1 ]
181// CHECK-NEXT: [ 10, callee_1_1_2, 2 ]
182// CHECK-NEXT: [ 10, callee_1_1_1, 1 ]
183// CHECK-NEXT: [ 11, callee_1_2_1, 3 ]
184// CHECK-NEXT: [ 11, callee_1_1_2, 2 ]
185// CHECK-NEXT: [ 11, callee_1_1_1, 1 ]
186// CHECK-NEXT: [ 12, callee_1_2_2, 4 ]
187// CHECK-NEXT: [ 12, callee_1_2_1, 3 ]
188// CHECK-NEXT: [ 12, callee_1_1_2, 2 ]
189// CHECK-NEXT: [ 12, callee_1_1_1, 1 ]
190// CHECK-NEXT: [ 13, callee_2_1_1, 5 ]
191// CHECK-NEXT: [ 13, callee_1_2_2, 4 ]
192// CHECK-NEXT: [ 13, callee_1_2_1, 3 ]
193// CHECK-NEXT: [ 13, callee_1_1_2, 2 ]
194// CHECK-NEXT: [ 13, callee_1_1_1, 1 ]
195// CHECK-NEXT: [ 14, callee_2_1_2, 6 ]
196// CHECK-NEXT: [ 14, callee_2_1_1, 5 ]
197// CHECK-NEXT: [ 14, callee_1_2_2, 4 ]
198// CHECK-NEXT: [ 14, callee_1_2_1, 3 ]
199// CHECK-NEXT: [ 14, callee_1_1_2, 2 ]
200// CHECK-NEXT: [ 14, callee_1_1_1, 1 ]
201// CHECK-NEXT: [ 15, callee_2_2_1, 7 ]
202// CHECK-NEXT: [ 15, callee_2_1_2, 6 ]
203// CHECK-NEXT: [ 15, callee_2_1_1, 5 ]
204// CHECK-NEXT: [ 15, callee_1_2_2, 4 ]
205// CHECK-NEXT: [ 15, callee_1_2_1, 3 ]
206// CHECK-NEXT: [ 15, callee_1_1_2, 2 ]
207// CHECK-NEXT: [ 15, callee_1_1_1, 1 ]
208// CHECK-NEXT: [ 17, callee_1_1_1, 1 ]
209// CHECK-NEXT: [ 18, callee_1_1_2, 2 ]
210// CHECK-NEXT: [ 18, callee_1_1_1, 1 ]
211// CHECK-NEXT: [ 19, callee_1_2_1, 3 ]
212// CHECK-NEXT: [ 19, callee_1_1_2, 2 ]
213// CHECK-NEXT: [ 19, callee_1_1_1, 1 ]
214// CHECK-NEXT: [ 20, callee_1_2_2, 4 ]
215// CHECK-NEXT: [ 20, callee_1_2_1, 3 ]
216// CHECK-NEXT: [ 20, callee_1_1_2, 2 ]
217// CHECK-NEXT: [ 20, callee_1_1_1, 1 ]
218// CHECK-NEXT: [ 21, callee_2_1_1, 5 ]
219// CHECK-NEXT: [ 21, callee_1_2_2, 4 ]
220// CHECK-NEXT: [ 21, callee_1_2_1, 3 ]
221// CHECK-NEXT: [ 21, callee_1_1_2, 2 ]
222// CHECK-NEXT: [ 21, callee_1_1_1, 1 ]
223// CHECK-NEXT: [ 22, callee_2_1_2, 6 ]
224// CHECK-NEXT: [ 22, callee_2_1_1, 5 ]
225// CHECK-NEXT: [ 22, callee_1_2_2, 4 ]
226// CHECK-NEXT: [ 22, callee_1_2_1, 3 ]
227// CHECK-NEXT: [ 22, callee_1_1_2, 2 ]
228// CHECK-NEXT: [ 22, callee_1_1_1, 1 ]
229
230

source code of compiler-rt/test/profile/instrprof-value-prof.c