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;
}
|