Commit 57a2eaf3 authored by Rumeet Dhindsa's avatar Rumeet Dhindsa
Browse files

Revert "[modules] Do not cache invalid state for modules that we attempted to load."

As per comment on https://reviews.llvm.org/D72860, it is suggested to
revert this change in the meantime, since it has introduced regression.

This reverts commit 83f4c3af.
parent 66945b62
Loading
Loading
Loading
Loading
+34 −8
Original line number Diff line number Diff line
@@ -45,35 +45,61 @@ class InMemoryModuleCache : public llvm::RefCountedBase<InMemoryModuleCache> {
  llvm::StringMap<PCM> PCMs;

public:
  /// There are four states for a PCM.  It must monotonically increase.
  ///
  ///  1. Unknown: the PCM has neither been read from disk nor built.
  ///  2. Tentative: the PCM has been read from disk but not yet imported or
  ///     built.  It might work.
  ///  3. ToBuild: the PCM read from disk did not work but a new one has not
  ///     been built yet.
  ///  4. Final: indicating that the current PCM was either built in this
  ///     process or has been successfully imported.
  enum State { Unknown, Tentative, ToBuild, Final };

  /// Get the state of the PCM.
  State getPCMState(llvm::StringRef Filename) const;

  /// Store the PCM under the Filename.
  ///
  /// \pre PCM for the same Filename shouldn't be in cache already.
  /// \pre state is Unknown
  /// \post state is Tentative
  /// \return a reference to the buffer as a convenience.
  llvm::MemoryBuffer &addPCM(llvm::StringRef Filename,
                             std::unique_ptr<llvm::MemoryBuffer> Buffer);

  /// Store a final PCM under the Filename.
  /// Store a just-built PCM under the Filename.
  ///
  /// \pre PCM for the same Filename shouldn't be in cache already.
  /// \pre state is Unknown or ToBuild.
  /// \pre state is not Tentative.
  /// \return a reference to the buffer as a convenience.
  llvm::MemoryBuffer &addFinalPCM(llvm::StringRef Filename,
  llvm::MemoryBuffer &addBuiltPCM(llvm::StringRef Filename,
                                  std::unique_ptr<llvm::MemoryBuffer> Buffer);

  /// Try to remove a PCM from the cache.  No effect if it is Final.
  /// Try to remove a buffer from the cache.  No effect if state is Final.
  ///
  /// \return false on success.
  bool tryToRemovePCM(llvm::StringRef Filename);
  /// \pre state is Tentative/Final.
  /// \post Tentative => ToBuild or Final => Final.
  /// \return false on success, i.e. if Tentative => ToBuild.
  bool tryToDropPCM(llvm::StringRef Filename);

  /// Mark a PCM as final.
  ///
  /// \pre state is Tentative or Final.
  /// \post state is Final.
  void finalizePCM(llvm::StringRef Filename);

  /// Get a pointer to the PCM if it exists; else nullptr.
  /// Get a pointer to the pCM if it exists; else nullptr.
  llvm::MemoryBuffer *lookupPCM(llvm::StringRef Filename) const;

  /// Check whether the PCM is final and has been shown to work.
  ///
  /// \return true iff state is Final.
  bool isPCMFinal(llvm::StringRef Filename) const;

  /// Check whether the PCM is waiting to be built.
  ///
  /// \return true iff state is ToBuild.
  bool shouldBuildPCM(llvm::StringRef Filename) const;
};

} // end namespace clang
+1 −1
Original line number Diff line number Diff line
@@ -4502,7 +4502,7 @@ ASTReader::ReadASTCore(StringRef FileName,
    if (ShouldFinalizePCM)
      MC.finalizePCM(FileName);
    else
      MC.tryToRemovePCM(FileName);
      MC.tryToDropPCM(FileName);
  });
  ModuleFile &F = *M;
  BitstreamCursor &Stream = F.Stream;
