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