Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -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">>,
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
13 changes: 10 additions & 3 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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")
Expand All @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions clang/test/Misc/time-passes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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; }
9 changes: 8 additions & 1 deletion clang/tools/driver/cc1_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down
4 changes: 0 additions & 4 deletions llvm/lib/Support/Timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading