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