Mercurial > hg > CbC > CbC_llvm
comparison lib/Analysis/ProfileSummaryInfo.cpp @ 120:1172e4bd9c6f
update 4.0.0
author | mir3636 |
---|---|
date | Fri, 25 Nov 2016 19:14:25 +0900 |
parents | |
children | 803732b1fca8 |
comparison
equal
deleted
inserted
replaced
101:34baf5011add | 120:1172e4bd9c6f |
---|---|
1 //===- ProfileSummaryInfo.cpp - Global profile summary information --------===// | |
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 the global profile summary | |
11 // information. | |
12 // | |
13 //===----------------------------------------------------------------------===// | |
14 | |
15 #include "llvm/Analysis/BlockFrequencyInfo.h" | |
16 #include "llvm/Analysis/ProfileSummaryInfo.h" | |
17 #include "llvm/IR/BasicBlock.h" | |
18 #include "llvm/IR/Metadata.h" | |
19 #include "llvm/IR/Module.h" | |
20 #include "llvm/IR/ProfileSummary.h" | |
21 using namespace llvm; | |
22 | |
23 // The following two parameters determine the threshold for a count to be | |
24 // considered hot/cold. These two parameters are percentile values (multiplied | |
25 // by 10000). If the counts are sorted in descending order, the minimum count to | |
26 // reach ProfileSummaryCutoffHot gives the threshold to determine a hot count. | |
27 // Similarly, the minimum count to reach ProfileSummaryCutoffCold gives the | |
28 // threshold for determining cold count (everything <= this threshold is | |
29 // considered cold). | |
30 | |
31 static cl::opt<int> ProfileSummaryCutoffHot( | |
32 "profile-summary-cutoff-hot", cl::Hidden, cl::init(999000), cl::ZeroOrMore, | |
33 cl::desc("A count is hot if it exceeds the minimum count to" | |
34 " reach this percentile of total counts.")); | |
35 | |
36 static cl::opt<int> ProfileSummaryCutoffCold( | |
37 "profile-summary-cutoff-cold", cl::Hidden, cl::init(999999), cl::ZeroOrMore, | |
38 cl::desc("A count is cold if it is below the minimum count" | |
39 " to reach this percentile of total counts.")); | |
40 | |
41 // Find the minimum count to reach a desired percentile of counts. | |
42 static uint64_t getMinCountForPercentile(SummaryEntryVector &DS, | |
43 uint64_t Percentile) { | |
44 auto Compare = [](const ProfileSummaryEntry &Entry, uint64_t Percentile) { | |
45 return Entry.Cutoff < Percentile; | |
46 }; | |
47 auto It = std::lower_bound(DS.begin(), DS.end(), Percentile, Compare); | |
48 // The required percentile has to be <= one of the percentiles in the | |
49 // detailed summary. | |
50 if (It == DS.end()) | |
51 report_fatal_error("Desired percentile exceeds the maximum cutoff"); | |
52 return It->MinCount; | |
53 } | |
54 | |
55 // The profile summary metadata may be attached either by the frontend or by | |
56 // any backend passes (IR level instrumentation, for example). This method | |
57 // checks if the Summary is null and if so checks if the summary metadata is now | |
58 // available in the module and parses it to get the Summary object. | |
59 void ProfileSummaryInfo::computeSummary() { | |
60 if (Summary) | |
61 return; | |
62 auto *SummaryMD = M.getProfileSummary(); | |
63 if (!SummaryMD) | |
64 return; | |
65 Summary.reset(ProfileSummary::getFromMD(SummaryMD)); | |
66 } | |
67 | |
68 /// Returns true if the function's entry is hot. If it returns false, it | |
69 /// either means it is not hot or it is unknown whether it is hot or not (for | |
70 /// example, no profile data is available). | |
71 bool ProfileSummaryInfo::isFunctionEntryHot(const Function *F) { | |
72 computeSummary(); | |
73 if (!F || !Summary) | |
74 return false; | |
75 auto FunctionCount = F->getEntryCount(); | |
76 // FIXME: The heuristic used below for determining hotness is based on | |
77 // preliminary SPEC tuning for inliner. This will eventually be a | |
78 // convenience method that calls isHotCount. | |
79 return FunctionCount && isHotCount(FunctionCount.getValue()); | |
80 } | |
81 | |
82 /// Returns true if the function's entry is a cold. If it returns false, it | |
83 /// either means it is not cold or it is unknown whether it is cold or not (for | |
84 /// example, no profile data is available). | |
85 bool ProfileSummaryInfo::isFunctionEntryCold(const Function *F) { | |
86 computeSummary(); | |
87 if (!F) | |
88 return false; | |
89 if (F->hasFnAttribute(Attribute::Cold)) { | |
90 return true; | |
91 } | |
92 if (!Summary) | |
93 return false; | |
94 auto FunctionCount = F->getEntryCount(); | |
95 // FIXME: The heuristic used below for determining coldness is based on | |
96 // preliminary SPEC tuning for inliner. This will eventually be a | |
97 // convenience method that calls isHotCount. | |
98 return FunctionCount && isColdCount(FunctionCount.getValue()); | |
99 } | |
100 | |
101 /// Compute the hot and cold thresholds. | |
102 void ProfileSummaryInfo::computeThresholds() { | |
103 if (!Summary) | |
104 computeSummary(); | |
105 if (!Summary) | |
106 return; | |
107 auto &DetailedSummary = Summary->getDetailedSummary(); | |
108 HotCountThreshold = | |
109 getMinCountForPercentile(DetailedSummary, ProfileSummaryCutoffHot); | |
110 ColdCountThreshold = | |
111 getMinCountForPercentile(DetailedSummary, ProfileSummaryCutoffCold); | |
112 } | |
113 | |
114 bool ProfileSummaryInfo::isHotCount(uint64_t C) { | |
115 if (!HotCountThreshold) | |
116 computeThresholds(); | |
117 return HotCountThreshold && C >= HotCountThreshold.getValue(); | |
118 } | |
119 | |
120 bool ProfileSummaryInfo::isColdCount(uint64_t C) { | |
121 if (!ColdCountThreshold) | |
122 computeThresholds(); | |
123 return ColdCountThreshold && C <= ColdCountThreshold.getValue(); | |
124 } | |
125 | |
126 bool ProfileSummaryInfo::isHotBB(const BasicBlock *B, BlockFrequencyInfo *BFI) { | |
127 auto Count = BFI->getBlockProfileCount(B); | |
128 if (Count && isHotCount(*Count)) | |
129 return true; | |
130 // Use extractProfTotalWeight to get BB count. | |
131 // For Sample PGO, BFI may not provide accurate BB count due to errors | |
132 // magnified during sample count propagation. This serves as a backup plan | |
133 // to ensure all hot BB will not be missed. | |
134 // The query currently has false positives as branch instruction cloning does | |
135 // not update/scale branch weights. Unlike false negatives, this will not cause | |
136 // performance problem. | |
137 uint64_t TotalCount; | |
138 if (B->getTerminator()->extractProfTotalWeight(TotalCount) && | |
139 isHotCount(TotalCount)) | |
140 return true; | |
141 return false; | |
142 } | |
143 | |
144 INITIALIZE_PASS(ProfileSummaryInfoWrapperPass, "profile-summary-info", | |
145 "Profile summary info", false, true) | |
146 | |
147 ProfileSummaryInfoWrapperPass::ProfileSummaryInfoWrapperPass() | |
148 : ImmutablePass(ID) { | |
149 initializeProfileSummaryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); | |
150 } | |
151 | |
152 bool ProfileSummaryInfoWrapperPass::doInitialization(Module &M) { | |
153 PSI.reset(new ProfileSummaryInfo(M)); | |
154 return false; | |
155 } | |
156 | |
157 bool ProfileSummaryInfoWrapperPass::doFinalization(Module &M) { | |
158 PSI.reset(); | |
159 return false; | |
160 } | |
161 | |
162 AnalysisKey ProfileSummaryAnalysis::Key; | |
163 ProfileSummaryInfo ProfileSummaryAnalysis::run(Module &M, | |
164 ModuleAnalysisManager &) { | |
165 return ProfileSummaryInfo(M); | |
166 } | |
167 | |
168 PreservedAnalyses ProfileSummaryPrinterPass::run(Module &M, | |
169 ModuleAnalysisManager &AM) { | |
170 ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M); | |
171 | |
172 OS << "Functions in " << M.getName() << " with hot/cold annotations: \n"; | |
173 for (auto &F : M) { | |
174 OS << F.getName(); | |
175 if (PSI.isFunctionEntryHot(&F)) | |
176 OS << " :hot entry "; | |
177 else if (PSI.isFunctionEntryCold(&F)) | |
178 OS << " :cold entry "; | |
179 OS << "\n"; | |
180 } | |
181 return PreservedAnalyses::all(); | |
182 } | |
183 | |
184 char ProfileSummaryInfoWrapperPass::ID = 0; |