reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    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;
}