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