Coverage Report

Created: 2019-03-22 08:08

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/Analysis/ProfileSummaryInfo.h
Line
Count
Source (jump to first uncovered line)
1
//===- llvm/Analysis/ProfileSummaryInfo.h - profile summary ---*- C++ -*-===//
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 profile summary
10
// information.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_ANALYSIS_PROFILE_SUMMARY_INFO_H
15
#define LLVM_ANALYSIS_PROFILE_SUMMARY_INFO_H
16
17
#include "llvm/ADT/ArrayRef.h"
18
#include "llvm/ADT/DenseMap.h"
19
#include "llvm/ADT/SmallSet.h"
20
#include "llvm/IR/Function.h"
21
#include "llvm/IR/Instructions.h"
22
#include "llvm/IR/PassManager.h"
23
#include "llvm/IR/ProfileSummary.h"
24
#include "llvm/IR/ValueHandle.h"
25
#include "llvm/Pass.h"
26
#include <memory>
27
28
namespace llvm {
29
class BasicBlock;
30
class BlockFrequencyInfo;
31
class CallSite;
32
class ProfileSummary;
33
/// Analysis providing profile information.
34
///
35
/// This is an immutable analysis pass that provides ability to query global
36
/// (program-level) profile information. The main APIs are isHotCount and
37
/// isColdCount that tells whether a given profile count is considered hot/cold
38
/// based on the profile summary. This also provides convenience methods to
39
/// check whether a function is hot or cold.
40
41
// FIXME: Provide convenience methods to determine hotness/coldness of other IR
42
// units. This would require making this depend on BFI.
43
class ProfileSummaryInfo {
44
private:
45
  Module &M;
46
  std::unique_ptr<ProfileSummary> Summary;
47
  bool computeSummary();
48
  void computeThresholds();
49
  // Count thresholds to answer isHotCount and isColdCount queries.
50
  Optional<uint64_t> HotCountThreshold, ColdCountThreshold;
51
  // True if the working set size of the code is considered huge,
52
  // because the number of profile counts required to reach the hot
53
  // percentile is above a huge threshold.
54
  Optional<bool> HasHugeWorkingSetSize;
55
56
public:
57
55.4k
  ProfileSummaryInfo(Module &M) : M(M) {}
58
  ProfileSummaryInfo(ProfileSummaryInfo &&Arg)
59
452
      : M(Arg.M), Summary(std::move(Arg.Summary)) {}
60
61
  /// Returns true if profile summary is available.
62
1.51M
  bool hasProfileSummary() { return computeSummary(); }
63
64
  /// Returns true if module \c M has sample profile.
65
628
  bool hasSampleProfile() {
66
628
    return hasProfileSummary() &&
67
628
           
Summary->getKind() == ProfileSummary::PSK_Sample338
;
68
628
  }
69
70
  /// Returns true if module \c M has instrumentation profile.
71
7
  bool hasInstrumentationProfile() {
72
7
    return hasProfileSummary() &&
73
7
           
Summary->getKind() == ProfileSummary::PSK_Instr6
;
74
7
  }
75
76
  /// Returns true if module \c M has context sensitive instrumentation profile.
77
  bool hasCSInstrumentationProfile() {
78
    return hasProfileSummary() &&
79
           Summary->getKind() == ProfileSummary::PSK_CSInstr;
80
  }
81
82
  /// Handle the invalidation of this information.
83
  ///
84
  /// When used as a result of \c ProfileSummaryAnalysis this method will be
85
  /// called when the module this was computed for changes. Since profile
86
  /// summary is immutable after it is annotated on the module, we return false
87
  /// here.
88
  bool invalidate(Module &, const PreservedAnalyses &,
89
251
                  ModuleAnalysisManager::Invalidator &) {
90
251
    return false;
91
251
  }
92
93
  /// Returns the profile count for \p CallInst.
94
  Optional<uint64_t> getProfileCount(const Instruction *CallInst,
95
                                     BlockFrequencyInfo *BFI);
96
  /// Returns true if the working set size of the code is considered huge.
97
  bool hasHugeWorkingSetSize();
98
  /// Returns true if \p F has hot function entry.
99
  bool isFunctionEntryHot(const Function *F);
100
  /// Returns true if \p F contains hot code.
101
  bool isFunctionHotInCallGraph(const Function *F, BlockFrequencyInfo &BFI);
102
  /// Returns true if \p F has cold function entry.
103
  bool isFunctionEntryCold(const Function *F);
104
  /// Returns true if \p F contains only cold code.
105
  bool isFunctionColdInCallGraph(const Function *F, BlockFrequencyInfo &BFI);
106
  /// Returns true if count \p C is considered hot.
107
  bool isHotCount(uint64_t C);
108
  /// Returns true if count \p C is considered cold.
109
  bool isColdCount(uint64_t C);
110
  /// Returns true if BasicBlock \p BB is considered hot.
111
  bool isHotBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI);
112
  /// Returns true if BasicBlock \p BB is considered cold.
113
  bool isColdBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI);
