1 // RUN: %clang_profgen -mllvm --enable-value-profiling=true -mllvm -vp-static-alloc=true -mllvm -vp-counters-per-site=3 -O2 -o %t %s 2 // RUN: %run %t %t.profraw 3 // RUN: llvm-profdata merge -o %t.profdata %t.profraw 4 // RUN: llvm-profdata show --all-functions --counts --ic-targets %t.profdata > %t.profdump 5 // RUN: FileCheck --input-file %t.profdump %s --check-prefix=FOO 6 // RUN: FileCheck --input-file %t.profdump %s --check-prefix=BAR 7 8 #include <stdint.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <sys/types.h> 12 #include <unistd.h> 13 14 int __llvm_profile_runtime = 0; 15 int __llvm_profile_write_file(); 16 void __llvm_profile_reset_counters(void); 17 void __llvm_profile_merge_from_buffer(const char *, uint64_t); 18 void __llvm_profile_set_filename(const char *); 19 struct __llvm_profile_data; 20 struct ValueProfData; 21 void lprofMergeValueProfData(struct ValueProfData *, struct __llvm_profile_data *); 22 /* Force the vp merger module to be linked in. */ 23 void *Dummy = &lprofMergeValueProfData; 24 25 void callee1() {} 26 void callee2() {} 27 void callee3() {} 28 29 typedef void (*FP)(void); 30 FP Fps[3] = {callee1, callee2, callee3}; 31 32 void foo(int N) { 33 int I, J; 34 for (I = 0; I < 3; I++) 35 for (J = 0; J < I * 2 + 1; J++) 36 Fps[I](); 37 38 if (N < 2) 39 return; 40 41 for (I = 0; I < 3; I++) 42 for (J = 0; J < I * 2 + 1; J++) 43 Fps[2 - I](); 44 } 45 46 /* This function is not profiled */ 47 void bar(void) { 48 int I; 49 for (I = 0; I < 20; I++) 50 Fps[I % 3](); 51 } 52 53 int main(int argc, const char *argv[]) { 54 int i; 55 if (argc < 2) 56 return 1; 57 58 const char *FileN = argv[1]; 59 __llvm_profile_set_filename(FileN); 60 /* Start profiling. */ 61 __llvm_profile_reset_counters(); 62 foo(1); 63 /* End profiling by freezing counters and 64 * dump them to the file. */ 65 if (__llvm_profile_write_file()) 66 return 1; 67 68 /* Read profile data into buffer. */ 69 FILE *File = fopen(FileN, "r"); 70 if (!File) 71 return 1; 72 fseek(File, 0, SEEK_END); 73 uint64_t Size = ftell(File); 74 fseek(File, 0, SEEK_SET); 75 char *Buffer = (char *)malloc(Size); 76 if (Size != fread(Buffer, 1, Size, File)) 77 return 1; 78 fclose(File); 79 80 /* Its profile will be discarded. */ 81 for (i = 0; i < 10; i++) 82 bar(); 83 84 /* Start profiling again and merge in previously 85 saved counters in buffer. */ 86 __llvm_profile_reset_counters(); 87 __llvm_profile_merge_from_buffer(Buffer, Size); 88 foo(2); 89 /* End profiling. */ 90 truncate(FileN, 0); 91 if (__llvm_profile_write_file()) 92 return 1; 93 94 /* Its profile will be discarded. */ 95 bar(); 96 97 return 0; 98 } 99 100 // FOO-LABEL: foo: 101 // FOO: Indirect Target Results: 102 // FOO-NEXT: [ 0, callee3, 10 ] 103 // FOO-NEXT: [ 0, callee2, 6 ] 104 // FOO-NEXT: [ 0, callee1, 2 ] 105 // FOO-NEXT: [ 1, callee1, 5 ] 106 // FOO-NEXT: [ 1, callee2, 3 ] 107 // FOO-NEXT: [ 1, callee3, 1 ] 108 109 // BAR-LABEL: bar: 110 // BAR: [ 0, callee1, 0 ] 111 // BAR-NEXT: [ 0, callee2, 0 ] 112 // BAR-NEXT: [ 0, callee3, 0 ] 113 114