callee_0()1 void callee_0() {}
callee_1()2 void callee_1() {}
callee_2()3 void callee_2() {}
callee_3()4 void callee_3() {}
5 
6 void *CalleeAddrs[] = {callee_0, callee_1, callee_2, callee_3};
7 extern void lprofSetMaxValsPerSite(unsigned);
8 
9 // sequences of callee ids
10 
11 // In the following sequences,
12 // there are two targets, the dominating target is
13 // target 0.
14 int CallSeqTwoTarget_1[] = {0, 0, 0, 0, 0, 1, 1};
15 int CallSeqTwoTarget_2[] = {1, 1, 0, 0, 0, 0, 0};
16 int CallSeqTwoTarget_3[] = {1, 0, 0, 1, 0, 0, 0};
17 int CallSeqTwoTarget_4[] = {0, 0, 0, 1, 0, 1, 0};
18 
19 // In the following sequences, there are three targets
20 // The dominating target is 0 and has > 50% of total
21 // counts.
22 int CallSeqThreeTarget_1[] = {0, 0, 0, 0, 0, 0, 1, 2, 1};
23 int CallSeqThreeTarget_2[] = {1, 2, 1, 0, 0, 0, 0, 0, 0};
24 int CallSeqThreeTarget_3[] = {1, 0, 0, 2, 0, 0, 0, 1, 0};
25 int CallSeqThreeTarget_4[] = {0, 0, 0, 1, 0, 1, 0, 0, 2};
26 
27 // Four target sequence --
28 // There are two cold targets which occupies the value counters
29 // early. There is also a very hot target and a medium hot target
30 // which are invoked in an interleaved fashion -- the length of each
31 // hot period in the sequence is shorter than the cold targets' count.
32 //  1. If only two values are tracked, the Hot and Medium hot targets
33 //     should surive in the end
34 //  2. If only three values are tracked, the top three targets should
35 //     surive in the end.
36 int CallSeqFourTarget_1[] = {1, 1, 1, 2, 2, 2, 2, 0, 0, 3, 0, 0, 3, 0, 0, 3,
37                              0, 0, 3, 0, 0, 3, 0, 0, 3, 0, 0, 3, 0, 0, 3};
38 
39 // Same as above, but the cold entries are invoked later.
40 int CallSeqFourTarget_2[] = {0, 0, 3, 0, 0, 3, 0, 0, 3, 0, 0, 3, 0, 0, 3, 0,
41                              0, 3, 0, 0, 3, 0, 0, 3, 1, 1, 1, 2, 2, 2, 2};
42 
43 // Same as above, but all the targets are interleaved.
44 int CallSeqFourTarget_3[] = {0, 3, 0, 0, 1, 3, 0, 0, 0, 2, 0, 0, 3, 3, 0, 3,
45                              2, 2, 0, 3, 3, 1, 0, 0, 1, 0, 0, 3, 0, 2, 0};
46 
47 typedef void (*FPT)(void);
48 
49 
50 // Testing value profiling eviction algorithm.
getCalleeFunc(int I)51 FPT getCalleeFunc(int I) { return CalleeAddrs[I]; }
52 
main()53 int main() {
54   int I;
55 
56 #define INDIRECT_CALLSITE(Sequence, NumValsTracked)                            \
57   lprofSetMaxValsPerSite(NumValsTracked);                                      \
58   for (I = 0; I < sizeof(Sequence) / sizeof(*Sequence); I++) {                 \
59     FPT FP = getCalleeFunc(Sequence[I]);                                       \
60     FP();                                                                      \
61   }
62 
63   // check site, target patterns
64   // CHECK: 0, callee_0
65   INDIRECT_CALLSITE(CallSeqTwoTarget_1, 1);
66 
67   // CHECK-NEXT: 1, callee_0
68   INDIRECT_CALLSITE(CallSeqTwoTarget_2, 1);
69 
70   // CHECK-NEXT: 2, callee_0
71   INDIRECT_CALLSITE(CallSeqTwoTarget_3, 1);
72 
73   // CHECK-NEXT: 3, callee_0
74   INDIRECT_CALLSITE(CallSeqTwoTarget_4, 1);
75 
76   // CHECK-NEXT: 4, callee_0
77   INDIRECT_CALLSITE(CallSeqThreeTarget_1, 1);
78 
79   // CHECK-NEXT: 5, callee_0
80   INDIRECT_CALLSITE(CallSeqThreeTarget_2, 1);
81 
82   // CHECK-NEXT: 6, callee_0
83   INDIRECT_CALLSITE(CallSeqThreeTarget_3, 1);
84 
85   // CHECK-NEXT: 7, callee_0
86   INDIRECT_CALLSITE(CallSeqThreeTarget_4, 1);
87 
88   // CHECK-NEXT: 8, callee_0
89   // CHECK-NEXT: 8, callee_1
90   INDIRECT_CALLSITE(CallSeqThreeTarget_1, 2);
91 
92   // CHECK-NEXT: 9, callee_0
93   // CHECK-NEXT: 9, callee_1
94   INDIRECT_CALLSITE(CallSeqThreeTarget_2, 2);
95 
96   // CHECK-NEXT: 10, callee_0
97   // CHECK-NEXT: 10, callee_1
98   INDIRECT_CALLSITE(CallSeqThreeTarget_3, 2);
99 
100   // CHECK-NEXT: 11, callee_0
101   // CHECK-NEXT: 11, callee_1
102   INDIRECT_CALLSITE(CallSeqThreeTarget_4, 2);
103 
104   // CHECK-NEXT: 12, callee_0
105   INDIRECT_CALLSITE(CallSeqFourTarget_1, 1);
106 
107   // CHECK-NEXT: 13, callee_0
108   INDIRECT_CALLSITE(CallSeqFourTarget_2, 1);
109 
110   // CHECK-NEXT: 14, callee_0
111   INDIRECT_CALLSITE(CallSeqFourTarget_3, 1);
112 
113   // CHECK-NEXT: 15, callee_0
114   // CHECK-NEXT: 15, callee_3
115   INDIRECT_CALLSITE(CallSeqFourTarget_1, 2);
116 
117   // CHECK-NEXT: 16, callee_0
118   // CHECK-NEXT: 16, callee_3
119   INDIRECT_CALLSITE(CallSeqFourTarget_2, 2);
120 
121   // CHECK-NEXT: 17, callee_0
122   // CHECK-NEXT: 17, callee_3
123   INDIRECT_CALLSITE(CallSeqFourTarget_3, 2);
124 
125   // CHECK-NEXT: 18, callee_0
126   // CHECK-NEXT: 18, callee_3
127   // CHECK-NEXT: 18, callee_2
128   INDIRECT_CALLSITE(CallSeqFourTarget_1, 3);
129 
130   // CHECK-NEXT: 19, callee_0
131   // CHECK-NEXT: 19, callee_3
132   // CHECK-NEXT: 19, callee_2
133   INDIRECT_CALLSITE(CallSeqFourTarget_2, 3);
134 
135   // CHECK-NEXT: 20, callee_0
136   // CHECK-NEXT: 20, callee_3
137   // CHECK-NEXT: 20, callee_2
138   INDIRECT_CALLSITE(CallSeqFourTarget_3, 3);
139 
140   return 0;
141 }
142