Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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_PROFILESUMMARYINFO_H
15
#define LLVM_ANALYSIS_PROFILESUMMARYINFO_H
16
 
17
#include "llvm/ADT/DenseMap.h"
18
#include "llvm/IR/PassManager.h"
19
#include "llvm/IR/ProfileSummary.h"
20
#include "llvm/Pass.h"
21
#include <memory>
22
#include <optional>
23
 
24
namespace llvm {
25
class BasicBlock;
26
class BlockFrequencyInfo;
27
class CallBase;
28
class Function;
29
 
30
/// Analysis providing profile information.
31
///
32
/// This is an immutable analysis pass that provides ability to query global
33
/// (program-level) profile information. The main APIs are isHotCount and
34
/// isColdCount that tells whether a given profile count is considered hot/cold
35
/// based on the profile summary. This also provides convenience methods to
36
/// check whether a function is hot or cold.
37
 
38
// FIXME: Provide convenience methods to determine hotness/coldness of other IR
39
// units. This would require making this depend on BFI.
40
class ProfileSummaryInfo {
41
private:
42
  const Module *M;
43
  std::unique_ptr<ProfileSummary> Summary;
44
  void computeThresholds();
45
  // Count thresholds to answer isHotCount and isColdCount queries.
46
  std::optional<uint64_t> HotCountThreshold, ColdCountThreshold;
47
  // True if the working set size of the code is considered huge,
48
  // because the number of profile counts required to reach the hot
49
  // percentile is above a huge threshold.
50
  std::optional<bool> HasHugeWorkingSetSize;
51
  // True if the working set size of the code is considered large,
52
  // because the number of profile counts required to reach the hot
53
  // percentile is above a large threshold.
54
  std::optional<bool> HasLargeWorkingSetSize;
55
  // Compute the threshold for a given cutoff.
56
  std::optional<uint64_t> computeThreshold(int PercentileCutoff) const;
57
  // The map that caches the threshold values. The keys are the percentile
58
  // cutoff values and the values are the corresponding threshold values.
59
  mutable DenseMap<int, uint64_t> ThresholdCache;
60
 
61
public:
62
  ProfileSummaryInfo(const Module &M) : M(&M) { refresh(); }
63
  ProfileSummaryInfo(ProfileSummaryInfo &&Arg) = default;
64
 
65
  /// If no summary is present, attempt to refresh.
66
  void refresh();
67
 
68
  /// Returns true if profile summary is available.
69
  bool hasProfileSummary() const { return Summary != nullptr; }
70
 
71
  /// Returns true if module \c M has sample profile.
72
  bool hasSampleProfile() const {
73
    return hasProfileSummary() &&
74
           Summary->getKind() == ProfileSummary::PSK_Sample;
75
  }
76
 
77
  /// Returns true if module \c M has instrumentation profile.
78
  bool hasInstrumentationProfile() const {
79
    return hasProfileSummary() &&
80
           Summary->getKind() == ProfileSummary::PSK_Instr;
81
  }
82
 
83
  /// Returns true if module \c M has context sensitive instrumentation profile.
84
  bool hasCSInstrumentationProfile() const {
85
    return hasProfileSummary() &&
86
           Summary->getKind() == ProfileSummary::PSK_CSInstr;
87
  }
88
 
89
  /// Handle the invalidation of this information.
90
  ///
91
  /// When used as a result of \c ProfileSummaryAnalysis this method will be
92
  /// called when the module this was computed for changes. Since profile
93
  /// summary is immutable after it is annotated on the module, we return false
94
  /// here.
95
  bool invalidate(Module &, const PreservedAnalyses &,
96
                  ModuleAnalysisManager::Invalidator &) {
97
    return false;
98
  }
99
 
100
  /// Returns the profile count for \p CallInst.
101
  std::optional<uint64_t> getProfileCount(const CallBase &CallInst,
102
                                          BlockFrequencyInfo *BFI,
103
                                          bool AllowSynthetic = false) const;
104
  /// Returns true if module \c M has partial-profile sample profile.
105
  bool hasPartialSampleProfile() const;
106
  /// Returns true if the working set size of the code is considered huge.
107
  bool hasHugeWorkingSetSize() const;
108
  /// Returns true if the working set size of the code is considered large.
109
  bool hasLargeWorkingSetSize() const;
110
  /// Returns true if \p F has hot function entry.
111
  bool isFunctionEntryHot(const Function *F) const;
112
  /// Returns true if \p F contains hot code.
113
  bool isFunctionHotInCallGraph(const Function *F,
114
                                BlockFrequencyInfo &BFI) const;
115
  /// Returns true if \p F has cold function entry.
116
  bool isFunctionEntryCold(const Function *F) const;
117
  /// Returns true if \p F contains only cold code.
118
  bool isFunctionColdInCallGraph(const Function *F,
119
                                 BlockFrequencyInfo &BFI) const;
120
  /// Returns true if the hotness of \p F is unknown.
121
  bool isFunctionHotnessUnknown(const Function &F) const;
122
  /// Returns true if \p F contains hot code with regard to a given hot
123
  /// percentile cutoff value.
124
  bool isFunctionHotInCallGraphNthPercentile(int PercentileCutoff,
125
                                             const Function *F,
126
                                             BlockFrequencyInfo &BFI) const;
127
  /// Returns true if \p F contains cold code with regard to a given cold
128
  /// percentile cutoff value.
129
  bool isFunctionColdInCallGraphNthPercentile(int PercentileCutoff,
130
                                              const Function *F,
131
                                              BlockFrequencyInfo &BFI) const;
132
  /// Returns true if count \p C is considered hot.
133
  bool isHotCount(uint64_t C) const;
134
  /// Returns true if count \p C is considered cold.
135
  bool isColdCount(uint64_t C) const;
136
  /// Returns true if count \p C is considered hot with regard to a given
137
  /// hot percentile cutoff value.
138
  /// PercentileCutoff is encoded as a 6 digit decimal fixed point number, where
139
  /// the first two digits are the whole part. E.g. 995000 for 99.5 percentile.
140
  bool isHotCountNthPercentile(int PercentileCutoff, uint64_t C) const;
141
  /// Returns true if count \p C is considered cold with regard to a given
142
  /// cold percentile cutoff value.
143
  /// PercentileCutoff is encoded as a 6 digit decimal fixed point number, where
144
  /// the first two digits are the whole part. E.g. 995000 for 99.5 percentile.
145
  bool isColdCountNthPercentile(int PercentileCutoff, uint64_t C) const;
146
  /// Returns true if BasicBlock \p BB is considered hot.
147
  bool isHotBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI) const;
148
  /// Returns true if BasicBlock \p BB is considered cold.
149
  bool isColdBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI) const;
