https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/98320
>From 03cc5fbebaf0c0c737e9304b8b3310ab4908fcaa Mon Sep 17 00:00:00 2001 From: Utkarsh Saxena <u...@google.com> Date: Wed, 10 Jul 2024 13:52:46 +0000 Subject: [PATCH 1/8] Add an option to add source file info to -ftime-trace --- clang/include/clang/Driver/Options.td | 4 ++++ clang/include/clang/Frontend/FrontendOptions.h | 3 +++ clang/lib/Sema/SemaTemplateInstantiate.cpp | 2 ++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 ++ 4 files changed, 11 insertions(+) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index be7c3b60c20f1..c15f1b57bafc9 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3989,6 +3989,10 @@ def ftime_trace_EQ : Joined<["-"], "ftime-trace=">, Group<f_Group>, HelpText<"Similar to -ftime-trace. Specify the JSON file or a directory which will contain the JSON file">, Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, MarshallingInfoString<FrontendOpts<"TimeTracePath">>; +def ftime_trace_add_filename : Flag<["-"], "ftime-trace-add-filename">, Group<f_Group>, + HelpText<"Adds filename to event details wherever supported. Eg: For template instantiation A<int>, details would include A<int>@source_file.h.">, + Visibility<[ClangOption, CLOption, DXCOption]>; + MarshallingInfoString<FrontendOpts<"TimeTraceAddFilename">>; def fproc_stat_report : Joined<["-"], "fproc-stat-report">, Group<f_Group>, HelpText<"Print subprocess statistics">; def fproc_stat_report_EQ : Joined<["-"], "fproc-stat-report=">, Group<f_Group>, diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index 5e5034fe01eb5..019a6737f8129 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -583,6 +583,9 @@ class FrontendOptions { /// Path which stores the output files for -ftime-trace std::string TimeTracePath; + /// Adds filename to event details wherever supported + bool TimeTraceAddFilename = false; + /// Output Path for module output file. std::string ModuleOutputPath; diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index a7bc6749c5852..f0fa7fd427906 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -3430,6 +3430,8 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, llvm::raw_string_ostream OS(Name); Instantiation->getNameForDiagnostic(OS, getPrintingPolicy(), /*Qualified=*/true); + if (llvm::timeTraceAddFilename()) + OS << "@" << SourceMgr.getFilename(Instantiation->getLocation()); return Name; }); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 88f6af80cbc55..ba55db4117c34 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4966,6 +4966,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, llvm::raw_string_ostream OS(Name); Function->getNameForDiagnostic(OS, getPrintingPolicy(), /*Qualified=*/true); + if (llvm::timeTraceAddFilename()) + OS << "@" << SourceMgr.getFilename(Function->getLocation()); return Name; }); >From ae991f8c88c21a0872a5fa63219b3cb9b2787d9a Mon Sep 17 00:00:00 2001 From: Utkarsh Saxena <u...@google.com> Date: Wed, 10 Jul 2024 15:52:55 +0000 Subject: [PATCH 2/8] Add tests --- clang/include/clang/Driver/Options.td | 4 ---- clang/include/clang/Frontend/FrontendOptions.h | 3 --- clang/lib/Sema/SemaTemplateInstantiate.cpp | 3 +-- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 3 +-- clang/test/Driver/ftime-trace-sections.py | 16 +++++++++++++++- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index c15f1b57bafc9..be7c3b60c20f1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3989,10 +3989,6 @@ def ftime_trace_EQ : Joined<["-"], "ftime-trace=">, Group<f_Group>, HelpText<"Similar to -ftime-trace. Specify the JSON file or a directory which will contain the JSON file">, Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, MarshallingInfoString<FrontendOpts<"TimeTracePath">>; -def ftime_trace_add_filename : Flag<["-"], "ftime-trace-add-filename">, Group<f_Group>, - HelpText<"Adds filename to event details wherever supported. Eg: For template instantiation A<int>, details would include A<int>@source_file.h.">, - Visibility<[ClangOption, CLOption, DXCOption]>; - MarshallingInfoString<FrontendOpts<"TimeTraceAddFilename">>; def fproc_stat_report : Joined<["-"], "fproc-stat-report">, Group<f_Group>, HelpText<"Print subprocess statistics">; def fproc_stat_report_EQ : Joined<["-"], "fproc-stat-report=">, Group<f_Group>, diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index 019a6737f8129..5e5034fe01eb5 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -583,9 +583,6 @@ class FrontendOptions { /// Path which stores the output files for -ftime-trace std::string TimeTracePath; - /// Adds filename to event details wherever supported - bool TimeTraceAddFilename = false; - /// Output Path for module output file. std::string ModuleOutputPath; diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index f0fa7fd427906..69f46a77d8067 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -3430,8 +3430,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, llvm::raw_string_ostream OS(Name); Instantiation->getNameForDiagnostic(OS, getPrintingPolicy(), /*Qualified=*/true); - if (llvm::timeTraceAddFilename()) - OS << "@" << SourceMgr.getFilename(Instantiation->getLocation()); + OS << "@" << SourceMgr.getFilename(Instantiation->getLocation()); return Name; }); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index ba55db4117c34..d835a217802ac 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4966,8 +4966,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, llvm::raw_string_ostream OS(Name); Function->getNameForDiagnostic(OS, getPrintingPolicy(), /*Qualified=*/true); - if (llvm::timeTraceAddFilename()) - OS << "@" << SourceMgr.getFilename(Function->getLocation()); + OS << "@" << SourceMgr.getFilename(Function->getLocation()); return Name; }); diff --git a/clang/test/Driver/ftime-trace-sections.py b/clang/test/Driver/ftime-trace-sections.py index 02afa4ac54eb7..cfec77fc97a8e 100644 --- a/clang/test/Driver/ftime-trace-sections.py +++ b/clang/test/Driver/ftime-trace-sections.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -import json, sys, time +import json, sys, time, re def is_inside(range1, range2): @@ -16,12 +16,18 @@ def is_before(range1, range2): c = range2["ts"] return b <= c +instantiation_pattern = re.compile("^.*<.*>@.*.cpp$") + +def is_valid_instantiation(instantiation): + return instantiation_pattern.match(instantiation["args"]["detail"]) + log_contents = json.loads(sys.stdin.read()) events = log_contents["traceEvents"] codegens = [event for event in events if event["name"] == "CodeGen Function"] frontends = [event for event in events if event["name"] == "Frontend"] backends = [event for event in events if event["name"] == "Backend"] +instantiations = [event for event in events if event["name"].startswith("Instantiate")] beginning_of_time = log_contents["beginningOfTime"] / 1000000 seconds_since_epoch = time.time() @@ -48,3 +54,11 @@ def is_before(range1, range2): ] ): sys.exit("Not all Frontend section are before all Backend sections!") + +if not all( + [ + is_valid_instantiation(instantiation) + for instantiation in instantiations + ] +): + sys.exit("Not all Frontend section are before all Backend sections!") >From afdaaddcb490668d0565c4a0a4de1bc49b9f41e9 Mon Sep 17 00:00:00 2001 From: Utkarsh Saxena <u...@google.com> Date: Wed, 10 Jul 2024 15:57:55 +0000 Subject: [PATCH 3/8] use , file: as separator --- clang/lib/Sema/SemaTemplateInstantiate.cpp | 2 +- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 +- clang/test/Driver/ftime-trace-sections.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 69f46a77d8067..3105f3eefa0ba 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -3430,7 +3430,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, llvm::raw_string_ostream OS(Name); Instantiation->getNameForDiagnostic(OS, getPrintingPolicy(), /*Qualified=*/true); - OS << "@" << SourceMgr.getFilename(Instantiation->getLocation()); + OS << ", file:" << SourceMgr.getFilename(Instantiation->getLocation()); return Name; }); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index d835a217802ac..88390d82260f5 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4966,7 +4966,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, llvm::raw_string_ostream OS(Name); Function->getNameForDiagnostic(OS, getPrintingPolicy(), /*Qualified=*/true); - OS << "@" << SourceMgr.getFilename(Function->getLocation()); + OS << ", file:" << SourceMgr.getFilename(Function->getLocation()); return Name; }); diff --git a/clang/test/Driver/ftime-trace-sections.py b/clang/test/Driver/ftime-trace-sections.py index cfec77fc97a8e..cec62db6b0d7b 100644 --- a/clang/test/Driver/ftime-trace-sections.py +++ b/clang/test/Driver/ftime-trace-sections.py @@ -16,7 +16,7 @@ def is_before(range1, range2): c = range2["ts"] return b <= c -instantiation_pattern = re.compile("^.*<.*>@.*.cpp$") +instantiation_pattern = re.compile("^.*<.*>, file:.*.cpp$") def is_valid_instantiation(instantiation): return instantiation_pattern.match(instantiation["args"]["detail"]) >From f3a5c475935f8519d85332750bb43c4ac99d7668 Mon Sep 17 00:00:00 2001 From: Utkarsh Saxena <u...@google.com> Date: Wed, 10 Jul 2024 16:01:08 +0000 Subject: [PATCH 4/8] format and fix error messages --- clang/test/Driver/ftime-trace-sections.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/clang/test/Driver/ftime-trace-sections.py b/clang/test/Driver/ftime-trace-sections.py index cec62db6b0d7b..c42fa3c406ff4 100644 --- a/clang/test/Driver/ftime-trace-sections.py +++ b/clang/test/Driver/ftime-trace-sections.py @@ -16,8 +16,10 @@ def is_before(range1, range2): c = range2["ts"] return b <= c + instantiation_pattern = re.compile("^.*<.*>, file:.*.cpp$") + def is_valid_instantiation(instantiation): return instantiation_pattern.match(instantiation["args"]["detail"]) @@ -55,10 +57,6 @@ def is_valid_instantiation(instantiation): ): sys.exit("Not all Frontend section are before all Backend sections!") -if not all( - [ - is_valid_instantiation(instantiation) - for instantiation in instantiations - ] -): - sys.exit("Not all Frontend section are before all Backend sections!") +for instantiation in instantiations: + if not is_valid_instantiation(instantiation): + sys.exit("Invalid instantiation: " + str(instantiation)) >From ecb326f79facf5287cf6cfa345d3c7c6d6ad3464 Mon Sep 17 00:00:00 2001 From: Utkarsh Saxena <u...@google.com> Date: Tue, 16 Jul 2024 15:57:25 +0000 Subject: [PATCH 5/8] add filename as structured json --- clang/lib/Sema/SemaTemplateInstantiate.cpp | 8 ++-- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 8 ++-- clang/test/Driver/ftime-trace-sections.py | 5 +-- llvm/include/llvm/Support/TimeProfiler.h | 14 +++++++ llvm/lib/Support/TimeProfiler.cpp | 38 +++++++++++++++++-- 5 files changed, 57 insertions(+), 16 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 3105f3eefa0ba..71880641e33af 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -3426,12 +3426,12 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, return true; llvm::TimeTraceScope TimeScope("InstantiateClass", [&]() { - std::string Name; - llvm::raw_string_ostream OS(Name); + llvm::TimeTraceMetadata M; + llvm::raw_string_ostream OS(M.Details); Instantiation->getNameForDiagnostic(OS, getPrintingPolicy(), /*Qualified=*/true); - OS << ", file:" << SourceMgr.getFilename(Instantiation->getLocation()); - return Name; + M.Filename = SourceMgr.getFilename(Instantiation->getLocation()); + return M; }); Pattern = PatternDef; diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 88390d82260f5..e3f12b37d45c7 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4962,12 +4962,12 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, } llvm::TimeTraceScope TimeScope("InstantiateFunction", [&]() { - std::string Name; - llvm::raw_string_ostream OS(Name); + llvm::TimeTraceMetadata M; + llvm::raw_string_ostream OS(M.Details); Function->getNameForDiagnostic(OS, getPrintingPolicy(), /*Qualified=*/true); - OS << ", file:" << SourceMgr.getFilename(Function->getLocation()); - return Name; + M.Filename = SourceMgr.getFilename(Function->getLocation()); + return M; }); // If we're performing recursive template instantiation, create our own diff --git a/clang/test/Driver/ftime-trace-sections.py b/clang/test/Driver/ftime-trace-sections.py index c42fa3c406ff4..ab05f90a1358d 100644 --- a/clang/test/Driver/ftime-trace-sections.py +++ b/clang/test/Driver/ftime-trace-sections.py @@ -17,11 +17,8 @@ def is_before(range1, range2): return b <= c -instantiation_pattern = re.compile("^.*<.*>, file:.*.cpp$") - - def is_valid_instantiation(instantiation): - return instantiation_pattern.match(instantiation["args"]["detail"]) + return instantiation["args"]["filename"].endswith(".cpp") log_contents = json.loads(sys.stdin.read()) diff --git a/llvm/include/llvm/Support/TimeProfiler.h b/llvm/include/llvm/Support/TimeProfiler.h index 31f7df10916db..d669c0d2a5e23 100644 --- a/llvm/include/llvm/Support/TimeProfiler.h +++ b/llvm/include/llvm/Support/TimeProfiler.h @@ -83,6 +83,12 @@ namespace llvm { class raw_pwrite_stream; +struct TimeTraceMetadata { + std::string Details; + // Source file information for the event. + std::string Filename; +}; + struct TimeTraceProfiler; TimeTraceProfiler *getTimeTraceProfilerInstance(); @@ -128,6 +134,10 @@ TimeTraceProfilerEntry * timeTraceProfilerBegin(StringRef Name, llvm::function_ref<std::string()> Detail); +TimeTraceProfilerEntry * +timeTraceProfilerBegin(StringRef Name, + llvm::function_ref<TimeTraceMetadata()> MetaData); + /// Manually begin a time section, with the given \p Name and \p Detail. /// This starts Async Events having \p Name as a category which is shown /// separately from other traces. See @@ -164,6 +174,10 @@ class TimeTraceScope { if (getTimeTraceProfilerInstance() != nullptr) Entry = timeTraceProfilerBegin(Name, Detail); } + TimeTraceScope(StringRef Name, llvm::function_ref<TimeTraceMetadata()> Metadata) { + if (getTimeTraceProfilerInstance() != nullptr) + Entry = timeTraceProfilerBegin(Name, Metadata); + } ~TimeTraceScope() { if (getTimeTraceProfilerInstance() != nullptr) timeTraceProfilerEnd(Entry); diff --git a/llvm/lib/Support/TimeProfiler.cpp b/llvm/lib/Support/TimeProfiler.cpp index 9612db7d30f98..4b0466b265db4 100644 --- a/llvm/lib/Support/TimeProfiler.cpp +++ b/llvm/lib/Support/TimeProfiler.cpp @@ -73,12 +73,20 @@ struct llvm::TimeTraceProfilerEntry { const TimePointType Start; TimePointType End; const std::string Name; - const std::string Detail; + TimeTraceMetadata Metadata; + const bool AsyncEvent = false; TimeTraceProfilerEntry(TimePointType &&S, TimePointType &&E, std::string &&N, std::string &&Dt, bool Ae) + : Start(std::move(S)), End(std::move(E)), Name(std::move(N)), Metadata(), + AsyncEvent(Ae) { + Metadata.Details = std::move(Dt); + } + + TimeTraceProfilerEntry(TimePointType &&S, TimePointType &&E, std::string &&N, + TimeTraceMetadata &&Mt, bool Ae) : Start(std::move(S)), End(std::move(E)), Name(std::move(N)), - Detail(std::move(Dt)), AsyncEvent(Ae) {} + Metadata(std::move(Mt)), AsyncEvent(Ae) {} // Calculate timings for FlameGraph. Cast time points to microsecond precision // rather than casting duration. This avoids truncation issues causing inner @@ -113,6 +121,15 @@ struct llvm::TimeTraceProfiler { return Stack.back().get(); } + TimeTraceProfilerEntry *begin(std::string Name, + llvm::function_ref<TimeTraceMetadata()>Metadata, + bool AsyncEvent = false) { + Stack.emplace_back(std::make_unique<TimeTraceProfilerEntry>( + ClockType::now(), TimePointType(), std::move(Name), Metadata(), + AsyncEvent)); + return Stack.back().get(); + } + void end() { assert(!Stack.empty() && "Must call begin() first"); end(*Stack.back()); @@ -184,8 +201,13 @@ struct llvm::TimeTraceProfiler { J.attribute("dur", DurUs); } J.attribute("name", E.Name); - if (!E.Detail.empty()) { - J.attributeObject("args", [&] { J.attribute("detail", E.Detail); }); + if (!E.Metadata.Details.empty()) { + J.attributeObject("args", + [&] { J.attribute("detail", E.Metadata.Details); }); + } + if (!E.Metadata.Filename.empty()) { + J.attributeObject( + "args", [&] { J.attribute("filename", E.Metadata.Filename); }); } }); @@ -381,6 +403,14 @@ llvm::timeTraceProfilerBegin(StringRef Name, return nullptr; } +TimeTraceProfilerEntry * +llvm::timeTraceProfilerBegin(StringRef Name, + llvm::function_ref<TimeTraceMetadata()> Metadata) { + if (TimeTraceProfilerInstance != nullptr) + return TimeTraceProfilerInstance->begin(std::string(Name), Metadata, false); + return nullptr; +} + TimeTraceProfilerEntry *llvm::timeTraceAsyncProfilerBegin(StringRef Name, StringRef Detail) { if (TimeTraceProfilerInstance != nullptr) >From 7032c5c7bf8f65eb4792bf9e5fdc5ba9b762c846 Mon Sep 17 00:00:00 2001 From: Utkarsh Saxena <u...@google.com> Date: Tue, 16 Jul 2024 15:59:20 +0000 Subject: [PATCH 6/8] prep for rebase. ignore ftime-trace-sections.py --- clang/test/Driver/ftime-trace-sections.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/clang/test/Driver/ftime-trace-sections.py b/clang/test/Driver/ftime-trace-sections.py index ab05f90a1358d..02afa4ac54eb7 100644 --- a/clang/test/Driver/ftime-trace-sections.py +++ b/clang/test/Driver/ftime-trace-sections.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -import json, sys, time, re +import json, sys, time def is_inside(range1, range2): @@ -17,16 +17,11 @@ def is_before(range1, range2): return b <= c -def is_valid_instantiation(instantiation): - return instantiation["args"]["filename"].endswith(".cpp") - - log_contents = json.loads(sys.stdin.read()) events = log_contents["traceEvents"] codegens = [event for event in events if event["name"] == "CodeGen Function"] frontends = [event for event in events if event["name"] == "Frontend"] backends = [event for event in events if event["name"] == "Backend"] -instantiations = [event for event in events if event["name"].startswith("Instantiate")] beginning_of_time = log_contents["beginningOfTime"] / 1000000 seconds_since_epoch = time.time() @@ -53,7 +48,3 @@ def is_valid_instantiation(instantiation): ] ): sys.exit("Not all Frontend section are before all Backend sections!") - -for instantiation in instantiations: - if not is_valid_instantiation(instantiation): - sys.exit("Invalid instantiation: " + str(instantiation)) >From 51035aff99a38bda1aeb994cd560fc0f798f2546 Mon Sep 17 00:00:00 2001 From: Utkarsh Saxena <u...@google.com> Date: Tue, 16 Jul 2024 16:06:10 +0000 Subject: [PATCH 7/8] rebase. add option. add unit tests. --- clang/include/clang/Driver/Options.td | 4 ++ .../include/clang/Frontend/FrontendOptions.h | 8 +++- clang/lib/Driver/ToolChains/Clang.cpp | 1 + clang/lib/Sema/SemaTemplateInstantiate.cpp | 5 ++- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 5 ++- clang/test/Driver/ftime-trace-sections.cpp | 2 +- clang/test/Driver/ftime-trace-sections.py | 6 ++- clang/test/Driver/ftime-trace.cpp | 39 ++++++++-------- clang/tools/driver/cc1_main.cpp | 3 +- clang/unittests/Support/TimeProfilerTest.cpp | 44 ++++++++++++------- llvm/include/llvm/Support/TimeProfiler.h | 14 ++++-- llvm/lib/Support/TimeProfiler.cpp | 43 +++++++++++------- 12 files changed, 112 insertions(+), 62 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 561aa28a52b1f..7d6e0bf01823b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3986,6 +3986,10 @@ def ftime_trace_granularity_EQ : Joined<["-"], "ftime-trace-granularity=">, Grou HelpText<"Minimum time granularity (in microseconds) traced by time profiler">, Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, MarshallingInfoInt<FrontendOpts<"TimeTraceGranularity">, "500u">; +def ftime_trace_verbose : Joined<["-"], "ftime-trace-verbose">, Group<f_Group>, + HelpText<"Make time trace capture verbose event details (eg. source filenames). This can increase the size of the output by 2-3 times">, + Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, + MarshallingInfoFlag<FrontendOpts<"TimeTraceVerbose">>; def ftime_trace_EQ : Joined<["-"], "ftime-trace=">, Group<f_Group>, HelpText<"Similar to -ftime-trace. Specify the JSON file or a directory which will contain the JSON file">, Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index 5e5034fe01eb5..cafacb8e54af7 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -580,6 +580,11 @@ class FrontendOptions { /// Minimum time granularity (in microseconds) traced by time profiler. unsigned TimeTraceGranularity; + /// Make time trace capture verbose event details (eg. source filenames). This + /// can increase the size of the output by 2-3 times. + LLVM_PREFERRED_TYPE(bool) + unsigned TimeTraceVerbose : 1; + /// Path which stores the output files for -ftime-trace std::string TimeTracePath; @@ -601,7 +606,8 @@ class FrontendOptions { EmitSymbolGraph(false), EmitExtensionSymbolGraphs(false), EmitSymbolGraphSymbolLabelsForTesting(false), EmitPrettySymbolGraphs(false), GenReducedBMI(false), - UseClangIRPipeline(false), TimeTraceGranularity(500) {} + UseClangIRPipeline(false), TimeTraceGranularity(500), + TimeTraceVerbose(false) {} /// getInputKindForExtension - Return the appropriate input kind for a file /// extension. For example, "c" would return Language::C. diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index d48b26cc74132..b3d2a0ff9a136 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6746,6 +6746,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (const char *Name = C.getTimeTraceFile(&JA)) { CmdArgs.push_back(Args.MakeArgString("-ftime-trace=" + Twine(Name))); Args.AddLastArg(CmdArgs, options::OPT_ftime_trace_granularity_EQ); + Args.AddLastArg(CmdArgs, options::OPT_ftime_trace_verbose); } if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) { diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 71880641e33af..12353686cfcc0 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -3427,10 +3427,11 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, llvm::TimeTraceScope TimeScope("InstantiateClass", [&]() { llvm::TimeTraceMetadata M; - llvm::raw_string_ostream OS(M.Details); + llvm::raw_string_ostream OS(M.Detail); Instantiation->getNameForDiagnostic(OS, getPrintingPolicy(), /*Qualified=*/true); - M.Filename = SourceMgr.getFilename(Instantiation->getLocation()); + if (llvm::isTimeTraceVerbose()) + M.Filename = SourceMgr.getFilename(Instantiation->getLocation()); return M; }); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 4c264b11a9c14..f8da6d6ecebf1 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4967,10 +4967,11 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, llvm::TimeTraceScope TimeScope("InstantiateFunction", [&]() { llvm::TimeTraceMetadata M; - llvm::raw_string_ostream OS(M.Details); + llvm::raw_string_ostream OS(M.Detail); Function->getNameForDiagnostic(OS, getPrintingPolicy(), /*Qualified=*/true); - M.Filename = SourceMgr.getFilename(Function->getLocation()); + if (llvm::isTimeTraceVerbose()) + M.Filename = SourceMgr.getFilename(Function->getLocation()); return M; }); diff --git a/clang/test/Driver/ftime-trace-sections.cpp b/clang/test/Driver/ftime-trace-sections.cpp index 0c16052bc0c3a..da7109b9d81a6 100644 --- a/clang/test/Driver/ftime-trace-sections.cpp +++ b/clang/test/Driver/ftime-trace-sections.cpp @@ -1,5 +1,5 @@ // RUN: rm -rf %t && mkdir %t && cd %t -// RUN: %clangxx -S -ftime-trace -ftime-trace-granularity=0 -o out %s +// RUN: %clangxx -S -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s // RUN: %python %S/ftime-trace-sections.py < out.json template <typename T> diff --git a/clang/test/Driver/ftime-trace-sections.py b/clang/test/Driver/ftime-trace-sections.py index b332931d29a62..b30fc1bc76ed3 100755 --- a/clang/test/Driver/ftime-trace-sections.py +++ b/clang/test/Driver/ftime-trace-sections.py @@ -51,7 +51,7 @@ def is_before(range1, range2): ] ): sys.exit("Not all Frontend section are before all Backend sections!") - +print( "\n\n" ,instants , "\n==================") # Check that entries for foo exist and are in a demangled form. if not any(e for e in instants if "foo<int>" in e["args"]["detail"]): sys.exit("Missing Instantiate entry for foo!") @@ -59,3 +59,7 @@ def is_before(range1, range2): sys.exit("Missing CodeGen entry for foo!") if not any(e for e in opts if "foo<int>" in e["args"]["detail"]): sys.exit("Missing Optimize entry for foo!") + +for i in instants: + if not i["args"]["filename"].endswith(".cpp"): + sys.exit("No filename in instantiation: " + str(i)) \ No newline at end of file diff --git a/clang/test/Driver/ftime-trace.cpp b/clang/test/Driver/ftime-trace.cpp index 5fe63de915a71..60c5885704b58 100644 --- a/clang/test/Driver/ftime-trace.cpp +++ b/clang/test/Driver/ftime-trace.cpp @@ -1,18 +1,18 @@ // RUN: rm -rf %t && mkdir -p %t && cd %t -// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace -ftime-trace-granularity=0 -o out %s +// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s // RUN: cat out.json \ // RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ // RUN: | FileCheck %s -// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=new-name.json -ftime-trace-granularity=0 -o out %s +// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=new-name.json -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s // RUN: cat new-name.json \ // RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ // RUN: | FileCheck %s // RUN: mkdir dir1 dir2 -// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir1 -ftime-trace-granularity=0 -o out %s +// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir1 -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s // RUN: cat dir1/out.json \ // RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ // RUN: | FileCheck %s -// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir2/ -ftime-trace-granularity=0 -o out %s +// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir2/ -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s // RUN: cat dir2/out.json \ // RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ // RUN: | FileCheck %s @@ -34,32 +34,33 @@ // RUN: mkdir d e f && cp %s d/a.cpp && touch d/b.c /// TODO: Support -fno-integrated-as. -// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 -fintegrated-as d/a.cpp -o e/a.o 2>&1 | FileCheck %s --check-prefix=COMPILE1 -// COMPILE1: -cc1{{.*}} "-ftime-trace=e/a.json" "-ftime-trace-granularity=0" +// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose -fintegrated-as d/a.cpp -o e/a.o 2>&1 | FileCheck %s --check-prefix=COMPILE1 +// COMPILE1: -cc1{{.*}} "-ftime-trace=e/a.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" -// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 d/a.cpp d/b.c -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=COMPILE2 -// COMPILE2: -cc1{{.*}} "-ftime-trace=f/a.json" "-ftime-trace-granularity=0" -// COMPILE2: -cc1{{.*}} "-ftime-trace=f/b.json" "-ftime-trace-granularity=0" +// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=COMPILE2 +// COMPILE2: -cc1{{.*}} "-ftime-trace=f/a.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" +// COMPILE2: -cc1{{.*}} "-ftime-trace=f/b.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" /// -o specifies the link output. Create ${output}-${basename}.json. -// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 d/a.cpp d/b.c -o e/x 2>&1 | FileCheck %s --check-prefix=LINK1 -// LINK1: -cc1{{.*}} "-ftime-trace=e/x-a.json" "-ftime-trace-granularity=0" -// LINK1: -cc1{{.*}} "-ftime-trace=e/x-b.json" "-ftime-trace-granularity=0" +// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -o e/x 2>&1 | FileCheck %s --check-prefix=LINK1 +// LINK1: -cc1{{.*}} "-ftime-trace=e/x-a.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" +// LINK1: -cc1{{.*}} "-ftime-trace=e/x-b.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" /// -dumpdir is f/g, not ending with a path separator. We create f/g${basename}.json. -// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 d/a.cpp d/b.c -o e/x -dumpdir f/g 2>&1 | FileCheck %s --check-prefix=LINK2 -// LINK2: -cc1{{.*}} "-ftime-trace=f/ga.json" "-ftime-trace-granularity=0" -// LINK2: -cc1{{.*}} "-ftime-trace=f/gb.json" "-ftime-trace-granularity=0" +// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -o e/x -dumpdir f/g 2>&1 | FileCheck %s --check-prefix=LINK2 +// LINK2: -cc1{{.*}} "-ftime-trace=f/ga.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" +// LINK2: -cc1{{.*}} "-ftime-trace=f/gb.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" -// RUN: %clang -### -ftime-trace=e -ftime-trace-granularity=0 d/a.cpp d/b.c -o f/x -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=LINK3 -// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}a-{{[^.]*}}.json" "-ftime-trace-granularity=0" -// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}b-{{[^.]*}}.json" "-ftime-trace-granularity=0" +// RUN: %clang -### -ftime-trace=e -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -o f/x -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=LINK3 +// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}a-{{[^.]*}}.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" +// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}b-{{[^.]*}}.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" -// RUN: %clang -### -ftime-trace -ftime-trace=e -ftime-trace-granularity=1 -xassembler d/a.cpp 2>&1 | \ +// RUN: %clang -### -ftime-trace -ftime-trace=e -ftime-trace-granularity=1 -ftime-trace-verbose -xassembler d/a.cpp 2>&1 | \ // RUN: FileCheck %s --check-prefix=UNUSED // UNUSED: warning: argument unused during compilation: '-ftime-trace' // UNUSED-NEXT: warning: argument unused during compilation: '-ftime-trace=e' // UNUSED-NEXT: warning: argument unused during compilation: '-ftime-trace-granularity=1' +// UNUSED-NEXT: warning: argument unused during compilation: '-ftime-trace-verbose' // UNUSED-NOT: warning: template <typename T> diff --git a/clang/tools/driver/cc1_main.cpp b/clang/tools/driver/cc1_main.cpp index c2ccb47a15bc8..f5e5fad36573e 100644 --- a/clang/tools/driver/cc1_main.cpp +++ b/clang/tools/driver/cc1_main.cpp @@ -241,7 +241,8 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) { if (!Clang->getFrontendOpts().TimeTracePath.empty()) { llvm::timeTraceProfilerInitialize( - Clang->getFrontendOpts().TimeTraceGranularity, Argv0); + Clang->getFrontendOpts().TimeTraceGranularity, Argv0, + Clang->getFrontendOpts().TimeTraceVerbose); } // --print-supported-cpus takes priority over the actual compilation. if (Clang->getFrontendOpts().PrintSupportedCPUs) diff --git a/clang/unittests/Support/TimeProfilerTest.cpp b/clang/unittests/Support/TimeProfilerTest.cpp index 5f3950ff033f1..35297601a9e4e 100644 --- a/clang/unittests/Support/TimeProfilerTest.cpp +++ b/clang/unittests/Support/TimeProfilerTest.cpp @@ -23,7 +23,8 @@ namespace { // Should be called before testing. void setupProfiler() { - timeTraceProfilerInitialize(/*TimeTraceGranularity=*/0, "test"); + timeTraceProfilerInitialize(/*TimeTraceGranularity=*/0, "test", + /*TimeTraceVerbose=*/true); } // Should be called after `compileFromString()`. @@ -65,8 +66,8 @@ std::string buildTraceGraph(StringRef Json) { struct EventRecord { int64_t TimestampBegin; int64_t TimestampEnd; - StringRef Name; - StringRef Detail; + std::string Name; + std::string Metadata; }; std::vector<EventRecord> Events; @@ -81,10 +82,16 @@ std::string buildTraceGraph(StringRef Json) { int64_t TimestampBegin = TraceEventObj->getInteger("ts").value_or(0); int64_t TimestampEnd = TimestampBegin + TraceEventObj->getInteger("dur").value_or(0); - StringRef Name = TraceEventObj->getString("name").value_or(""); - StringRef Detail = ""; - if (json::Object *Args = TraceEventObj->getObject("args")) - Detail = Args->getString("detail").value_or(""); + std::string Name = TraceEventObj->getString("name").value_or("").str(); + std::string Metadata = ""; + if (json::Object *Args = TraceEventObj->getObject("args")) { + if (StringRef Detail = Args->getString("detail").value_or(""); + !Detail.empty()) + Metadata += Detail.str(); + if (StringRef File = Args->getString("filename").value_or(""); + !File.empty()) + Metadata += ", " + File.str(); + } // This is a "summary" event, like "Total PerformPendingInstantiations", // skip it @@ -92,7 +99,7 @@ std::string buildTraceGraph(StringRef Json) { continue; Events.emplace_back( - EventRecord{TimestampBegin, TimestampEnd, Name, Detail}); + EventRecord{TimestampBegin, TimestampEnd, Name, Metadata}); } // There can be nested events that are very fast, for example: @@ -132,9 +139,9 @@ std::string buildTraceGraph(StringRef Json) { Stream << "| "; } Stream.write(Event.Name.data(), Event.Name.size()); - if (!Event.Detail.empty()) { + if (!Event.Metadata.empty()) { Stream << " ("; - Stream.write(Event.Detail.data(), Event.Detail.size()); + Stream.write(Event.Metadata.data(), Event.Metadata.size()); Stream << ")"; } Stream << "\n"; @@ -170,13 +177,16 @@ int slow_arr[12 + 34 * 56 + // 22nd line static_cast<int>(slow_namespace::slow_func())]; // 23rd line constexpr int slow_init_list[] = {1, 1, 2, 3, 5, 8, 13, 21}; // 25th line + +template <typename T> +void foo(T) {} +void bar() { foo(0); } )"; setupProfiler(); ASSERT_TRUE(compileFromString(Code, "-std=c++20", "test.cc")); std::string Json = teardownProfiler(); - std::string TraceGraph = buildTraceGraph(Json); - ASSERT_TRUE(TraceGraph == R"( + ASSERT_EQ(R"( Frontend | ParseDeclarationOrFunctionDefinition (test.cc:2:1) | ParseDeclarationOrFunctionDefinition (test.cc:6:1) @@ -201,11 +211,13 @@ Frontend | | EvaluateAsRValue (<test.cc:22:14, line:23:58>) | ParseDeclarationOrFunctionDefinition (test.cc:25:1) | | EvaluateAsInitializer (slow_init_list) +| ParseFunctionDefinition (foo) +| ParseDeclarationOrFunctionDefinition (test.cc:29:1) +| | ParseFunctionDefinition (bar) | PerformPendingInstantiations -)"); - - // NOTE: If this test is failing, run this test with - // `llvm::errs() << TraceGraph;` and change the assert above. +| | InstantiateFunction (foo<int>, test.cc) +)", + buildTraceGraph(Json)); } TEST(TimeProfilerTest, ConstantEvaluationC99) { diff --git a/llvm/include/llvm/Support/TimeProfiler.h b/llvm/include/llvm/Support/TimeProfiler.h index d669c0d2a5e23..f61aedb3bc37e 100644 --- a/llvm/include/llvm/Support/TimeProfiler.h +++ b/llvm/include/llvm/Support/TimeProfiler.h @@ -84,21 +84,26 @@ namespace llvm { class raw_pwrite_stream; struct TimeTraceMetadata { - std::string Details; + std::string Detail; // Source file information for the event. - std::string Filename; + std::string Filename; + + bool isEmpty() const { return Detail.empty() && Filename.empty(); } }; struct TimeTraceProfiler; TimeTraceProfiler *getTimeTraceProfilerInstance(); +bool isTimeTraceVerbose(); + struct TimeTraceProfilerEntry; /// Initialize the time trace profiler. /// This sets up the global \p TimeTraceProfilerInstance /// variable to be the profiler instance. void timeTraceProfilerInitialize(unsigned TimeTraceGranularity, - StringRef ProcName); + StringRef ProcName, + bool TimeTraceVerbose = false); /// Cleanup the time trace profiler, if it was initialized. void timeTraceProfilerCleanup(); @@ -174,7 +179,8 @@ class TimeTraceScope { if (getTimeTraceProfilerInstance() != nullptr) Entry = timeTraceProfilerBegin(Name, Detail); } - TimeTraceScope(StringRef Name, llvm::function_ref<TimeTraceMetadata()> Metadata) { + TimeTraceScope(StringRef Name, + llvm::function_ref<TimeTraceMetadata()> Metadata) { if (getTimeTraceProfilerInstance() != nullptr) Entry = timeTraceProfilerBegin(Name, Metadata); } diff --git a/llvm/lib/Support/TimeProfiler.cpp b/llvm/lib/Support/TimeProfiler.cpp index 4b0466b265db4..ccea04b1940a2 100644 --- a/llvm/lib/Support/TimeProfiler.cpp +++ b/llvm/lib/Support/TimeProfiler.cpp @@ -80,7 +80,7 @@ struct llvm::TimeTraceProfilerEntry { std::string &&Dt, bool Ae) : Start(std::move(S)), End(std::move(E)), Name(std::move(N)), Metadata(), AsyncEvent(Ae) { - Metadata.Details = std::move(Dt); + Metadata.Detail = std::move(Dt); } TimeTraceProfilerEntry(TimePointType &&S, TimePointType &&E, std::string &&N, @@ -105,10 +105,12 @@ struct llvm::TimeTraceProfilerEntry { }; struct llvm::TimeTraceProfiler { - TimeTraceProfiler(unsigned TimeTraceGranularity = 0, StringRef ProcName = "") + TimeTraceProfiler(unsigned TimeTraceGranularity = 0, StringRef ProcName = "", + bool TimeTraceVerbose = false) : BeginningOfTime(system_clock::now()), StartTime(ClockType::now()), ProcName(ProcName), Pid(sys::Process::getProcessId()), - Tid(llvm::get_threadid()), TimeTraceGranularity(TimeTraceGranularity) { + Tid(llvm::get_threadid()), TimeTraceGranularity(TimeTraceGranularity), + TimeTraceVerbose(TimeTraceVerbose) { llvm::get_thread_name(ThreadName); } @@ -121,9 +123,9 @@ struct llvm::TimeTraceProfiler { return Stack.back().get(); } - TimeTraceProfilerEntry *begin(std::string Name, - llvm::function_ref<TimeTraceMetadata()>Metadata, - bool AsyncEvent = false) { + TimeTraceProfilerEntry * + begin(std::string Name, llvm::function_ref<TimeTraceMetadata()> Metadata, + bool AsyncEvent = false) { Stack.emplace_back(std::make_unique<TimeTraceProfilerEntry>( ClockType::now(), TimePointType(), std::move(Name), Metadata(), AsyncEvent)); @@ -201,13 +203,13 @@ struct llvm::TimeTraceProfiler { J.attribute("dur", DurUs); } J.attribute("name", E.Name); - if (!E.Metadata.Details.empty()) { - J.attributeObject("args", - [&] { J.attribute("detail", E.Metadata.Details); }); - } - if (!E.Metadata.Filename.empty()) { - J.attributeObject( - "args", [&] { J.attribute("filename", E.Metadata.Filename); }); + if (!E.Metadata.isEmpty()) { + J.attributeObject("args", [&] { + if (!E.Metadata.Detail.empty()) + J.attribute("detail", E.Metadata.Detail); + if (!E.Metadata.Filename.empty()) + J.attribute("filename", E.Metadata.Filename); + }); } }); @@ -329,14 +331,25 @@ struct llvm::TimeTraceProfiler { // Minimum time granularity (in microseconds) const unsigned TimeTraceGranularity; + + // Make time trace capture verbose event details (eg. source filenames). This + // can increase the size of the output by 2-3 times. + const bool TimeTraceVerbose; }; +bool llvm::isTimeTraceVerbose() { + return getTimeTraceProfilerInstance() && + getTimeTraceProfilerInstance()->TimeTraceVerbose; +} + void llvm::timeTraceProfilerInitialize(unsigned TimeTraceGranularity, - StringRef ProcName) { + StringRef ProcName, + bool TimeTraceVerbose) { assert(TimeTraceProfilerInstance == nullptr && "Profiler should not be initialized"); TimeTraceProfilerInstance = new TimeTraceProfiler( - TimeTraceGranularity, llvm::sys::path::filename(ProcName)); + TimeTraceGranularity, llvm::sys::path::filename(ProcName), + TimeTraceVerbose); } // Removes all TimeTraceProfilerInstances. >From d9fd50b845de2e978ffc68fa10aaf5fcc0e26746 Mon Sep 17 00:00:00 2001 From: Utkarsh Saxena <u...@google.com> Date: Wed, 17 Jul 2024 09:00:19 +0000 Subject: [PATCH 8/8] format. release notes --- clang/docs/ReleaseNotes.rst | 3 +++ clang/test/Driver/ftime-trace-sections.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index cb96c5a16f261..640bb44f42bb2 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -719,6 +719,9 @@ Improvements to Clang's time-trace - Clang now specifies that using ``auto`` in a lambda parameter is a C++14 extension when appropriate. (`#46059: <https://github.com/llvm/llvm-project/issues/46059>`_). +- Clang now adds source file infomation for template instantiations as ``event["args"]["filename"]``. This + added behind an option ``-ftime-trace-verbose``. This is expected to increase the size of trace by 2-3 times. + Improvements to Coverage Mapping -------------------------------- diff --git a/clang/test/Driver/ftime-trace-sections.py b/clang/test/Driver/ftime-trace-sections.py index b30fc1bc76ed3..a5ed2de1239b3 100755 --- a/clang/test/Driver/ftime-trace-sections.py +++ b/clang/test/Driver/ftime-trace-sections.py @@ -51,7 +51,7 @@ def is_before(range1, range2): ] ): sys.exit("Not all Frontend section are before all Backend sections!") -print( "\n\n" ,instants , "\n==================") + # Check that entries for foo exist and are in a demangled form. if not any(e for e in instants if "foo<int>" in e["args"]["detail"]): sys.exit("Missing Instantiate entry for foo!") _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits