1
- // ===- bolt/Passes/ContinuityStats.cpp - function cfg continuity analysis ---*-
2
- // C++ -*-===//
1
+ // ===- bolt/Passes/ContinuityStats.cpp --------------------------*- C++ -*-===//
3
2
//
4
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5
4
// See https://llvm.org/LICENSE.txt for license information.
6
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7
6
//
8
7
// ===----------------------------------------------------------------------===//
9
8
//
10
- // Conduct function CFG continuity analysis .
9
+ // This file implements the continuity stats calculation pass .
11
10
//
12
11
// ===----------------------------------------------------------------------===//
13
12
@@ -27,29 +26,11 @@ using namespace bolt;
27
26
28
27
namespace opts {
29
28
extern cl::opt<unsigned > Verbosity;
30
- cl::opt<unsigned >
31
- NumTopFunctions (" num-top-functions" ,
32
- cl::desc (" number of hottest functions to print aggregated "
33
- " CFG discontinuity stats of." ),
34
- cl::init(1000 ), cl::ZeroOrMore, cl::Hidden,
35
- cl::cat(BoltOptCategory));
36
- cl::opt<bool >
37
- PrintBucketedStats (" print-bucketed-stats" ,
38
- cl::desc (" print CFG discontinuity stats for the top "
39
- " functions divided into buckets "
40
- " based on their execution counts." ),
41
- cl::Hidden, cl::cat(BoltCategory));
42
- cl::opt<unsigned >
43
- NumFunctionsPerBucket (" num-functions-per-bucket" ,
44
- cl::desc (" maximum number of functions per bucket." ),
45
- cl::init(500 ), cl::ZeroOrMore, cl::Hidden,
46
- cl::cat(BoltOptCategory));
47
- cl::opt<unsigned >
48
- MinNumFunctions (" min-num-functions" ,
49
- cl::desc (" minimum number of hot functions in the binary to "
50
- " trigger profile CFG continuity check." ),
51
- cl::init(5 ), cl::ZeroOrMore, cl::Hidden,
52
- cl::cat(BoltOptCategory));
29
+ cl::opt<unsigned > NumFunctionsForContinuityCheck (
30
+ " num-functions-for-continuity-check" ,
31
+ cl::desc (" number of hottest functions to print aggregated "
32
+ " CFG discontinuity stats of." ),
33
+ cl::init(1000 ), cl::ZeroOrMore, cl::Hidden, cl::cat(BoltOptCategory));
53
34
} // namespace opts
54
35
55
36
namespace {
@@ -159,8 +140,7 @@ void printCFGContinuityStats(raw_ostream &OS,
159
140
size_t SumUnreachableBBEC = SumAllBBEC - SumReachableBBEC;
160
141
double FractionECUnreachable = (double )SumUnreachableBBEC / SumAllBBEC;
161
142
162
- if (opts::Verbosity >= 2 && FractionECUnreachable > 0.1 &&
163
- SumUnreachableBBEC > 50 ) {
143
+ if (opts::Verbosity >= 2 && FractionECUnreachable >= 0.05 ) {
164
144
OS << " Non-trivial CFG discontinuity observed in function "
165
145
<< Function->getPrintName () << " \n " ;
166
146
LLVM_DEBUG (Function->dump ());
@@ -171,15 +151,17 @@ void printCFGContinuityStats(raw_ostream &OS,
171
151
FractionECUnreachables.push_back (FractionECUnreachable);
172
152
}
173
153
154
+ if (FractionECUnreachables.empty ())
155
+ return ;
156
+
157
+ size_t NumConsideredFunctions =
158
+ std::distance (Functions.begin (), Functions.end ());
174
159
if (!Verbose) {
175
- if (FractionECUnreachables.empty ()) {
176
- OS << " no functions have more than 1 basic block and hence no CFG "
177
- " discontinuity.\n " ;
178
- return ;
179
- }
180
160
std::sort (FractionECUnreachables.begin (), FractionECUnreachables.end ());
181
161
int Rank = int (FractionECUnreachables.size () * 0.95 );
182
- OS << format (" the TOP 5%% function CFG discontinuity is %.2lf%%" ,
162
+ OS << format (" BOLT-INFO: among the hottest %zu functions " ,
163
+ NumConsideredFunctions)
164
+ << format (" the top 5%% function CFG discontinuity is %.2lf%%" ,
183
165
FractionECUnreachables[Rank] * 100 )
184
166
<< " \n " ;
185
167
return ;
@@ -189,53 +171,41 @@ void printCFGContinuityStats(raw_ostream &OS,
189
171
" least 2 basic blocks\n " ,
190
172
SumECUnreachables.size (),
191
173
100.0 * (double )SumECUnreachables.size () /
192
- ( std::distance (Functions. begin (), Functions. end ())) );
174
+ NumConsideredFunctions );
193
175
194
- if (!NumUnreachables.empty ()) {
195
- OS << " - Distribution of NUM(unreachable POS BBs) among all focal "
196
- " functions\n " ;
197
- printDistribution (OS, NumUnreachables);
198
- }
199
- if (!SumECUnreachables.empty ()) {
200
- OS << " - Distribution of SUM(unreachable POS BBs) among all focal "
201
- " functions\n " ;
202
- printDistribution (OS, SumECUnreachables);
203
- }
204
- if (!FractionECUnreachables.empty ()) {
205
- OS << " - Distribution of [(SUM(unreachable POS BBs) / SUM(all "
206
- " POS BBs))] among all focal functions\n " ;
207
- printDistribution (OS, FractionECUnreachables, /* Fraction=*/ true );
208
- }
176
+ OS << " - Distribution of NUM(unreachable POS BBs) among all focal "
177
+ " functions\n " ;
178
+ printDistribution (OS, NumUnreachables);
179
+
180
+ OS << " - Distribution of SUM(unreachable POS BBs) among all focal "
181
+ " functions\n " ;
182
+ printDistribution (OS, SumECUnreachables);
183
+
184
+ OS << " - Distribution of [(SUM(unreachable POS BBs) / SUM(all "
185
+ " POS BBs))] among all focal functions\n " ;
186
+ printDistribution (OS, FractionECUnreachables, /* Fraction=*/ true );
209
187
}
210
188
211
189
void printAll (BinaryContext &BC, FunctionListType &ValidFunctions,
212
- size_t NumFunctionsPerBucket, size_t NumTopFunctions) {
190
+ size_t NumTopFunctions) {
213
191
// Sort the list of functions by execution counts (reverse).
214
192
llvm::sort (ValidFunctions,
215
193
[&](const BinaryFunction *A, const BinaryFunction *B) {
216
194
return A->getKnownExecutionCount () > B->getKnownExecutionCount ();
217
195
});
218
196
219
197
size_t RealNumTopFunctions = std::min (NumTopFunctions, ValidFunctions.size ());
220
- if (RealNumTopFunctions <= opts::MinNumFunctions)
221
- return ;
222
- BC.outs () << format (" BOLT-INFO: among the hottest %zu functions " ,
223
- RealNumTopFunctions);
198
+
224
199
iterator_range<function_iterator> Functions (
225
200
ValidFunctions.begin (), ValidFunctions.begin () + RealNumTopFunctions);
226
201
printCFGContinuityStats (BC.outs (), Functions, /* Verbose=*/ false );
227
202
228
203
// Print more detailed bucketed stats if requested.
229
- if (opts::PrintBucketedStats) {
230
- size_t PerBucketSize =
231
- std::min (NumFunctionsPerBucket, ValidFunctions.size ());
232
- if (PerBucketSize == 0 )
233
- return ;
234
- size_t NumBuckets = RealNumTopFunctions / PerBucketSize +
235
- (RealNumTopFunctions % PerBucketSize != 0 );
204
+ if (opts::Verbosity >= 1 && RealNumTopFunctions >= 5 ) {
205
+ size_t PerBucketSize = RealNumTopFunctions / 5 ;
236
206
BC.outs () << format (
237
- " Detailed stats for %zu buckets, each with at most %zu functions:\n " ,
238
- NumBuckets, PerBucketSize);
207
+ " Detailed stats for 5 buckets, each with %zu functions:\n " ,
208
+ PerBucketSize);
239
209
BC.outs () << " For each considered function, identify positive "
240
210
" execution-count basic blocks\n "
241
211
<< " (abbr. POS BBs) that are *unreachable* from the function "
@@ -244,10 +214,9 @@ void printAll(BinaryContext &BC, FunctionListType &ValidFunctions,
244
214
245
215
// For each bucket, print the CFG continuity stats of the functions in the
246
216
// bucket.
247
- for (size_t BucketIndex = 0 ; BucketIndex < NumBuckets ; ++BucketIndex) {
217
+ for (size_t BucketIndex = 0 ; BucketIndex < 5 ; ++BucketIndex) {
248
218
const size_t StartIndex = BucketIndex * PerBucketSize;
249
- size_t EndIndex = std::min (StartIndex + PerBucketSize, NumTopFunctions);
250
- EndIndex = std::min (EndIndex, ValidFunctions.size ());
219
+ size_t EndIndex = StartIndex + PerBucketSize;
251
220
iterator_range<function_iterator> Functions (
252
221
ValidFunctions.begin () + StartIndex,
253
222
ValidFunctions.begin () + EndIndex);
@@ -282,7 +251,9 @@ Error PrintContinuityStats::runOnFunctions(BinaryContext &BC) {
282
251
if (PrintContinuityStats::shouldOptimize (*Function))
283
252
ValidFunctions.push_back (Function);
284
253
}
285
- printAll (BC, ValidFunctions, opts::NumFunctionsPerBucket,
286
- opts::NumTopFunctions);
254
+ if (ValidFunctions.empty () || opts::NumFunctionsForContinuityCheck == 0 )
255
+ return Error::success ();
256
+
257
+ printAll (BC, ValidFunctions, opts::NumFunctionsForContinuityCheck);
287
258
return Error::success ();
288
259
}
0 commit comments