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