Revert "[clang][modules] Timestamp-less validation API" (#139987)
Reverts llvm/llvm-project#138983
This commit is contained in:
parent
41fcd7e78b
commit
18b885f66b
@ -207,8 +207,7 @@ bool IsModuleFileUpToDate(PathRef ModuleFilePath,
|
||||
Preprocessor PP(PPOpts, *Diags, LangOpts, SourceMgr, HeaderInfo,
|
||||
ModuleLoader);
|
||||
|
||||
IntrusiveRefCntPtr<ModuleCache> ModCache =
|
||||
createCrossProcessModuleCache(HSOpts.BuildSessionTimestamp);
|
||||
IntrusiveRefCntPtr<ModuleCache> ModCache = createCrossProcessModuleCache();
|
||||
PCHContainerOperations PCHOperations;
|
||||
ASTReader Reader(PP, *ModCache, /*ASTContext=*/nullptr,
|
||||
PCHOperations.getRawReader(), {});
|
||||
|
@ -33,14 +33,17 @@ public:
|
||||
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.
|
||||
|
||||
/// Checks whether the inputs of the module file were marked as validated.
|
||||
virtual bool isMarkedUpToDate(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;
|
||||
|
||||
/// Marks the inputs of the module file as validated.
|
||||
virtual void markUpToDate(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;
|
||||
@ -55,8 +58,7 @@ public:
|
||||
/// operated on by multiple processes. This instance must be used across all
|
||||
/// \c CompilerInstance instances participating in building modules for single
|
||||
/// translation unit in order to share the same \c InMemoryModuleCache.
|
||||
IntrusiveRefCntPtr<ModuleCache>
|
||||
createCrossProcessModuleCache(std::time_t BuildSessionTimestamp);
|
||||
IntrusiveRefCntPtr<ModuleCache> createCrossProcessModuleCache();
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
|
@ -270,9 +270,11 @@ public:
|
||||
// system input files reside at [NumUserInputFiles, InputFilesLoaded.size()).
|
||||
unsigned NumUserInputFiles = 0;
|
||||
|
||||
/// Specifies whether the input files have been validated (i.e. checked
|
||||
/// whether they are up-to-date).
|
||||
bool InputFilesValidated = false;
|
||||
/// If non-zero, specifies the time when we last validated input
|
||||
/// files. Zero means we never validated them.
|
||||
///
|
||||
/// The time is specified in seconds since the start of the Epoch.
|
||||
uint64_t InputFilesValidationTimestamp = 0;
|
||||
|
||||
// === Source Locations ===
|
||||
|
||||
|
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
|
||||
ModuleCacheEntries &getModuleCacheEntries() { return ModCacheEntries; }
|
||||
|
||||
std::time_t getBuildSessionTimestamp() const { return BuildSessionTimestamp; }
|
||||
|
||||
private:
|
||||
const ScanningMode Mode;
|
||||
const ScanningOutputFormat Format;
|
||||
@ -115,6 +120,8 @@ private:
|
||||
DependencyScanningFilesystemSharedCache SharedCache;
|
||||
/// The global module cache entries.
|
||||
ModuleCacheEntries ModCacheEntries;
|
||||
/// The build session timestamp.
|
||||
std::time_t BuildSessionTimestamp;
|
||||
};
|
||||
|
||||
} // end namespace dependencies
|
||||
|
@ -20,7 +20,7 @@ namespace tooling {
|
||||
namespace dependencies {
|
||||
struct ModuleCacheEntry {
|
||||
std::shared_mutex CompilationMutex;
|
||||
std::atomic<bool> UpToDate = false;
|
||||
std::atomic<std::time_t> Timestamp = 0;
|
||||
};
|
||||
|
||||
struct ModuleCacheEntries {
|
||||
|
@ -829,10 +829,9 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
|
||||
AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
|
||||
AST->getFileManager(),
|
||||
UserFilesAreVolatile);
|
||||
AST->ModCache = createCrossProcessModuleCache();
|
||||
AST->HSOpts = std::make_unique<HeaderSearchOptions>(HSOpts);
|
||||
AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.getFormats().front());
|
||||
AST->ModCache =
|
||||
createCrossProcessModuleCache(AST->HSOpts->BuildSessionTimestamp);
|
||||
AST->HeaderInfo.reset(new HeaderSearch(AST->getHeaderSearchOpts(),
|
||||
AST->getSourceManager(),
|
||||
AST->getDiagnostics(),
|
||||
@ -1549,8 +1548,7 @@ ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
|
||||
AST->UserFilesAreVolatile = UserFilesAreVolatile;
|
||||
AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
|
||||
UserFilesAreVolatile);
|
||||
AST->ModCache = createCrossProcessModuleCache(
|
||||
AST->Invocation->getHeaderSearchOpts().BuildSessionTimestamp);
|
||||
AST->ModCache = createCrossProcessModuleCache();
|
||||
|
||||
return AST;
|
||||
}
|
||||
@ -1836,6 +1834,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine(
|
||||
AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
|
||||
AST->StorePreamblesInMemory = StorePreamblesInMemory;
|
||||
AST->PreambleStoragePath = PreambleStoragePath;
|
||||
AST->ModCache = createCrossProcessModuleCache();
|
||||
AST->OnlyLocalDecls = OnlyLocalDecls;
|
||||
AST->CaptureDiagnostics = CaptureDiagnostics;
|
||||
AST->TUKind = TUKind;
|
||||
@ -1844,8 +1843,6 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine(
|
||||
= IncludeBriefCommentsInCodeCompletion;
|
||||
AST->UserFilesAreVolatile = UserFilesAreVolatile;
|
||||
AST->Invocation = CI;
|
||||
AST->ModCache = createCrossProcessModuleCache(
|
||||
AST->Invocation->getHeaderSearchOpts().BuildSessionTimestamp);
|
||||
AST->SkipFunctionBodies = SkipFunctionBodies;
|
||||
if (ForSerialization)
|
||||
AST->WriterData.reset(new ASTWriterData(*AST->ModCache));
|
||||
@ -2381,6 +2378,7 @@ bool ASTUnit::serialize(raw_ostream &OS) {
|
||||
|
||||
SmallString<128> Buffer;
|
||||
llvm::BitstreamWriter Stream(Buffer);
|
||||
IntrusiveRefCntPtr<ModuleCache> ModCache = createCrossProcessModuleCache();
|
||||
ASTWriter Writer(Stream, Buffer, *ModCache, {});
|
||||
return serializeUnit(Writer, Buffer, getSema(), OS);
|
||||
}
|
||||
|
@ -72,9 +72,7 @@ CompilerInstance::CompilerInstance(
|
||||
ModuleCache *ModCache)
|
||||
: ModuleLoader(/*BuildingModule=*/ModCache),
|
||||
Invocation(std::move(Invocation)),
|
||||
ModCache(ModCache ? ModCache
|
||||
: createCrossProcessModuleCache(
|
||||
getHeaderSearchOpts().BuildSessionTimestamp)),
|
||||
ModCache(ModCache ? ModCache : createCrossProcessModuleCache()),
|
||||
ThePCHContainerOperations(std::move(PCHContainerOps)) {
|
||||
assert(this->Invocation && "Invocation must not be null");
|
||||
}
|
||||
|
@ -3103,7 +3103,8 @@ ASTReader::ReadControlBlock(ModuleFile &F,
|
||||
|
||||
unsigned N = ValidateSystemInputs ? NumInputs : NumUserInputs;
|
||||
if (HSOpts.ModulesValidateOncePerBuildSession &&
|
||||
F.InputFilesValidated && F.Kind == MK_ImplicitModule)
|
||||
F.InputFilesValidationTimestamp > HSOpts.BuildSessionTimestamp &&
|
||||
F.Kind == MK_ImplicitModule)
|
||||
N = ForceValidateUserInputs ? NumUserInputs : 0;
|
||||
|
||||
for (unsigned I = 0; I < N; ++I) {
|
||||
@ -4949,8 +4950,10 @@ 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];
|
||||
if (M.Mod->Kind == MK_ImplicitModule && !M.Mod->InputFilesValidated)
|
||||
getModuleManager().getModuleCache().markUpToDate(M.Mod->FileName);
|
||||
if (M.Mod->Kind == MK_ImplicitModule &&
|
||||
M.Mod->InputFilesValidationTimestamp < HSOpts.BuildSessionTimestamp)
|
||||
getModuleManager().getModuleCache().updateModuleTimestamp(
|
||||
M.Mod->FileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5391,7 +5391,7 @@ ASTWriter::WriteAST(llvm::PointerUnion<Sema *, Preprocessor *> Subject,
|
||||
if (WritingModule && PPRef.getHeaderSearchInfo()
|
||||
.getHeaderSearchOpts()
|
||||
.ModulesValidateOncePerBuildSession)
|
||||
ModCache.markUpToDate(OutputFile);
|
||||
ModCache.updateModuleTimestamp(OutputFile);
|
||||
|
||||
if (ShouldCacheASTInMemory) {
|
||||
// Construct MemoryBuffer and update buffer manager.
|
||||
|
@ -20,12 +20,7 @@ namespace {
|
||||
class CrossProcessModuleCache : public ModuleCache {
|
||||
InMemoryModuleCache InMemory;
|
||||
|
||||
std::time_t BuildSessionTimestamp;
|
||||
|
||||
public:
|
||||
explicit CrossProcessModuleCache(std::time_t BuildSessionTimestamp)
|
||||
: BuildSessionTimestamp(BuildSessionTimestamp) {}
|
||||
|
||||
void prepareForGetLock(StringRef ModuleFilename) override {
|
||||
// FIXME: Do this in LockFileManager and only if the directory doesn't
|
||||
// exist.
|
||||
@ -38,17 +33,16 @@ public:
|
||||
return std::make_unique<llvm::LockFileManager>(ModuleFilename);
|
||||
}
|
||||
|
||||
bool isMarkedUpToDate(StringRef ModuleFilename) override {
|
||||
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 false;
|
||||
return llvm::sys::toTimeT(Status.getLastModificationTime()) >
|
||||
BuildSessionTimestamp;
|
||||
return 0;
|
||||
return llvm::sys::toTimeT(Status.getLastModificationTime());
|
||||
}
|
||||
|
||||
void markUpToDate(StringRef ModuleFilename) override {
|
||||
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(
|
||||
@ -68,8 +62,6 @@ public:
|
||||
};
|
||||
} // namespace
|
||||
|
||||
IntrusiveRefCntPtr<ModuleCache>
|
||||
clang::createCrossProcessModuleCache(std::time_t BuildSessionTimestamp) {
|
||||
return llvm::makeIntrusiveRefCnt<CrossProcessModuleCache>(
|
||||
BuildSessionTimestamp);
|
||||
IntrusiveRefCntPtr<ModuleCache> clang::createCrossProcessModuleCache() {
|
||||
return llvm::makeIntrusiveRefCnt<CrossProcessModuleCache>();
|
||||
}
|
||||
|
@ -174,11 +174,11 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
|
||||
NewModule->Index = Chain.size();
|
||||
NewModule->FileName = FileName.str();
|
||||
NewModule->ImportLoc = ImportLoc;
|
||||
NewModule->InputFilesValidated = false;
|
||||
NewModule->InputFilesValidationTimestamp = 0;
|
||||
|
||||
if (NewModule->Kind == MK_ImplicitModule)
|
||||
NewModule->InputFilesValidated =
|
||||
ModCache->isMarkedUpToDate(NewModule->FileName);
|
||||
NewModule->InputFilesValidationTimestamp =
|
||||
ModCache->getModuleTimestamp(NewModule->FileName);
|
||||
|
||||
// Load the contents of the module
|
||||
if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
|
||||
|
@ -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) {}
|
||||
|
@ -428,6 +428,10 @@ public:
|
||||
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
|
||||
|
@ -75,29 +75,29 @@ public:
|
||||
return std::make_unique<ReaderWriterLock>(CompilationMutex);
|
||||
}
|
||||
|
||||
bool isMarkedUpToDate(StringRef Filename) override {
|
||||
auto &IsUpToDate = [&]() -> std::atomic<bool> & {
|
||||
std::time_t getModuleTimestamp(StringRef Filename) override {
|
||||
auto &Timestamp = [&]() -> std::atomic<std::time_t> & {
|
||||
std::lock_guard<std::mutex> Lock(Entries.Mutex);
|
||||
auto &Entry = Entries.Map[Filename];
|
||||
if (!Entry)
|
||||
Entry = std::make_unique<ModuleCacheEntry>();
|
||||
return Entry->UpToDate;
|
||||
return Entry->Timestamp;
|
||||
}();
|
||||
|
||||
return IsUpToDate;
|
||||
return Timestamp.load();
|
||||
}
|
||||
|
||||
void markUpToDate(StringRef Filename) override {
|
||||
void updateModuleTimestamp(StringRef Filename) override {
|
||||
// Note: This essentially replaces FS contention with mutex contention.
|
||||
auto &IsUpToDate = [&]() -> std::atomic<bool> & {
|
||||
auto &Timestamp = [&]() -> std::atomic<std::time_t> & {
|
||||
std::lock_guard<std::mutex> Lock(Entries.Mutex);
|
||||
auto &Entry = Entries.Map[Filename];
|
||||
if (!Entry)
|
||||
Entry = std::make_unique<ModuleCacheEntry>();
|
||||
return Entry->UpToDate;
|
||||
return Entry->Timestamp;
|
||||
}();
|
||||
|
||||
IsUpToDate = true;
|
||||
Timestamp.store(llvm::sys::toTimeT(std::chrono::system_clock::now()));
|
||||
}
|
||||
|
||||
InMemoryModuleCache &getInMemoryModuleCache() override { return InMemory; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user