[PATCH] D83621: [clang][Tooling] Try to avoid file system access if there is no record for the file in compile_commads.json
Aleksandr Platonov via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sat Jul 11 06:05:05 PDT 2020
ArcsinX created this revision.
Herald added subscribers: cfe-commits, usaxena95, kadircet, ilya-biryukov.
Herald added a project: clang.
If there is no record in compile_commands.json, we try to find suitable record with `MatchTrie.findEquivalent()` call.
This is very expensive operation with a lot of `llvm::sys::fs::equivalent()` calls in some cases.
This patch adds caching for `MatchTrie.findEquivalent()` call result.
Example scenario without this patch:
- compile_commands.json generated at clangd build (contains ~3000 files)..
- it tooks more than 1 second to get compile command for newly created file in the root folder of LLVM project.
- we wait for 1 second every time when clangd requests compile command for this file (at file change).
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D83621
Files:
clang/include/clang/Tooling/JSONCompilationDatabase.h
clang/lib/Tooling/JSONCompilationDatabase.cpp
Index: clang/lib/Tooling/JSONCompilationDatabase.cpp
===================================================================
--- clang/lib/Tooling/JSONCompilationDatabase.cpp
+++ clang/lib/Tooling/JSONCompilationDatabase.cpp
@@ -230,14 +230,28 @@
SmallString<128> NativeFilePath;
llvm::sys::path::native(FilePath, NativeFilePath);
- std::string Error;
- llvm::raw_string_ostream ES(Error);
- StringRef Match = MatchTrie.findEquivalent(NativeFilePath, ES);
- if (Match.empty())
- return {};
- const auto CommandsRefI = IndexByFile.find(Match);
- if (CommandsRefI == IndexByFile.end())
- return {};
+ // Avoid usage of `MatchTrie` if possible.
+ auto CommandsRefI = IndexByFile.find(NativeFilePath);
+ if (CommandsRefI == IndexByFile.end()) {
+ llvm::StringRef Match;
+ // Try to get cached value.
+ auto MatchIt = MatchCache.find(NativeFilePath);
+ if (MatchIt == MatchCache.end()) {
+ std::string Error;
+ llvm::raw_string_ostream ES(Error);
+ Match = MatchTrie.findEquivalent(NativeFilePath, ES);
+ // Save into cache even if the match result is empty.
+ MatchCache[NativeFilePath] = Match;
+ } else {
+ // Cached value.
+ Match = MatchIt->second;
+ }
+ if (Match.empty())
+ return {};
+ CommandsRefI = IndexByFile.find(Match);
+ if (CommandsRefI == IndexByFile.end())
+ return {};
+ }
std::vector<CompileCommand> Commands;
getCommands(CommandsRefI->getValue(), Commands);
return Commands;
Index: clang/include/clang/Tooling/JSONCompilationDatabase.h
===================================================================
--- clang/include/clang/Tooling/JSONCompilationDatabase.h
+++ clang/include/clang/Tooling/JSONCompilationDatabase.h
@@ -129,6 +129,8 @@
std::vector<CompileCommandRef> AllCommands;
FileMatchTrie MatchTrie;
+ // Cache for `MatchTrie`.
+ mutable llvm::StringMap<llvm::StringRef> MatchCache;
std::unique_ptr<llvm::MemoryBuffer> Database;
JSONCommandLineSyntax Syntax;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D83621.277235.patch
Type: text/x-patch
Size: 2003 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200711/4d673c3f/attachment.bin>
More information about the cfe-commits
mailing list