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