llvm.org GIT mirror llvm / b920b27
Revert r271728 as it breaks Windows build git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271738 91177308-0d34-0410-b5e6-96231b3b80d8 Easwaran Raman 4 years ago
8 changed file(s) with 2 addition(s) and 320 deletion(s). Raw diff Collapse all Expand all
+0
-111
include/llvm/Analysis/ProfileSummaryInfo.h less more
None //===- llvm/Analysis/ProfileSummaryInfo.h - profile summary ---*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
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
27
28 namespace llvm {
29 class ProfileSummary;
30 /// \brief 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 Module &M;
43 std::unique_ptr Summary;
44 void computeSummary();
45 void computeThresholds();
46 // Count thresholds to answer isHotCount and isColdCount queries.
47 Optional HotCountThreshold, ColdCountThreshold;
48
49 public:
50 ProfileSummaryInfo(Module &M) : M(M) {}
51 /// \brief Returns true if \p F is a hot function.
52 bool isHotFunction(const Function *F);
53 /// \brief Returns true if \p F is a cold function.
54 bool isColdFunction(const Function *F);
55 /// \brief Returns true if count \p C is considered hot.
56 bool isHotCount(uint64_t C);
57 /// \brief Returns true if count \p C is considered cold.
58 bool isColdCount(uint64_t C);
59 };
60
61 /// An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
62 class ProfileSummaryInfoWrapperPass : public ImmutablePass {
63 std::unique_ptr PSI;
64
65 public:
66 static char ID;
67 ProfileSummaryInfoWrapperPass();
68
69 ProfileSummaryInfo *getPSI(Module &M);
70 void getAnalysisUsage(AnalysisUsage &AU) const override {
71 AU.setPreservesAll();
72 }
73 };
74
75 /// An analysis pass based on the new PM to deliver ProfileSummaryInfo.
76 class ProfileSummaryAnalysis
77 : public AnalysisInfoMixin {
78 public:
79 typedef ProfileSummaryInfo Result;
80
81 ProfileSummaryAnalysis() {}
82 ProfileSummaryAnalysis(const ProfileSummaryAnalysis &Arg) {}
83 ProfileSummaryAnalysis(ProfileSummaryAnalysis &&Arg) {}
84 ProfileSummaryAnalysis &operator=(const ProfileSummaryAnalysis &RHS) {
85 return *this;
86 }
87 ProfileSummaryAnalysis &operator=(ProfileSummaryAnalysis &&RHS) {
88 return *this;
89 }
90
91 Result run(Module &M);
92
93 private:
94 friend AnalysisInfoMixin;
95 static char PassID;
96 };
97
98 /// \brief Printer pass that uses \c ProfileSummaryAnalysis.
99 class ProfileSummaryPrinterPass
100 : public PassInfoMixin {
101 raw_ostream &OS;
102
103 public:
104 explicit ProfileSummaryPrinterPass(raw_ostream &OS) : OS(OS) {}
105 PreservedAnalyses run(Module &M, AnalysisManager &AM);
106 };
107
108 } // end namespace llvm
109
110 #endif
253253 void initializePrintFunctionPassWrapperPass(PassRegistry&);
254254 void initializePrintModulePassWrapperPass(PassRegistry&);
255255 void initializePrintBasicBlockPassPass(PassRegistry&);
256 void initializeProfileSummaryInfoWrapperPassPass(PassRegistry &);
257256 void initializeProcessImplicitDefsPass(PassRegistry&);
258257 void initializePromotePassPass(PassRegistry&);
259258 void initializePruneEHPass(PassRegistry&);
5656 OrderedBasicBlock.cpp
5757 PHITransAddr.cpp
5858 PostDominators.cpp
59 ProfileSummaryInfo.cpp
6059 PtrUseVisitor.cpp
6160 RegionInfo.cpp
6261 RegionPass.cpp
+0
-161
lib/Analysis/ProfileSummaryInfo.cpp less more
None //===- ProfileSummaryInfo.cpp - Global profile summary information --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
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/IR/Metadata.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/IR/ProfileSummary.h"
18 using namespace llvm;
19
20 // The following two parameters determine the threshold for a count to be
21 // considered hot/cold. These two parameters are percentile values (multiplied
22 // by 10000). If the counts are sorted in descending order, the minimum count to
23 // reach ProfileSummaryCutoffHot gives the threshold to determine a hot count.
24 // Similarly, the minimum count to reach ProfileSummaryCutoffCold gives the
25 // threshold for determining cold count (everything <= this threshold is
26 // considered cold).
27
28 static cl::opt ProfileSummaryCutoffHot(
29 "profile-summary-cutoff-hot", cl::Hidden, cl::init(999000), cl::ZeroOrMore,
30 cl::desc("A count is hot if it exceeds the minimum count to"
31 " reach this percentile of total counts."));
32
33 static cl::opt ProfileSummaryCutoffCold(
34 "profile-summary-cutoff-cold", cl::Hidden, cl::init(999999), cl::ZeroOrMore,
35 cl::desc("A count is cold if it is below the minimum count"
36 " to reach this percentile of total counts."));
37
38 // Find the minimum count to reach a desired percentile of counts.
39 static uint64_t getMinCountForPercentile(SummaryEntryVector &DS,
40 uint64_t Percentile) {
41 auto Compare = [](const ProfileSummaryEntry &Entry, uint64_t Percentile) {
42 return Entry.Cutoff < Percentile;
43 };
44 auto It = std::lower_bound(DS.begin(), DS.end(), Percentile, Compare);
45 // The required percentile has to be <= one of the percentiles in the
46 // detailed summary.
47 if (It == DS.end())
48 report_fatal_error("Desired percentile exceeds the maximum cutoff");
49 return It->MinCount;
50 }
51
52 // The profile summary metadata may be attached either by the frontend or by
53 // any backend passes (IR level instrumentation, for example). This method
54 // checks if the Summary is null and if so checks if the summary metadata is now
55 // available in the module and parses it to get the Summary object.
56 void ProfileSummaryInfo::computeSummary() {
57 if (Summary)
58 return;
59 auto *SummaryMD = M.getProfileSummary();
60 if (!SummaryMD)
61 return;
62 Summary.reset(ProfileSummary::getFromMD(SummaryMD));
63 }
64
65 // Returns true if the function is a hot function. If it returns false, it
66 // either means it is not hot or it is unknown whether F is hot or not (for
67 // example, no profile data is available).
68 bool ProfileSummaryInfo::isHotFunction(const Function *F) {
69 computeSummary();
70 if (!F || !Summary)
71 return false;
72 auto FunctionCount = F->getEntryCount();
73 // FIXME: The heuristic used below for determining hotness is based on
74 // preliminary SPEC tuning for inliner. This will eventually be a
75 // convenience method that calls isHotCount.
76 return (FunctionCount &&
77 FunctionCount.getValue() >=
78 (uint64_t)(0.3 * (double)Summary->getMaxFunctionCount()));
79 }
80
81 // Returns true if the function is a cold function. If it returns false, it
82 // either means it is not cold or it is unknown whether F is cold or not (for
83 // example, no profile data is available).
84 bool ProfileSummaryInfo::isColdFunction(const Function *F) {
85 computeSummary();
86 if (F->hasFnAttribute(Attribute::Cold)) {
87 return true;
88 }
89 auto FunctionCount = F->getEntryCount();
90 // FIXME: The heuristic used below for determining coldness is based on
91 // preliminary SPEC tuning for inliner. This will eventually be a
92 // convenience method that calls isHotCount.
93 return (FunctionCount &&
94 FunctionCount.getValue() <=
95 (uint64_t)(0.01 * (double)Summary->getMaxFunctionCount()));
96 }
97
98 // Compute the hot and cold thresholds.
99 void ProfileSummaryInfo::computeThresholds() {
100 if (!Summary)
101 computeSummary();
102 if (!Summary)
103 return;
104 auto &DetailedSummary = Summary->getDetailedSummary();
105 HotCountThreshold =
106 getMinCountForPercentile(DetailedSummary, ProfileSummaryCutoffHot);
107 ColdCountThreshold =
108 getMinCountForPercentile(DetailedSummary, ProfileSummaryCutoffCold);
109 }
110
111 bool ProfileSummaryInfo::isHotCount(uint64_t C) {
112 if (!HotCountThreshold)
113 computeThresholds();
114 return HotCountThreshold && C >= HotCountThreshold.getValue();
115 }
116
117 bool ProfileSummaryInfo::isColdCount(uint64_t C) {
118 if (!ColdCountThreshold)
119 computeThresholds();
120 return ColdCountThreshold && C <= ColdCountThreshold.getValue();
121 }
122
123 ProfileSummaryInfo *ProfileSummaryInfoWrapperPass::getPSI(Module &M) {
124 if (!PSI)
125 PSI.reset(new ProfileSummaryInfo(M));
126 return PSI.get();
127 }
128
129 INITIALIZE_PASS(ProfileSummaryInfoWrapperPass, "profile-summary-info",
130 "Profile summary info", false, true)
131
132 ProfileSummaryInfoWrapperPass::ProfileSummaryInfoWrapperPass()
133 : ImmutablePass(ID) {
134 initializeProfileSummaryInfoWrapperPassPass(*PassRegistry::getPassRegistry());
135 }
136
137 char ProfileSummaryAnalysis::PassID;
138 ProfileSummaryInfo ProfileSummaryAnalysis::run(Module &M) {
139 return ProfileSummaryInfo(M);
140 }
141
142 // FIXME: This only tests isHotFunction and isColdFunction and not the
143 // isHotCount and isColdCount calls.
144 PreservedAnalyses ProfileSummaryPrinterPass::run(Module &M,
145 AnalysisManager &AM) {
146 ProfileSummaryInfo &PSI = AM.getResult(M);
147
148 OS << "Functions in " << M.getName() << " with hot/cold annotations: \n";
149 for (auto &F : M) {
150 OS << F.getName();
151 if (PSI.isHotFunction(&F))
152 OS << " :hot ";
153 else if (PSI.isColdFunction(&F))
154 OS << " :cold ";
155 OS << "\n";
156 }
157 return PreservedAnalyses::all();
158 }
159
160 char ProfileSummaryInfoWrapperPass::ID = 0;
143143 }
144144
145145 ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) {
146 if (!MD)
147 return nullptr;
148146 if (!isa(MD))
149147 return nullptr;
150148 MDTuple *Tuple = cast(MD);
3434 #include "llvm/Analysis/LoopInfo.h"
3535 #include "llvm/Analysis/MemoryDependenceAnalysis.h"
3636 #include "llvm/Analysis/PostDominators.h"
37 #include "llvm/Analysis/ProfileSummaryInfo.h"
3837 #include "llvm/Analysis/RegionInfo.h"
3938 #include "llvm/Analysis/ScalarEvolution.h"
4039 #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
6867 #include "llvm/Transforms/Scalar/DCE.h"
6968 #include "llvm/Transforms/Scalar/DeadStoreElimination.h"
7069 #include "llvm/Transforms/Scalar/EarlyCSE.h"
70 #include "llvm/Transforms/Scalar/GVN.h"
7171 #include "llvm/Transforms/Scalar/GuardWidening.h"
72 #include "llvm/Transforms/Scalar/GVN.h"
7372 #include "llvm/Transforms/Scalar/LoopRotation.h"
7473 #include "llvm/Transforms/Scalar/LoopSimplifyCFG.h"
7574 #include "llvm/Transforms/Scalar/LowerAtomic.h"
2121 MODULE_ANALYSIS("callgraph", CallGraphAnalysis())
2222 MODULE_ANALYSIS("lcg", LazyCallGraphAnalysis())
2323 MODULE_ANALYSIS("no-op-module", NoOpModuleAnalysis())
24 MODULE_ANALYSIS("profile-summary", ProfileSummaryAnalysis())
2524 MODULE_ANALYSIS("targetlibinfo", TargetLibraryAnalysis())
2625 MODULE_ANALYSIS("verify", VerifierAnalysis())
2726
5049 MODULE_PASS("pgo-icall-prom", PGOIndirectCallPromotion())
5150 MODULE_PASS("pgo-instr-gen", PGOInstrumentationGen())
5251 MODULE_PASS("pgo-instr-use", PGOInstrumentationUse())
53 MODULE_PASS("print-profile-summary", ProfileSummaryPrinterPass(dbgs()))
52 MODULE_PASS("print", PrintModulePass(dbgs()))
5453 MODULE_PASS("print-callgraph", CallGraphPrinterPass(dbgs()))
55 MODULE_PASS("print", PrintModulePass(dbgs()))
5654 MODULE_PASS("print-lcg", LazyCallGraphPrinterPass(dbgs()))
5755 MODULE_PASS("sample-profile", SampleProfileLoaderPass())
5856 MODULE_PASS("strip-dead-prototypes", StripDeadPrototypesPass())
+0
-39
test/Analysis/ProfileSummary/basic.ll less more
None ; RUN: opt < %s -disable-output -passes=print-profile-summary -S 2>&1 | FileCheck %s
1
2 define void @f1() !prof !20 {
3 ; CHECK-LABEL: f1 :hot
4
5 ret void
6 }
7
8 define void @f2() !prof !21 {
9 ; CHECK-LABEL: f2 :cold
10
11 ret void
12 }
13
14 define void @f3() !prof !22 {
15 ; CHECK-LABEL: f3
16
17 ret void
18 }
19
20 !llvm.module.flags = !{!1}
21 !20 = !{!"function_entry_count", i64 400}
22 !21 = !{!"function_entry_count", i64 1}
23 !22 = !{!"function_entry_count", i64 100}
24
25 !1 = !{i32 1, !"ProfileSummary", !2}
26 !2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
27 !3 = !{!"ProfileFormat", !"InstrProf"}
28 !4 = !{!"TotalCount", i64 10000}
29 !5 = !{!"MaxCount", i64 10}
30 !6 = !{!"MaxInternalCount", i64 1}
31 !7 = !{!"MaxFunctionCount", i64 1000}
32 !8 = !{!"NumCounts", i64 3}
33 !9 = !{!"NumFunctions", i64 3}
34 !10 = !{!"DetailedSummary", !11}
35 !11 = !{!12, !13, !14}
36 !12 = !{i32 10000, i64 100, i32 1}
37 !13 = !{i32 999000, i64 100, i32 1}
38 !14 = !{i32 999999, i64 1, i32 2}