-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang] Implement JSON formatted -ftime-report #137737
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This patch adds a new flag, -ftime-report-json, which outputs the same information as -ftime-report but as JSON instead of -ftime-report's pretty printed format.
@llvm/pr-subscribers-llvm-support @llvm/pr-subscribers-clang Author: Alan Zhao (alanzhao1) ChangesThis patch adds a new flag, -ftime-report-json, which outputs the same information as -ftime-report but as JSON instead of -ftime-report's pretty printed format. Full diff: https://github.com/llvm/llvm-project/pull/137737.diff 7 Files Affected:
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index c5990fb248689..927972015c3dc 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -318,8 +318,9 @@ CODEGENOPT(SpeculativeLoadHardening, 1, 0) ///< Enable speculative load hardenin
CODEGENOPT(FineGrainedBitfieldAccesses, 1, 0) ///< Enable fine-grained bitfield accesses.
CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition.
CODEGENOPT(StrictVTablePointers, 1, 0) ///< Optimize based on the strict vtable pointers
-CODEGENOPT(TimePasses , 1, 0) ///< Set when -ftime-report or -ftime-report= is enabled.
+CODEGENOPT(TimePasses , 1, 0) ///< Set when -ftime-report or -ftime-report= or -ftime-report-json is enabled.
CODEGENOPT(TimePassesPerRun , 1, 0) ///< Set when -ftime-report=per-pass-run is enabled.
+CODEGENOPT(TimePassesJson , 1, 0) ///< Set when -ftime-report-json is enabled.
CODEGENOPT(TimeTrace , 1, 0) ///< Set when -ftime-trace is enabled.
VALUE_CODEGENOPT(TimeTraceGranularity, 32, 500) ///< Minimum time granularity (in microseconds),
///< traced by time profiler
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index a9f4083920663..c822736e5d585 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4083,6 +4083,11 @@ defm ms_tls_guards : BoolFOption<"ms-tls-guards",
def ftime_report : Flag<["-"], "ftime-report">, Group<f_Group>,
Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
MarshallingInfoFlag<CodeGenOpts<"TimePasses">>;
+def ftime_report_json
+ : Flag<["-"], "ftime-report-json">,
+ Group<f_Group>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
+ MarshallingInfoFlag<CodeGenOpts<"TimePassesJson">>;
def ftime_report_EQ: Joined<["-"], "ftime-report=">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>, Values<"per-pass,per-pass-run">,
MarshallingInfoFlag<CodeGenOpts<"TimePassesPerRun">>,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 762f8af886920..a2462b8f7a63b 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7011,6 +7011,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
Args.AddLastArg(CmdArgs, options::OPT_ftime_report_EQ);
+ Args.AddLastArg(CmdArgs, options::OPT_ftime_report_json);
Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
Args.AddLastArg(CmdArgs, options::OPT_malign_double);
Args.AddLastArg(CmdArgs, options::OPT_fno_temp_file);
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 8ff62ae2552c3..c7d11e6027ccf 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1699,6 +1699,9 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts,
GenerateArg(Consumer, OPT_ftime_report_EQ, "per-pass-run");
else
GenerateArg(Consumer, OPT_ftime_report);
+
+ if (Opts.TimePassesJson)
+ GenerateArg(Consumer, OPT_ftime_report_json);
}
if (Opts.PrepareForLTO && !Opts.PrepareForThinLTO)
@@ -2000,12 +2003,13 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
: llvm::codegenoptions::DebugTemplateNamesKind::Mangled);
}
- if (const Arg *A = Args.getLastArg(OPT_ftime_report, OPT_ftime_report_EQ)) {
+ if (const Arg *A = Args.getLastArg(OPT_ftime_report, OPT_ftime_report_EQ,
+ OPT_ftime_report_json)) {
Opts.TimePasses = true;
// -ftime-report= is only for new pass manager.
- if (A->getOption().getID() == OPT_ftime_report_EQ) {
- StringRef Val = A->getValue();
+ if (const Arg *EQ = Args.getLastArg(OPT_ftime_report_EQ)) {
+ StringRef Val = EQ->getValue();
if (Val == "per-pass")
Opts.TimePassesPerRun = false;
else if (Val == "per-pass-run")
@@ -2014,6 +2018,9 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
}
+
+ if (Args.getLastArg(OPT_ftime_report_json))
+ Opts.TimePassesJson = true;
}
Opts.PrepareForLTO = false;
diff --git a/clang/test/Misc/time-passes.c b/clang/test/Misc/time-passes.c
index c1669826b2268..35b5e1634ee73 100644
--- a/clang/test/Misc/time-passes.c
+++ b/clang/test/Misc/time-passes.c
@@ -8,6 +8,9 @@
// RUN: %clang_cc1 -emit-obj -O1 \
// RUN: -ftime-report=per-pass-run %s -o /dev/null 2>&1 | \
// RUN: FileCheck %s --check-prefixes=TIME,NPM-PER-INVOKE
+// RUN: %clang_cc1 -emit-obj -O1 \
+// RUN: -ftime-report-json %s -o /dev/null 2>&1 | \
+// RUN: FileCheck %s --check-prefixes=JSON
// TIME: Pass execution timing report
// TIME: Total Execution Time:
@@ -19,5 +22,10 @@
// NPM: InstCombinePass{{$}}
// NPM-NOT: InstCombinePass #
// TIME: Total{{$}}
+// JSON:{
+// JSON: "time.pass.InstCombinePass.wall": {{.*}},
+// JSON: "time.pass.InstCombinePass.user": {{.*}},
+// JSON: "time.pass.InstCombinePass.sys": {{.*}},
+// JSON:}
int foo(int x, int y) { return x + y; }
diff --git a/clang/tools/driver/cc1_main.cpp b/clang/tools/driver/cc1_main.cpp
index 341520c6a6f73..a2fc8fc465d8e 100644
--- a/clang/tools/driver/cc1_main.cpp
+++ b/clang/tools/driver/cc1_main.cpp
@@ -296,7 +296,14 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
// 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());
+ // llvm::TimerGroup::printAll(llvm::errs());
+ if (Clang->getCodeGenOpts().TimePassesJson) {
+ llvm::errs() << "{\n";
+ llvm::TimerGroup::printAllJSONValues(llvm::errs(), "");
+ llvm::errs() << "\n}\n";
+ } else {
+ llvm::TimerGroup::printAll(llvm::errs());
+ }
llvm::TimerGroup::clearAll();
if (llvm::timeTraceProfilerEnabled()) {
diff --git a/llvm/lib/Support/Timer.cpp b/llvm/lib/Support/Timer.cpp
index 69a1846fec29b..22811d7b4af0a 100644
--- a/llvm/lib/Support/Timer.cpp
+++ b/llvm/lib/Support/Timer.cpp
@@ -442,10 +442,6 @@ void TimerGroup::clearAll() {
void TimerGroup::printJSONValue(raw_ostream &OS, const PrintRecord &R,
const char *suffix, double Value) {
- assert(yaml::needsQuotes(Name) == yaml::QuotingType::None &&
- "TimerGroup name should not need quotes");
- assert(yaml::needsQuotes(R.Name) == yaml::QuotingType::None &&
- "Timer name should not need quotes");
constexpr auto max_digits10 = std::numeric_limits<double>::max_digits10;
OS << "\t\"time." << Name << '.' << R.Name << suffix
<< "\": " << format("%.*e", max_digits10 - 1, Value);
|
@aeubanks this PR doesn't implement redirecting the output to a file, but I figured I'd implement that in another PR to keep things organized. |
The buildkite failure can be ignored; the offending test (Unwind/split-machine-functions.test) also fails on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, although I'd like @AaronBallman to take a quick look to make sure this seems ok (e.g. naming)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes LGTM, but they should come with a release note in clang/docs/ReleaseNotes.rst
so users know about the improvement, and we should also start documenting more about time reports (orthogonal to this PR).
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/137/builds/17770 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/18/builds/15309 Here is the relevant piece of the build log for the reference
|
This patch adds a new flag, -ftime-report-json, which outputs the same information as -ftime-report but as JSON instead of -ftime-report's pretty printed format.
This patch adds a new flag, -ftime-report-json, which outputs the same information as -ftime-report but as JSON instead of -ftime-report's pretty printed format.
This patch adds a new flag, -ftime-report-json, which outputs the same information as -ftime-report but as JSON instead of -ftime-report's pretty printed format.
This patch adds a new flag, -ftime-report-json, which outputs the same information as -ftime-report but as JSON instead of -ftime-report's pretty printed format.
This patch adds a new flag, -ftime-report-json, which outputs the same information as -ftime-report but as JSON instead of -ftime-report's pretty printed format.
This patch adds a new flag, -ftime-report-json, which outputs the same information as -ftime-report but as JSON instead of -ftime-report's pretty printed format.