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