Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Analysis/ProfileSummaryInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- ProfileSummaryInfo.cpp - Global profile summary information --------===//
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 a pass that provides access to the global profile summary
10
// information.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "llvm/Analysis/ProfileSummaryInfo.h"
15
#include "llvm/Analysis/BlockFrequencyInfo.h"
16
#include "llvm/IR/BasicBlock.h"
17
#include "llvm/IR/CallSite.h"
18
#include "llvm/IR/Metadata.h"
19
#include "llvm/IR/Module.h"
20
#include "llvm/IR/ProfileSummary.h"
21
using namespace llvm;
22
23
// The following two parameters determine the threshold for a count to be
24
// considered hot/cold. These two parameters are percentile values (multiplied
25
// by 10000). If the counts are sorted in descending order, the minimum count to
26
// reach ProfileSummaryCutoffHot gives the threshold to determine a hot count.
27
// Similarly, the minimum count to reach ProfileSummaryCutoffCold gives the
28
// threshold for determining cold count (everything <= this threshold is
29
// considered cold).
30
31
static cl::opt<int> ProfileSummaryCutoffHot(
32
    "profile-summary-cutoff-hot", cl::Hidden, cl::init(990000), cl::ZeroOrMore,
33
    cl::desc("A count is hot if it exceeds the minimum count to"
34
             " reach this percentile of total counts."));
35
36
static cl::opt<int> ProfileSummaryCutoffCold(
37
    "profile-summary-cutoff-cold", cl::Hidden, cl::init(999999), cl::ZeroOrMore,
38
    cl::desc("A count is cold if it is below the minimum count"
39
             " to reach this percentile of total counts."));
40
41
static cl::opt<unsigned> ProfileSummaryHugeWorkingSetSizeThreshold(
42
    "profile-summary-huge-working-set-size-threshold", cl::Hidden,
43
    cl::init(15000), cl::ZeroOrMore,
44
    cl::desc("The code working set size is considered huge if the number of"
45
             " blocks required to reach the -profile-summary-cutoff-hot"
46
             " percentile exceeds this count."));
47
48
// The next two options override the counts derived from summary computation and
49
// are useful for debugging purposes.
50
static cl::opt<int> ProfileSummaryHotCount(
51
    "profile-summary-hot-count", cl::ReallyHidden, cl::ZeroOrMore,
52
    cl::desc("A fixed hot count that overrides the count derived from"
53
             " profile-summary-cutoff-hot"));
54
55
static cl::opt<int> ProfileSummaryColdCount(
56
    "profile-summary-cold-count", cl::ReallyHidden, cl::ZeroOrMore,
57
    cl::desc("A fixed cold count that overrides the count derived from"
58
             " profile-summary-cutoff-cold"));
