https://github.com/jansvoboda11 updated https://github.com/llvm/llvm-project/pull/88326
>From c543c01b144f702e57d04c961fbfd5ebfa43e863 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 1/2] [llvm][support] Implement tracing virtual file system --- .../DependencyScanningFilesystemTest.cpp | 34 +--------- llvm/include/llvm/Support/VirtualFileSystem.h | 54 ++++++++++++++++ llvm/lib/Support/VirtualFileSystem.cpp | 13 ++++ .../Support/VirtualFileSystemTest.cpp | 64 +++++++++++++++++++ 4 files changed, 134 insertions(+), 31 deletions(-) diff --git a/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp b/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp index 87bb67cfd9327c..691cd3641eb045 100644 --- a/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp +++ b/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp @@ -13,39 +13,11 @@ using namespace clang::tooling::dependencies; -namespace { -struct InstrumentingFilesystem - : llvm::RTTIExtends<InstrumentingFilesystem, llvm::vfs::ProxyFileSystem> { - unsigned NumStatusCalls = 0; - unsigned NumGetRealPathCalls = 0; - unsigned NumExistsCalls = 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); - } - - bool exists(const llvm::Twine &Path) override { - ++NumExistsCalls; - return ProxyFileSystem::exists(Path); - } -}; -} // 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); @@ -71,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); @@ -157,7 +129,7 @@ TEST(DependencyScanningFilesystem, RealPathAndStatusInvariants) { TEST(DependencyScanningFilesystem, CacheStatOnExists) { auto InMemoryFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>(); auto InstrumentingFS = - llvm::makeIntrusiveRefCnt<InstrumentingFilesystem>(InMemoryFS); + llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(InMemoryFS); InMemoryFS->setCurrentWorkingDirectory("/"); InMemoryFS->addFile("/foo", 0, llvm::MemoryBuffer::getMemBuffer("")); InMemoryFS->addFile("/bar", 0, llvm::MemoryBuffer::getMemBuffer("")); diff --git a/llvm/include/llvm/Support/VirtualFileSystem.h b/llvm/include/llvm/Support/VirtualFileSystem.h index f7cfcd4058e722..2531c075f262d7 100644 --- a/llvm/include/llvm/Support/VirtualFileSystem.h +++ b/llvm/include/llvm/Support/VirtualFileSystem.h @@ -1132,6 +1132,60 @@ 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 NumExistsCalls = 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); + } + + bool exists(const Twine &Path) override { + ++NumExistsCalls; + return ProxyFileSystem::exists(Path); + } + + 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 9d21eba9df635f..163d9ff938a5f1 100644 --- a/llvm/lib/Support/VirtualFileSystem.cpp +++ b/llvm/lib/Support/VirtualFileSystem.cpp @@ -2945,8 +2945,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 d4717ce18eafc9..0a2e0fdbe98524 100644 --- a/llvm/unittests/Support/VirtualFileSystemTest.cpp +++ b/llvm/unittests/Support/VirtualFileSystemTest.cpp @@ -3565,3 +3565,67 @@ TEST(RedirectingFileSystemTest, ExistsRedirectOnly) { EXPECT_FALSE(Redirecting->exists("/b")); EXPECT_TRUE(Redirecting->exists("/vfile")); } + +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->NumExistsCalls, 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->NumExistsCalls, 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->NumExistsCalls, 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->NumExistsCalls, 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->NumExistsCalls, 0u); + EXPECT_EQ(TracingFS->NumIsLocalCalls, 0u); + + (void)TracingFS->exists("/foo"); + EXPECT_EQ(TracingFS->NumStatusCalls, 1u); + EXPECT_EQ(TracingFS->NumOpenFileForReadCalls, 1u); + EXPECT_EQ(TracingFS->NumDirBeginCalls, 1u); + EXPECT_EQ(TracingFS->NumGetRealPathCalls, 1u); + EXPECT_EQ(TracingFS->NumExistsCalls, 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->NumExistsCalls, 1u); + EXPECT_EQ(TracingFS->NumIsLocalCalls, 1u); +} >From af447898398d37e32ba76184aa1e8a0a1e4612cc Mon Sep 17 00:00:00 2001 From: Jan Svoboda <jan_svob...@apple.com> Date: Mon, 12 Aug 2024 14:55:00 -0700 Subject: [PATCH 2/2] Print the stats --- llvm/lib/Support/VirtualFileSystem.cpp | 13 +++++ .../Support/VirtualFileSystemTest.cpp | 50 +++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp index 163d9ff938a5f1..ddace563b8bd35 100644 --- a/llvm/lib/Support/VirtualFileSystem.cpp +++ b/llvm/lib/Support/VirtualFileSystem.cpp @@ -2952,6 +2952,19 @@ void TracingFileSystem::printImpl(raw_ostream &OS, PrintType Type, if (Type == PrintType::Summary) return; + printIndent(OS, IndentLevel); + OS << "NumStatusCalls=" << NumStatusCalls << "\n"; + printIndent(OS, IndentLevel); + OS << "NumOpenFileForReadCalls=" << NumOpenFileForReadCalls << "\n"; + printIndent(OS, IndentLevel); + OS << "NumDirBeginCalls=" << NumDirBeginCalls << "\n"; + printIndent(OS, IndentLevel); + OS << "NumGetRealPathCalls=" << NumGetRealPathCalls << "\n"; + printIndent(OS, IndentLevel); + OS << "NumExistsCalls=" << NumExistsCalls << "\n"; + printIndent(OS, IndentLevel); + OS << "NumIsLocalCalls=" << NumIsLocalCalls << "\n"; + if (Type == PrintType::Contents) Type = PrintType::Summary; getUnderlyingFS().print(OS, Type, IndentLevel + 1); diff --git a/llvm/unittests/Support/VirtualFileSystemTest.cpp b/llvm/unittests/Support/VirtualFileSystemTest.cpp index 0a2e0fdbe98524..d5764f64876f9c 100644 --- a/llvm/unittests/Support/VirtualFileSystemTest.cpp +++ b/llvm/unittests/Support/VirtualFileSystemTest.cpp @@ -3629,3 +3629,53 @@ TEST(TracingFileSystemTest, TracingWorks) { EXPECT_EQ(TracingFS->NumExistsCalls, 1u); EXPECT_EQ(TracingFS->NumIsLocalCalls, 1u); } + +TEST(TracingFileSystemTest, PrintOutput) { + auto InMemoryFS = makeIntrusiveRefCnt<vfs::InMemoryFileSystem>(); + auto TracingFS = + makeIntrusiveRefCnt<vfs::TracingFileSystem>(std::move(InMemoryFS)); + + (void)TracingFS->status("/foo"); + + (void)TracingFS->openFileForRead("/foo"); + (void)TracingFS->openFileForRead("/foo"); + + std::error_code EC; + (void)TracingFS->dir_begin("/foo", EC); + (void)TracingFS->dir_begin("/foo", EC); + (void)TracingFS->dir_begin("/foo", EC); + + llvm::SmallString<128> RealPath; + (void)TracingFS->getRealPath("/foo", RealPath); + (void)TracingFS->getRealPath("/foo", RealPath); + (void)TracingFS->getRealPath("/foo", RealPath); + (void)TracingFS->getRealPath("/foo", RealPath); + + (void)TracingFS->exists("/foo"); + (void)TracingFS->exists("/foo"); + (void)TracingFS->exists("/foo"); + (void)TracingFS->exists("/foo"); + (void)TracingFS->exists("/foo"); + + bool IsLocal; + (void)TracingFS->isLocal("/foo", IsLocal); + (void)TracingFS->isLocal("/foo", IsLocal); + (void)TracingFS->isLocal("/foo", IsLocal); + (void)TracingFS->isLocal("/foo", IsLocal); + (void)TracingFS->isLocal("/foo", IsLocal); + (void)TracingFS->isLocal("/foo", IsLocal); + + std::string Output; + llvm::raw_string_ostream OS(Output); + TracingFS->print(OS); + + ASSERT_EQ("TracingFileSystem\n" + "NumStatusCalls=1\n" + "NumOpenFileForReadCalls=2\n" + "NumDirBeginCalls=3\n" + "NumGetRealPathCalls=4\n" + "NumExistsCalls=5\n" + "NumIsLocalCalls=6\n" + " InMemoryFileSystem\n", + Output); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits