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 > %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((__llvm_profile_data *)Data, 59 0 /*IPVK_IndirectCallTarget */, 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((uint64_t)callee1Ptr, (void *)Data, S); 68 if (C % 2 == 0) 69 __llvm_profile_instrument_target((uint64_t)callee2Ptr, (void *)Data, S); 70 } 71 } 72 } 73 } 74 75 // CHECK-1-LABEL: caller_with_value_site_never_called2: 76 // CHECK-1-NEXT: Hash: 0x0000000000000000 77 // CHECK-1-NEXT: Counters: 78 // CHECK-1-NEXT: Function count 79 // CHECK-1-NEXT: Indirect Call Site Count: 10 80 // CHECK-1-NEXT: Indirect Target Results: 81 // CHECK-2-LABEL: caller_with_vp2: 82 // CHECK-2-NEXT: Hash: 0x0000000000000000 83 // CHECK-2-NEXT: Counters: 84 // CHECK-2-NEXT: Function count: 85 // CHECK-2-NEXT: Indirect Call Site Count: 10 86 // CHECK-2-NEXT: Indirect Target Results: 87 // CHECK-2-NEXT: [ 0, callee1, 1 ] 88 // CHECK-2-NEXT: [ 0, callee2, 1 ] 89 // CHECK-2-NEXT: [ 1, callee1, 2 ] 90 // CHECK-2-NEXT: [ 1, callee2, 1 ] 91 // CHECK-2-NEXT: [ 2, callee1, 3 ] 92 // CHECK-2-NEXT: [ 2, callee2, 2 ] 93 // CHECK-2-NEXT: [ 3, callee1, 4 ] 94 // CHECK-2-NEXT: [ 3, callee2, 2 ] 95 // CHECK-2-NEXT: [ 4, callee1, 5 ] 96 // CHECK-2-NEXT: [ 4, callee2, 3 ] 97 // CHECK-2-NEXT: [ 5, callee1, 6 ] 98 // CHECK-2-NEXT: [ 5, callee2, 3 ] 99 // CHECK-2-NEXT: [ 6, callee1, 7 ] 100 // CHECK-2-NEXT: [ 6, callee2, 4 ] 101 // CHECK-2-NEXT: [ 7, callee1, 8 ] 102 // CHECK-2-NEXT: [ 7, callee2, 4 ] 103 // CHECK-2-NEXT: [ 8, callee1, 9 ] 104 // CHECK-2-NEXT: [ 8, callee2, 5 ] 105 // CHECK-2-NEXT: [ 9, callee1, 10 ] 106 // CHECK-2-NEXT: [ 9, callee2, 5 ] 107 // CHECK-3-LABEL: caller_with_vp1: 108 // CHECK-3-NEXT: Hash: 0x0000000000000000 109 // CHECK-3-NEXT: Counters: 110 // CHECK-3-NEXT: Function count 111 // CHECK-3-NEXT: Indirect Call Site Count: 10 112 // CHECK-3-NEXT: Indirect Target Results: 113 // CHECK-3-NEXT: [ 0, callee1, 1 ] 114 // CHECK-3-NEXT: [ 0, callee2, 1 ] 115 // CHECK-3-NEXT: [ 1, callee1, 2 ] 116 // CHECK-3-NEXT: [ 1, callee2, 1 ] 117 // CHECK-3-NEXT: [ 2, callee1, 3 ] 118 // CHECK-3-NEXT: [ 2, callee2, 2 ] 119 // CHECK-3-NEXT: [ 3, callee1, 4 ] 120 // CHECK-3-NEXT: [ 3, callee2, 2 ] 121 // CHECK-3-NEXT: [ 4, callee1, 5 ] 122 // CHECK-3-NEXT: [ 4, callee2, 3 ] 123 // CHECK-3-NEXT: [ 5, callee1, 6 ] 124 // CHECK-3-NEXT: [ 5, callee2, 3 ] 125 // CHECK-3-NEXT: [ 6, callee1, 7 ] 126 // CHECK-3-NEXT: [ 6, callee2, 4 ] 127 // CHECK-3-NEXT: [ 7, callee1, 8 ] 128 // CHECK-3-NEXT: [ 7, callee2, 4 ] 129 // CHECK-3-NEXT: [ 8, callee1, 9 ] 130 // CHECK-3-NEXT: [ 8, callee2, 5 ] 131 // CHECK-3-NEXT: [ 9, callee1, 10 ] 132 // CHECK-3-NEXT: [ 9, callee2, 5 ] 133 // CHECK-4-LABEL: caller_with_value_site_never_called1: 134 // CHECK-4-NEXT: Hash: 0x0000000000000000 135 // CHECK-4-NEXT: Counters: 136 // CHECK-4-NEXT: Function count: 137 // CHECK-4-NEXT: Indirect Call Site Count: 10 138 // CHECK-4-NEXT: Indirect Target Results: 139 // CHECK-5-LABEL: caller_without_value_site2: 140 // CHECK-5-NEXT: Hash: 0x0000000000000000 141 // CHECK-5-NEXT: Counters: 142 // CHECK-5-NEXT: Function count: 143 // CHECK-5-NEXT: Indirect Call Site Count: 0 144 // CHECK-5-NEXT: Indirect Target Results: 145 // CHECK-6-LABEL: caller_without_value_site1: 146 // CHECK-6-NEXT: Hash: 0x0000000000000000 147 // CHECK-6-NEXT: Counters: 148 // CHECK-6-NEXT: Function count: 149 // CHECK-6-NEXT: Indirect Call Site Count: 0 150 // CHECK-6-NEXT: Indirect Target Results: 151