+1 −1
Original line number Diff line number Diff line
@@ -4317,7 +4317,7 @@ ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef,
  WritingAST = false;
  if (ShouldCacheASTInMemory) {
    // Construct MemoryBuffer and update buffer manager.
    ModuleCache.addFinalPCM(OutputFile,
    ModuleCache.addBuiltPCM(OutputFile,
                            llvm::MemoryBuffer::getMemBufferCopy(
                                StringRef(Buffer.begin(), Buffer.size())));
  }
+21 −8
Original line number Diff line number Diff line
@@ -11,6 +11,16 @@

using namespace clang;

InMemoryModuleCache::State
InMemoryModuleCache::getPCMState(llvm::StringRef Filename) const {
  auto I = PCMs.find(Filename);
  if (I == PCMs.end())
    return Unknown;
  if (I->second.IsFinal)
    return Final;
  return I->second.Buffer ? Tentative : ToBuild;
}

llvm::MemoryBuffer &
InMemoryModuleCache::addPCM(llvm::StringRef Filename,
                            std::unique_ptr<llvm::MemoryBuffer> Buffer) {
@@ -20,11 +30,11 @@ InMemoryModuleCache::addPCM(llvm::StringRef Filename,
}

llvm::MemoryBuffer &
InMemoryModuleCache::addFinalPCM(llvm::StringRef Filename,
InMemoryModuleCache::addBuiltPCM(llvm::StringRef Filename,
                                 std::unique_ptr<llvm::MemoryBuffer> Buffer) {
  auto &PCM = PCMs[Filename];
  assert(!PCM.IsFinal && "Trying to override finalized PCM?");
  assert(!PCM.Buffer && "Already has a non-final PCM");
  assert(!PCM.Buffer && "Trying to override tentative PCM?");
  PCM.Buffer = std::move(Buffer);
  PCM.IsFinal = true;
  return *PCM.Buffer;
@@ -39,21 +49,24 @@ InMemoryModuleCache::lookupPCM(llvm::StringRef Filename) const {
}

bool InMemoryModuleCache::isPCMFinal(llvm::StringRef Filename) const {
  auto I = PCMs.find(Filename);
  if (I == PCMs.end())
    return false;
  return I->second.IsFinal;
  return getPCMState(Filename) == Final;
}

bool InMemoryModuleCache::tryToRemovePCM(llvm::StringRef Filename) {
bool InMemoryModuleCache::shouldBuildPCM(llvm::StringRef Filename) const {
  return getPCMState(Filename) == ToBuild;
}

bool InMemoryModuleCache::tryToDropPCM(llvm::StringRef Filename) {
  auto I = PCMs.find(Filename);
  assert(I != PCMs.end() && "PCM to remove is unknown...");

  auto &PCM = I->second;
  assert(PCM.Buffer && "PCM to remove is scheduled to be built...");

  if (PCM.IsFinal)
    return true;

  PCMs.erase(I);
  PCM.Buffer.reset();
  return false;
}

+7 −4
Original line number Diff line number Diff line
@@ -163,7 +163,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
  // Load the contents of the module
  if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
    // The buffer was already provided for us.
    NewModule->Buffer = &ModuleCache->addFinalPCM(FileName, std::move(Buffer));
    NewModule->Buffer = &ModuleCache->addBuiltPCM(FileName, std::move(Buffer));
    // Since the cached buffer is reused, it is safe to close the file
    // descriptor that was opened while stat()ing the PCM in
    // lookupModuleFile() above, it won't be needed any longer.
@@ -173,6 +173,11 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
    NewModule->Buffer = Buffer;
    // As above, the file descriptor is no longer needed.
    Entry->closeFile();
  } else if (getModuleCache().shouldBuildPCM(FileName)) {
    // Report that the module is out of date, since we tried (and failed) to
    // import it earlier.
    Entry->closeFile();
    return OutOfDate;
  } else {
    // Open the AST file.
    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf((std::error_code()));
@@ -180,9 +185,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
      Buf = llvm::MemoryBuffer::getSTDIN();
    } else {
      // Get a buffer of the file and close the file descriptor when done.
      // The file is volatile because in a parallel build we expect multiple
      // compiler processes to use the same module file rebuilding it if needed.
      Buf = FileMgr.getBufferForFile(NewModule->File, /*isVolatile=*/true);
      Buf = FileMgr.getBufferForFile(NewModule->File, /*isVolatile=*/false);
    }

    if (!Buf) {
Loading