This is an archive of the discontinued LLVM Phabricator instance.

Optimise findRefs for XRefs and docHighlights
ClosedPublic

Authored by usaxena95 on May 16 2022, 2:51 AM.

Details

Summary

Reduces time spent in findRef by ~66%.

Ran crude measurement clangd --check=clang/lib/Serialization/ASTReader.cpp
Previous time: 52 min
New time: 12 min
This include time for much more than just docHighlight (hover, definition, tweaks,..). So in this case the speedup is at least 77%.
Moreover running docHighlight on each token previously was O(N^2) and is now O(N) in size of main file. Therefore speedup % would be O(N) instead of a constant. In practice for long-tail large files, I have seen 60-80% speedups.

Diff Detail

Event Timeline

usaxena95 created this revision.May 16 2022, 2:51 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 16 2022, 2:51 AM
usaxena95 requested review of this revision.May 16 2022, 2:51 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 16 2022, 2:51 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

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)

clang-tools-extra/clangd/XRefs.cpp
895

nit: no need for braces

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

953

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?

1257

i mean directly inserting canonicaldecls here.

1258–1259

no need for this and the following loop anymore.

usaxena95 updated this revision to Diff 429696.May 16 2022, 6:12 AM
usaxena95 marked 4 inline comments as done.

Address comments.

clang-tools-extra/clangd/XRefs.cpp
953

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).

1257

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.

kadircet accepted this revision.May 16 2022, 6:56 AM

thanks for noticing this, LGTM!

clang-tools-extra/clangd/XRefs.cpp
953

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.

962

s/TargetDeclAndID/TargetDeclToID

966–968

i'd actually update the interface here to just take an ArrayRef<Decl*> 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.

1257

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.

1917

can you revert this change?

This revision is now accepted and ready to land.May 16 2022, 6:56 AM
usaxena95 edited the summary of this revision. (Show Details)May 16 2022, 11:36 AM
usaxena95 marked 4 inline comments as done.

Addressed comments and added performance measurements.

This revision was landed with ongoing or failed builds.May 16 2022, 12:07 PM
This revision was automatically updated to reflect the committed changes.