Author: Jan Svoboda Date: 2022-12-01T20:07:01-08:00 New Revision: 66cf61abd849072d04da96408b122eea436dbc90
URL: https://github.com/llvm/llvm-project/commit/66cf61abd849072d04da96408b122eea436dbc90 DIFF: https://github.com/llvm/llvm-project/commit/66cf61abd849072d04da96408b122eea436dbc90.diff LOG: [clang][serialization] NFCI: Avoid re-reading input file info This patch resolves a FIXME that points out an inefficiency in first deserializing the input file info and the whole input file, which redundantly deserializes the input file info again. Reviewed By: Bigcheese Differential Revision: https://reviews.llvm.org/D137192 Added: Modified: clang/include/clang/Serialization/ASTReader.h clang/include/clang/Serialization/ModuleFile.h clang/lib/Serialization/ASTReader.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 5569c0147bbd6..21cbe4f5b1a50 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -1247,18 +1247,8 @@ class ASTReader /// Reads a statement from the specified cursor. Stmt *ReadStmtFromStream(ModuleFile &F); - struct InputFileInfo { - std::string Filename; - uint64_t ContentHash; - off_t StoredSize; - time_t StoredTime; - bool Overridden; - bool Transient; - bool TopLevelModuleMap; - }; - - /// Reads the stored information about an input file. - InputFileInfo readInputFileInfo(ModuleFile &F, unsigned ID); + /// Retrieve the stored information about an input file. + serialization::InputFileInfo getInputFileInfo(ModuleFile &F, unsigned ID); /// Retrieve the file entry and 'overridden' bit for an input /// file in the given module file. diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h index 500dab59ed5e0..655ae022a488a 100644 --- a/clang/include/clang/Serialization/ModuleFile.h +++ b/clang/include/clang/Serialization/ModuleFile.h @@ -59,6 +59,17 @@ enum ModuleKind { MK_PrebuiltModule }; +/// The input file info that has been loaded from an AST file. +struct InputFileInfo { + std::string Filename; + uint64_t ContentHash; + off_t StoredSize; + time_t StoredTime; + bool Overridden; + bool Transient; + bool TopLevelModuleMap; +}; + /// The input file that has been loaded from this AST file, along with /// bools indicating whether this was an overridden buffer or if it was /// out-of-date or not-found. @@ -235,6 +246,9 @@ class ModuleFile { /// The input files that have been loaded from this AST file. std::vector<InputFile> InputFilesLoaded; + /// The input file infos that have been loaded from this AST file. + std::vector<InputFileInfo> InputFileInfosLoaded; + // All user input files reside at the index range [0, NumUserInputFiles), and // system input files reside at [NumUserInputFiles, InputFilesLoaded.size()). unsigned NumUserInputFiles = 0; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index ff324cab57bf7..97fdfbe332ad5 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -2266,8 +2266,15 @@ bool ASTReader::shouldDisableValidationForFile( return false; } -ASTReader::InputFileInfo -ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) { +InputFileInfo ASTReader::getInputFileInfo(ModuleFile &F, unsigned ID) { + // If this ID is bogus, just return an empty input file. + if (ID == 0 || ID > F.InputFileInfosLoaded.size()) + return InputFileInfo(); + + // If we've already loaded this input file, return it. + if (!F.InputFileInfosLoaded[ID - 1].Filename.empty()) + return F.InputFileInfosLoaded[ID - 1]; + // Go find this input file. BitstreamCursor &Cursor = F.InputFilesCursor; SavedStreamPosition SavedPosition(Cursor); @@ -2320,6 +2327,9 @@ ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) { } R.ContentHash = (static_cast<uint64_t>(Record[1]) << 32) | static_cast<uint64_t>(Record[0]); + + // Note that we've loaded this input file info. + F.InputFileInfosLoaded[ID - 1] = R; return R; } @@ -2344,7 +2354,7 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { consumeError(std::move(Err)); } - InputFileInfo FI = readInputFileInfo(F, ID); + InputFileInfo FI = getInputFileInfo(F, ID); off_t StoredSize = FI.StoredSize; time_t StoredTime = FI.StoredTime; bool Overridden = FI.Overridden; @@ -2691,7 +2701,7 @@ ASTReader::ReadControlBlock(ModuleFile &F, : NumUserInputs; for (unsigned I = 0; I < N; ++I) { bool IsSystem = I >= NumUserInputs; - InputFileInfo FI = readInputFileInfo(F, I+1); + InputFileInfo FI = getInputFileInfo(F, I + 1); Listener->visitInputFile(FI.Filename, IsSystem, FI.Overridden, F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule); @@ -2968,6 +2978,7 @@ ASTReader::ReadControlBlock(ModuleFile &F, F.InputFileOffsets = (const llvm::support::unaligned_uint64_t *)Blob.data(); F.InputFilesLoaded.resize(NumInputs); + F.InputFileInfosLoaded.resize(NumInputs); F.NumUserInputFiles = NumUserInputs; break; } @@ -2983,7 +2994,7 @@ void ASTReader::readIncludedFiles(ModuleFile &F, StringRef Blob, for (unsigned I = 0; I < FileCount; ++I) { size_t ID = endian::readNext<uint32_t, little, unaligned>(D); - InputFileInfo IFI = readInputFileInfo(F, ID); + InputFileInfo IFI = getInputFileInfo(F, ID); if (llvm::ErrorOr<const FileEntry *> File = PP.getFileManager().getFile(IFI.Filename)) PP.getIncludedFiles().insert(*File); @@ -9217,9 +9228,8 @@ void ASTReader::visitTopLevelModuleMaps( llvm::function_ref<void(FileEntryRef FE)> Visitor) { unsigned NumInputs = MF.InputFilesLoaded.size(); for (unsigned I = 0; I < NumInputs; ++I) { - InputFileInfo IFI = readInputFileInfo(MF, I + 1); + InputFileInfo IFI = getInputFileInfo(MF, I + 1); if (IFI.TopLevelModuleMap) - // FIXME: This unnecessarily re-reads the InputFileInfo. if (auto FE = getInputFile(MF, I + 1).getFile()) Visitor(*FE); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits