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