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