[clang-tools-extra] 1b7631a - [clang-doc] Improve clang-doc performance through memoization (#96809)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 24 23:03:23 PDT 2024
Author: PeterChou1
Date: 2024-07-25T02:03:20-04:00
New Revision: 1b7631a699e6af7f497548a1ceb5be0570c60ed0
URL: https://github.com/llvm/llvm-project/commit/1b7631a699e6af7f497548a1ceb5be0570c60ed0
DIFF: https://github.com/llvm/llvm-project/commit/1b7631a699e6af7f497548a1ceb5be0570c60ed0.diff
LOG: [clang-doc] Improve clang-doc performance through memoization (#96809)
Added:
Modified:
clang-tools-extra/clang-doc/Mapper.cpp
clang-tools-extra/clang-doc/Mapper.h
clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-doc/Mapper.cpp b/clang-tools-extra/clang-doc/Mapper.cpp
index bb8b7952980ac..6c90db03424c6 100644
--- a/clang-tools-extra/clang-doc/Mapper.cpp
+++ b/clang-tools-extra/clang-doc/Mapper.cpp
@@ -12,16 +12,28 @@
#include "clang/AST/Comment.h"
#include "clang/Index/USRGeneration.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/Error.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Mutex.h"
namespace clang {
namespace doc {
+static llvm::StringSet<> USRVisited;
+static llvm::sys::Mutex USRVisitedGuard;
+
+template <typename T> bool isTypedefAnonRecord(const T *D) {
+ if (const auto *C = dyn_cast<CXXRecordDecl>(D)) {
+ return C->getTypedefNameForAnonDecl();
+ }
+ return false;
+}
+
void MapASTVisitor::HandleTranslationUnit(ASTContext &Context) {
TraverseDecl(Context.getTranslationUnitDecl());
}
-template <typename T> bool MapASTVisitor::mapDecl(const T *D) {
+template <typename T>
+bool MapASTVisitor::mapDecl(const T *D, bool IsDefinition) {
// If we're looking a decl not in user files, skip this decl.
if (D->getASTContext().getSourceManager().isInSystemHeader(D->getLocation()))
return true;
@@ -34,6 +46,16 @@ template <typename T> bool MapASTVisitor::mapDecl(const T *D) {
// If there is an error generating a USR for the decl, skip this decl.
if (index::generateUSRForDecl(D, USR))
return true;
+ // Prevent Visiting USR twice
+ {
+ std::lock_guard<llvm::sys::Mutex> Guard(USRVisitedGuard);
+ StringRef Visited = USR.str();
+ if (USRVisited.count(Visited) && !isTypedefAnonRecord<T>(D))
+ return true;
+ // We considered a USR to be visited only when its defined
+ if (IsDefinition)
+ USRVisited.insert(Visited);
+ }
bool IsFileInRootDir;
llvm::SmallString<128> File =
getFile(D, D->getASTContext(), CDCtx.SourceRoot, IsFileInRootDir);
@@ -53,30 +75,34 @@ template <typename T> bool MapASTVisitor::mapDecl(const T *D) {
}
bool MapASTVisitor::VisitNamespaceDecl(const NamespaceDecl *D) {
- return mapDecl(D);
+ return mapDecl(D, /*isDefinition=*/true);
}
-bool MapASTVisitor::VisitRecordDecl(const RecordDecl *D) { return mapDecl(D); }
+bool MapASTVisitor::VisitRecordDecl(const RecordDecl *D) {
+ return mapDecl(D, D->isThisDeclarationADefinition());
+}
-bool MapASTVisitor::VisitEnumDecl(const EnumDecl *D) { return mapDecl(D); }
+bool MapASTVisitor::VisitEnumDecl(const EnumDecl *D) {
+ return mapDecl(D, D->isThisDeclarationADefinition());
+}
bool MapASTVisitor::VisitCXXMethodDecl(const CXXMethodDecl *D) {
- return mapDecl(D);
+ return mapDecl(D, D->isThisDeclarationADefinition());
}
bool MapASTVisitor::VisitFunctionDecl(const FunctionDecl *D) {
// Don't visit CXXMethodDecls twice
if (isa<CXXMethodDecl>(D))
return true;
- return mapDecl(D);
+ return mapDecl(D, D->isThisDeclarationADefinition());
}
bool MapASTVisitor::VisitTypedefDecl(const TypedefDecl *D) {
- return mapDecl(D);
+ return mapDecl(D, /*isDefinition=*/true);
}
bool MapASTVisitor::VisitTypeAliasDecl(const TypeAliasDecl *D) {
- return mapDecl(D);
+ return mapDecl(D, /*isDefinition=*/true);
}
comments::FullComment *
diff --git a/clang-tools-extra/clang-doc/Mapper.h b/clang-tools-extra/clang-doc/Mapper.h
index cedde935ab743..75c8e947c8f90 100644
--- a/clang-tools-extra/clang-doc/Mapper.h
+++ b/clang-tools-extra/clang-doc/Mapper.h
@@ -43,7 +43,7 @@ class MapASTVisitor : public clang::RecursiveASTVisitor<MapASTVisitor>,
bool VisitTypeAliasDecl(const TypeAliasDecl *D);
private:
- template <typename T> bool mapDecl(const T *D);
+ template <typename T> bool mapDecl(const T *D, bool IsDefinition);
int getLine(const NamedDecl *D, const ASTContext &Context) const;
llvm::SmallString<128> getFile(const NamedDecl *D, const ASTContext &Context,
diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index 6198a6e0cdcc3..3363cafeded5e 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -303,7 +303,6 @@ Example usage for a project using a compile commands database:
for (auto &Group : USRToBitcode) {
Pool.async([&]() {
std::vector<std::unique_ptr<doc::Info>> Infos;
-
for (auto &Bitcode : Group.getValue()) {
llvm::BitstreamCursor Stream(Bitcode);
doc::ClangDocBitcodeReader Reader(Stream);
More information about the cfe-commits
mailing list