41
41
#include " llvm/Support/Process.h"
42
42
#include " llvm/Support/Signals.h"
43
43
#include " llvm/Support/ThreadPool.h"
44
+ #include " llvm/Support/TimeProfiler.h"
44
45
#include " llvm/Support/raw_ostream.h"
45
46
#include < atomic>
46
47
#include < mutex>
@@ -99,6 +100,16 @@ URL of repository that hosts code.
99
100
Used for links to definition locations.)" ),
100
101
llvm::cl::cat(ClangDocCategory));
101
102
103
+ static llvm::cl::opt<bool > FTimeTrace (" ftime-trace" , llvm::cl::desc(R"(
104
+ Turn on time profiler. Generates clang-doc-tracing.json)" ),
105
+ llvm::cl::init(false ),
106
+ llvm::cl::cat(ClangDocCategory));
107
+
108
+ static llvm::cl::opt<int > FTimeGranularity (" ftime-gran" , llvm::cl::desc(R"(
109
+ Specify granularity for ftime-trace defaults to 200)" ),
110
+ llvm::cl::init(200 ),
111
+ llvm::cl::cat(ClangDocCategory));
112
+
102
113
enum OutputFormatTy {
103
114
md,
104
115
yaml,
@@ -229,6 +240,12 @@ Example usage for a project using a compile commands database:
229
240
return 1 ;
230
241
}
231
242
243
+ // turns on ftime trace profiling
244
+ if (FTimeTrace)
245
+ llvm::timeTraceProfilerInitialize (FTimeGranularity, " clang-doc" );
246
+
247
+ llvm::TimeTraceScope (" clang-doc" , " main" );
248
+
232
249
// Fail early if an invalid format was provided.
233
250
std::string Format = getFormatString ();
234
251
llvm::outs () << " Emiting docs in " << Format << " format.\n " ;
@@ -249,11 +266,12 @@ Example usage for a project using a compile commands database:
249
266
Executor->get ()->getExecutionContext (),
250
267
ProjectName,
251
268
PublicOnly,
269
+ FTimeTrace,
270
+ FTimeGranularity,
252
271
OutDirectory,
253
272
SourceRoot,
254
273
RepositoryUrl,
255
- {UserStylesheets.begin (), UserStylesheets.end ()}
256
- };
274
+ {UserStylesheets.begin (), UserStylesheets.end ()}};
257
275
258
276
if (Format == " html" ) {
259
277
if (auto Err = getHtmlAssetFiles (argv[0 ], CDCtx)) {
@@ -262,6 +280,7 @@ Example usage for a project using a compile commands database:
262
280
}
263
281
}
264
282
283
+ llvm::timeTraceProfilerBegin (" mapping phase" , " mapping" );
265
284
// Mapping phase
266
285
llvm::outs () << " Mapping decls...\n " ;
267
286
auto Err =
@@ -276,24 +295,28 @@ Example usage for a project using a compile commands database:
276
295
return 1 ;
277
296
}
278
297
}
298
+ llvm::timeTraceProfilerEnd ();
279
299
280
300
// Collect values into output by key.
281
301
// In ToolResults, the Key is the hashed USR and the value is the
282
302
// bitcode-encoded representation of the Info object.
303
+ llvm::timeTraceProfilerBegin (" clang-doc" , " collection phase" );
283
304
llvm::outs () << " Collecting infos...\n " ;
284
305
llvm::StringMap<std::vector<StringRef>> USRToBitcode;
285
306
Executor->get ()->getToolResults ()->forEachResult (
286
307
[&](StringRef Key, StringRef Value) {
287
308
auto R = USRToBitcode.try_emplace (Key, std::vector<StringRef>());
288
309
R.first ->second .emplace_back (Value);
289
310
});
311
+ llvm::timeTraceProfilerEnd ();
290
312
291
313
// Collects all Infos according to their unique USR value. This map is added
292
314
// to from the thread pool below and is protected by the USRToInfoMutex.
293
315
llvm::sys::Mutex USRToInfoMutex;
294
316
llvm::StringMap<std::unique_ptr<doc::Info>> USRToInfo;
295
317
296
318
// First reducing phase (reduce all decls into one info per decl).
319
+ llvm::timeTraceProfilerBegin (" reduction phase" , " reducing" );
297
320
llvm::outs () << " Reducing " << USRToBitcode.size () << " infos...\n " ;
298
321
std::atomic<bool > Error;
299
322
Error = false ;
@@ -302,8 +325,11 @@ Example usage for a project using a compile commands database:
302
325
llvm::DefaultThreadPool Pool (llvm::hardware_concurrency (ExecutorConcurrency));
303
326
for (auto &Group : USRToBitcode) {
304
327
Pool.async ([&]() {
305
- std::vector<std::unique_ptr<doc::Info>> Infos;
328
+ if (FTimeTrace)
329
+ llvm::timeTraceProfilerInitialize (FTimeGranularity, " clang-doc" );
306
330
331
+ llvm::timeTraceProfilerBegin (" decoding bitcode phase" , " decoding" );
332
+ std::vector<std::unique_ptr<doc::Info>> Infos;
307
333
for (auto &Bitcode : Group.getValue ()) {
308
334
llvm::BitstreamCursor Stream (Bitcode);
309
335
doc::ClangDocBitcodeReader Reader (Stream);
@@ -316,32 +342,39 @@ Example usage for a project using a compile commands database:
316
342
std::move (ReadInfos->begin (), ReadInfos->end (),
317
343
std::back_inserter (Infos));
318
344
}
345
+ llvm::timeTraceProfilerEnd ();
319
346
347
+ llvm::timeTraceProfilerBegin (" merging bitcode phase" , " merging" );
320
348
auto Reduced = doc::mergeInfos (Infos);
321
349
if (!Reduced) {
322
350
llvm::errs () << llvm::toString (Reduced.takeError ());
323
351
return ;
324
352
}
353
+ llvm::timeTraceProfilerEnd ();
325
354
326
355
// Add a reference to this Info in the Index
327
356
{
328
357
std::lock_guard<llvm::sys::Mutex> Guard (IndexMutex);
329
358
clang::doc::Generator::addInfoToIndex (CDCtx.Idx , Reduced.get ().get ());
330
359
}
331
-
332
360
// Save in the result map (needs a lock due to threaded access).
333
361
{
334
362
std::lock_guard<llvm::sys::Mutex> Guard (USRToInfoMutex);
335
363
USRToInfo[Group.getKey ()] = std::move (Reduced.get ());
336
364
}
365
+
366
+ if (CDCtx.FTimeTrace )
367
+ llvm::timeTraceProfilerFinishThread ();
337
368
});
338
369
}
370
+ llvm::timeTraceProfilerEnd ();
339
371
340
372
Pool.wait ();
341
373
342
374
if (Error)
343
375
return 1 ;
344
376
377
+ llvm::timeTraceProfilerBegin (" generating phase" , " generating" );
345
378
// Ensure the root output directory exists.
346
379
if (std::error_code Err = llvm::sys::fs::create_directories (OutDirectory);
347
380
Err != std::error_code ()) {
@@ -362,6 +395,17 @@ Example usage for a project using a compile commands database:
362
395
if (Err) {
363
396
llvm::outs () << " warning: " << toString (std::move (Err)) << " \n " ;
364
397
}
365
-
398
+ llvm::timeTraceProfilerEnd ();
399
+
400
+ if (FTimeTrace) {
401
+ std::error_code EC;
402
+ llvm::raw_fd_ostream OS (" clang-doc-tracing.json" , EC,
403
+ llvm::sys::fs::OF_Text);
404
+ if (!EC) {
405
+ llvm::timeTraceProfilerWrite (OS);
406
+ } else {
407
+ llvm::errs () << " Error opening file: " << EC.message () << " \n " ;
408
+ }
409
+ }
366
410
return 0 ;
367
411
}
0 commit comments