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,11 @@ 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
+
102
108
enum OutputFormatTy {
103
109
md,
104
110
yaml,
@@ -229,6 +235,12 @@ Example usage for a project using a compile commands database:
229
235
return 1 ;
230
236
}
231
237
238
+ // turns on ftime trace profiling
239
+ if (FTimeTrace)
240
+ llvm::timeTraceProfilerInitialize (200 , " clang-doc" );
241
+
242
+ llvm::TimeTraceScope (" main" );
243
+
232
244
// Fail early if an invalid format was provided.
233
245
std::string Format = getFormatString ();
234
246
llvm::outs () << " Emiting docs in " << Format << " format.\n " ;
@@ -252,8 +264,8 @@ Example usage for a project using a compile commands database:
252
264
OutDirectory,
253
265
SourceRoot,
254
266
RepositoryUrl,
255
- {UserStylesheets.begin (), UserStylesheets.end ()}
256
- };
267
+ {UserStylesheets.begin (), UserStylesheets.end ()},
268
+ FTimeTrace };
257
269
258
270
if (Format == " html" ) {
259
271
if (auto Err = getHtmlAssetFiles (argv[0 ], CDCtx)) {
@@ -262,6 +274,7 @@ Example usage for a project using a compile commands database:
262
274
}
263
275
}
264
276
277
+ llvm::timeTraceProfilerBegin (" Mapping declaration" , " total runtime" );
265
278
// Mapping phase
266
279
llvm::outs () << " Mapping decls...\n " ;
267
280
auto Err =
@@ -276,24 +289,28 @@ Example usage for a project using a compile commands database:
276
289
return 1 ;
277
290
}
278
291
}
292
+ llvm::timeTraceProfilerEnd ();
279
293
280
294
// Collect values into output by key.
281
295
// In ToolResults, the Key is the hashed USR and the value is the
282
296
// bitcode-encoded representation of the Info object.
297
+ llvm::timeTraceProfilerBegin (" Collect Info" , " total runtime" );
283
298
llvm::outs () << " Collecting infos...\n " ;
284
299
llvm::StringMap<std::vector<StringRef>> USRToBitcode;
285
300
Executor->get ()->getToolResults ()->forEachResult (
286
301
[&](StringRef Key, StringRef Value) {
287
302
auto R = USRToBitcode.try_emplace (Key, std::vector<StringRef>());
288
303
R.first ->second .emplace_back (Value);
289
304
});
305
+ llvm::timeTraceProfilerEnd ();
290
306
291
307
// Collects all Infos according to their unique USR value. This map is added
292
308
// to from the thread pool below and is protected by the USRToInfoMutex.
293
309
llvm::sys::Mutex USRToInfoMutex;
294
310
llvm::StringMap<std::unique_ptr<doc::Info>> USRToInfo;
295
311
296
312
// First reducing phase (reduce all decls into one info per decl).
313
+ llvm::timeTraceProfilerBegin (" Reducing infos" , " total runtime" );
297
314
llvm::outs () << " Reducing " << USRToBitcode.size () << " infos...\n " ;
298
315
std::atomic<bool > Error;
299
316
Error = false ;
@@ -302,8 +319,11 @@ Example usage for a project using a compile commands database:
302
319
llvm::DefaultThreadPool Pool (llvm::hardware_concurrency (ExecutorConcurrency));
303
320
for (auto &Group : USRToBitcode) {
304
321
Pool.async ([&]() {
305
- std::vector<std::unique_ptr<doc::Info>> Infos;
322
+ if (FTimeTrace)
323
+ llvm::timeTraceProfilerInitialize (200 , " clang-doc" );
306
324
325
+ llvm::timeTraceProfilerBegin (" Reducing infos" , " decoding bitcode" );
326
+ std::vector<std::unique_ptr<doc::Info>> Infos;
307
327
for (auto &Bitcode : Group.getValue ()) {
308
328
llvm::BitstreamCursor Stream (Bitcode);
309
329
doc::ClangDocBitcodeReader Reader (Stream);
@@ -316,32 +336,40 @@ Example usage for a project using a compile commands database:
316
336
std::move (ReadInfos->begin (), ReadInfos->end (),
317
337
std::back_inserter (Infos));
318
338
}
339
+ llvm::timeTraceProfilerEnd ();
319
340
341
+ llvm::timeTraceProfilerBegin (" Reducing infos" , " merging bitcode" );
320
342
auto Reduced = doc::mergeInfos (Infos);
321
343
if (!Reduced) {
322
344
llvm::errs () << llvm::toString (Reduced.takeError ());
323
345
return ;
324
346
}
347
+ llvm::timeTraceProfilerEnd ();
325
348
326
349
// Add a reference to this Info in the Index
327
350
{
328
351
std::lock_guard<llvm::sys::Mutex> Guard (IndexMutex);
329
352
clang::doc::Generator::addInfoToIndex (CDCtx.Idx , Reduced.get ().get ());
330
353
}
331
-
332
354
// Save in the result map (needs a lock due to threaded access).
355
+
333
356
{
334
357
std::lock_guard<llvm::sys::Mutex> Guard (USRToInfoMutex);
335
358
USRToInfo[Group.getKey ()] = std::move (Reduced.get ());
336
359
}
360
+
361
+ if (CDCtx.FTimeTrace )
362
+ llvm::timeTraceProfilerFinishThread ();
337
363
});
338
364
}
365
+ llvm::timeTraceProfilerEnd ();
339
366
340
367
Pool.wait ();
341
368
342
369
if (Error)
343
370
return 1 ;
344
371
372
+ llvm::timeTraceProfilerBegin (" Writing output" , " total runtime" );
345
373
// Ensure the root output directory exists.
346
374
if (std::error_code Err = llvm::sys::fs::create_directories (OutDirectory);
347
375
Err != std::error_code ()) {
@@ -362,6 +390,16 @@ Example usage for a project using a compile commands database:
362
390
if (Err) {
363
391
llvm::outs () << " warning: " << toString (std::move (Err)) << " \n " ;
364
392
}
365
-
393
+ llvm::timeTraceProfilerEnd ();
394
+
395
+ if (FTimeTrace) {
396
+ std::error_code EC;
397
+ llvm::raw_fd_ostream OS (" clang-doc-tracing.json" , EC,
398
+ llvm::sys::fs::OF_Text);
399
+ if (!EC)
400
+ llvm::timeTraceProfilerWrite (OS);
401
+ else
402
+ return 1 ;
403
+ }
366
404
return 0 ;
367
405
}
0 commit comments