1 | void callee_0() {} |
2 | void callee_1() {} |
3 | void callee_2() {} |
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. |
51 | FPT getCalleeFunc(int I) { return CalleeAddrs[I]; } |
52 | |
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 | |