[clang] [clang][modules][deps] Optimize in-process timestamping of PCMs (PR #137363)
Jan Svoboda via cfe-commits
cfe-commits at lists.llvm.org
Thu May 1 07:39:13 PDT 2025
https://github.com/jansvoboda11 updated https://github.com/llvm/llvm-project/pull/137363
>From f5b5bc95209c2c44c30481754870d319df20f78f Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Thu, 24 Apr 2025 14:35:59 -0700
Subject: [PATCH 1/5] [clang][deps] Optimize in-process timestamping of PCMs
---
.../include/clang/Serialization/ModuleCache.h | 12 ++++-
.../DependencyScanningService.h | 6 +--
.../DependencyScanning/InProcessModuleCache.h | 11 ++--
clang/lib/Serialization/ASTCommon.cpp | 12 -----
clang/lib/Serialization/ASTCommon.h | 2 -
clang/lib/Serialization/ASTReader.cpp | 9 +++-
clang/lib/Serialization/ASTWriter.cpp | 2 +-
clang/lib/Serialization/ModuleCache.cpp | 23 +++++++++
clang/lib/Serialization/ModuleManager.cpp | 12 ++---
.../DependencyScanningWorker.cpp | 2 +-
.../InProcessModuleCache.cpp | 50 +++++++++++++++----
11 files changed, 97 insertions(+), 44 deletions(-)
diff --git a/clang/include/clang/Serialization/ModuleCache.h b/clang/include/clang/Serialization/ModuleCache.h
index a7ba26bc4daae..a23ae6c257a69 100644
--- a/clang/include/clang/Serialization/ModuleCache.h
+++ b/clang/include/clang/Serialization/ModuleCache.h
@@ -12,6 +12,8 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include <ctime>
+
namespace llvm {
class AdvisoryLock;
} // namespace llvm
@@ -31,11 +33,19 @@ class ModuleCache : public RefCountedBase<ModuleCache> {
virtual std::unique_ptr<llvm::AdvisoryLock>
getLock(StringRef ModuleFilename) = 0;
+ /// Returns the timestamp denoting the last time inputs of the module file
+ /// were validated.
+ virtual std::time_t getModuleTimestamp(StringRef ModuleFilename) = 0;
+
+ /// Updates the timestamp denoting the last time inputs of the module file
+ /// were validated.
+ virtual void updateModuleTimestamp(StringRef ModuleFilename) = 0;
+
/// Returns this process's view of the module cache.
virtual InMemoryModuleCache &getInMemoryModuleCache() = 0;
virtual const InMemoryModuleCache &getInMemoryModuleCache() const = 0;
- // TODO: Virtualize writing/reading PCM files, timestamping, pruning, etc.
+ // TODO: Virtualize writing/reading PCM files, pruning, etc.
virtual ~ModuleCache() = default;
};
diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
index 5e8b37e791383..22f670cb821e2 100644
--- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
+++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
@@ -100,7 +100,7 @@ class DependencyScanningService {
return SharedCache;
}
- ModuleCacheMutexes &getModuleCacheMutexes() { return ModCacheMutexes; }
+ ModuleCacheEntries &getModuleCacheEntries() { return ModCacheEntries; }
private:
const ScanningMode Mode;
@@ -113,8 +113,8 @@ class DependencyScanningService {
const bool TraceVFS;
/// The global file system cache.
DependencyScanningFilesystemSharedCache SharedCache;
- /// The global module cache mutexes.
- ModuleCacheMutexes ModCacheMutexes;
+ /// The global module cache entries.
+ ModuleCacheEntries ModCacheEntries;
};
} // end namespace dependencies
diff --git a/clang/include/clang/Tooling/DependencyScanning/InProcessModuleCache.h b/clang/include/clang/Tooling/DependencyScanning/InProcessModuleCache.h
index ba0454380b665..213e60b39c199 100644
--- a/clang/include/clang/Tooling/DependencyScanning/InProcessModuleCache.h
+++ b/clang/include/clang/Tooling/DependencyScanning/InProcessModuleCache.h
@@ -18,13 +18,18 @@
namespace clang {
namespace tooling {
namespace dependencies {
-struct ModuleCacheMutexes {
+struct ModuleCacheEntry {
+ std::shared_mutex CompilationMutex;
+ std::atomic<std::time_t> Timestamp = 0;
+};
+
+struct ModuleCacheEntries {
std::mutex Mutex;
- llvm::StringMap<std::unique_ptr<std::shared_mutex>> Map;
+ llvm::StringMap<std::unique_ptr<ModuleCacheEntry>> Map;
};
IntrusiveRefCntPtr<ModuleCache>
-makeInProcessModuleCache(ModuleCacheMutexes &Mutexes);
+makeInProcessModuleCache(ModuleCacheEntries &Entries);
} // namespace dependencies
} // namespace tooling
} // namespace clang
diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp
index 320ee0e65dbea..ad277f19711ff 100644
--- a/clang/lib/Serialization/ASTCommon.cpp
+++ b/clang/lib/Serialization/ASTCommon.cpp
@@ -510,15 +510,3 @@ bool serialization::needsAnonymousDeclarationNumber(const NamedDecl *D) {
return false;
return isa<TagDecl, FieldDecl>(D);
}
-
-void serialization::updateModuleTimestamp(StringRef ModuleFilename) {
- // Overwrite the timestamp file contents so that file's mtime changes.
- std::error_code EC;
- llvm::raw_fd_ostream OS(ModuleFile::getTimestampFilename(ModuleFilename), EC,
- llvm::sys::fs::OF_TextWithCRLF);
- if (EC)
- return;
- OS << "Timestamp file\n";
- OS.close();
- OS.clear_error(); // Avoid triggering a fatal error.
-}
diff --git a/clang/lib/Serialization/ASTCommon.h b/clang/lib/Serialization/ASTCommon.h
index ed6b8d00115ea..371db4bace013 100644
--- a/clang/lib/Serialization/ASTCommon.h
+++ b/clang/lib/Serialization/ASTCommon.h
@@ -100,8 +100,6 @@ inline bool isPartOfPerModuleInitializer(const Decl *D) {
return false;
}
-void updateModuleTimestamp(StringRef ModuleFilename);
-
} // namespace serialization
} // namespace clang
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index f1ed67afaab7a..682cf71ec3a1e 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -3102,6 +3102,9 @@ ASTReader::ReadControlBlock(ModuleFile &F,
// files.
unsigned N = ValidateSystemInputs ? NumInputs : NumUserInputs;
+ // FIXME: F.InputFilesValidationTimestamp comes from std::chrono, but
+ // HSOpts.BuildSessionTimestamp comes from the FS. They may not be
+ // comparable.
if (HSOpts.ModulesValidateOncePerBuildSession &&
F.InputFilesValidationTimestamp > HSOpts.BuildSessionTimestamp &&
F.Kind == MK_ImplicitModule)
@@ -4950,9 +4953,13 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, ModuleKind Type,
// timestamp files are up-to-date in this build session.
for (unsigned I = 0, N = Loaded.size(); I != N; ++I) {
ImportedModule &M = Loaded[I];
+ // FIXME: F.InputFilesValidationTimestamp comes from std::chrono, but
+ // HSOpts.BuildSessionTimestamp comes from the FS. They may not be
+ // comparable.
if (M.Mod->Kind == MK_ImplicitModule &&
M.Mod->InputFilesValidationTimestamp < HSOpts.BuildSessionTimestamp)
- updateModuleTimestamp(M.Mod->FileName);
+ getModuleManager().getModuleCache().updateModuleTimestamp(
+ M.Mod->FileName);
}
}
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 2772038bf3755..76832958b6a93 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -5394,7 +5394,7 @@ ASTWriter::WriteAST(llvm::PointerUnion<Sema *, Preprocessor *> Subject,
if (WritingModule && PPRef.getHeaderSearchInfo()
.getHeaderSearchOpts()
.ModulesValidateOncePerBuildSession)
- updateModuleTimestamp(OutputFile);
+ ModCache.updateModuleTimestamp(OutputFile);
if (ShouldCacheASTInMemory) {
// Construct MemoryBuffer and update buffer manager.
diff --git a/clang/lib/Serialization/ModuleCache.cpp b/clang/lib/Serialization/ModuleCache.cpp
index 955e5f322bcc3..3ffd16fd3f7d0 100644
--- a/clang/lib/Serialization/ModuleCache.cpp
+++ b/clang/lib/Serialization/ModuleCache.cpp
@@ -9,6 +9,7 @@
#include "clang/Serialization/ModuleCache.h"
#include "clang/Serialization/InMemoryModuleCache.h"
+#include "clang/Serialization/ModuleFile.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/LockFileManager.h"
#include "llvm/Support/Path.h"
@@ -32,6 +33,28 @@ class CrossProcessModuleCache : public ModuleCache {
return std::make_unique<llvm::LockFileManager>(ModuleFilename);
}
+ std::time_t getModuleTimestamp(StringRef ModuleFilename) override {
+ std::string TimestampFilename =
+ serialization::ModuleFile::getTimestampFilename(ModuleFilename);
+ llvm::sys::fs::file_status Status;
+ if (llvm::sys::fs::status(ModuleFilename, Status) != std::error_code{})
+ return {};
+ return llvm::sys::toTimeT(Status.getLastModificationTime());
+ }
+
+ void updateModuleTimestamp(StringRef ModuleFilename) override {
+ // Overwrite the timestamp file contents so that file's mtime changes.
+ std::error_code EC;
+ llvm::raw_fd_ostream OS(
+ serialization::ModuleFile::getTimestampFilename(ModuleFilename), EC,
+ llvm::sys::fs::OF_TextWithCRLF);
+ if (EC)
+ return;
+ OS << "Timestamp file\n";
+ OS.close();
+ OS.clear_error(); // Avoid triggering a fatal error.
+ }
+
InMemoryModuleCache &getInMemoryModuleCache() override { return InMemory; }
const InMemoryModuleCache &getInMemoryModuleCache() const override {
return InMemory;
diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp
index d466ea06301a6..e3d7ff4fd82a7 100644
--- a/clang/lib/Serialization/ModuleManager.cpp
+++ b/clang/lib/Serialization/ModuleManager.cpp
@@ -174,15 +174,9 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
NewModule->ImportLoc = ImportLoc;
NewModule->InputFilesValidationTimestamp = 0;
- if (NewModule->Kind == MK_ImplicitModule) {
- std::string TimestampFilename =
- ModuleFile::getTimestampFilename(NewModule->FileName);
- llvm::vfs::Status Status;
- // A cached stat value would be fine as well.
- if (!FileMgr.getNoncachedStatValue(TimestampFilename, Status))
- NewModule->InputFilesValidationTimestamp =
- llvm::sys::toTimeT(Status.getLastModificationTime());
- }
+ if (NewModule->Kind == MK_ImplicitModule)
+ NewModule->InputFilesValidationTimestamp =
+ ModCache->getModuleTimestamp(NewModule->FileName);
// Load the contents of the module
if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
index 2443918526263..d78aba461ef91 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -411,7 +411,7 @@ class DependencyScanningAction : public tooling::ToolAction {
Scanned = true;
// Create a compiler instance to handle the actual work.
- auto ModCache = makeInProcessModuleCache(Service.getModuleCacheMutexes());
+ auto ModCache = makeInProcessModuleCache(Service.getModuleCacheEntries());
ScanInstanceStorage.emplace(std::move(Invocation),
std::move(PCHContainerOps), ModCache.get());
CompilerInstance &ScanInstance = *ScanInstanceStorage;
diff --git a/clang/lib/Tooling/DependencyScanning/InProcessModuleCache.cpp b/clang/lib/Tooling/DependencyScanning/InProcessModuleCache.cpp
index 71ce4d098932b..f65d0ec6aad68 100644
--- a/clang/lib/Tooling/DependencyScanning/InProcessModuleCache.cpp
+++ b/clang/lib/Tooling/DependencyScanning/InProcessModuleCache.cpp
@@ -10,6 +10,7 @@
#include "clang/Serialization/InMemoryModuleCache.h"
#include "llvm/Support/AdvisoryLock.h"
+#include "llvm/Support/Chrono.h"
#include <mutex>
@@ -50,7 +51,7 @@ class ReaderWriterLock : public llvm::AdvisoryLock {
};
class InProcessModuleCache : public ModuleCache {
- ModuleCacheMutexes &Mutexes;
+ ModuleCacheEntries &Entries;
// TODO: If we changed the InMemoryModuleCache API and relied on strict
// context hash, we could probably create more efficient thread-safe
@@ -59,19 +60,46 @@ class InProcessModuleCache : public ModuleCache {
InMemoryModuleCache InMemory;
public:
- InProcessModuleCache(ModuleCacheMutexes &Mutexes) : Mutexes(Mutexes) {}
+ InProcessModuleCache(ModuleCacheEntries &Entries) : Entries(Entries) {}
void prepareForGetLock(StringRef Filename) override {}
std::unique_ptr<llvm::AdvisoryLock> getLock(StringRef Filename) override {
- auto &Mtx = [&]() -> std::shared_mutex & {
- std::lock_guard<std::mutex> Lock(Mutexes.Mutex);
- auto &Mutex = Mutexes.Map[Filename];
- if (!Mutex)
- Mutex = std::make_unique<std::shared_mutex>();
- return *Mutex;
+ auto &CompilationMutex = [&]() -> std::shared_mutex & {
+ std::lock_guard Lock(Entries.Mutex);
+ auto &Entry = Entries.Map[Filename];
+ if (!Entry)
+ Entry = std::make_unique<ModuleCacheEntry>();
+ return Entry->CompilationMutex;
}();
- return std::make_unique<ReaderWriterLock>(Mtx);
+ return std::make_unique<ReaderWriterLock>(CompilationMutex);
+ }
+
+ std::time_t getModuleTimestamp(StringRef Filename) override {
+ auto &Timestamp = [&]() -> std::atomic<std::time_t> & {
+ std::lock_guard Lock(Entries.Mutex);
+ auto &Entry = Entries.Map[Filename];
+ if (!Entry)
+ Entry = std::make_unique<ModuleCacheEntry>();
+ return Entry->Timestamp;
+ }();
+
+ return Timestamp.load();
+ }
+
+ void updateModuleTimestamp(StringRef Filename) override {
+ // Note: This essentially replaces FS contention with mutex contention.
+ auto &Timestamp = [&]() -> std::atomic<std::time_t> & {
+ std::lock_guard Lock(Entries.Mutex);
+ auto &Entry = Entries.Map[Filename];
+ if (!Entry)
+ Entry = std::make_unique<ModuleCacheEntry>();
+ return Entry->Timestamp;
+ }();
+
+ std::time_t Expected = 0;
+ std::time_t Now = llvm::sys::toTimeT(std::chrono::system_clock::now());
+ Timestamp.compare_exchange_weak(Expected, Now);
}
InMemoryModuleCache &getInMemoryModuleCache() override { return InMemory; }
@@ -82,6 +110,6 @@ class InProcessModuleCache : public ModuleCache {
} // namespace
IntrusiveRefCntPtr<ModuleCache>
-dependencies::makeInProcessModuleCache(ModuleCacheMutexes &Mutexes) {
- return llvm::makeIntrusiveRefCnt<InProcessModuleCache>(Mutexes);
+dependencies::makeInProcessModuleCache(ModuleCacheEntries &Entries) {
+ return llvm::makeIntrusiveRefCnt<InProcessModuleCache>(Entries);
}
>From 94ab68b675eef2dc6d28a87f73722a5acf5ff9ba Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Thu, 24 Apr 2025 14:36:22 -0700
Subject: [PATCH 2/5] [clang][deps] Initialize build session timestamp properly
---
.../DependencyScanning/DependencyScanningService.h | 9 ++++++++-
clang/lib/Serialization/ASTReader.cpp | 6 ------
.../DependencyScanning/DependencyScanningService.cpp | 6 ++++--
.../DependencyScanning/DependencyScanningWorker.cpp | 4 ++++
4 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
index 22f670cb821e2..4e97c7bc9f36e 100644
--- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
+++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
@@ -12,6 +12,7 @@
#include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h"
#include "clang/Tooling/DependencyScanning/InProcessModuleCache.h"
#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/Support/Chrono.h"
namespace clang {
namespace tooling {
@@ -84,7 +85,9 @@ class DependencyScanningService {
DependencyScanningService(
ScanningMode Mode, ScanningOutputFormat Format,
ScanningOptimizations OptimizeArgs = ScanningOptimizations::Default,
- bool EagerLoadModules = false, bool TraceVFS = false);
+ bool EagerLoadModules = false, bool TraceVFS = false,
+ std::time_t BuildSessionTimestamp =
+ llvm::sys::toTimeT(std::chrono::system_clock::now()));
ScanningMode getMode() const { return Mode; }
@@ -102,6 +105,8 @@ class DependencyScanningService {
ModuleCacheEntries &getModuleCacheEntries() { return ModCacheEntries; }
+ std::time_t getBuildSessionTimestamp() const { return BuildSessionTimestamp; }
+
private:
const ScanningMode Mode;
const ScanningOutputFormat Format;
@@ -115,6 +120,8 @@ class DependencyScanningService {
DependencyScanningFilesystemSharedCache SharedCache;
/// The global module cache entries.
ModuleCacheEntries ModCacheEntries;
+ /// The build session timestamp.
+ std::time_t BuildSessionTimestamp;
};
} // end namespace dependencies
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 682cf71ec3a1e..ca92a361a312a 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -3102,9 +3102,6 @@ ASTReader::ReadControlBlock(ModuleFile &F,
// files.
unsigned N = ValidateSystemInputs ? NumInputs : NumUserInputs;
- // FIXME: F.InputFilesValidationTimestamp comes from std::chrono, but
- // HSOpts.BuildSessionTimestamp comes from the FS. They may not be
- // comparable.
if (HSOpts.ModulesValidateOncePerBuildSession &&
F.InputFilesValidationTimestamp > HSOpts.BuildSessionTimestamp &&
F.Kind == MK_ImplicitModule)
@@ -4953,9 +4950,6 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, ModuleKind Type,
// timestamp files are up-to-date in this build session.
for (unsigned I = 0, N = Loaded.size(); I != N; ++I) {
ImportedModule &M = Loaded[I];
- // FIXME: F.InputFilesValidationTimestamp comes from std::chrono, but
- // HSOpts.BuildSessionTimestamp comes from the FS. They may not be
- // comparable.
if (M.Mod->Kind == MK_ImplicitModule &&
M.Mod->InputFilesValidationTimestamp < HSOpts.BuildSessionTimestamp)
getModuleManager().getModuleCache().updateModuleTimestamp(
diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp
index 96fe40c079c65..7f40c99f07287 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp
@@ -14,6 +14,8 @@ using namespace dependencies;
DependencyScanningService::DependencyScanningService(
ScanningMode Mode, ScanningOutputFormat Format,
- ScanningOptimizations OptimizeArgs, bool EagerLoadModules, bool TraceVFS)
+ ScanningOptimizations OptimizeArgs, bool EagerLoadModules, bool TraceVFS,
+ std::time_t BuildSessionTimestamp)
: Mode(Mode), Format(Format), OptimizeArgs(OptimizeArgs),
- EagerLoadModules(EagerLoadModules), TraceVFS(TraceVFS) {}
+ EagerLoadModules(EagerLoadModules), TraceVFS(TraceVFS),
+ BuildSessionTimestamp(BuildSessionTimestamp) {}
diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
index d78aba461ef91..5c9cf3e416ca5 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -428,6 +428,10 @@ class DependencyScanningAction : public tooling::ToolAction {
ScanInstance.getPreprocessorOpts().AllowPCHWithDifferentModulesCachePath =
true;
+ if (ScanInstance.getHeaderSearchOpts().ModulesValidateOncePerBuildSession)
+ ScanInstance.getHeaderSearchOpts().BuildSessionTimestamp =
+ Service.getBuildSessionTimestamp();
+
ScanInstance.getFrontendOpts().GenerateGlobalModuleIndex = false;
ScanInstance.getFrontendOpts().UseGlobalModuleIndex = false;
// This will prevent us compiling individual modules asynchronously since
>From a0d03ad2cafbd0a34ff4e2973b8a521d6fdbdc9f Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Fri, 25 Apr 2025 09:36:55 -0700
Subject: [PATCH 3/5] Add TODOs
---
clang/include/clang/Serialization/ModuleCache.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/clang/include/clang/Serialization/ModuleCache.h b/clang/include/clang/Serialization/ModuleCache.h
index a23ae6c257a69..3117d954a09cc 100644
--- a/clang/include/clang/Serialization/ModuleCache.h
+++ b/clang/include/clang/Serialization/ModuleCache.h
@@ -33,6 +33,10 @@ class ModuleCache : public RefCountedBase<ModuleCache> {
virtual std::unique_ptr<llvm::AdvisoryLock>
getLock(StringRef ModuleFilename) = 0;
+ // TODO: Abstract away timestamps with isUpToDate() and markUpToDate().
+ // TODO: Consider exposing a "validation lock" API to prevent multiple clients
+ // concurrently noticing an out-of-date module file and validating its inputs.
+
/// Returns the timestamp denoting the last time inputs of the module file
/// were validated.
virtual std::time_t getModuleTimestamp(StringRef ModuleFilename) = 0;
>From cd14ffe8a6c1bdab5e7e7a4b72a55c8bc40b439d Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Tue, 29 Apr 2025 09:05:40 -0700
Subject: [PATCH 4/5] `{}` -> `0` for clarity
---
clang/lib/Serialization/ModuleCache.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Serialization/ModuleCache.cpp b/clang/lib/Serialization/ModuleCache.cpp
index 3ffd16fd3f7d0..4ae49c4ec9a05 100644
--- a/clang/lib/Serialization/ModuleCache.cpp
+++ b/clang/lib/Serialization/ModuleCache.cpp
@@ -38,7 +38,7 @@ class CrossProcessModuleCache : public ModuleCache {
serialization::ModuleFile::getTimestampFilename(ModuleFilename);
llvm::sys::fs::file_status Status;
if (llvm::sys::fs::status(ModuleFilename, Status) != std::error_code{})
- return {};
+ return 0;
return llvm::sys::toTimeT(Status.getLastModificationTime());
}
>From ac45c17b4de879c68e93815132dc10321c2a1c98 Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Tue, 29 Apr 2025 09:05:54 -0700
Subject: [PATCH 5/5] Keep the latest timestamp
---
clang/lib/Tooling/DependencyScanning/InProcessModuleCache.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/clang/lib/Tooling/DependencyScanning/InProcessModuleCache.cpp b/clang/lib/Tooling/DependencyScanning/InProcessModuleCache.cpp
index f65d0ec6aad68..eb05821e2bc02 100644
--- a/clang/lib/Tooling/DependencyScanning/InProcessModuleCache.cpp
+++ b/clang/lib/Tooling/DependencyScanning/InProcessModuleCache.cpp
@@ -97,9 +97,7 @@ class InProcessModuleCache : public ModuleCache {
return Entry->Timestamp;
}();
- std::time_t Expected = 0;
- std::time_t Now = llvm::sys::toTimeT(std::chrono::system_clock::now());
- Timestamp.compare_exchange_weak(Expected, Now);
+ Timestamp.store(llvm::sys::toTimeT(std::chrono::system_clock::now()));
}
InMemoryModuleCache &getInMemoryModuleCache() override { return InMemory; }
More information about the cfe-commits
mailing list