Home | History | Annotate | Download | only in profile
      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