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