jansvoboda11 created this revision. jansvoboda11 added reviewers: benlangmuir, vsapsai, Bigcheese. Herald added a subscriber: ributzka. Herald added a project: All. jansvoboda11 requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
In D114095 <https://reviews.llvm.org/D114095>, `HeaderFileInfo::NumIncludes` was moved into `Preprocessor`. This still makes sense, because we want to track this on the granularity of submodules (D112915 <https://reviews.llvm.org/D112915>, D114173 <https://reviews.llvm.org/D114173>), but the way this information is serialized is not ideal. In `ASTWriter`, the set of included files gets deserialized eagerly, issuing lots of calls to `FileManager::getFile()` for input files the PCM consumer might not be interested in. This patch makes the information part of the header file info table, taking advantage of its lazy deserialization which typically happens when a file is about to be included. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D155131 Files: clang/include/clang/Serialization/ASTBitCodes.h clang/include/clang/Serialization/ASTReader.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTReaderInternals.h clang/lib/Serialization/ASTWriter.cpp
Index: clang/lib/Serialization/ASTWriter.cpp =================================================================== --- clang/lib/Serialization/ASTWriter.cpp +++ clang/lib/Serialization/ASTWriter.cpp @@ -866,7 +866,6 @@ RECORD(CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH); RECORD(PP_CONDITIONAL_STACK); RECORD(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS); - RECORD(PP_INCLUDED_FILES); RECORD(PP_ASSUME_NONNULL_LOC); // SourceManager Block. @@ -1763,6 +1762,7 @@ struct data_type { const HeaderFileInfo &HFI; + bool AlreadyIncluded; ArrayRef<ModuleMap::KnownHeader> KnownHeaders; UnresolvedModule Unresolved; }; @@ -1808,7 +1808,8 @@ endian::Writer LE(Out, little); uint64_t Start = Out.tell(); (void)Start; - unsigned char Flags = (Data.HFI.isImport << 5) + unsigned char Flags = (Data.AlreadyIncluded << 6) + | (Data.HFI.isImport << 5) | (Data.HFI.isPragmaOnce << 4) | (Data.HFI.DirInfo << 1) | Data.HFI.IndexHeaderMapHeader; @@ -1909,7 +1910,7 @@ HeaderFileInfoTrait::key_type Key = { FilenameDup, *U.Size, IncludeTimestamps ? *U.ModTime : 0}; HeaderFileInfoTrait::data_type Data = { - Empty, {}, {M, ModuleMap::headerKindToRole(U.Kind)}}; + Empty, false, {}, {M, ModuleMap::headerKindToRole(U.Kind)}}; // FIXME: Deal with cases where there are multiple unresolved header // directives in different submodules for the same header. Generator.insert(Key, Data, GeneratorTrait); @@ -1952,11 +1953,13 @@ SavedStrings.push_back(Filename.data()); } + bool Included = PP->alreadyIncluded(File); + HeaderFileInfoTrait::key_type Key = { Filename, File->getSize(), getTimestampForOutput(File) }; HeaderFileInfoTrait::data_type Data = { - *HFI, HS.getModuleMap().findResolvedModulesForHeader(File), {} + *HFI, Included, HS.getModuleMap().findResolvedModulesForHeader(File), {} }; Generator.insert(Key, Data, GeneratorTrait); ++NumHeaderSearchEntries; @@ -2533,20 +2536,6 @@ MacroOffsetsBase - ASTBlockStartOffset}; Stream.EmitRecordWithBlob(MacroOffsetAbbrev, Record, bytes(MacroOffsets)); } - - { - auto Abbrev = std::make_shared<BitCodeAbbrev>(); - Abbrev->Add(BitCodeAbbrevOp(PP_INCLUDED_FILES)); - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); - unsigned IncludedFilesAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); - - SmallString<2048> Buffer; - raw_svector_ostream Out(Buffer); - writeIncludedFiles(Out, PP); - RecordData::value_type Record[] = {PP_INCLUDED_FILES}; - Stream.EmitRecordWithBlob(IncludedFilesAbbrev, Record, Buffer.data(), - Buffer.size()); - } } void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec, Index: clang/lib/Serialization/ASTReaderInternals.h =================================================================== --- clang/lib/Serialization/ASTReaderInternals.h +++ clang/lib/Serialization/ASTReaderInternals.h @@ -276,6 +276,9 @@ static internal_key_type ReadKey(const unsigned char *d, unsigned); data_type ReadData(internal_key_ref,const unsigned char *d, unsigned DataLen); + +private: + const FileEntry *getFile(const internal_key_type &Key); }; /// The on-disk hash table used for known header files. Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -1875,6 +1875,21 @@ return LocalID + I->second; } +const FileEntry *HeaderFileInfoTrait::getFile(const internal_key_type &Key) { + FileManager &FileMgr = Reader.getFileManager(); + if (!Key.Imported) { + if (auto File = FileMgr.getFile(Key.Filename)) + return *File; + return nullptr; + } + + std::string Resolved = std::string(Key.Filename); + Reader.ResolveImportedPath(M, Resolved); + if (auto File = FileMgr.getFile(Resolved)) + return *File; + return nullptr; +} + unsigned HeaderFileInfoTrait::ComputeHash(internal_key_ref ikey) { return llvm::hash_combine(ikey.Size, ikey.ModTime); } @@ -1895,23 +1910,8 @@ return true; // Determine whether the actual files are equivalent. - FileManager &FileMgr = Reader.getFileManager(); - auto GetFile = [&](const internal_key_type &Key) -> const FileEntry* { - if (!Key.Imported) { - if (auto File = FileMgr.getFile(Key.Filename)) - return *File; - return nullptr; - } - - std::string Resolved = std::string(Key.Filename); - Reader.ResolveImportedPath(M, Resolved); - if (auto File = FileMgr.getFile(Resolved)) - return *File; - return nullptr; - }; - - const FileEntry *FEA = GetFile(a); - const FileEntry *FEB = GetFile(b); + const FileEntry *FEA = getFile(a); + const FileEntry *FEB = getFile(b); return FEA && FEA == FEB; } @@ -1940,6 +1940,12 @@ const unsigned char *End = d + DataLen; HeaderFileInfo HFI; unsigned Flags = *d++; + + bool Included = (Flags >> 6) & 0x01; + if (Included) + if (const FileEntry *FE = getFile(key)) + Reader.getPreprocessor().getIncludedFiles().insert(FE); + // FIXME: Refactor with mergeHeaderFileInfo in HeaderSearch.cpp. HFI.isImport |= (Flags >> 5) & 0x01; HFI.isPragmaOnce |= (Flags >> 4) & 0x01; @@ -3028,22 +3034,6 @@ } } -void ASTReader::readIncludedFiles(ModuleFile &F, StringRef Blob, - Preprocessor &PP) { - using namespace llvm::support; - - const unsigned char *D = (const unsigned char *)Blob.data(); - unsigned FileCount = endian::readNext<uint32_t, little, unaligned>(D); - - for (unsigned I = 0; I < FileCount; ++I) { - size_t ID = endian::readNext<uint32_t, little, unaligned>(D); - InputFileInfo IFI = getInputFileInfo(F, ID); - if (llvm::ErrorOr<const FileEntry *> File = - PP.getFileManager().getFile(IFI.Filename)) - PP.getIncludedFiles().insert(*File); - } -} - llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { BitstreamCursor &Stream = F.Stream; @@ -3795,10 +3785,6 @@ break; } - case PP_INCLUDED_FILES: - readIncludedFiles(F, Blob, PP); - break; - case LATE_PARSED_TEMPLATE: LateParsedTemplates.emplace_back( std::piecewise_construct, std::forward_as_tuple(&F), Index: clang/include/clang/Serialization/ASTReader.h =================================================================== --- clang/include/clang/Serialization/ASTReader.h +++ clang/include/clang/Serialization/ASTReader.h @@ -1391,7 +1391,6 @@ void ParseLineTable(ModuleFile &F, const RecordData &Record); llvm::Error ReadSourceManagerBlock(ModuleFile &F); SourceLocation getImportLocation(ModuleFile *F); - void readIncludedFiles(ModuleFile &F, StringRef Blob, Preprocessor &PP); ASTReadResult ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, const ModuleFile *ImportedBy, unsigned ClientLoadCapabilities); Index: clang/include/clang/Serialization/ASTBitCodes.h =================================================================== --- clang/include/clang/Serialization/ASTBitCodes.h +++ clang/include/clang/Serialization/ASTBitCodes.h @@ -41,7 +41,7 @@ /// Version 4 of AST files also requires that the version control branch and /// revision match exactly, since there is no backward compatibility of /// AST files at this time. -const unsigned VERSION_MAJOR = 25; +const unsigned VERSION_MAJOR = 26; /// AST file minor version number supported by this version of /// Clang. @@ -696,8 +696,7 @@ /// Record code for \#pragma float_control options. FLOAT_CONTROL_PRAGMA_OPTIONS = 65, - /// Record code for included files. - PP_INCLUDED_FILES = 66, + /// ID 66 used to be the list of included files. /// Record code for an unterminated \#pragma clang assume_nonnull begin /// recorded in a preamble.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits