1//=-- ProfilesummaryBuilder.cpp - Profile summary computation ---------------=//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains support for computing profile summary data.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/IR/Attributes.h"
15#include "llvm/IR/Constants.h"
16#include "llvm/IR/Function.h"
17#include "llvm/IR/Metadata.h"
18#include "llvm/IR/Type.h"
19#include "llvm/ProfileData/InstrProf.h"
20#include "llvm/ProfileData/ProfileCommon.h"
21#include "llvm/ProfileData/SampleProf.h"
22#include "llvm/Support/Casting.h"
23
24using namespace llvm;
25
26// A set of cutoff values. Each value, when divided by ProfileSummary::Scale
27// (which is 1000000) is a desired percentile of total counts.
28static const uint32_t DefaultCutoffsData[] = {
29    10000,  /*  1% */
30    100000, /* 10% */
31    200000, 300000, 400000, 500000, 600000, 500000, 600000, 700000,
32    800000, 900000, 950000, 990000, 999000, 999900, 999990, 999999};
33const ArrayRef<uint32_t> ProfileSummaryBuilder::DefaultCutoffs =
34    DefaultCutoffsData;
35
36void InstrProfSummaryBuilder::addRecord(const InstrProfRecord &R) {
37  // The first counter is not necessarily an entry count for IR
38  // instrumentation profiles.
39  // Eventually MaxFunctionCount will become obsolete and this can be
40  // removed.
41  addEntryCount(R.Counts[0]);
42  for (size_t I = 1, E = R.Counts.size(); I < E; ++I)
43    addInternalCount(R.Counts[I]);
44}
45
46// To compute the detailed summary, we consider each line containing samples as
47// equivalent to a block with a count in the instrumented profile.
48void SampleProfileSummaryBuilder::addRecord(
49    const sampleprof::FunctionSamples &FS) {
50  NumFunctions++;
51  if (FS.getHeadSamples() > MaxFunctionCount)
52    MaxFunctionCount = FS.getHeadSamples();
53  for (const auto &I : FS.getBodySamples())
54    addCount(I.second.getSamples());
55}
56
57// The argument to this method is a vector of cutoff percentages and the return
58// value is a vector of (Cutoff, MinCount, NumCounts) triplets.
59void ProfileSummaryBuilder::computeDetailedSummary() {
60  if (DetailedSummaryCutoffs.empty())
61    return;
62  auto Iter = CountFrequencies.begin();
63  auto End = CountFrequencies.end();
64  std::sort(DetailedSummaryCutoffs.begin(), DetailedSummaryCutoffs.end());
65
66  uint32_t CountsSeen = 0;
67  uint64_t CurrSum = 0, Count = 0;
68
69  for (uint32_t Cutoff : DetailedSummaryCutoffs) {
70    assert(Cutoff <= 999999);
71    APInt Temp(128, TotalCount);
72    APInt N(128, Cutoff);
73    APInt D(128, ProfileSummary::Scale);
74    Temp *= N;
75    Temp = Temp.sdiv(D);
76    uint64_t DesiredCount = Temp.getZExtValue();
77    assert(DesiredCount <= TotalCount);
78    while (CurrSum < DesiredCount && Iter != End) {
79      Count = Iter->first;
80      uint32_t Freq = Iter->second;
81      CurrSum += (Count * Freq);
82      CountsSeen += Freq;
83      Iter++;
84    }
85    assert(CurrSum >= DesiredCount);
86    ProfileSummaryEntry PSE = {Cutoff, Count, CountsSeen};
87    DetailedSummary.push_back(PSE);
88  }
89}
90
91std::unique_ptr<ProfileSummary> SampleProfileSummaryBuilder::getSummary() {
92  computeDetailedSummary();
93  return llvm::make_unique<ProfileSummary>(
94      ProfileSummary::PSK_Sample, DetailedSummary, TotalCount, MaxCount, 0,
95      MaxFunctionCount, NumCounts, NumFunctions);
96}
97
98std::unique_ptr<ProfileSummary> InstrProfSummaryBuilder::getSummary() {
99  computeDetailedSummary();
100  return llvm::make_unique<ProfileSummary>(
101      ProfileSummary::PSK_Instr, DetailedSummary, TotalCount, MaxCount,
102      MaxInternalBlockCount, MaxFunctionCount, NumCounts, NumFunctions);
103}
104
105void InstrProfSummaryBuilder::addEntryCount(uint64_t Count) {
106  addCount(Count);
107  NumFunctions++;
108  if (Count > MaxFunctionCount)
109    MaxFunctionCount = Count;
110}
111
112void InstrProfSummaryBuilder::addInternalCount(uint64_t Count) {
113  addCount(Count);
114  if (Count > MaxInternalBlockCount)
115    MaxInternalBlockCount = Count;
116}
117