[PATCH] D125675: Optimise findRefs for XRefs and docHighlights

2022-05-16 Thread Utkarsh Saxena via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG2fb6ece2ca83: Optimise findRefs for XRefs and docHighlights 
(authored by usaxena95).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D125675/new/

https://reviews.llvm.org/D125675

Files:
  clang-tools-extra/clangd/XRefs.cpp

Index: clang-tools-extra/clangd/XRefs.cpp
===
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -18,6 +18,7 @@
 #include "index/Index.h"
 #include "index/Merge.h"
 #include "index/Relation.h"
+#include "index/SymbolID.h"
 #include "index/SymbolLocation.h"
 #include "support/Logger.h"
 #include "clang/AST/ASTContext.h"
@@ -47,10 +48,12 @@
 #include "clang/Index/USRGeneration.h"
 #include "clang/Tooling/Syntax/Tokens.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Error.h"
@@ -397,8 +400,8 @@
 }
   }
   // Special case: void foo() ^override: jump to the overridden method.
-if (NodeKind.isSame(ASTNodeKind::getFromNodeKind()) ||
-NodeKind.isSame(ASTNodeKind::getFromNodeKind())) {
+  if (NodeKind.isSame(ASTNodeKind::getFromNodeKind()) ||
+  NodeKind.isSame(ASTNodeKind::getFromNodeKind())) {
 // We may be overridding multiple methods - offer them all.
 for (const NamedDecl *ND : CMD->overridden_methods())
   AddResultDecl(ND);
@@ -887,8 +890,13 @@
   };
 
   ReferenceFinder(const ParsedAST ,
-  const llvm::DenseSet , bool PerToken)
-  : PerToken(PerToken), AST(AST), TargetIDs(TargetIDs) {}
+  const llvm::ArrayRef Targets, bool PerToken)
+  : PerToken(PerToken), AST(AST) {
+for (const NamedDecl *ND : Targets) {
+  const Decl *CD = ND->getCanonicalDecl();
+  TargetDeclToID[CD] = getSymbolID(CD);
+}
+  }
 
   std::vector take() && {
 llvm::sort(References, [](const Reference , const Reference ) {
@@ -913,12 +921,12 @@
llvm::ArrayRef Relations,
SourceLocation Loc,
index::IndexDataConsumer::ASTNodeInfo ASTNode) override {
+auto DeclID = TargetDeclToID.find(D->getCanonicalDecl());
+if (DeclID == TargetDeclToID.end())
+  return true;
 const SourceManager  = AST.getSourceManager();
 if (!isInsideMainFile(Loc, SM))
   return true;
-SymbolID ID = getSymbolID(D);
-if (!TargetIDs.contains(ID))
-  return true;
 const auto  = AST.getTokens();
 
 llvm::SmallVector Locs;
@@ -942,7 +950,7 @@
 for (SourceLocation L : Locs) {
   L = SM.getFileLoc(L);
   if (const auto *Tok = TB.spelledTokenAt(L))
-References.push_back({*Tok, Roles, ID});
+References.push_back({*Tok, Roles, DeclID->getSecond()});
 }
 return true;
   }
@@ -951,12 +959,13 @@
   bool PerToken; // If true, report 3 references for split ObjC selector names.
   std::vector References;
   const ParsedAST 
-  const llvm::DenseSet 
+  llvm::DenseMap TargetDeclToID;
 };
 
 std::vector
-findRefs(const llvm::DenseSet , ParsedAST , bool PerToken) {
-  ReferenceFinder RefFinder(AST, IDs, PerToken);
+findRefs(const llvm::ArrayRef TargetDecls, ParsedAST ,
+ bool PerToken) {
+  ReferenceFinder RefFinder(AST, TargetDecls, PerToken);
   index::IndexingOptions IndexOpts;
   IndexOpts.SystemSymbolFilter =
   index::IndexingOptions::SystemSymbolFilterKind::All;
@@ -1242,16 +1251,12 @@
 if (const SelectionTree::Node *N = ST.commonAncestor()) {
   DeclRelationSet Relations =
   DeclRelation::TemplatePattern | DeclRelation::Alias;
-  auto Decls =
-  targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver());
-  if (!Decls.empty()) {
+  auto TargetDecls=
+   targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver());
+  if (!TargetDecls.empty()) {
 // FIXME: we may get multiple DocumentHighlights with the same location
 // and different kinds, deduplicate them.
-llvm::DenseSet Targets;
-for (const NamedDecl *ND : Decls)
-  if (auto ID = getSymbolID(ND))
-Targets.insert(ID);
-for (const auto  : findRefs(Targets, AST, /*PerToken=*/true))
+for (const auto  : findRefs(TargetDecls, AST, /*PerToken=*/true))
   Result.push_back(toHighlight(Ref, SM));
 return true;
   }
@@ -1377,12 +1382,12 @@
 DeclRelation::TemplatePattern | DeclRelation::Alias;
 std::vector Decls =
 getDeclAtPosition(AST, *CurLoc, Relations);
-llvm::DenseSet TargetsInMainFile;
+llvm::SmallVector 

[PATCH] D125675: Optimise findRefs for XRefs and docHighlights

2022-05-16 Thread Utkarsh Saxena via Phabricator via cfe-commits
usaxena95 updated this revision to Diff 429807.
usaxena95 marked 4 inline comments as done.
usaxena95 added a comment.

Addressed comments and added performance measurements.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D125675/new/

https://reviews.llvm.org/D125675

Files:
  clang-tools-extra/clangd/XRefs.cpp

Index: clang-tools-extra/clangd/XRefs.cpp
===
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -18,6 +18,7 @@
 #include "index/Index.h"
 #include "index/Merge.h"
 #include "index/Relation.h"
+#include "index/SymbolID.h"
 #include "index/SymbolLocation.h"
 #include "support/Logger.h"
 #include "clang/AST/ASTContext.h"
@@ -47,10 +48,12 @@
 #include "clang/Index/USRGeneration.h"
 #include "clang/Tooling/Syntax/Tokens.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Error.h"
@@ -397,8 +400,8 @@
 }
   }
   // Special case: void foo() ^override: jump to the overridden method.
-if (NodeKind.isSame(ASTNodeKind::getFromNodeKind()) ||
-NodeKind.isSame(ASTNodeKind::getFromNodeKind())) {
+  if (NodeKind.isSame(ASTNodeKind::getFromNodeKind()) ||
+  NodeKind.isSame(ASTNodeKind::getFromNodeKind())) {
 // We may be overridding multiple methods - offer them all.
 for (const NamedDecl *ND : CMD->overridden_methods())
   AddResultDecl(ND);
@@ -887,8 +890,13 @@
   };
 
   ReferenceFinder(const ParsedAST ,
-  const llvm::DenseSet , bool PerToken)
-  : PerToken(PerToken), AST(AST), TargetIDs(TargetIDs) {}
+  const llvm::ArrayRef Targets, bool PerToken)
+  : PerToken(PerToken), AST(AST) {
+for (const NamedDecl *ND : Targets) {
+  const Decl *CD = ND->getCanonicalDecl();
+  TargetDeclToID[CD] = getSymbolID(CD);
+}
+  }
 
   std::vector take() && {
 llvm::sort(References, [](const Reference , const Reference ) {
@@ -913,12 +921,12 @@
llvm::ArrayRef Relations,
SourceLocation Loc,
index::IndexDataConsumer::ASTNodeInfo ASTNode) override {
+auto DeclID = TargetDeclToID.find(D->getCanonicalDecl());
+if (DeclID == TargetDeclToID.end())
+  return true;
 const SourceManager  = AST.getSourceManager();
 if (!isInsideMainFile(Loc, SM))
   return true;
-SymbolID ID = getSymbolID(D);
-if (!TargetIDs.contains(ID))
-  return true;
 const auto  = AST.getTokens();
 
 llvm::SmallVector Locs;
@@ -942,7 +950,7 @@
 for (SourceLocation L : Locs) {
   L = SM.getFileLoc(L);
   if (const auto *Tok = TB.spelledTokenAt(L))
-References.push_back({*Tok, Roles, ID});
+References.push_back({*Tok, Roles, DeclID->getSecond()});
 }
 return true;
   }
@@ -951,12 +959,13 @@
   bool PerToken; // If true, report 3 references for split ObjC selector names.
   std::vector References;
   const ParsedAST 
-  const llvm::DenseSet 
+  llvm::DenseMap TargetDeclToID;
 };
 
 std::vector
-findRefs(const llvm::DenseSet , ParsedAST , bool PerToken) {
-  ReferenceFinder RefFinder(AST, IDs, PerToken);
+findRefs(const llvm::ArrayRef TargetDecls, ParsedAST ,
+ bool PerToken) {
+  ReferenceFinder RefFinder(AST, TargetDecls, PerToken);
   index::IndexingOptions IndexOpts;
   IndexOpts.SystemSymbolFilter =
   index::IndexingOptions::SystemSymbolFilterKind::All;
@@ -1242,16 +1251,12 @@
 if (const SelectionTree::Node *N = ST.commonAncestor()) {
   DeclRelationSet Relations =
   DeclRelation::TemplatePattern | DeclRelation::Alias;
-  auto Decls =
-  targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver());
-  if (!Decls.empty()) {
+  auto TargetDecls=
+   targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver());
+  if (!TargetDecls.empty()) {
 // FIXME: we may get multiple DocumentHighlights with the same location
 // and different kinds, deduplicate them.
-llvm::DenseSet Targets;
-for (const NamedDecl *ND : Decls)
-  if (auto ID = getSymbolID(ND))
-Targets.insert(ID);
-for (const auto  : findRefs(Targets, AST, /*PerToken=*/true))
+for (const auto  : findRefs(TargetDecls, AST, /*PerToken=*/true))
   Result.push_back(toHighlight(Ref, SM));
 return true;
   }
@@ -1377,12 +1382,12 @@
 DeclRelation::TemplatePattern | DeclRelation::Alias;
 std::vector Decls =
 getDeclAtPosition(AST, *CurLoc, Relations);
-llvm::DenseSet TargetsInMainFile;
+llvm::SmallVector TargetsInMainFile;
 for (const NamedDecl *D : Decls) {
   auto 

[PATCH] D125675: Optimise findRefs for XRefs and docHighlights

2022-05-16 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added a comment.
This revision is now accepted and ready to land.

thanks for noticing this, LGTM!




Comment at: clang-tools-extra/clangd/XRefs.cpp:961
   const ParsedAST 
-  const llvm::DenseSet 
+  llvm::DenseMap TargetDeclAndID;
 };

s/TargetDeclAndID/TargetDeclToID



Comment at: clang-tools-extra/clangd/XRefs.cpp:965
 std::vector
-findRefs(const llvm::DenseSet , ParsedAST , bool PerToken) {
-  ReferenceFinder RefFinder(AST, IDs, PerToken);
+findRefs(const llvm::DenseSet , ParsedAST ,
+ bool PerToken) {

i'd actually update the interface here to just take an `ArrayRef` as 
targets, as we're currently building those extra dense sets just to iterate 
over them. both `allTargetDecls` and `getDeclAtPosition` (which uses 
`allTargetDecls` underneath) are guaranteed to not return duplicates. So we can 
pass their result directly here. Up to you though.



Comment at: clang-tools-extra/clangd/XRefs.cpp:1919
   // If there's a specific type alias, point at that rather than unwrapping.
-  if (const auto* TDT = T->getAs())
+  if (const auto *TDT = T->getAs())
 return QualType(TDT, 0);

can you revert this change?



Comment at: clang-tools-extra/clangd/XRefs.cpp:951
   if (const auto *Tok = TB.spelledTokenAt(L))
-References.push_back({*Tok, Roles, ID});
+References.push_back({*Tok, Roles, getSymbolID(D)});
 }

usaxena95 wrote:
> kadircet wrote:
> > we're still calling getsymbolid here lots of times, for probably the same 
> > symbol.
> > 
> > as discussed, what about building a lookup table on construction from 
> > canonicaldecl to symbolid and use that lookup table instead of calling 
> > getsymbolid over and over here?
> I don't mind adding a lookup table for this but this is not huge, only 
> O(#ref) as compared to previous O(size of TU). 
> 
> 
thanks. previous one was also size of main file, not the whole TU (if you see 
indications of the latter in a different application let's take a look at that 
separately).

but there are big enough files in which you can have thousands of references to 
stringref and what not. so i think this actually matters.



Comment at: clang-tools-extra/clangd/XRefs.cpp:1255
+   targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver())) {
+TargetDecls.insert(D);
+  }

usaxena95 wrote:
> kadircet wrote:
> > i mean directly inserting canonicaldecls here.
> This would make it messy to duplicate this on each end of the call. 
> + This has potential of introducing bugs in future findRef calls if we don't 
> pass the canonical decls. Or we would have to assert that we only get 
> canonical decls.
> I think this is an implementation detail of findRefs and should not be 
> visible outside its API for simplicity.
SG, it's an implementation detail of this file already so not a big deal. But 
moreover we're building a separate lookup table already now, so obsolete.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D125675/new/

https://reviews.llvm.org/D125675

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D125675: Optimise findRefs for XRefs and docHighlights

2022-05-16 Thread Utkarsh Saxena via Phabricator via cfe-commits
usaxena95 updated this revision to Diff 429697.
usaxena95 added a comment.

Format.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D125675/new/

https://reviews.llvm.org/D125675

Files:
  clang-tools-extra/clangd/XRefs.cpp

Index: clang-tools-extra/clangd/XRefs.cpp
===
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -18,6 +18,7 @@
 #include "index/Index.h"
 #include "index/Merge.h"
 #include "index/Relation.h"
+#include "index/SymbolID.h"
 #include "index/SymbolLocation.h"
 #include "support/Logger.h"
 #include "clang/AST/ASTContext.h"
@@ -47,6 +48,7 @@
 #include "clang/Index/USRGeneration.h"
 #include "clang/Tooling/Syntax/Tokens.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
@@ -397,8 +399,8 @@
 }
   }
   // Special case: void foo() ^override: jump to the overridden method.
-if (NodeKind.isSame(ASTNodeKind::getFromNodeKind()) ||
-NodeKind.isSame(ASTNodeKind::getFromNodeKind())) {
+  if (NodeKind.isSame(ASTNodeKind::getFromNodeKind()) ||
+  NodeKind.isSame(ASTNodeKind::getFromNodeKind())) {
 // We may be overridding multiple methods - offer them all.
 for (const NamedDecl *ND : CMD->overridden_methods())
   AddResultDecl(ND);
@@ -887,8 +889,13 @@
   };
 
   ReferenceFinder(const ParsedAST ,
-  const llvm::DenseSet , bool PerToken)
-  : PerToken(PerToken), AST(AST), TargetIDs(TargetIDs) {}
+  const llvm::DenseSet , bool PerToken)
+  : PerToken(PerToken), AST(AST) {
+for (const Decl *D : Target) {
+  const Decl *CD = D->getCanonicalDecl();
+  TargetDeclAndID[CD] = getSymbolID(CD);
+}
+  }
 
   std::vector take() && {
 llvm::sort(References, [](const Reference , const Reference ) {
@@ -913,12 +920,12 @@
llvm::ArrayRef Relations,
SourceLocation Loc,
index::IndexDataConsumer::ASTNodeInfo ASTNode) override {
+auto DeclID = TargetDeclAndID.find(D->getCanonicalDecl());
+if (DeclID == TargetDeclAndID.end())
+  return true;
 const SourceManager  = AST.getSourceManager();
 if (!isInsideMainFile(Loc, SM))
   return true;
-SymbolID ID = getSymbolID(D);
-if (!TargetIDs.contains(ID))
-  return true;
 const auto  = AST.getTokens();
 
 llvm::SmallVector Locs;
@@ -942,7 +949,7 @@
 for (SourceLocation L : Locs) {
   L = SM.getFileLoc(L);
   if (const auto *Tok = TB.spelledTokenAt(L))
-References.push_back({*Tok, Roles, ID});
+References.push_back({*Tok, Roles, DeclID->getSecond()});
 }
 return true;
   }
@@ -951,12 +958,13 @@
   bool PerToken; // If true, report 3 references for split ObjC selector names.
   std::vector References;
   const ParsedAST 
-  const llvm::DenseSet 
+  llvm::DenseMap TargetDeclAndID;
 };
 
 std::vector
-findRefs(const llvm::DenseSet , ParsedAST , bool PerToken) {
-  ReferenceFinder RefFinder(AST, IDs, PerToken);
+findRefs(const llvm::DenseSet , ParsedAST ,
+ bool PerToken) {
+  ReferenceFinder RefFinder(AST, TargetDecls, PerToken);
   index::IndexingOptions IndexOpts;
   IndexOpts.SystemSymbolFilter =
   index::IndexingOptions::SystemSymbolFilterKind::All;
@@ -1242,16 +1250,15 @@
 if (const SelectionTree::Node *N = ST.commonAncestor()) {
   DeclRelationSet Relations =
   DeclRelation::TemplatePattern | DeclRelation::Alias;
-  auto Decls =
-  targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver());
-  if (!Decls.empty()) {
+  llvm::DenseSet TargetDecls;
+  for (const NamedDecl *D :
+   targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver())) {
+TargetDecls.insert(D);
+  }
+  if (!TargetDecls.empty()) {
 // FIXME: we may get multiple DocumentHighlights with the same location
 // and different kinds, deduplicate them.
-llvm::DenseSet Targets;
-for (const NamedDecl *ND : Decls)
-  if (auto ID = getSymbolID(ND))
-Targets.insert(ID);
-for (const auto  : findRefs(Targets, AST, /*PerToken=*/true))
+for (const auto  : findRefs(TargetDecls, AST, /*PerToken=*/true))
   Result.push_back(toHighlight(Ref, SM));
 return true;
   }
@@ -1377,12 +1384,12 @@
 DeclRelation::TemplatePattern | DeclRelation::Alias;
 std::vector Decls =
 getDeclAtPosition(AST, *CurLoc, Relations);
-llvm::DenseSet TargetsInMainFile;
+llvm::DenseSet TargetsInMainFile;
 for (const NamedDecl *D : Decls) {
   auto ID = getSymbolID(D);
   if (!ID)
 continue;
-  TargetsInMainFile.insert(ID);
+  TargetsInMainFile.insert(D);
   // Not all symbols can be referenced from outside (e.g. 

[PATCH] D125675: Optimise findRefs for XRefs and docHighlights

2022-05-16 Thread Utkarsh Saxena via Phabricator via cfe-commits
usaxena95 added inline comments.



Comment at: clang-tools-extra/clangd/XRefs.cpp:951
   if (const auto *Tok = TB.spelledTokenAt(L))
-References.push_back({*Tok, Roles, ID});
+References.push_back({*Tok, Roles, getSymbolID(D)});
 }

kadircet wrote:
> we're still calling getsymbolid here lots of times, for probably the same 
> symbol.
> 
> as discussed, what about building a lookup table on construction from 
> canonicaldecl to symbolid and use that lookup table instead of calling 
> getsymbolid over and over here?
I don't mind adding a lookup table for this but this is not huge, only O(#ref) 
as compared to previous O(size of TU). 





Comment at: clang-tools-extra/clangd/XRefs.cpp:1255
+   targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver())) {
+TargetDecls.insert(D);
+  }

kadircet wrote:
> i mean directly inserting canonicaldecls here.
This would make it messy to duplicate this on each end of the call. 
+ This has potential of introducing bugs in future findRef calls if we don't 
pass the canonical decls. Or we would have to assert that we only get canonical 
decls.
I think this is an implementation detail of findRefs and should not be visible 
outside its API for simplicity.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D125675/new/

https://reviews.llvm.org/D125675

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D125675: Optimise findRefs for XRefs and docHighlights

2022-05-16 Thread Utkarsh Saxena via Phabricator via cfe-commits
usaxena95 updated this revision to Diff 429696.
usaxena95 marked 4 inline comments as done.
usaxena95 added a comment.

Address comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D125675/new/

https://reviews.llvm.org/D125675

Files:
  clang-tools-extra/clangd/XRefs.cpp

Index: clang-tools-extra/clangd/XRefs.cpp
===
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -18,6 +18,7 @@
 #include "index/Index.h"
 #include "index/Merge.h"
 #include "index/Relation.h"
+#include "index/SymbolID.h"
 #include "index/SymbolLocation.h"
 #include "support/Logger.h"
 #include "clang/AST/ASTContext.h"
@@ -47,6 +48,7 @@
 #include "clang/Index/USRGeneration.h"
 #include "clang/Tooling/Syntax/Tokens.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
@@ -397,8 +399,8 @@
 }
   }
   // Special case: void foo() ^override: jump to the overridden method.
-if (NodeKind.isSame(ASTNodeKind::getFromNodeKind()) ||
-NodeKind.isSame(ASTNodeKind::getFromNodeKind())) {
+  if (NodeKind.isSame(ASTNodeKind::getFromNodeKind()) ||
+  NodeKind.isSame(ASTNodeKind::getFromNodeKind())) {
 // We may be overridding multiple methods - offer them all.
 for (const NamedDecl *ND : CMD->overridden_methods())
   AddResultDecl(ND);
@@ -887,8 +889,13 @@
   };
 
   ReferenceFinder(const ParsedAST ,
-  const llvm::DenseSet , bool PerToken)
-  : PerToken(PerToken), AST(AST), TargetIDs(TargetIDs) {}
+  const llvm::DenseSet , bool PerToken)
+  : PerToken(PerToken), AST(AST) {
+for (const Decl *D : Target) {
+  const Decl *CD = D->getCanonicalDecl();
+  TargetDeclAndID[CD] = getSymbolID(CD);
+}
+  }
 
   std::vector take() && {
 llvm::sort(References, [](const Reference , const Reference ) {
@@ -913,12 +920,12 @@
llvm::ArrayRef Relations,
SourceLocation Loc,
index::IndexDataConsumer::ASTNodeInfo ASTNode) override {
+auto DeclID = TargetDeclAndID.find(D->getCanonicalDecl());
+if (DeclID == TargetDeclAndID.end())
+  return true;
 const SourceManager  = AST.getSourceManager();
 if (!isInsideMainFile(Loc, SM))
   return true;
-SymbolID ID = getSymbolID(D);
-if (!TargetIDs.contains(ID))
-  return true;
 const auto  = AST.getTokens();
 
 llvm::SmallVector Locs;
@@ -942,7 +949,7 @@
 for (SourceLocation L : Locs) {
   L = SM.getFileLoc(L);
   if (const auto *Tok = TB.spelledTokenAt(L))
-References.push_back({*Tok, Roles, ID});
+References.push_back({*Tok, Roles, DeclID->getSecond()});
 }
 return true;
   }
@@ -951,12 +958,13 @@
   bool PerToken; // If true, report 3 references for split ObjC selector names.
   std::vector References;
   const ParsedAST 
-  const llvm::DenseSet 
+  llvm::DenseMap TargetDeclAndID;
 };
 
 std::vector
-findRefs(const llvm::DenseSet , ParsedAST , bool PerToken) {
-  ReferenceFinder RefFinder(AST, IDs, PerToken);
+findRefs(const llvm::DenseSet , ParsedAST ,
+ bool PerToken) {
+  ReferenceFinder RefFinder(AST, TargetDecls, PerToken);
   index::IndexingOptions IndexOpts;
   IndexOpts.SystemSymbolFilter =
   index::IndexingOptions::SystemSymbolFilterKind::All;
@@ -1242,16 +1250,15 @@
 if (const SelectionTree::Node *N = ST.commonAncestor()) {
   DeclRelationSet Relations =
   DeclRelation::TemplatePattern | DeclRelation::Alias;
-  auto Decls =
-  targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver());
-  if (!Decls.empty()) {
+  llvm::DenseSet TargetDecls;
+  for (const NamedDecl *D :
+   targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver())) {
+TargetDecls.insert(D);
+  }
+  if (!TargetDecls.empty()) {
 // FIXME: we may get multiple DocumentHighlights with the same location
 // and different kinds, deduplicate them.
-llvm::DenseSet Targets;
-for (const NamedDecl *ND : Decls)
-  if (auto ID = getSymbolID(ND))
-Targets.insert(ID);
-for (const auto  : findRefs(Targets, AST, /*PerToken=*/true))
+for (const auto  : findRefs(TargetDecls, AST, /*PerToken=*/true))
   Result.push_back(toHighlight(Ref, SM));
 return true;
   }
@@ -1377,12 +1384,12 @@
 DeclRelation::TemplatePattern | DeclRelation::Alias;
 std::vector Decls =
 getDeclAtPosition(AST, *CurLoc, Relations);
-llvm::DenseSet TargetsInMainFile;
+llvm::DenseSet TargetInMainFile;
 for (const NamedDecl *D : Decls) {
   auto ID = getSymbolID(D);
   if (!ID)
 continue;
-  TargetsInMainFile.insert(ID);
+  TargetInMainFile.insert(D);
   // Not all 

[PATCH] D125675: Optimise findRefs for XRefs and docHighlights

2022-05-16 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a reviewer: kadircet.
kadircet added a comment.

66% win sounds great, it would be nice to have some detailed numbers (but this 
is clearly a huge win, so no need to reperform the experiments if numbers are 
gone)




Comment at: clang-tools-extra/clangd/XRefs.cpp:895
+  : PerToken(PerToken), AST(AST) {
+for (const Decl *D : TD) {
+  TargetDecls.insert(D->getCanonicalDecl());

nit: no need for braces

you can directly build the set with canonicaldecls and consume it here



Comment at: clang-tools-extra/clangd/XRefs.cpp:951
   if (const auto *Tok = TB.spelledTokenAt(L))
-References.push_back({*Tok, Roles, ID});
+References.push_back({*Tok, Roles, getSymbolID(D)});
 }

we're still calling getsymbolid here lots of times, for probably the same 
symbol.

as discussed, what about building a lookup table on construction from 
canonicaldecl to symbolid and use that lookup table instead of calling 
getsymbolid over and over here?



Comment at: clang-tools-extra/clangd/XRefs.cpp:1255
+   targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver())) {
+TargetDecls.insert(D);
+  }

i mean directly inserting canonicaldecls here.



Comment at: clang-tools-extra/clangd/XRefs.cpp:1260
 // and different kinds, deduplicate them.
 llvm::DenseSet Targets;
+for (const Decl *D : TargetDecls)

no need for this and the following loop anymore.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D125675/new/

https://reviews.llvm.org/D125675

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D125675: Optimise findRefs for XRefs and docHighlights

2022-05-16 Thread Utkarsh Saxena via Phabricator via cfe-commits
usaxena95 created this revision.
Herald added subscribers: kadircet, arphaman.
Herald added a project: All.
usaxena95 requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Reduces time spent in findRef by 66%.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D125675

Files:
  clang-tools-extra/clangd/XRefs.cpp

Index: clang-tools-extra/clangd/XRefs.cpp
===
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -18,6 +18,7 @@
 #include "index/Index.h"
 #include "index/Merge.h"
 #include "index/Relation.h"
+#include "index/SymbolID.h"
 #include "index/SymbolLocation.h"
 #include "support/Logger.h"
 #include "clang/AST/ASTContext.h"
@@ -47,6 +48,7 @@
 #include "clang/Index/USRGeneration.h"
 #include "clang/Tooling/Syntax/Tokens.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
@@ -54,6 +56,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Error.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -887,8 +890,12 @@
   };
 
   ReferenceFinder(const ParsedAST ,
-  const llvm::DenseSet , bool PerToken)
-  : PerToken(PerToken), AST(AST), TargetIDs(TargetIDs) {}
+  const llvm::DenseSet , bool PerToken)
+  : PerToken(PerToken), AST(AST) {
+for (const Decl *D : TD) {
+  TargetDecls.insert(D->getCanonicalDecl());
+}
+  }
 
   std::vector take() && {
 llvm::sort(References, [](const Reference , const Reference ) {
@@ -913,12 +920,11 @@
llvm::ArrayRef Relations,
SourceLocation Loc,
index::IndexDataConsumer::ASTNodeInfo ASTNode) override {
+if (!TargetDecls.contains(D->getCanonicalDecl()))
+  return true;
 const SourceManager  = AST.getSourceManager();
 if (!isInsideMainFile(Loc, SM))
   return true;
-SymbolID ID = getSymbolID(D);
-if (!TargetIDs.contains(ID))
-  return true;
 const auto  = AST.getTokens();
 
 llvm::SmallVector Locs;
@@ -942,7 +948,7 @@
 for (SourceLocation L : Locs) {
   L = SM.getFileLoc(L);
   if (const auto *Tok = TB.spelledTokenAt(L))
-References.push_back({*Tok, Roles, ID});
+References.push_back({*Tok, Roles, getSymbolID(D)});
 }
 return true;
   }
@@ -951,12 +957,13 @@
   bool PerToken; // If true, report 3 references for split ObjC selector names.
   std::vector References;
   const ParsedAST 
-  const llvm::DenseSet 
+  llvm::DenseSet TargetDecls;
 };
 
 std::vector
-findRefs(const llvm::DenseSet , ParsedAST , bool PerToken) {
-  ReferenceFinder RefFinder(AST, IDs, PerToken);
+findRefs(const llvm::DenseSet , ParsedAST ,
+ bool PerToken) {
+  ReferenceFinder RefFinder(AST, TargetDecls, PerToken);
   index::IndexingOptions IndexOpts;
   IndexOpts.SystemSymbolFilter =
   index::IndexingOptions::SystemSymbolFilterKind::All;
@@ -1242,16 +1249,19 @@
 if (const SelectionTree::Node *N = ST.commonAncestor()) {
   DeclRelationSet Relations =
   DeclRelation::TemplatePattern | DeclRelation::Alias;
-  auto Decls =
-  targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver());
-  if (!Decls.empty()) {
+  llvm::DenseSet TargetDecls;
+  for (const NamedDecl *D :
+   targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver())) {
+TargetDecls.insert(D);
+  }
+  if (!TargetDecls.empty()) {
 // FIXME: we may get multiple DocumentHighlights with the same location
 // and different kinds, deduplicate them.
 llvm::DenseSet Targets;
-for (const NamedDecl *ND : Decls)
-  if (auto ID = getSymbolID(ND))
+for (const Decl *D : TargetDecls)
+  if (auto ID = getSymbolID(D))
 Targets.insert(ID);
-for (const auto  : findRefs(Targets, AST, /*PerToken=*/true))
+for (const auto  : findRefs(TargetDecls, AST, /*PerToken=*/true))
   Result.push_back(toHighlight(Ref, SM));
 return true;
   }
@@ -1377,12 +1387,12 @@
 DeclRelation::TemplatePattern | DeclRelation::Alias;
 std::vector Decls =
 getDeclAtPosition(AST, *CurLoc, Relations);
-llvm::DenseSet TargetsInMainFile;
+llvm::DenseSet TargetDeclsInMainFile;
 for (const NamedDecl *D : Decls) {
   auto ID = getSymbolID(D);
   if (!ID)
 continue;
-  TargetsInMainFile.insert(ID);
+  TargetDeclsInMainFile.insert(D);
   // Not all symbols can be referenced from outside (e.g. function-locals).
   // TODO: we could skip TU-scoped symbols here (e.g. static functions) if
   // we know this file isn't a header. The details might be tricky.
@@ -1408,7 +1418,8 @@