[clang] [clang][deps] Cache `VFS::getRealPath()` (PR #68645)

2024-04-12 Thread Jan Svoboda via cfe-commits

https://github.com/jansvoboda11 closed 
https://github.com/llvm/llvm-project/pull/68645
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][deps] Cache `VFS::getRealPath()` (PR #68645)

2024-04-12 Thread Jan Svoboda via cfe-commits

https://github.com/jansvoboda11 updated 
https://github.com/llvm/llvm-project/pull/68645

>From 3b89f001adf027b2128c72c7b907b41717ce1e4c Mon Sep 17 00:00:00 2001
From: Jan Svoboda 
Date: Mon, 9 Oct 2023 10:14:22 -0700
Subject: [PATCH 01/13] [clang][deps] Cache `VFS::getRealPath()`

---
 .../DependencyScanningFilesystem.h| 46 ++-
 .../DependencyScanningFilesystem.cpp  | 76 +++
 2 files changed, 121 insertions(+), 1 deletion(-)

diff --git 
a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h 
b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
index 4cd0f958fcff82..467b161fc2f0e3 100644
--- 
a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
+++ 
b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
@@ -142,6 +142,8 @@ class CachedFileSystemEntry {
   CachedFileContents *Contents;
 };
 
+using CachedRealPath = llvm::ErrorOr;
+
 /// This class is a shared cache, that caches the 'stat' and 'open' calls to 
the
 /// underlying real file system, and the scanned preprocessor directives of
 /// files.
@@ -168,6 +170,12 @@ class DependencyScanningFilesystemSharedCache {
 /// The backing storage for cached contents.
 llvm::SpecificBumpPtrAllocator ContentsStorage;
 
+/// Map from filenames to cached real paths.
+llvm::StringMap RealPathsByFilename;
+
+/// The backing storage for cached real paths.
+llvm::SpecificBumpPtrAllocator RealPathStorage;
+
 /// Returns entry associated with the filename or nullptr if none is found.
 const CachedFileSystemEntry *findEntryByFilename(StringRef Filename) const;
 
@@ -194,6 +202,17 @@ class DependencyScanningFilesystemSharedCache {
 const CachedFileSystemEntry &
 getOrInsertEntryForFilename(StringRef Filename,
 const CachedFileSystemEntry );
+
+/// Returns real path associated with the filename or nullptr if none is
+/// found.
+const CachedRealPath *findRealPathByFilename(StringRef Filename) const;
+
+/// Returns real path associated with the filename if there is some.
+/// Otherwise, constructs new one with the given one, associates it with 
the
+/// filename and returns the result.
+const CachedRealPath &
+getOrEmplaceRealPathForFilename(StringRef Filename,
+llvm::ErrorOr RealPath);
   };
 
   DependencyScanningFilesystemSharedCache();
@@ -212,6 +231,8 @@ class DependencyScanningFilesystemSharedCache {
 class DependencyScanningFilesystemLocalCache {
   llvm::StringMap Cache;
 
+  llvm::StringMap 
RealPathCache;
+
 public:
   /// Returns entry associated with the filename or nullptr if none is found.
   const CachedFileSystemEntry *findEntryByFilename(StringRef Filename) const {
@@ -230,6 +251,26 @@ class DependencyScanningFilesystemLocalCache {
 assert(InsertedEntry ==  && "entry already present");
 return *InsertedEntry;
   }
+
+  /// Returns real path associated with the filename or nullptr if none is
+  /// found.
+  const CachedRealPath *findRealPathByFilename(StringRef Filename) const {
+assert(llvm::sys::path::is_absolute_gnu(Filename));
+auto It = RealPathCache.find(Filename);
+return It == RealPathCache.end() ? nullptr : It->getValue();
+  }
+
+  /// Associates the given real path with the filename and returns the given
+  /// entry pointer (for convenience).
+  const CachedRealPath &
+  insertRealPathForFilename(StringRef Filename,
+const CachedRealPath ) {
+assert(llvm::sys::path::is_absolute_gnu(Filename));
+const auto *InsertedRealPath =
+RealPathCache.insert({Filename, }).first->second;
+assert(InsertedRealPath ==  && "entry already present");
+return *InsertedRealPath;
+  }
 };
 
 /// Reference to a CachedFileSystemEntry.
@@ -296,6 +337,9 @@ class DependencyScanningWorkerFilesystem
   llvm::ErrorOr>
   openFileForRead(const Twine ) override;
 
+  std::error_code getRealPath(const Twine ,
+  SmallVectorImpl ) const override;
+
   std::error_code setCurrentWorkingDirectory(const Twine ) override;
 
   /// Returns entry for the given filename.
@@ -395,7 +439,7 @@ class DependencyScanningWorkerFilesystem
   DependencyScanningFilesystemSharedCache 
   /// The local cache is used by the worker thread to cache file system queries
   /// locally instead of querying the global cache every time.
-  DependencyScanningFilesystemLocalCache LocalCache;
+  mutable DependencyScanningFilesystemLocalCache LocalCache;
 
   /// The working directory to use for making relative paths absolute before
   /// using them for cache lookups.
diff --git 
a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp 
b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp
index c66780d50fa184..b44db58745d62c 100644
--- 

[clang] [clang][deps] Cache `VFS::getRealPath()` (PR #68645)

2024-04-08 Thread Jan Svoboda via cfe-commits


@@ -230,6 +251,26 @@ class DependencyScanningFilesystemLocalCache {
 assert(InsertedEntry ==  && "entry already present");
 return *InsertedEntry;
   }
+
+  /// Returns real path associated with the filename or nullptr if none is
+  /// found.
+  const CachedRealPath *findRealPathByFilename(StringRef Filename) const {
+assert(llvm::sys::path::is_absolute_gnu(Filename));
+auto It = RealPathCache.find(Filename);
+return It == RealPathCache.end() ? nullptr : It->getValue();
+  }
+
+  /// Associates the given real path with the filename and returns the given
+  /// entry pointer (for convenience).
+  const CachedRealPath &
+  insertRealPathForFilename(StringRef Filename,
+const CachedRealPath ) {

jansvoboda11 wrote:

I see your point. I used a reference here to be consistent with existing code 
in this file. I think the original motivation for using references was the 
"non-null pointer" aspect of it. I tried converting all uses of `const 
CachedFileSystemEntry &` in the existing code to pointers, but that's 
impossible to understand. Doing that just for arguments to insert-like 
functions is a bit better, but I'm not sure it's clear win in 
readability/understandability.

https://github.com/llvm/llvm-project/pull/68645
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][deps] Cache `VFS::getRealPath()` (PR #68645)

2024-01-23 Thread Jan Svoboda via cfe-commits

https://github.com/jansvoboda11 updated 
https://github.com/llvm/llvm-project/pull/68645

>From 3970f76778923189a9b1e7ec5fef457ac8dba357 Mon Sep 17 00:00:00 2001
From: Jan Svoboda 
Date: Mon, 9 Oct 2023 10:14:17 -0700
Subject: [PATCH 1/3] [clang] Move lookup filename into function

---
 .../DependencyScanningFilesystem.h|  4 ++
 .../DependencyScanningFilesystem.cpp  | 41 ---
 2 files changed, 30 insertions(+), 15 deletions(-)

diff --git 
a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h 
b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
index dbe219b6dd8d723..c3cd69ab720effd 100644
--- 
a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
+++ 
b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
@@ -400,6 +400,10 @@ class DependencyScanningWorkerFilesystem : public 
llvm::vfs::ProxyFileSystem {
   llvm::ErrorOr WorkingDirForCacheLookup;
 
   void updateWorkingDirForCacheLookup();
+
+  llvm::ErrorOr
+  tryGetFilenameForLookup(StringRef OriginalFilename,
+  llvm::SmallVectorImpl ) const;
 };
 
 } // end namespace dependencies
diff --git 
a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp 
b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp
index 3e53c8fc5740875..44b39c5195c62b6 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp
@@ -258,26 +258,17 @@ DependencyScanningWorkerFilesystem::computeAndStoreResult(
 llvm::ErrorOr
 DependencyScanningWorkerFilesystem::getOrCreateFileSystemEntry(
 StringRef OriginalFilename, bool DisableDirectivesScanning) {
-  StringRef FilenameForLookup;
   SmallString<256> PathBuf;
-  if (llvm::sys::path::is_absolute_gnu(OriginalFilename)) {
-FilenameForLookup = OriginalFilename;
-  } else if (!WorkingDirForCacheLookup) {
-return WorkingDirForCacheLookup.getError();
-  } else {
-StringRef RelFilename = OriginalFilename;
-RelFilename.consume_front("./");
-PathBuf = *WorkingDirForCacheLookup;
-llvm::sys::path::append(PathBuf, RelFilename);
-FilenameForLookup = PathBuf.str();
-  }
-  assert(llvm::sys::path::is_absolute_gnu(FilenameForLookup));
+  auto FilenameForLookup = tryGetFilenameForLookup(OriginalFilename, PathBuf);
+  if (!FilenameForLookup)
+return FilenameForLookup.getError();
+
   if (const auto *Entry =
-  findEntryByFilenameWithWriteThrough(FilenameForLookup))
+  findEntryByFilenameWithWriteThrough(*FilenameForLookup))
 return scanForDirectivesIfNecessary(*Entry, OriginalFilename,
 DisableDirectivesScanning)
 .unwrapError();
-  auto MaybeEntry = computeAndStoreResult(OriginalFilename, FilenameForLookup);
+  auto MaybeEntry = computeAndStoreResult(OriginalFilename, 
*FilenameForLookup);
   if (!MaybeEntry)
 return MaybeEntry.getError();
   return scanForDirectivesIfNecessary(*MaybeEntry, OriginalFilename,
@@ -379,3 +370,23 @@ void 
DependencyScanningWorkerFilesystem::updateWorkingDirForCacheLookup() {
   assert(!WorkingDirForCacheLookup ||
  llvm::sys::path::is_absolute_gnu(*WorkingDirForCacheLookup));
 }
+
+llvm::ErrorOr
+DependencyScanningWorkerFilesystem::tryGetFilenameForLookup(
+StringRef OriginalFilename, llvm::SmallVectorImpl ) const {
+  StringRef FilenameForLookup;
+  if (llvm::sys::path::is_absolute_gnu(OriginalFilename)) {
+FilenameForLookup = OriginalFilename;
+  } else if (!WorkingDirForCacheLookup) {
+return WorkingDirForCacheLookup.getError();
+  } else {
+StringRef RelFilename = OriginalFilename;
+RelFilename.consume_front("./");
+PathBuf.assign(WorkingDirForCacheLookup->begin(),
+   WorkingDirForCacheLookup->end());
+llvm::sys::path::append(PathBuf, RelFilename);
+FilenameForLookup = StringRef{PathBuf.begin(), PathBuf.size()};
+  }
+  assert(llvm::sys::path::is_absolute_gnu(FilenameForLookup));
+  return FilenameForLookup;
+}

>From bdccf1e7858826b5f41791cd0826f9e230de9197 Mon Sep 17 00:00:00 2001
From: Jan Svoboda 
Date: Mon, 9 Oct 2023 10:14:22 -0700
Subject: [PATCH 2/3] [clang][deps] Cache `VFS::getRealPath()`

---
 .../DependencyScanningFilesystem.h| 46 ++-
 .../DependencyScanningFilesystem.cpp  | 76 +++
 2 files changed, 121 insertions(+), 1 deletion(-)

diff --git 
a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h 
b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
index c3cd69ab720effd..b7ffd377ea017fa 100644
--- 
a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
+++ 
b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
@@ -142,6 +142,8 @@ class CachedFileSystemEntry {
   CachedFileContents *Contents;
 };
 
+using 

[clang] [clang][deps] Cache `VFS::getRealPath()` (PR #68645)

2023-10-26 Thread Ben Langmuir via cfe-commits


@@ -168,6 +170,12 @@ class DependencyScanningFilesystemSharedCache {
 /// The backing storage for cached contents.
 llvm::SpecificBumpPtrAllocator ContentsStorage;
 
+/// Map from filenames to cached real paths.
+llvm::StringMap RealPathsByFilename;

benlangmuir wrote:

I would lean towards combining them unless there's a drawback I'm not seeing - 
the keys are fairly large here so it's nice to share storage for that.  I would 
maybe feel differently for a DenseMap of small keys :shrug:

https://github.com/llvm/llvm-project/pull/68645
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][deps] Cache `VFS::getRealPath()` (PR #68645)

2023-10-26 Thread Ben Langmuir via cfe-commits


@@ -230,6 +251,26 @@ class DependencyScanningFilesystemLocalCache {
 assert(InsertedEntry ==  && "entry already present");
 return *InsertedEntry;
   }
+
+  /// Returns real path associated with the filename or nullptr if none is
+  /// found.
+  const CachedRealPath *findRealPathByFilename(StringRef Filename) const {
+assert(llvm::sys::path::is_absolute_gnu(Filename));
+auto It = RealPathCache.find(Filename);
+return It == RealPathCache.end() ? nullptr : It->getValue();
+  }
+
+  /// Associates the given real path with the filename and returns the given
+  /// entry pointer (for convenience).
+  const CachedRealPath &
+  insertRealPathForFilename(StringRef Filename,
+const CachedRealPath ) {

benlangmuir wrote:

Since you are storing a pointer to this not the value I would suggest this take 
a pointer parameter. Otherwise it's easy to assume it's being copied and would 
be safe to pass a stack variable.

https://github.com/llvm/llvm-project/pull/68645
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][deps] Cache `VFS::getRealPath()` (PR #68645)

2023-10-09 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff ac0dda894231e6281e7739aa0ea01a4e9697c747 
bdccf1e7858826b5f41791cd0826f9e230de9197 -- 
clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h 
clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp
``





View the diff from clang-format here.


``diff
diff --git 
a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp 
b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp
index 01b94efce6a8..e440b1cc9d32 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp
@@ -406,8 +406,8 @@ std::error_code 
DependencyScanningWorkerFilesystem::getRealPath(
   auto  = SharedCache.getShardForFilename(*FilenameForLookup);
   if (const auto *ShardRealPath =
   Shard.findRealPathByFilename(*FilenameForLookup)) {
-const auto  =
-LocalCache.insertRealPathForFilename(*FilenameForLookup, 
*ShardRealPath);
+const auto  = LocalCache.insertRealPathForFilename(
+*FilenameForLookup, *ShardRealPath);
 return HandleCachedRealPath(RealPath);
   }
 

``




https://github.com/llvm/llvm-project/pull/68645
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][deps] Cache `VFS::getRealPath()` (PR #68645)

2023-10-09 Thread Jan Svoboda via cfe-commits


@@ -168,6 +170,12 @@ class DependencyScanningFilesystemSharedCache {
 /// The backing storage for cached contents.
 llvm::SpecificBumpPtrAllocator ContentsStorage;
 
+/// Map from filenames to cached real paths.
+llvm::StringMap RealPathsByFilename;

jansvoboda11 wrote:

I guess this could be inlined into something like
```c++
llvm::StringMap> InfoByFilename
```

Any preferences?

https://github.com/llvm/llvm-project/pull/68645
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][deps] Cache `VFS::getRealPath()` (PR #68645)

2023-10-09 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Jan Svoboda (jansvoboda11)


Changes

This PR starts caching calls to 
`DependencyScanningWorkerFilesystem::getRealPath()` that we use whenever we 
canonicalize module map path. In the case of the real VFS, this functions 
performs an expensive syscall that we'd like to do as rarely as possible.

This PR keeps the real path out of `CachedFileSystemEntry`, since that's 
**immutable**; populating the real path on creation of this data structure 
(every stat/open) would be expensive.

---
Full diff: https://github.com/llvm/llvm-project/pull/68645.diff


2 Files Affected:

- (modified) 
clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h 
(+49-1) 
- (modified) 
clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp (+102-15) 


``diff
diff --git 
a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h 
b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
index dbe219b6dd8d723..b7ffd377ea017fa 100644
--- 
a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
+++ 
b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
@@ -142,6 +142,8 @@ class CachedFileSystemEntry {
   CachedFileContents *Contents;
 };
 
+using CachedRealPath = llvm::ErrorOr;
+
 /// This class is a shared cache, that caches the 'stat' and 'open' calls to 
the
 /// underlying real file system, and the scanned preprocessor directives of
 /// files.
@@ -168,6 +170,12 @@ class DependencyScanningFilesystemSharedCache {
 /// The backing storage for cached contents.
 llvm::SpecificBumpPtrAllocator ContentsStorage;
 
+/// Map from filenames to cached real paths.
+llvm::StringMap RealPathsByFilename;
+
+/// The backing storage for cached real paths.
+llvm::SpecificBumpPtrAllocator RealPathStorage;
+
 /// Returns entry associated with the filename or nullptr if none is found.
 const CachedFileSystemEntry *findEntryByFilename(StringRef Filename) const;
 
@@ -194,6 +202,17 @@ class DependencyScanningFilesystemSharedCache {
 const CachedFileSystemEntry &
 getOrInsertEntryForFilename(StringRef Filename,
 const CachedFileSystemEntry );
+
+/// Returns real path associated with the filename or nullptr if none is
+/// found.
+const CachedRealPath *findRealPathByFilename(StringRef Filename) const;
+
+/// Returns real path associated with the filename if there is some.
+/// Otherwise, constructs new one with the given one, associates it with 
the
+/// filename and returns the result.
+const CachedRealPath &
+getOrEmplaceRealPathForFilename(StringRef Filename,
+llvm::ErrorOr RealPath);
   };
 
   DependencyScanningFilesystemSharedCache();
@@ -212,6 +231,8 @@ class DependencyScanningFilesystemSharedCache {
 class DependencyScanningFilesystemLocalCache {
   llvm::StringMap Cache;
 
+  llvm::StringMap 
RealPathCache;
+
 public:
   /// Returns entry associated with the filename or nullptr if none is found.
   const CachedFileSystemEntry *findEntryByFilename(StringRef Filename) const {
@@ -230,6 +251,26 @@ class DependencyScanningFilesystemLocalCache {
 assert(InsertedEntry ==  && "entry already present");
 return *InsertedEntry;
   }
+
+  /// Returns real path associated with the filename or nullptr if none is
+  /// found.
+  const CachedRealPath *findRealPathByFilename(StringRef Filename) const {
+assert(llvm::sys::path::is_absolute_gnu(Filename));
+auto It = RealPathCache.find(Filename);
+return It == RealPathCache.end() ? nullptr : It->getValue();
+  }
+
+  /// Associates the given real path with the filename and returns the given
+  /// entry pointer (for convenience).
+  const CachedRealPath &
+  insertRealPathForFilename(StringRef Filename,
+const CachedRealPath ) {
+assert(llvm::sys::path::is_absolute_gnu(Filename));
+const auto *InsertedRealPath =
+RealPathCache.insert({Filename, }).first->second;
+assert(InsertedRealPath ==  && "entry already present");
+return *InsertedRealPath;
+  }
 };
 
 /// Reference to a CachedFileSystemEntry.
@@ -290,6 +331,9 @@ class DependencyScanningWorkerFilesystem : public 
llvm::vfs::ProxyFileSystem {
   llvm::ErrorOr>
   openFileForRead(const Twine ) override;
 
+  std::error_code getRealPath(const Twine ,
+  SmallVectorImpl ) const override;
+
   std::error_code setCurrentWorkingDirectory(const Twine ) override;
 
   /// Returns entry for the given filename.
@@ -393,13 +437,17 @@ class DependencyScanningWorkerFilesystem : public 
llvm::vfs::ProxyFileSystem {
   DependencyScanningFilesystemSharedCache 
   /// The local cache is used by the worker thread to cache file system queries
   /// locally instead of querying the global cache every time.
-  DependencyScanningFilesystemLocalCache 

[clang] [clang][deps] Cache `VFS::getRealPath()` (PR #68645)

2023-10-09 Thread Jan Svoboda via cfe-commits

https://github.com/jansvoboda11 created 
https://github.com/llvm/llvm-project/pull/68645

This PR starts caching calls to 
`DependencyScanningWorkerFilesystem::getRealPath()` that we use whenever we 
canonicalize module map path. In the case of the real VFS, this functions 
performs an expensive syscall that we'd like to do as rarely as possible.

This PR keeps the real path out of `CachedFileSystemEntry`, since that's 
**immutable**; populating the real path on creation of this data structure 
(every stat/open) would be expensive.

>From 3970f76778923189a9b1e7ec5fef457ac8dba357 Mon Sep 17 00:00:00 2001
From: Jan Svoboda 
Date: Mon, 9 Oct 2023 10:14:17 -0700
Subject: [PATCH 1/2] [clang] Move lookup filename into function

---
 .../DependencyScanningFilesystem.h|  4 ++
 .../DependencyScanningFilesystem.cpp  | 41 ---
 2 files changed, 30 insertions(+), 15 deletions(-)

diff --git 
a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h 
b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
index dbe219b6dd8d723..c3cd69ab720effd 100644
--- 
a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
+++ 
b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
@@ -400,6 +400,10 @@ class DependencyScanningWorkerFilesystem : public 
llvm::vfs::ProxyFileSystem {
   llvm::ErrorOr WorkingDirForCacheLookup;
 
   void updateWorkingDirForCacheLookup();
+
+  llvm::ErrorOr
+  tryGetFilenameForLookup(StringRef OriginalFilename,
+  llvm::SmallVectorImpl ) const;
 };
 
 } // end namespace dependencies
diff --git 
a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp 
b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp
index 3e53c8fc5740875..44b39c5195c62b6 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp
@@ -258,26 +258,17 @@ DependencyScanningWorkerFilesystem::computeAndStoreResult(
 llvm::ErrorOr
 DependencyScanningWorkerFilesystem::getOrCreateFileSystemEntry(
 StringRef OriginalFilename, bool DisableDirectivesScanning) {
-  StringRef FilenameForLookup;
   SmallString<256> PathBuf;
-  if (llvm::sys::path::is_absolute_gnu(OriginalFilename)) {
-FilenameForLookup = OriginalFilename;
-  } else if (!WorkingDirForCacheLookup) {
-return WorkingDirForCacheLookup.getError();
-  } else {
-StringRef RelFilename = OriginalFilename;
-RelFilename.consume_front("./");
-PathBuf = *WorkingDirForCacheLookup;
-llvm::sys::path::append(PathBuf, RelFilename);
-FilenameForLookup = PathBuf.str();
-  }
-  assert(llvm::sys::path::is_absolute_gnu(FilenameForLookup));
+  auto FilenameForLookup = tryGetFilenameForLookup(OriginalFilename, PathBuf);
+  if (!FilenameForLookup)
+return FilenameForLookup.getError();
+
   if (const auto *Entry =
-  findEntryByFilenameWithWriteThrough(FilenameForLookup))
+  findEntryByFilenameWithWriteThrough(*FilenameForLookup))
 return scanForDirectivesIfNecessary(*Entry, OriginalFilename,
 DisableDirectivesScanning)
 .unwrapError();
-  auto MaybeEntry = computeAndStoreResult(OriginalFilename, FilenameForLookup);
+  auto MaybeEntry = computeAndStoreResult(OriginalFilename, 
*FilenameForLookup);
   if (!MaybeEntry)
 return MaybeEntry.getError();
   return scanForDirectivesIfNecessary(*MaybeEntry, OriginalFilename,
@@ -379,3 +370,23 @@ void 
DependencyScanningWorkerFilesystem::updateWorkingDirForCacheLookup() {
   assert(!WorkingDirForCacheLookup ||
  llvm::sys::path::is_absolute_gnu(*WorkingDirForCacheLookup));
 }
+
+llvm::ErrorOr
+DependencyScanningWorkerFilesystem::tryGetFilenameForLookup(
+StringRef OriginalFilename, llvm::SmallVectorImpl ) const {
+  StringRef FilenameForLookup;
+  if (llvm::sys::path::is_absolute_gnu(OriginalFilename)) {
+FilenameForLookup = OriginalFilename;
+  } else if (!WorkingDirForCacheLookup) {
+return WorkingDirForCacheLookup.getError();
+  } else {
+StringRef RelFilename = OriginalFilename;
+RelFilename.consume_front("./");
+PathBuf.assign(WorkingDirForCacheLookup->begin(),
+   WorkingDirForCacheLookup->end());
+llvm::sys::path::append(PathBuf, RelFilename);
+FilenameForLookup = StringRef{PathBuf.begin(), PathBuf.size()};
+  }
+  assert(llvm::sys::path::is_absolute_gnu(FilenameForLookup));
+  return FilenameForLookup;
+}

>From bdccf1e7858826b5f41791cd0826f9e230de9197 Mon Sep 17 00:00:00 2001
From: Jan Svoboda 
Date: Mon, 9 Oct 2023 10:14:22 -0700
Subject: [PATCH 2/2] [clang][deps] Cache `VFS::getRealPath()`

---
 .../DependencyScanningFilesystem.h| 46 ++-
 .../DependencyScanningFilesystem.cpp  | 76 +++
 2 files changed, 121 insertions(+), 1 deletion(-)

diff --git