Adds `-ftime-trace` option to clang that produces Chrome `chrome://tracing` compatible JSON profiling output dumps.
This change adds hierarchical "time trace" profiling blocks that can be visualized in Chrome, in a "flame chart" style. Each profiling block can have a "detail" string that for example indicates the file being processed, template name being instantiated, function being optimized etc.
This is taken from GitHub PR: https://github.com/aras-p/llvm-project-20170507/pull/2
Patch by Aras Pranckevičius.
Differential Revision: https://reviews.llvm.org/D58675
llvm-svn: 357340
diff --git a/clang/tools/driver/cc1_main.cpp b/clang/tools/driver/cc1_main.cpp
index be5818e..337c7d7 100644
--- a/clang/tools/driver/cc1_main.cpp
+++ b/clang/tools/driver/cc1_main.cpp
@@ -34,8 +34,10 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdio>
@@ -194,6 +196,9 @@
bool Success = CompilerInvocation::CreateFromArgs(
Clang->getInvocation(), Argv.begin(), Argv.end(), Diags);
+ if (Clang->getFrontendOpts().TimeTrace)
+ llvm::timeTraceProfilerInitialize();
+
// Infer the builtin include path if unspecified.
if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
Clang->getHeaderSearchOpts().ResourceDir.empty())
@@ -215,12 +220,29 @@
return 1;
// Execute the frontend actions.
- Success = ExecuteCompilerInvocation(Clang.get());
+ {
+ llvm::TimeTraceScope TimeScope("ExecuteCompiler", StringRef(""));
+ Success = ExecuteCompilerInvocation(Clang.get());
+ }
// If any timers were active but haven't been destroyed yet, print their
// results now. This happens in -disable-free mode.
llvm::TimerGroup::printAll(llvm::errs());
+ if (llvm::timeTraceProfilerEnabled()) {
+ SmallString<128> Path(Clang->getFrontendOpts().OutputFile);
+ llvm::sys::path::replace_extension(Path, "json");
+ auto profilerOutput =
+ Clang->createOutputFile(Path.str(),
+ /*Binary=*/false,
+ /*RemoveFileOnSignal=*/false, "",
+ /*Extension=*/"json",
+ /*useTemporary=*/false);
+
+ llvm::timeTraceProfilerWrite(profilerOutput);
+ llvm::timeTraceProfilerCleanup();
+ }
+
// Our error handler depends on the Diagnostics object, which we're
// potentially about to delete. Uninstall the handler now so that any
// later errors use the default handling behavior instead.