[clang-tools-extra] [clang-doc] add ftime profiling (PR #97644)

via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 15 02:30:30 PDT 2024


https://github.com/PeterChou1 updated https://github.com/llvm/llvm-project/pull/97644

>From cbb9d73b4827206ea7f5da58cc4a765a9297d620 Mon Sep 17 00:00:00 2001
From: PeterChou1 <peter.chou at mail.utoronto.ca>
Date: Thu, 4 Jul 2024 03:39:22 -0400
Subject: [PATCH 1/5] [clang-doc] add ftime trace

---
 clang-tools-extra/clang-doc/BitcodeReader.cpp |  8 +++
 clang-tools-extra/clang-doc/Mapper.cpp        |  9 ++++
 .../clang-doc/Representation.cpp              |  2 +
 clang-tools-extra/clang-doc/Representation.h  |  5 +-
 .../clang-doc/tool/ClangDocMain.cpp           | 54 +++++++++++++++++--
 5 files changed, 72 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index bfb04e7407b38..eef8c1b6e7f0a 100644
--- a/clang-tools-extra/clang-doc/BitcodeReader.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp
@@ -9,6 +9,7 @@
 #include "BitcodeReader.h"
 #include "llvm/ADT/IndexedMap.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/raw_ostream.h"
 #include <optional>
 
@@ -670,6 +671,7 @@ llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) {
 
 template <>
 llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) {
+  llvm::TimeTraceScope("clang-doc", "readRecord Reference");
   Record R;
   llvm::StringRef Blob;
   llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
@@ -681,6 +683,7 @@ llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) {
 // Read a block of records into a single info.
 template <typename T>
 llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) {
+  llvm::TimeTraceScope("readBlock", "ClangDocBitcodeReader");
   if (llvm::Error Err = Stream.EnterSubBlock(ID))
     return Err;
 
@@ -711,6 +714,7 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) {
 
 template <typename T>
 llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
+  llvm::TimeTraceScope("readSubBlock", "ClangDocBitcodeReader");
   switch (ID) {
   // Blocks can only have certain types of sub blocks.
   case BI_COMMENT_BLOCK_ID: {
@@ -817,6 +821,7 @@ llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
 
 ClangDocBitcodeReader::Cursor
 ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) {
+  llvm::TimeTraceScope("skipUntilRecordOrBlock", "ClangDocBitcodeReader");
   BlockOrRecordID = 0;
 
   while (!Stream.AtEndOfStream()) {
@@ -878,6 +883,7 @@ llvm::Error ClangDocBitcodeReader::validateStream() {
 }
 
 llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
+  llvm::TimeTraceScope("readBlockInfoBlock", "ClangDocBitcodeReader");
   Expected<std::optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
       Stream.ReadBlockInfoBlock();
   if (!MaybeBlockInfo)
@@ -894,6 +900,7 @@ llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
 template <typename T>
 llvm::Expected<std::unique_ptr<Info>>
 ClangDocBitcodeReader::createInfo(unsigned ID) {
+  llvm::TimeTraceScope("createInfo", "ClangDocBitcodeReader");
   std::unique_ptr<Info> I = std::make_unique<T>();
   if (auto Err = readBlock(ID, static_cast<T *>(I.get())))
     return std::move(Err);
@@ -902,6 +909,7 @@ ClangDocBitcodeReader::createInfo(unsigned ID) {
 
 llvm::Expected<std::unique_ptr<Info>>
 ClangDocBitcodeReader::readBlockToInfo(unsigned ID) {
+  llvm::TimeTraceScope("readBlockToInfo", "ClangDocBitcodeReader");
   switch (ID) {
   case BI_NAMESPACE_BLOCK_ID:
     return createInfo<NamespaceInfo>(ID);
diff --git a/clang-tools-extra/clang-doc/Mapper.cpp b/clang-tools-extra/clang-doc/Mapper.cpp
index bb8b7952980ac..4a9e8721c9ff4 100644
--- a/clang-tools-extra/clang-doc/Mapper.cpp
+++ b/clang-tools-extra/clang-doc/Mapper.cpp
@@ -13,12 +13,17 @@
 #include "clang/Index/USRGeneration.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/TimeProfiler.h"
 
 namespace clang {
 namespace doc {
 
 void MapASTVisitor::HandleTranslationUnit(ASTContext &Context) {
+  if (CDCtx.FTimeTrace)
+    llvm::timeTraceProfilerInitialize(CDCtx.Granularity, "clang-doc");
   TraverseDecl(Context.getTranslationUnitDecl());
+  if (CDCtx.FTimeTrace)
+    llvm::timeTraceProfilerFinishThread();
 }
 
 template <typename T> bool MapASTVisitor::mapDecl(const T *D) {
@@ -30,6 +35,7 @@ template <typename T> bool MapASTVisitor::mapDecl(const T *D) {
   if (D->getParentFunctionOrMethod())
     return true;
 
+  llvm::timeTraceProfilerBegin("emit info phase", "emit info");
   llvm::SmallString<128> USR;
   // If there is an error generating a USR for the decl, skip this decl.
   if (index::generateUSRForDecl(D, USR))
@@ -40,7 +46,9 @@ template <typename T> bool MapASTVisitor::mapDecl(const T *D) {
   auto I = serialize::emitInfo(D, getComment(D, D->getASTContext()),
                                getLine(D, D->getASTContext()), File,
                                IsFileInRootDir, CDCtx.PublicOnly);
+  llvm::timeTraceProfilerEnd();
 
+  llvm::timeTraceProfilerBegin("serializing info", "serializing");
   // A null in place of I indicates that the serializer is skipping this decl
   // for some reason (e.g. we're only reporting public decls).
   if (I.first)
@@ -49,6 +57,7 @@ template <typename T> bool MapASTVisitor::mapDecl(const T *D) {
   if (I.second)
     CDCtx.ECtx->reportResult(llvm::toHex(llvm::toStringRef(I.second->USR)),
                              serialize::serialize(I.second));
+  llvm::timeTraceProfilerEnd();
   return true;
 }
 
diff --git a/clang-tools-extra/clang-doc/Representation.cpp b/clang-tools-extra/clang-doc/Representation.cpp
index d08afbb962189..23e739a675789 100644
--- a/clang-tools-extra/clang-doc/Representation.cpp
+++ b/clang-tools-extra/clang-doc/Representation.cpp
@@ -366,10 +366,12 @@ void Index::sort() {
 
 ClangDocContext::ClangDocContext(tooling::ExecutionContext *ECtx,
                                  StringRef ProjectName, bool PublicOnly,
+                                 bool FTimeTrace, int Granularity,
                                  StringRef OutDirectory, StringRef SourceRoot,
                                  StringRef RepositoryUrl,
                                  std::vector<std::string> UserStylesheets)
     : ECtx(ECtx), ProjectName(ProjectName), PublicOnly(PublicOnly),
+      FTimeTrace(FTimeTrace), Granularity(Granularity),
       OutDirectory(OutDirectory), UserStylesheets(UserStylesheets) {
   llvm::SmallString<128> SourceRootDir(SourceRoot);
   if (SourceRoot.empty())
diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h
index d70c279f7a2bd..619fa34da8779 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -480,12 +480,15 @@ mergeInfos(std::vector<std::unique_ptr<Info>> &Values);
 struct ClangDocContext {
   ClangDocContext() = default;
   ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName,
-                  bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot,
+                  bool PublicOnly, bool FTimeTrace, int Granularity,
+                  StringRef OutDirectory, StringRef SourceRoot,
                   StringRef RepositoryUrl,
                   std::vector<std::string> UserStylesheets);
   tooling::ExecutionContext *ECtx;
   std::string ProjectName; // Name of project clang-doc is documenting.
   bool PublicOnly; // Indicates if only public declarations are documented.
+  bool FTimeTrace; // Indicates if ftime trace is turned on
+  int Granularity; // Granularity of ftime trace
   std::string OutDirectory; // Directory for outputting generated files.
   std::string SourceRoot;   // Directory where processed files are stored. Links
                             // to definition locations will only be generated if
diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index 6198a6e0cdcc3..c8d1798110f1c 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -41,6 +41,7 @@
 #include "llvm/Support/Process.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/ThreadPool.h"
+#include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/raw_ostream.h"
 #include <atomic>
 #include <mutex>
@@ -99,6 +100,16 @@ URL of repository that hosts code.
 Used for links to definition locations.)"),
                   llvm::cl::cat(ClangDocCategory));
 
+static llvm::cl::opt<bool> FTimeTrace("ftime-trace", llvm::cl::desc(R"(
+Turn on time profiler. Generates clang-doc-tracing.json)"),
+                                      llvm::cl::init(false),
+                                      llvm::cl::cat(ClangDocCategory));
+
+static llvm::cl::opt<int> FTimeGranularity("ftime-gran", llvm::cl::desc(R"(
+Specify granularity for ftime-trace defaults to 200)"),
+                                           llvm::cl::init(200),
+                                           llvm::cl::cat(ClangDocCategory));
+
 enum OutputFormatTy {
   md,
   yaml,
@@ -229,6 +240,12 @@ Example usage for a project using a compile commands database:
     return 1;
   }
 
+  // turns on ftime trace profiling
+  if (FTimeTrace)
+    llvm::timeTraceProfilerInitialize(FTimeGranularity, "clang-doc");
+
+  llvm::TimeTraceScope("clang-doc", "main");
+
   // Fail early if an invalid format was provided.
   std::string Format = getFormatString();
   llvm::outs() << "Emiting docs in " << Format << " format.\n";
@@ -249,11 +266,12 @@ Example usage for a project using a compile commands database:
       Executor->get()->getExecutionContext(),
       ProjectName,
       PublicOnly,
+      FTimeTrace,
+      FTimeGranularity,
       OutDirectory,
       SourceRoot,
       RepositoryUrl,
-      {UserStylesheets.begin(), UserStylesheets.end()}
-  };
+      {UserStylesheets.begin(), UserStylesheets.end()}};
 
   if (Format == "html") {
     if (auto Err = getHtmlAssetFiles(argv[0], CDCtx)) {
@@ -262,6 +280,7 @@ Example usage for a project using a compile commands database:
     }
   }
 
+  llvm::timeTraceProfilerBegin("mapping phase", "mapping");
   // Mapping phase
   llvm::outs() << "Mapping decls...\n";
   auto Err =
@@ -276,10 +295,12 @@ Example usage for a project using a compile commands database:
       return 1;
     }
   }
+  llvm::timeTraceProfilerEnd();
 
   // Collect values into output by key.
   // In ToolResults, the Key is the hashed USR and the value is the
   // bitcode-encoded representation of the Info object.
+  llvm::timeTraceProfilerBegin("clang-doc", "collection phase");
   llvm::outs() << "Collecting infos...\n";
   llvm::StringMap<std::vector<StringRef>> USRToBitcode;
   Executor->get()->getToolResults()->forEachResult(
@@ -287,6 +308,7 @@ Example usage for a project using a compile commands database:
         auto R = USRToBitcode.try_emplace(Key, std::vector<StringRef>());
         R.first->second.emplace_back(Value);
       });
+  llvm::timeTraceProfilerEnd();
 
   // Collects all Infos according to their unique USR value. This map is added
   // to from the thread pool below and is protected by the USRToInfoMutex.
@@ -294,6 +316,7 @@ Example usage for a project using a compile commands database:
   llvm::StringMap<std::unique_ptr<doc::Info>> USRToInfo;
 
   // First reducing phase (reduce all decls into one info per decl).
+  llvm::timeTraceProfilerBegin("reduction phase", "reducing");
   llvm::outs() << "Reducing " << USRToBitcode.size() << " infos...\n";
   std::atomic<bool> Error;
   Error = false;
@@ -302,8 +325,11 @@ Example usage for a project using a compile commands database:
   llvm::DefaultThreadPool Pool(llvm::hardware_concurrency(ExecutorConcurrency));
   for (auto &Group : USRToBitcode) {
     Pool.async([&]() {
-      std::vector<std::unique_ptr<doc::Info>> Infos;
+      if (FTimeTrace)
+        llvm::timeTraceProfilerInitialize(FTimeGranularity, "clang-doc");
 
+      llvm::timeTraceProfilerBegin("decoding bitcode phase", "decoding");
+      std::vector<std::unique_ptr<doc::Info>> Infos;
       for (auto &Bitcode : Group.getValue()) {
         llvm::BitstreamCursor Stream(Bitcode);
         doc::ClangDocBitcodeReader Reader(Stream);
@@ -316,32 +342,39 @@ Example usage for a project using a compile commands database:
         std::move(ReadInfos->begin(), ReadInfos->end(),
                   std::back_inserter(Infos));
       }
+      llvm::timeTraceProfilerEnd();
 
+      llvm::timeTraceProfilerBegin("merging bitcode phase", "merging");
       auto Reduced = doc::mergeInfos(Infos);
       if (!Reduced) {
         llvm::errs() << llvm::toString(Reduced.takeError());
         return;
       }
+      llvm::timeTraceProfilerEnd();
 
       // Add a reference to this Info in the Index
       {
         std::lock_guard<llvm::sys::Mutex> Guard(IndexMutex);
         clang::doc::Generator::addInfoToIndex(CDCtx.Idx, Reduced.get().get());
       }
-
       // Save in the result map (needs a lock due to threaded access).
       {
         std::lock_guard<llvm::sys::Mutex> Guard(USRToInfoMutex);
         USRToInfo[Group.getKey()] = std::move(Reduced.get());
       }
+
+      if (CDCtx.FTimeTrace)
+        llvm::timeTraceProfilerFinishThread();
     });
   }
+  llvm::timeTraceProfilerEnd();
 
   Pool.wait();
 
   if (Error)
     return 1;
 
+  llvm::timeTraceProfilerBegin("generating phase", "generating");
   // Ensure the root output directory exists.
   if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory);
       Err != std::error_code()) {
@@ -362,6 +395,17 @@ Example usage for a project using a compile commands database:
   if (Err) {
     llvm::outs() << "warning: " << toString(std::move(Err)) << "\n";
   }
-
+  llvm::timeTraceProfilerEnd();
+
+  if (FTimeTrace) {
+    std::error_code EC;
+    llvm::raw_fd_ostream OS("clang-doc-tracing.json", EC,
+                            llvm::sys::fs::OF_Text);
+    if (!EC) {
+      llvm::timeTraceProfilerWrite(OS);
+    } else {
+      llvm::errs() << "Error opening file: " << EC.message() << "\n";
+    }
+  }
   return 0;
 }

>From 181614ef6b1caf1dca602847a73706b028776f69 Mon Sep 17 00:00:00 2001
From: PeterChou1 <peter.chou at mail.utoronto.ca>
Date: Thu, 4 Jul 2024 04:30:59 -0400
Subject: [PATCH 2/5] [clang-doc] modify unittest

---
 clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
index e4a7340318b93..d146cc303c793 100644
--- a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
@@ -30,7 +30,7 @@ ClangDocContext
 getClangDocContext(std::vector<std::string> UserStylesheets = {},
                    StringRef RepositoryUrl = "") {
   ClangDocContext CDCtx{
-      {}, "test-project", {}, {}, {}, RepositoryUrl, UserStylesheets};
+      {}, "test-project", {}, {}, {}, {}, {}, RepositoryUrl, UserStylesheets};
   CDCtx.UserStylesheets.insert(
       CDCtx.UserStylesheets.begin(),
       "../share/clang/clang-doc-default-stylesheet.css");

>From 66ed0cc62b57eb9756a25db8c5cd3b7fb0461fdf Mon Sep 17 00:00:00 2001
From: PeterChou1 <peter.chou at mail.utoronto.ca>
Date: Fri, 12 Jul 2024 06:17:09 -0400
Subject: [PATCH 3/5] [clang-doc] address pr comments

---
 clang-tools-extra/clang-doc/BitcodeReader.cpp | 14 +++----
 clang-tools-extra/clang-doc/Mapper.cpp        |  6 +--
 .../clang-doc/Representation.cpp              |  8 ++--
 clang-tools-extra/clang-doc/Representation.h  |  6 +--
 .../clang-doc/tool/ClangDocMain.cpp           | 37 ++++++++-----------
 .../unittests/clang-doc/HTMLGeneratorTest.cpp |  2 +-
 6 files changed, 34 insertions(+), 39 deletions(-)

diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index eef8c1b6e7f0a..b7e2e377d38a9 100644
--- a/clang-tools-extra/clang-doc/BitcodeReader.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp
@@ -671,7 +671,7 @@ llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) {
 
 template <>
 llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) {
-  llvm::TimeTraceScope("clang-doc", "readRecord Reference");
+  llvm::TimeTraceScope("readRecord");
   Record R;
   llvm::StringRef Blob;
   llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
@@ -683,7 +683,7 @@ llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) {
 // Read a block of records into a single info.
 template <typename T>
 llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) {
-  llvm::TimeTraceScope("readBlock", "ClangDocBitcodeReader");
+  llvm::TimeTraceScope("readBlock");
   if (llvm::Error Err = Stream.EnterSubBlock(ID))
     return Err;
 
@@ -714,7 +714,7 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) {
 
 template <typename T>
 llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
-  llvm::TimeTraceScope("readSubBlock", "ClangDocBitcodeReader");
+  llvm::TimeTraceScope("readSubBlock");
   switch (ID) {
   // Blocks can only have certain types of sub blocks.
   case BI_COMMENT_BLOCK_ID: {
@@ -821,7 +821,7 @@ llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
 
 ClangDocBitcodeReader::Cursor
 ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) {
-  llvm::TimeTraceScope("skipUntilRecordOrBlock", "ClangDocBitcodeReader");
+  llvm::TimeTraceScope("skipUntilRecordOrBlock");
   BlockOrRecordID = 0;
 
   while (!Stream.AtEndOfStream()) {
@@ -883,7 +883,7 @@ llvm::Error ClangDocBitcodeReader::validateStream() {
 }
 
 llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
-  llvm::TimeTraceScope("readBlockInfoBlock", "ClangDocBitcodeReader");
+  llvm::TimeTraceScope("readBlockInfoBlock");
   Expected<std::optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
       Stream.ReadBlockInfoBlock();
   if (!MaybeBlockInfo)
@@ -900,7 +900,7 @@ llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
 template <typename T>
 llvm::Expected<std::unique_ptr<Info>>
 ClangDocBitcodeReader::createInfo(unsigned ID) {
-  llvm::TimeTraceScope("createInfo", "ClangDocBitcodeReader");
+  llvm::TimeTraceScope("createInfo");
   std::unique_ptr<Info> I = std::make_unique<T>();
   if (auto Err = readBlock(ID, static_cast<T *>(I.get())))
     return std::move(Err);
@@ -909,7 +909,7 @@ ClangDocBitcodeReader::createInfo(unsigned ID) {
 
 llvm::Expected<std::unique_ptr<Info>>
 ClangDocBitcodeReader::readBlockToInfo(unsigned ID) {
-  llvm::TimeTraceScope("readBlockToInfo", "ClangDocBitcodeReader");
+  llvm::TimeTraceScope("readBlockToInfo");
   switch (ID) {
   case BI_NAMESPACE_BLOCK_ID:
     return createInfo<NamespaceInfo>(ID);
diff --git a/clang-tools-extra/clang-doc/Mapper.cpp b/clang-tools-extra/clang-doc/Mapper.cpp
index 4a9e8721c9ff4..65a8cdafb4bc9 100644
--- a/clang-tools-extra/clang-doc/Mapper.cpp
+++ b/clang-tools-extra/clang-doc/Mapper.cpp
@@ -20,7 +20,7 @@ namespace doc {
 
 void MapASTVisitor::HandleTranslationUnit(ASTContext &Context) {
   if (CDCtx.FTimeTrace)
-    llvm::timeTraceProfilerInitialize(CDCtx.Granularity, "clang-doc");
+    llvm::timeTraceProfilerInitialize(200, "clang-doc");
   TraverseDecl(Context.getTranslationUnitDecl());
   if (CDCtx.FTimeTrace)
     llvm::timeTraceProfilerFinishThread();
@@ -35,7 +35,7 @@ template <typename T> bool MapASTVisitor::mapDecl(const T *D) {
   if (D->getParentFunctionOrMethod())
     return true;
 
-  llvm::timeTraceProfilerBegin("emit info phase", "emit info");
+  llvm::timeTraceProfilerBegin("emitInfo", "emit info from ast node");
   llvm::SmallString<128> USR;
   // If there is an error generating a USR for the decl, skip this decl.
   if (index::generateUSRForDecl(D, USR))
@@ -48,7 +48,7 @@ template <typename T> bool MapASTVisitor::mapDecl(const T *D) {
                                IsFileInRootDir, CDCtx.PublicOnly);
   llvm::timeTraceProfilerEnd();
 
-  llvm::timeTraceProfilerBegin("serializing info", "serializing");
+  llvm::timeTraceProfilerBegin("serialize", "serialize info");
   // A null in place of I indicates that the serializer is skipping this decl
   // for some reason (e.g. we're only reporting public decls).
   if (I.first)
diff --git a/clang-tools-extra/clang-doc/Representation.cpp b/clang-tools-extra/clang-doc/Representation.cpp
index 23e739a675789..64abacac37112 100644
--- a/clang-tools-extra/clang-doc/Representation.cpp
+++ b/clang-tools-extra/clang-doc/Representation.cpp
@@ -366,13 +366,13 @@ void Index::sort() {
 
 ClangDocContext::ClangDocContext(tooling::ExecutionContext *ECtx,
                                  StringRef ProjectName, bool PublicOnly,
-                                 bool FTimeTrace, int Granularity,
                                  StringRef OutDirectory, StringRef SourceRoot,
                                  StringRef RepositoryUrl,
-                                 std::vector<std::string> UserStylesheets)
+                                 std::vector<std::string> UserStylesheets,
+                                 bool FTimeTrace)
     : ECtx(ECtx), ProjectName(ProjectName), PublicOnly(PublicOnly),
-      FTimeTrace(FTimeTrace), Granularity(Granularity),
-      OutDirectory(OutDirectory), UserStylesheets(UserStylesheets) {
+      OutDirectory(OutDirectory), UserStylesheets(UserStylesheets),
+      FTimeTrace(FTimeTrace) {
   llvm::SmallString<128> SourceRootDir(SourceRoot);
   if (SourceRoot.empty())
     // If no SourceRoot was provided the current path is used as the default
diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h
index 619fa34da8779..7de154d642c8b 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -480,10 +480,10 @@ mergeInfos(std::vector<std::unique_ptr<Info>> &Values);
 struct ClangDocContext {
   ClangDocContext() = default;
   ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName,
-                  bool PublicOnly, bool FTimeTrace, int Granularity,
-                  StringRef OutDirectory, StringRef SourceRoot,
+                  bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot,
                   StringRef RepositoryUrl,
-                  std::vector<std::string> UserStylesheets);
+                  std::vector<std::string> UserStylesheets,
+                  bool FTimeTrace = false);
   tooling::ExecutionContext *ECtx;
   std::string ProjectName; // Name of project clang-doc is documenting.
   bool PublicOnly; // Indicates if only public declarations are documented.
diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index c8d1798110f1c..f1ba35fa2e4f6 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -105,11 +105,6 @@ Turn on time profiler. Generates clang-doc-tracing.json)"),
                                       llvm::cl::init(false),
                                       llvm::cl::cat(ClangDocCategory));
 
-static llvm::cl::opt<int> FTimeGranularity("ftime-gran", llvm::cl::desc(R"(
-Specify granularity for ftime-trace defaults to 200)"),
-                                           llvm::cl::init(200),
-                                           llvm::cl::cat(ClangDocCategory));
-
 enum OutputFormatTy {
   md,
   yaml,
@@ -242,9 +237,9 @@ Example usage for a project using a compile commands database:
 
   // turns on ftime trace profiling
   if (FTimeTrace)
-    llvm::timeTraceProfilerInitialize(FTimeGranularity, "clang-doc");
+    llvm::timeTraceProfilerInitialize(200, "clang-doc");
 
-  llvm::TimeTraceScope("clang-doc", "main");
+  llvm::TimeTraceScope("main", "clang-doc");
 
   // Fail early if an invalid format was provided.
   std::string Format = getFormatString();
@@ -266,12 +261,11 @@ Example usage for a project using a compile commands database:
       Executor->get()->getExecutionContext(),
       ProjectName,
       PublicOnly,
-      FTimeTrace,
-      FTimeGranularity,
       OutDirectory,
       SourceRoot,
       RepositoryUrl,
-      {UserStylesheets.begin(), UserStylesheets.end()}};
+      {UserStylesheets.begin(), UserStylesheets.end()},
+      FTimeTrace};
 
   if (Format == "html") {
     if (auto Err = getHtmlAssetFiles(argv[0], CDCtx)) {
@@ -280,7 +274,7 @@ Example usage for a project using a compile commands database:
     }
   }
 
-  llvm::timeTraceProfilerBegin("mapping phase", "mapping");
+  llvm::timeTraceProfilerBegin("mapping decls", "clang-doc");
   // Mapping phase
   llvm::outs() << "Mapping decls...\n";
   auto Err =
@@ -300,7 +294,7 @@ Example usage for a project using a compile commands database:
   // Collect values into output by key.
   // In ToolResults, the Key is the hashed USR and the value is the
   // bitcode-encoded representation of the Info object.
-  llvm::timeTraceProfilerBegin("clang-doc", "collection phase");
+  llvm::timeTraceProfilerBegin("collecting infos", "clang-doc");
   llvm::outs() << "Collecting infos...\n";
   llvm::StringMap<std::vector<StringRef>> USRToBitcode;
   Executor->get()->getToolResults()->forEachResult(
@@ -316,7 +310,7 @@ Example usage for a project using a compile commands database:
   llvm::StringMap<std::unique_ptr<doc::Info>> USRToInfo;
 
   // First reducing phase (reduce all decls into one info per decl).
-  llvm::timeTraceProfilerBegin("reduction phase", "reducing");
+  llvm::timeTraceProfilerBegin("reducing infos", "clang-doc");
   llvm::outs() << "Reducing " << USRToBitcode.size() << " infos...\n";
   std::atomic<bool> Error;
   Error = false;
@@ -326,9 +320,9 @@ Example usage for a project using a compile commands database:
   for (auto &Group : USRToBitcode) {
     Pool.async([&]() {
       if (FTimeTrace)
-        llvm::timeTraceProfilerInitialize(FTimeGranularity, "clang-doc");
+        llvm::timeTraceProfilerInitialize(200, "clang-doc");
 
-      llvm::timeTraceProfilerBegin("decoding bitcode phase", "decoding");
+      llvm::timeTraceProfilerBegin("decoding bitcode", "decoding");
       std::vector<std::unique_ptr<doc::Info>> Infos;
       for (auto &Bitcode : Group.getValue()) {
         llvm::BitstreamCursor Stream(Bitcode);
@@ -344,7 +338,7 @@ Example usage for a project using a compile commands database:
       }
       llvm::timeTraceProfilerEnd();
 
-      llvm::timeTraceProfilerBegin("merging bitcode phase", "merging");
+      llvm::timeTraceProfilerBegin("merging infos", "clang-doc");
       auto Reduced = doc::mergeInfos(Infos);
       if (!Reduced) {
         llvm::errs() << llvm::toString(Reduced.takeError());
@@ -358,6 +352,7 @@ Example usage for a project using a compile commands database:
         clang::doc::Generator::addInfoToIndex(CDCtx.Idx, Reduced.get().get());
       }
       // Save in the result map (needs a lock due to threaded access).
+
       {
         std::lock_guard<llvm::sys::Mutex> Guard(USRToInfoMutex);
         USRToInfo[Group.getKey()] = std::move(Reduced.get());
@@ -374,7 +369,7 @@ Example usage for a project using a compile commands database:
   if (Error)
     return 1;
 
-  llvm::timeTraceProfilerBegin("generating phase", "generating");
+  llvm::timeTraceProfilerBegin("generating docs", "clang-doc");
   // Ensure the root output directory exists.
   if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory);
       Err != std::error_code()) {
@@ -401,11 +396,11 @@ Example usage for a project using a compile commands database:
     std::error_code EC;
     llvm::raw_fd_ostream OS("clang-doc-tracing.json", EC,
                             llvm::sys::fs::OF_Text);
-    if (!EC) {
+    if (!EC)
       llvm::timeTraceProfilerWrite(OS);
-    } else {
-      llvm::errs() << "Error opening file: " << EC.message() << "\n";
-    }
+    else
+      return 1;
+
   }
   return 0;
 }
diff --git a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
index d146cc303c793..e4a7340318b93 100644
--- a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
@@ -30,7 +30,7 @@ ClangDocContext
 getClangDocContext(std::vector<std::string> UserStylesheets = {},
                    StringRef RepositoryUrl = "") {
   ClangDocContext CDCtx{
-      {}, "test-project", {}, {}, {}, {}, {}, RepositoryUrl, UserStylesheets};
+      {}, "test-project", {}, {}, {}, RepositoryUrl, UserStylesheets};
   CDCtx.UserStylesheets.insert(
       CDCtx.UserStylesheets.begin(),
       "../share/clang/clang-doc-default-stylesheet.css");

>From 29d6540eb5ba1d076052a44cee082c7d757a5eff Mon Sep 17 00:00:00 2001
From: PeterChou1 <peter.chou at mail.utoronto.ca>
Date: Fri, 12 Jul 2024 06:38:19 -0400
Subject: [PATCH 4/5] [clang-doc] address  pr comments

---
 clang-tools-extra/clang-doc/tool/ClangDocMain.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index f1ba35fa2e4f6..a1b23535cab13 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -239,7 +239,7 @@ Example usage for a project using a compile commands database:
   if (FTimeTrace)
     llvm::timeTraceProfilerInitialize(200, "clang-doc");
 
-  llvm::TimeTraceScope("main", "clang-doc");
+  llvm::TimeTraceScope("main");
 
   // Fail early if an invalid format was provided.
   std::string Format = getFormatString();
@@ -400,7 +400,6 @@ Example usage for a project using a compile commands database:
       llvm::timeTraceProfilerWrite(OS);
     else
       return 1;
-
   }
   return 0;
 }

>From 4196d1b22fbf48c2764860a2f2ecba9ea8fdfe05 Mon Sep 17 00:00:00 2001
From: PeterChou1 <peter.chou at mail.utoronto.ca>
Date: Mon, 15 Jul 2024 05:30:08 -0400
Subject: [PATCH 5/5] [clang-doc] fix ftime trace labels

---
 clang-tools-extra/clang-doc/BitcodeReader.cpp     | 14 +++++++-------
 clang-tools-extra/clang-doc/Mapper.cpp            |  6 ++++--
 clang-tools-extra/clang-doc/tool/ClangDocMain.cpp | 12 ++++++------
 3 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index b7e2e377d38a9..3c4e0ea1b64e5 100644
--- a/clang-tools-extra/clang-doc/BitcodeReader.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp
@@ -671,7 +671,7 @@ llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) {
 
 template <>
 llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) {
-  llvm::TimeTraceScope("readRecord");
+  llvm::TimeTraceScope("Reducing infos", "readRecord");
   Record R;
   llvm::StringRef Blob;
   llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
@@ -683,7 +683,7 @@ llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) {
 // Read a block of records into a single info.
 template <typename T>
 llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) {
-  llvm::TimeTraceScope("readBlock");
+  llvm::TimeTraceScope("Reducing infos", "readBlock");
   if (llvm::Error Err = Stream.EnterSubBlock(ID))
     return Err;
 
@@ -714,7 +714,7 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) {
 
 template <typename T>
 llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
-  llvm::TimeTraceScope("readSubBlock");
+  llvm::TimeTraceScope("Reducing infos", "readSubBlock");
   switch (ID) {
   // Blocks can only have certain types of sub blocks.
   case BI_COMMENT_BLOCK_ID: {
@@ -821,7 +821,7 @@ llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
 
 ClangDocBitcodeReader::Cursor
 ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) {
-  llvm::TimeTraceScope("skipUntilRecordOrBlock");
+  llvm::TimeTraceScope("Reducing infos","skipUntilRecordOrBlock");
   BlockOrRecordID = 0;
 
   while (!Stream.AtEndOfStream()) {
@@ -883,7 +883,7 @@ llvm::Error ClangDocBitcodeReader::validateStream() {
 }
 
 llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
-  llvm::TimeTraceScope("readBlockInfoBlock");
+  llvm::TimeTraceScope("Reducing infos", "readBlockInfoBlock");
   Expected<std::optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
       Stream.ReadBlockInfoBlock();
   if (!MaybeBlockInfo)
@@ -900,7 +900,7 @@ llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
 template <typename T>
 llvm::Expected<std::unique_ptr<Info>>
 ClangDocBitcodeReader::createInfo(unsigned ID) {
-  llvm::TimeTraceScope("createInfo");
+  llvm::TimeTraceScope("Reducing infos", "createInfo");
   std::unique_ptr<Info> I = std::make_unique<T>();
   if (auto Err = readBlock(ID, static_cast<T *>(I.get())))
     return std::move(Err);
@@ -909,7 +909,7 @@ ClangDocBitcodeReader::createInfo(unsigned ID) {
 
 llvm::Expected<std::unique_ptr<Info>>
 ClangDocBitcodeReader::readBlockToInfo(unsigned ID) {
-  llvm::TimeTraceScope("readBlockToInfo");
+  llvm::TimeTraceScope("Reducing infos", "readBlockToInfo");
   switch (ID) {
   case BI_NAMESPACE_BLOCK_ID:
     return createInfo<NamespaceInfo>(ID);
diff --git a/clang-tools-extra/clang-doc/Mapper.cpp b/clang-tools-extra/clang-doc/Mapper.cpp
index 65a8cdafb4bc9..e87bddcde53dd 100644
--- a/clang-tools-extra/clang-doc/Mapper.cpp
+++ b/clang-tools-extra/clang-doc/Mapper.cpp
@@ -35,7 +35,8 @@ template <typename T> bool MapASTVisitor::mapDecl(const T *D) {
   if (D->getParentFunctionOrMethod())
     return true;
 
-  llvm::timeTraceProfilerBegin("emitInfo", "emit info from ast node");
+  llvm::timeTraceProfilerBegin("Mapping declaration",
+                               "emit info from astnode");
   llvm::SmallString<128> USR;
   // If there is an error generating a USR for the decl, skip this decl.
   if (index::generateUSRForDecl(D, USR))
@@ -48,7 +49,8 @@ template <typename T> bool MapASTVisitor::mapDecl(const T *D) {
                                IsFileInRootDir, CDCtx.PublicOnly);
   llvm::timeTraceProfilerEnd();
 
-  llvm::timeTraceProfilerBegin("serialize", "serialize info");
+  llvm::timeTraceProfilerBegin("Mapping declaration",
+                               "serialized info into bitcode");
   // A null in place of I indicates that the serializer is skipping this decl
   // for some reason (e.g. we're only reporting public decls).
   if (I.first)
diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index a1b23535cab13..97648af7cf8fd 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -274,7 +274,7 @@ Example usage for a project using a compile commands database:
     }
   }
 
-  llvm::timeTraceProfilerBegin("mapping decls", "clang-doc");
+  llvm::timeTraceProfilerBegin("Mapping declaration", "total runtime");
   // Mapping phase
   llvm::outs() << "Mapping decls...\n";
   auto Err =
@@ -294,7 +294,7 @@ Example usage for a project using a compile commands database:
   // Collect values into output by key.
   // In ToolResults, the Key is the hashed USR and the value is the
   // bitcode-encoded representation of the Info object.
-  llvm::timeTraceProfilerBegin("collecting infos", "clang-doc");
+  llvm::timeTraceProfilerBegin("Collect Info", "total runtime");
   llvm::outs() << "Collecting infos...\n";
   llvm::StringMap<std::vector<StringRef>> USRToBitcode;
   Executor->get()->getToolResults()->forEachResult(
@@ -310,7 +310,7 @@ Example usage for a project using a compile commands database:
   llvm::StringMap<std::unique_ptr<doc::Info>> USRToInfo;
 
   // First reducing phase (reduce all decls into one info per decl).
-  llvm::timeTraceProfilerBegin("reducing infos", "clang-doc");
+  llvm::timeTraceProfilerBegin("Reducing infos", "total runtime");
   llvm::outs() << "Reducing " << USRToBitcode.size() << " infos...\n";
   std::atomic<bool> Error;
   Error = false;
@@ -322,7 +322,7 @@ Example usage for a project using a compile commands database:
       if (FTimeTrace)
         llvm::timeTraceProfilerInitialize(200, "clang-doc");
 
-      llvm::timeTraceProfilerBegin("decoding bitcode", "decoding");
+      llvm::timeTraceProfilerBegin("Reducing infos", "decoding bitcode");
       std::vector<std::unique_ptr<doc::Info>> Infos;
       for (auto &Bitcode : Group.getValue()) {
         llvm::BitstreamCursor Stream(Bitcode);
@@ -338,7 +338,7 @@ Example usage for a project using a compile commands database:
       }
       llvm::timeTraceProfilerEnd();
 
-      llvm::timeTraceProfilerBegin("merging infos", "clang-doc");
+      llvm::timeTraceProfilerBegin("Reducing infos", "merging bitcode");
       auto Reduced = doc::mergeInfos(Infos);
       if (!Reduced) {
         llvm::errs() << llvm::toString(Reduced.takeError());
@@ -369,7 +369,7 @@ Example usage for a project using a compile commands database:
   if (Error)
     return 1;
 
-  llvm::timeTraceProfilerBegin("generating docs", "clang-doc");
+  llvm::timeTraceProfilerBegin("Writing output", "total runtime");
   // Ensure the root output directory exists.
   if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory);
       Err != std::error_code()) {



More information about the cfe-commits mailing list