https://github.com/jansvoboda11 updated https://github.com/llvm/llvm-project/pull/88326
>From b395e907fcb3895941b58e0d00ef69f14b07c4ae Mon Sep 17 00:00:00 2001 From: Jan Svoboda <jan_svob...@apple.com> Date: Fri, 12 Apr 2024 10:47:13 -0700 Subject: [PATCH] [llvm][support] Implement tracing virtual file system --- .../DependencyScanningFilesystemTest.cpp | 26 +--------- llvm/include/llvm/Support/VirtualFileSystem.h | 48 ++++++++++++++++++ llvm/lib/Support/VirtualFileSystem.cpp | 13 +++++ .../Support/VirtualFileSystemTest.cpp | 50 +++++++++++++++++++ 4 files changed, 113 insertions(+), 24 deletions(-) diff --git a/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp b/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp index 697b7d70ff035a..c1a06c1f5ea20e 100644 --- a/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp +++ b/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp @@ -13,33 +13,11 @@ using namespace clang::tooling::dependencies; -namespace { -struct InstrumentingFilesystem - : llvm::RTTIExtends<InstrumentingFilesystem, llvm::vfs::ProxyFileSystem> { - unsigned NumStatusCalls = 0; - unsigned NumGetRealPathCalls = 0; - - using llvm::RTTIExtends<InstrumentingFilesystem, - llvm::vfs::ProxyFileSystem>::RTTIExtends; - - llvm::ErrorOr<llvm::vfs::Status> status(const llvm::Twine &Path) override { - ++NumStatusCalls; - return ProxyFileSystem::status(Path); - } - - std::error_code getRealPath(const llvm::Twine &Path, - llvm::SmallVectorImpl<char> &Output) override { - ++NumGetRealPathCalls; - return ProxyFileSystem::getRealPath(Path, Output); - } -}; -} // namespace - TEST(DependencyScanningWorkerFilesystem, CacheStatusFailures) { auto InMemoryFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>(); auto InstrumentingFS = - llvm::makeIntrusiveRefCnt<InstrumentingFilesystem>(InMemoryFS); + llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(InMemoryFS); DependencyScanningFilesystemSharedCache SharedCache; DependencyScanningWorkerFilesystem DepFS(SharedCache, InstrumentingFS); @@ -65,7 +43,7 @@ TEST(DependencyScanningFilesystem, CacheGetRealPath) { InMemoryFS->addFile("/bar", 0, llvm::MemoryBuffer::getMemBuffer("")); auto InstrumentingFS = - llvm::makeIntrusiveRefCnt<InstrumentingFilesystem>(InMemoryFS); + llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(InMemoryFS); DependencyScanningFilesystemSharedCache SharedCache; DependencyScanningWorkerFilesystem DepFS(SharedCache, InstrumentingFS); diff --git a/llvm/include/llvm/Support/VirtualFileSystem.h b/llvm/include/llvm/Support/VirtualFileSystem.h index 4b1ca0c3d262b6..1d851d4d9aea51 100644 --- a/llvm/include/llvm/Support/VirtualFileSystem.h +++ b/llvm/include/llvm/Support/VirtualFileSystem.h @@ -1125,6 +1125,54 @@ class YAMLVFSWriter { void write(llvm::raw_ostream &OS); }; +/// File system that tracks the number of calls to the underlying file system. +/// This is particularly useful when wrapped around \c RealFileSystem to add +/// lightweight tracking of expensive syscalls. +class TracingFileSystem + : public llvm::RTTIExtends<TracingFileSystem, ProxyFileSystem> { +public: + static const char ID; + + std::size_t NumStatusCalls = 0; + std::size_t NumOpenFileForReadCalls = 0; + std::size_t NumDirBeginCalls = 0; + std::size_t NumGetRealPathCalls = 0; + std::size_t NumIsLocalCalls = 0; + + TracingFileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) + : RTTIExtends(std::move(FS)) {} + + ErrorOr<Status> status(const Twine &Path) override { + ++NumStatusCalls; + return ProxyFileSystem::status(Path); + } + + ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) override { + ++NumOpenFileForReadCalls; + return ProxyFileSystem::openFileForRead(Path); + } + + directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override { + ++NumDirBeginCalls; + return ProxyFileSystem::dir_begin(Dir, EC); + } + + std::error_code getRealPath(const Twine &Path, + SmallVectorImpl<char> &Output) override { + ++NumGetRealPathCalls; + return ProxyFileSystem::getRealPath(Path, Output); + } + + std::error_code isLocal(const Twine &Path, bool &Result) override { + ++NumIsLocalCalls; + return ProxyFileSystem::isLocal(Path, Result); + } + +protected: + void printImpl(raw_ostream &OS, PrintType Type, + unsigned IndentLevel) const override; +}; + } // namespace vfs } // namespace llvm diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp index 32b480028e71b4..fe8924585e1ceb 100644 --- a/llvm/lib/Support/VirtualFileSystem.cpp +++ b/llvm/lib/Support/VirtualFileSystem.cpp @@ -2877,8 +2877,21 @@ recursive_directory_iterator::increment(std::error_code &EC) { return *this; } +void TracingFileSystem::printImpl(raw_ostream &OS, PrintType Type, + unsigned IndentLevel) const { + printIndent(OS, IndentLevel); + OS << "TracingFileSystem\n"; + if (Type == PrintType::Summary) + return; + + if (Type == PrintType::Contents) + Type = PrintType::Summary; + getUnderlyingFS().print(OS, Type, IndentLevel + 1); +} + const char FileSystem::ID = 0; const char OverlayFileSystem::ID = 0; const char ProxyFileSystem::ID = 0; const char InMemoryFileSystem::ID = 0; const char RedirectingFileSystem::ID = 0; +const char TracingFileSystem::ID = 0; diff --git a/llvm/unittests/Support/VirtualFileSystemTest.cpp b/llvm/unittests/Support/VirtualFileSystemTest.cpp index 49a2e19e4f74cd..c692590eca2725 100644 --- a/llvm/unittests/Support/VirtualFileSystemTest.cpp +++ b/llvm/unittests/Support/VirtualFileSystemTest.cpp @@ -3395,3 +3395,53 @@ TEST(RedirectingFileSystemTest, ExternalPaths) { EXPECT_EQ(CheckFS->SeenPaths, Expected); } + +TEST(TracingFileSystemTest, TracingWorks) { + auto InMemoryFS = makeIntrusiveRefCnt<vfs::InMemoryFileSystem>(); + auto TracingFS = + makeIntrusiveRefCnt<vfs::TracingFileSystem>(std::move(InMemoryFS)); + + EXPECT_EQ(TracingFS->NumStatusCalls, 0u); + EXPECT_EQ(TracingFS->NumOpenFileForReadCalls, 0u); + EXPECT_EQ(TracingFS->NumDirBeginCalls, 0u); + EXPECT_EQ(TracingFS->NumGetRealPathCalls, 0u); + EXPECT_EQ(TracingFS->NumIsLocalCalls, 0u); + + (void)TracingFS->status("/foo"); + EXPECT_EQ(TracingFS->NumStatusCalls, 1u); + EXPECT_EQ(TracingFS->NumOpenFileForReadCalls, 0u); + EXPECT_EQ(TracingFS->NumDirBeginCalls, 0u); + EXPECT_EQ(TracingFS->NumGetRealPathCalls, 0u); + EXPECT_EQ(TracingFS->NumIsLocalCalls, 0u); + + (void)TracingFS->openFileForRead("/foo"); + EXPECT_EQ(TracingFS->NumStatusCalls, 1u); + EXPECT_EQ(TracingFS->NumOpenFileForReadCalls, 1u); + EXPECT_EQ(TracingFS->NumDirBeginCalls, 0u); + EXPECT_EQ(TracingFS->NumGetRealPathCalls, 0u); + EXPECT_EQ(TracingFS->NumIsLocalCalls, 0u); + + std::error_code EC; + (void)TracingFS->dir_begin("/foo", EC); + EXPECT_EQ(TracingFS->NumStatusCalls, 1u); + EXPECT_EQ(TracingFS->NumOpenFileForReadCalls, 1u); + EXPECT_EQ(TracingFS->NumDirBeginCalls, 1u); + EXPECT_EQ(TracingFS->NumGetRealPathCalls, 0u); + EXPECT_EQ(TracingFS->NumIsLocalCalls, 0u); + + SmallString<128> RealPath; + (void)TracingFS->getRealPath("/foo", RealPath); + EXPECT_EQ(TracingFS->NumStatusCalls, 1u); + EXPECT_EQ(TracingFS->NumOpenFileForReadCalls, 1u); + EXPECT_EQ(TracingFS->NumDirBeginCalls, 1u); + EXPECT_EQ(TracingFS->NumGetRealPathCalls, 1u); + EXPECT_EQ(TracingFS->NumIsLocalCalls, 0u); + + bool IsLocal; + (void)TracingFS->isLocal("/foo", IsLocal); + EXPECT_EQ(TracingFS->NumStatusCalls, 1u); + EXPECT_EQ(TracingFS->NumOpenFileForReadCalls, 1u); + EXPECT_EQ(TracingFS->NumDirBeginCalls, 1u); + EXPECT_EQ(TracingFS->NumGetRealPathCalls, 1u); + EXPECT_EQ(TracingFS->NumIsLocalCalls, 1u); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits