Coverage Report

Created: 2018-12-11 00:00

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