59
60
// Find the summary entry for a desired percentile of counts.
61
static const ProfileSummaryEntry &getEntryForPercentile(SummaryEntryVector &DS,
62
244
                                                        uint64_t Percentile) {
63
816
  auto It = partition_point(DS, [=](const ProfileSummaryEntry &Entry) {
64
816
    return Entry.Cutoff < Percentile;
65
816
  });
66
244
  // The required percentile has to be <= one of the percentiles in the
67
244
  // detailed summary.
68
244
  if (It == DS.end())
69
0
    report_fatal_error("Desired percentile exceeds the maximum cutoff");
70
244
  return *It;
71
244
}
72
73
// The profile summary metadata may be attached either by the frontend or by
74
// any backend passes (IR level instrumentation, for example). This method
75
// checks if the Summary is null and if so checks if the summary metadata is now
76
// available in the module and parses it to get the Summary object. Returns true
77
// if a valid Summary is available.
78
8.11M
bool ProfileSummaryInfo::computeSummary() {
79
8.11M
  if (Summary)
80
1.57k
    return true;
81
8.11M
  // First try to get context sensitive ProfileSummary.
82
8.11M
  auto *SummaryMD = M.getProfileSummary(/* IsCS */ true);
83
8.11M
  if (SummaryMD) {
84
2
    Summary.reset(ProfileSummary::getFromMD(SummaryMD));
85
2
    return true;
86
2
  }
87
8.11M
  // This will actually return PSK_Instr or PSK_Sample summary.
88
8.11M
  SummaryMD = M.getProfileSummary(/* IsCS */ false);
89
8.11M
  if (!SummaryMD)
90
8.11M
    return false;
91
107
  Summary.reset(ProfileSummary::getFromMD(SummaryMD));
92
107
  return true;
93
107
}
94
95
Optional<uint64_t>
96
ProfileSummaryInfo::getProfileCount(const Instruction *Inst,
97
                                    BlockFrequencyInfo *BFI,
98
534
                                    bool AllowSynthetic) {
99
534
  if (!Inst)
100
0
    return None;
101
534
  assert((isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) &&
102
534
         "We can only get profile count for call/invoke instruction.");
103
534
  if (hasSampleProfile()) {
104
85
    // In sample PGO mode, check if there is a profile metadata on the
105
85
    // instruction. If it is present, determine hotness solely based on that,
106
85
    // since the sampled entry count may not be accurate. If there is no
107
85
    // annotated on the instruction, return None.
108
85
    uint64_t TotalCount;
109
85
    if (Inst->extractProfTotalWeight(TotalCount))
110
44
      return TotalCount;
111
41
    return None;
112
41
  }
113
449
  if (BFI)
114
361
    return BFI->getBlockProfileCount(Inst->getParent(), AllowSynthetic);
115
88
  return None;
116
88
}
117
118
/// Returns true if the function's entry is hot. If it returns false, it
119
/// either means it is not hot or it is unknown whether it is hot or not (for
120
/// example, no profile data is available).
121
787k
bool ProfileSummaryInfo::isFunctionEntryHot(const Function *F) {
122
787k
  if (!F || !computeSummary())
123
786k
    return false;
124
90
  auto FunctionCount = F->getEntryCount();
125
90
  // FIXME: The heuristic used below for determining hotness is based on
126
90
  // preliminary SPEC tuning for inliner. This will eventually be a
127
90
  // convenience method that calls isHotCount.
128
90
  return FunctionCount && 
isHotCount(FunctionCount.getCount())86
;
129
90
}
130
131
/// Returns true if the function contains hot code. This can include a hot
132
/// function entry count, hot basic block, or (in the case of Sample PGO)
133
/// hot total call edge count.
134
/// If it returns false, it either means it is not hot or it is unknown
135
/// (for example, no profile data is available).
136
bool ProfileSummaryInfo::isFunctionHotInCallGraph(const Function *F,
137
490k
                                                  BlockFrequencyInfo &BFI) {
138
490k
  if (
!F490k
|| !computeSummary())
139
490k
    return false;
140
52
  if (auto FunctionCount = F->getEntryCount())
141
31
    if (isHotCount(FunctionCount.getCount()))
142
9
      return true;
143
43
144
43
  if (hasSampleProfile()) {
145
19
    uint64_t TotalCallCount = 0;
146
19
    for (const auto &BB : *F)
147
35
      for (const auto &I : BB)
148
80
        if (isa<CallInst>(I) || 
isa<InvokeInst>(I)60
)
149
20
          if (auto CallCount = getProfileCount(&I, nullptr))
150
9
            TotalCallCount += CallCount.getValue();
151
19
    if (isHotCount(TotalCallCount))
152
8
      return true;
153
35
  }
154
35
  for (const auto &BB : *F)
155
60
    if (isHotBlock(&BB, &BFI))
156
3
      return true;
157
35
  
return false32
;
158
35
}
159
160
/// Returns true if the function only contains cold code. This means that
161
/// the function entry and blocks are all cold, and (in the case of Sample PGO)
162
/// the total call edge count is cold.
163
/// If it returns false, it either means it is not cold or it is unknown
164
/// (for example, no profile data is available).
165
bool ProfileSummaryInfo::isFunctionColdInCallGraph(const Function *F,
166
490k
                                                   BlockFrequencyInfo &BFI) {
167
490k
  if (!F || 
!computeSummary()490k
)
168
490k
    return false;
169
41
  if (auto FunctionCount = F->getEntryCount())
170
23
    if (!isColdCount(FunctionCount.getCount()))
171
0
      return false;
172
41
173
41
  if (hasSampleProfile()) {
174
9
    uint64_t TotalCallCount = 0;
175
9
    for (const auto &BB : *F)
176
14
      for (const auto &I : BB)
177
29
        if (isa<CallInst>(I) || 
isa<InvokeInst>(I)18
)
178
11
          if (auto CallCount = getProfileCount(&I, nullptr))
179
4
            TotalCallCount += CallCount.getValue();
180
9
    if (!isColdCount(TotalCallCount))
181
1
      return false;
182
40
  }
183
40
  for (const auto &BB : *F)
184
56
    if (!isColdBlock(&BB, &BFI))
185
29
      return false;
186
40
  
return true11
;
187
40
}
188
189
/// Returns true if the function's entry is a cold. If it returns false, it
190
/// either means it is not cold or it is unknown whether it is cold or not (for
191
/// example, no profile data is available).
192
787k
bool ProfileSummaryInfo::isFunctionEntryCold(const Function *F) {
193
787k
  if (!F)
194
0
    return false;
195
787k
  if (F->hasFnAttribute(Attribute::Cold))
196
17
    return true;
197
787k
  if (!computeSummary())
198
787k
    return false;
199
31
  auto FunctionCount = F->getEntryCount();
200
31
  // FIXME: The heuristic used below for determining coldness is based on
201
31
  // preliminary SPEC tuning for inliner. This will eventually be a
202
31
  // convenience method that calls isHotCount.
203
31
  return FunctionCount && 
isColdCount(FunctionCount.getCount())25
;
204
31
}
205
206
/// Compute the hot and cold thresholds.
207
486k
void ProfileSummaryInfo::computeThresholds() {
208
486k
  if (!computeSummary())
209
486k
    return;
210
122
  auto &DetailedSummary = Summary->getDetailedSummary();
211
122
  auto &HotEntry =
212
122
      getEntryForPercentile(DetailedSummary, ProfileSummaryCutoffHot);
213
122
  HotCountThreshold = HotEntry.MinCount;
214
122
  if (ProfileSummaryHotCount.getNumOccurrences() > 0)
215
2
    HotCountThreshold = ProfileSummaryHotCount;
216
122
  auto &ColdEntry =
217
122
      getEntryForPercentile(DetailedSummary, ProfileSummaryCutoffCold);
218
122
  ColdCountThreshold = ColdEntry.MinCount;
219
122
  if (ProfileSummaryColdCount.getNumOccurrences() > 0)
220
2
    ColdCountThreshold = ProfileSummaryColdCount;
221
122
  assert(ColdCountThreshold <= HotCountThreshold &&
222
122
         "Cold count threshold cannot exceed hot count threshold!");
223
122
  HasHugeWorkingSetSize =
224
122
      HotEntry.NumCounts > ProfileSummaryHugeWorkingSetSizeThreshold;
225
122
}
226
227
486k
bool ProfileSummaryInfo::hasHugeWorkingSetSize() {
228
486k
  if (!HasHugeWorkingSetSize)
229
486k
    computeThresholds();
230
486k
  return HasHugeWorkingSetSize && 
HasHugeWorkingSetSize.getValue()63
;
231
486k
}
232
233
377
bool ProfileSummaryInfo::isHotCount(uint64_t C) {
234
377
  if (!HotCountThreshold)
235
114
    computeThresholds();
236
377
  return HotCountThreshold && 
C >= HotCountThreshold.getValue()367
;
237
377
}
238
239
198
bool ProfileSummaryInfo::isColdCount(uint64_t C) {
240
198
  if (!ColdCountThreshold)
241
22
    computeThresholds();
242
198
  return ColdCountThreshold && 
C <= ColdCountThreshold.getValue()188
;
243
198
}
244
245
8
uint64_t ProfileSummaryInfo::getOrCompHotCountThreshold() {
246
8
  if (!HotCountThreshold)
247
0
    computeThresholds();
248
8
  return HotCountThreshold ? HotCountThreshold.getValue() : UINT64_MAX;
249
8
}
250
251
0
uint64_t ProfileSummaryInfo::getOrCompColdCountThreshold() {
252
0
  if (!ColdCountThreshold)
253
0
    computeThresholds();
254
0
  return ColdCountThreshold ? ColdCountThreshold.getValue() : 0;
255
0
}
256
257
69
bool ProfileSummaryInfo::isHotBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI) {
258
69
  auto Count = BFI->getBlockProfileCount(BB);
259
69
  return Count && 
isHotCount(*Count)40
;
260
69
}
261
262
bool ProfileSummaryInfo::isColdBlock(const BasicBlock *BB,
263
123
                                  BlockFrequencyInfo *BFI) {
264
123
  auto Count = BFI->getBlockProfileCount(BB);
265
123
  return Count && 
isColdCount(*Count)90
;
266
123
}
267
268
bool ProfileSummaryInfo::isHotCallSite(const CallSite &CS,
269
66
                                       BlockFrequencyInfo *BFI) {
270
66
  auto C = getProfileCount(CS.getInstruction(), BFI);
271
66
  return C && 
isHotCount(*C)34
;
272
66
}
273
274
bool ProfileSummaryInfo::isColdCallSite(const CallSite &CS,
275
47
                                        BlockFrequencyInfo *BFI) {
276
47
  auto C = getProfileCount(CS.getInstruction(), BFI);
277
47
  if (C)
278
16
    return isColdCount(*C);
279
31
280
31
  // In SamplePGO, if the caller has been sampled, and there is no profile
281
31
  // annotated on the callsite, we consider the callsite as cold.
282
31
  return hasSampleProfile() && 
CS.getCaller()->hasProfileData()9
;
283
31
}
284
285
INITIALIZE_PASS(ProfileSummaryInfoWrapperPass, "profile-summary-info",
286
                "Profile summary info", false, true)
