Coverage Report

Created: 2019-02-20 07:29

/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.0k
  ProfileSummaryInfo(Module &M) : M(M) {}
58
  ProfileSummaryInfo(ProfileSummaryInfo &&Arg)
59
400
      : M(Arg.M), Summary(std::move(Arg.Summary)) {}
60
61
  /// Returns true if profile summary is available.
62
1.49M
  bool hasProfileSummary() { return computeSummary(); }
63
64
  /// Returns true if module \c M has sample profile.
65
551
  bool hasSampleProfile() {
66
551
    return hasProfileSummary() &&
67
551
           
Summary->getKind() == ProfileSummary::PSK_Sample262
;
68
551
  }
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
  /// Handle the invalidation of this information.
77
  ///
78
  /// When used as a result of \c ProfileSummaryAnalysis this method will be
79
  /// called when the module this was computed for changes. Since profile
80
  /// summary is immutable after it is annotated on the module, we return false
81
  /// here.
82
  bool invalidate(Module &, const PreservedAnalyses &,
83
211
                  ModuleAnalysisManager::Invalidator &) {
84
211
    return false;
85
211
  }
86
87
  /// Returns the profile count for \p CallInst.
88
  Optional<uint64_t> getProfileCount(const Instruction *CallInst,
89
                                     BlockFrequencyInfo *BFI);
90
  /// Returns true if the working set size of the code is considered huge.
91
  bool hasHugeWorkingSetSize();
92
  /// Returns true if \p F has hot function entry.
93
  bool isFunctionEntryHot(const Function *F);
94
  /// Returns true if \p F contains hot code.
95
  bool isFunctionHotInCallGraph(const Function *F, BlockFrequencyInfo &BFI);
96
  /// Returns true if \p F has cold function entry.
97
  bool isFunctionEntryCold(const Function *F);
98
  /// Returns true if \p F contains only cold code.
99
  bool isFunctionColdInCallGraph(const Function *F, BlockFrequencyInfo &BFI);
100
  /// Returns true if count \p C is considered hot.
101
  bool isHotCount(uint64_t C);
102
  /// Returns true if count \p C is considered cold.
103
  bool isColdCount(uint64_t C);
104
  /// Returns true if BasicBlock \p BB is considered hot.
105
  bool isHotBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI);
106
  /// Returns true if BasicBlock \p BB is considered cold.
107
  bool isColdBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI);
108
  /// Returns true if CallSite \p CS is considered hot.
109
  bool isHotCallSite(const CallSite &CS, BlockFrequencyInfo *BFI);
110
  /// Returns true if Callsite \p CS is considered cold.
111
  bool isColdCallSite(const CallSite &CS, BlockFrequencyInfo *BFI);
112
  /// Returns HotCountThreshold if set. Recompute HotCountThreshold
113
  /// if not set.
114
  uint64_t getOrCompHotCountThreshold();
115
  /// Returns ColdCountThreshold if set. Recompute HotCountThreshold
116
  /// if not set.
117
  uint64_t getOrCompColdCountThreshold();
118
  /// Returns HotCountThreshold if set.
119
  uint64_t getHotCountThreshold() {
120
    return HotCountThreshold ? HotCountThreshold.getValue() : 0;
121
  }
122
  /// Returns ColdCountThreshold if set.
123
  uint64_t getColdCountThreshold() {
124
    return ColdCountThreshold ? ColdCountThreshold.getValue() : 0;
125
  }
126
};
127
128
/// An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
129
class ProfileSummaryInfoWrapperPass : public ImmutablePass {
130
  std::unique_ptr<ProfileSummaryInfo> PSI;
131
132
public:
133
  static char ID;
134
  ProfileSummaryInfoWrapperPass();
135
136
1.30M
  ProfileSummaryInfo &getPSI() { return *PSI; }
137
0
  const ProfileSummaryInfo &getPSI() const { return *PSI; }
138
139
  bool doInitialization(Module &M) override;
140
  bool doFinalization(Module &M) override;
141
54.7k
  void getAnalysisUsage(AnalysisUsage &AU) const override {
142
54.7k
    AU.setPreservesAll();
143
54.7k
  }
144
};
145
146
/// An analysis pass based on the new PM to deliver ProfileSummaryInfo.
147
class ProfileSummaryAnalysis
148
    : public AnalysisInfoMixin<ProfileSummaryAnalysis> {
149
public:
150
  typedef ProfileSummaryInfo Result;
151
152
  Result run(Module &M, ModuleAnalysisManager &);
153
154
private:
155
  friend AnalysisInfoMixin<ProfileSummaryAnalysis>;
156
  static AnalysisKey Key;
157
};
158
159
/// Printer pass that uses \c ProfileSummaryAnalysis.
160
class ProfileSummaryPrinterPass
161
    : public PassInfoMixin<ProfileSummaryPrinterPass> {
162
  raw_ostream &OS;
163
164
public:
165
4
  explicit ProfileSummaryPrinterPass(raw_ostream &OS) : OS(OS) {}
166
  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
167
};
168
169
} // end namespace llvm
170
171
#endif