1void callee_0() {}
2void callee_1() {}
3void callee_2() {}
4void callee_3() {}
5
6void *CalleeAddrs[] = {callee_0, callee_1, callee_2, callee_3};
7extern 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.
14int CallSeqTwoTarget_1[] = {0, 0, 0, 0, 0, 1, 1};
15int CallSeqTwoTarget_2[] = {1, 1, 0, 0, 0, 0, 0};
16int CallSeqTwoTarget_3[] = {1, 0, 0, 1, 0, 0, 0};
17int 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.
22int CallSeqThreeTarget_1[] = {0, 0, 0, 0, 0, 0, 1, 2, 1};
23int CallSeqThreeTarget_2[] = {1, 2, 1, 0, 0, 0, 0, 0, 0};
24int CallSeqThreeTarget_3[] = {1, 0, 0, 2, 0, 0, 0, 1, 0};
25int 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.
36int 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.
40int 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.
44int 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
47typedef void (*FPT)(void);
48
49
50// Testing value profiling eviction algorithm.
51FPT getCalleeFunc(int I) { return CalleeAddrs[I]; }
52
53int 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