287
288
ProfileSummaryInfoWrapperPass::ProfileSummaryInfoWrapperPass()
289
59.0k
    : ImmutablePass(ID) {
290
59.0k
  initializeProfileSummaryInfoWrapperPassPass(*PassRegistry::getPassRegistry());
291
59.0k
}
292
293
58.9k
bool ProfileSummaryInfoWrapperPass::doInitialization(Module &M) {
294
58.9k
  PSI.reset(new ProfileSummaryInfo(M));
295
58.9k
  return false;
296
58.9k
}
297
298
58.8k
bool ProfileSummaryInfoWrapperPass::doFinalization(Module &M) {
299
58.8k
  PSI.reset();
300
58.8k
  return false;
301
58.8k
}
302
303
AnalysisKey ProfileSummaryAnalysis::Key;
304
ProfileSummaryInfo ProfileSummaryAnalysis::run(Module &M,
305
281
                                               ModuleAnalysisManager &) {
306
281
  return ProfileSummaryInfo(M);
307
281
}
308
309
PreservedAnalyses ProfileSummaryPrinterPass::run(Module &M,
310
4
                                                 ModuleAnalysisManager &AM) {
311
4
  ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M);
312
4
313
4
  OS << "Functions in " << M.getName() << " with hot/cold annotations: \n";
314
12
  for (auto &F : M) {
315
12
    OS << F.getName();
316
12
    if (PSI.isFunctionEntryHot(&F))
317
4
      OS << " :hot entry ";
318
8
    else if (PSI.isFunctionEntryCold(&F))
319
4
      OS << " :cold entry ";
320
12
    OS << "\n";
321
12
  }
322
4
  return PreservedAnalyses::all();
323
4
}
324
325
char ProfileSummaryInfoWrapperPass::ID = 0;