150
  /// Returns true if BasicBlock \p BB is considered hot with regard to a given
151
  /// hot percentile cutoff value.
152
  /// PercentileCutoff is encoded as a 6 digit decimal fixed point number, where
153
  /// the first two digits are the whole part. E.g. 995000 for 99.5 percentile.
154
  bool isHotBlockNthPercentile(int PercentileCutoff, const BasicBlock *BB,
155
                               BlockFrequencyInfo *BFI) const;
156
  /// Returns true if BasicBlock \p BB is considered cold with regard to a given
157
  /// cold percentile cutoff value.
158
  /// PercentileCutoff is encoded as a 6 digit decimal fixed point number, where
159
  /// the first two digits are the whole part. E.g. 995000 for 99.5 percentile.
160
  bool isColdBlockNthPercentile(int PercentileCutoff, const BasicBlock *BB,
161
                                BlockFrequencyInfo *BFI) const;
162
  /// Returns true if the call site \p CB is considered hot.
163
  bool isHotCallSite(const CallBase &CB, BlockFrequencyInfo *BFI) const;
164
  /// Returns true if call site \p CB is considered cold.
165
  bool isColdCallSite(const CallBase &CB, BlockFrequencyInfo *BFI) const;
166
  /// Returns HotCountThreshold if set. Recompute HotCountThreshold
167
  /// if not set.
168
  uint64_t getOrCompHotCountThreshold() const;
169
  /// Returns ColdCountThreshold if set. Recompute HotCountThreshold
170
  /// if not set.
171
  uint64_t getOrCompColdCountThreshold() const;
172
  /// Returns HotCountThreshold if set.
173
  uint64_t getHotCountThreshold() const {
174
    return HotCountThreshold.value_or(0);
175
  }
176
  /// Returns ColdCountThreshold if set.
177
  uint64_t getColdCountThreshold() const {
178
    return ColdCountThreshold.value_or(0);
179
  }
180
 
181
 private:
182
   template <bool isHot>
183
   bool isFunctionHotOrColdInCallGraphNthPercentile(
184
       int PercentileCutoff, const Function *F, BlockFrequencyInfo &BFI) const;
185
   template <bool isHot>
186
   bool isHotOrColdCountNthPercentile(int PercentileCutoff, uint64_t C) const;
187
   template <bool isHot>
188
   bool isHotOrColdBlockNthPercentile(int PercentileCutoff,
189
                                      const BasicBlock *BB,
190
                                      BlockFrequencyInfo *BFI) const;
191
};
192
 
193
/// An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
194
class ProfileSummaryInfoWrapperPass : public ImmutablePass {
195
  std::unique_ptr<ProfileSummaryInfo> PSI;
196
 
197
public:
198
  static char ID;
199
  ProfileSummaryInfoWrapperPass();
200
 
201
  ProfileSummaryInfo &getPSI() { return *PSI; }
202
  const ProfileSummaryInfo &getPSI() const { return *PSI; }
203
 
204
  bool doInitialization(Module &M) override;
205
  bool doFinalization(Module &M) override;
206
  void getAnalysisUsage(AnalysisUsage &AU) const override {
207
    AU.setPreservesAll();
208
  }
209
};
210
 
211
/// An analysis pass based on the new PM to deliver ProfileSummaryInfo.
212
class ProfileSummaryAnalysis
213
    : public AnalysisInfoMixin<ProfileSummaryAnalysis> {
214
public:
215
  typedef ProfileSummaryInfo Result;
216
 
217
  Result run(Module &M, ModuleAnalysisManager &);
218
 
219
private:
220
  friend AnalysisInfoMixin<ProfileSummaryAnalysis>;
221
  static AnalysisKey Key;
222
};
223
 
224
/// Printer pass that uses \c ProfileSummaryAnalysis.
225
class ProfileSummaryPrinterPass
226
    : public PassInfoMixin<ProfileSummaryPrinterPass> {
227
  raw_ostream &OS;
228
 
229
public:
230
  explicit ProfileSummaryPrinterPass(raw_ostream &OS) : OS(OS) {}
231
  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
232
};
233
 
234
} // end namespace llvm
235
 
236
#endif