114
  /// Returns true if CallSite \p CS is considered hot.
115
  bool isHotCallSite(const CallSite &CS, BlockFrequencyInfo *BFI);
116
  /// Returns true if Callsite \p CS is considered cold.
117
  bool isColdCallSite(const CallSite &CS, BlockFrequencyInfo *BFI);
118
  /// Returns HotCountThreshold if set. Recompute HotCountThreshold
119
  /// if not set.
120
  uint64_t getOrCompHotCountThreshold();
121
  /// Returns ColdCountThreshold if set. Recompute HotCountThreshold
122
  /// if not set.
123
  uint64_t getOrCompColdCountThreshold();
124
  /// Returns HotCountThreshold if set.
125
  uint64_t getHotCountThreshold() {
126
    return HotCountThreshold ? HotCountThreshold.getValue() : 0;
127
  }
128
  /// Returns ColdCountThreshold if set.
129
  uint64_t getColdCountThreshold() {
130
    return ColdCountThreshold ? ColdCountThreshold.getValue() : 0;
131
  }
132
};
133
134
/// An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
135
class ProfileSummaryInfoWrapperPass : public ImmutablePass {
136
  std::unique_ptr<ProfileSummaryInfo> PSI;
137
138
public:
139
  static char ID;
140
  ProfileSummaryInfoWrapperPass();
141
142
1.31M
  ProfileSummaryInfo &getPSI() { return *PSI; }
143
0
  const ProfileSummaryInfo &getPSI() const { return *PSI; }
144
145
  bool doInitialization(Module &M) override;
146
  bool doFinalization(Module &M) override;
147
55.2k
  void getAnalysisUsage(AnalysisUsage &AU) const override {
148
55.2k
    AU.setPreservesAll();
149
55.2k
  }
150
};
151
152
/// An analysis pass based on the new PM to deliver ProfileSummaryInfo.
153
class ProfileSummaryAnalysis
154
    : public AnalysisInfoMixin<ProfileSummaryAnalysis> {
155
public:
156
  typedef ProfileSummaryInfo Result;
157
158
  Result run(Module &M, ModuleAnalysisManager &);
159
160
private:
161
  friend AnalysisInfoMixin<ProfileSummaryAnalysis>;
162
  static AnalysisKey Key;
163
};
164
165
/// Printer pass that uses \c ProfileSummaryAnalysis.
166
class ProfileSummaryPrinterPass
167
    : public PassInfoMixin<ProfileSummaryPrinterPass> {
168
  raw_ostream &OS;
169
170
public:
171
4
  explicit ProfileSummaryPrinterPass(raw_ostream &OS) : OS(OS) {}
172
  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
173
};
174
175
} // end namespace llvm
176
177
#endif