From 9451eecd7614cc6f73d018ad4d6340b4e8c25e26 Mon Sep 17 00:00:00 2001 From: Yuka Takahashi <yukatkh@gmail.com> Date: Mon, 19 Nov 2018 16:11:32 +0100 Subject: [PATCH] [D54097]Optimize clang::ASTReader by using DenseMap instead of vector (#2903) Optimize clang::ASTReader by using DenseMap instead of vector This gives ~20 MB memory improvement. --- .../include/clang/Serialization/ASTReader.h | 15 ++-- .../clang/lib/Serialization/ASTReader.cpp | 75 ++++++++++--------- .../clang/lib/Serialization/ASTReaderDecl.cpp | 5 +- 3 files changed, 52 insertions(+), 43 deletions(-) diff --git a/interpreter/llvm/src/tools/clang/include/clang/Serialization/ASTReader.h b/interpreter/llvm/src/tools/clang/include/clang/Serialization/ASTReader.h index ab6f4f00436..da44613aed9 100644 --- a/interpreter/llvm/src/tools/clang/include/clang/Serialization/ASTReader.h +++ b/interpreter/llvm/src/tools/clang/include/clang/Serialization/ASTReader.h @@ -446,7 +446,8 @@ private: /// /// When the pointer at index I is non-NULL, the type with /// ID = (I + 1) << FastQual::Width has already been loaded - std::vector<QualType> TypesLoaded; + llvm::DenseMap<unsigned, QualType> TypesLoaded; + unsigned NumTypesLoaded = 0; typedef ContinuousRangeMap<serialization::TypeID, ModuleFile *, 4> GlobalTypeMapType; @@ -460,7 +461,8 @@ private: /// /// When the pointer at index I is non-NULL, the declaration with ID /// = I + 1 has already been loaded. - std::vector<Decl *> DeclsLoaded; + llvm::DenseMap<unsigned, Decl *> DeclsLoaded; + unsigned NumDeclsLoaded = 0; typedef ContinuousRangeMap<serialization::DeclID, ModuleFile *, 4> GlobalDeclMapType; @@ -602,7 +604,8 @@ private: /// If the pointer at index I is non-NULL, then it refers to the /// MacroInfo for the identifier with ID=I+1 that has already /// been loaded. - std::vector<MacroInfo *> MacrosLoaded; + llvm::DenseMap<unsigned, MacroInfo *> MacrosLoaded; + unsigned NumMacrosLoaded = 0; typedef std::pair<IdentifierInfo *, serialization::SubmoduleID> LoadedMacroInfo; @@ -1668,17 +1671,17 @@ public: /// \brief Returns the number of macros found in the chain. unsigned getTotalNumMacros() const { - return static_cast<unsigned>(MacrosLoaded.size()); + return NumMacrosLoaded; } /// \brief Returns the number of types found in the chain. unsigned getTotalNumTypes() const { - return static_cast<unsigned>(TypesLoaded.size()); + return NumTypesLoaded; } /// \brief Returns the number of declarations found in the chain. unsigned getTotalNumDecls() const { - return static_cast<unsigned>(DeclsLoaded.size()); + return NumDeclsLoaded; } /// \brief Returns the number of submodules known. diff --git a/interpreter/llvm/src/tools/clang/lib/Serialization/ASTReader.cpp b/interpreter/llvm/src/tools/clang/lib/Serialization/ASTReader.cpp index eb85593ae16..e05c3eec007 100644 --- a/interpreter/llvm/src/tools/clang/lib/Serialization/ASTReader.cpp +++ b/interpreter/llvm/src/tools/clang/lib/Serialization/ASTReader.cpp @@ -2769,7 +2769,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { std::make_pair(LocalBaseTypeIndex, F.BaseTypeIndex - LocalBaseTypeIndex)); - TypesLoaded.resize(TypesLoaded.size() + F.LocalNumTypes); + NumTypesLoaded += F.LocalNumTypes; } break; } @@ -2799,7 +2799,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { // module. F.GlobalToLocalDeclIDs[&F] = LocalBaseDeclID; - DeclsLoaded.resize(DeclsLoaded.size() + F.LocalNumDecls); + NumDeclsLoaded += F.LocalNumDecls; } break; } @@ -3333,7 +3333,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { std::make_pair(LocalBaseMacroID, F.BaseMacroID - LocalBaseMacroID)); - MacrosLoaded.resize(MacrosLoaded.size() + F.LocalNumMacros); + NumMacrosLoaded += F.LocalNumMacros; } break; } @@ -6766,19 +6766,19 @@ QualType ASTReader::GetType(TypeID ID) { } Index -= NUM_PREDEF_TYPE_IDS; - assert(Index < TypesLoaded.size() && "Type index out-of-range"); - if (TypesLoaded[Index].isNull()) { - TypesLoaded[Index] = readTypeRecord(Index); - if (TypesLoaded[Index].isNull()) + assert(Index < NumTypesLoaded && "Type index out-of-range"); + if (TypesLoaded.find(Index) == TypesLoaded.end()) { + QualType QualTy = readTypeRecord(Index); + TypesLoaded.insert({Index, QualTy}); + if (TypesLoaded.find(Index) == TypesLoaded.end()) return QualType(); - TypesLoaded[Index]->setFromAST(); + QualTy->setFromAST(); if (DeserializationListener) - DeserializationListener->TypeRead(TypeIdx::fromTypeID(ID), - TypesLoaded[Index]); + DeserializationListener->TypeRead(TypeIdx::fromTypeID(ID), QualTy); } - return TypesLoaded[Index].withFastQualifiers(FastQuals); + return TypesLoaded.find(Index)->second.withFastQualifiers(FastQuals); } QualType ASTReader::getLocalType(ModuleFile &F, unsigned LocalID) { @@ -7016,13 +7016,14 @@ SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) { unsigned Index = ID - NUM_PREDEF_DECL_IDS; - if (Index > DeclsLoaded.size()) { + if (Index > NumDeclsLoaded) { Error("declaration ID out-of-range for AST file"); return SourceLocation(); } - if (Decl *D = DeclsLoaded[Index]) - return D->getLocation(); + auto FindRes = DeclsLoaded.find(Index); + if (FindRes != DeclsLoaded.end()) + return FindRes->second->getLocation(); SourceLocation Loc; DeclCursorForID(ID, Loc); @@ -7101,13 +7102,17 @@ Decl *ASTReader::GetExistingDecl(DeclID ID) { unsigned Index = ID - NUM_PREDEF_DECL_IDS; - if (Index >= DeclsLoaded.size()) { + if (Index >= NumDeclsLoaded) { assert(0 && "declaration ID out-of-range for AST file"); Error("declaration ID out-of-range for AST file"); return nullptr; } - return DeclsLoaded[Index]; + auto FindRes = DeclsLoaded.find(Index); + if (FindRes == DeclsLoaded.end()) + return nullptr; + + return FindRes->second; } Decl *ASTReader::GetDecl(DeclID ID) { @@ -7116,19 +7121,19 @@ Decl *ASTReader::GetDecl(DeclID ID) { unsigned Index = ID - NUM_PREDEF_DECL_IDS; - if (Index >= DeclsLoaded.size()) { + if (Index >= NumDeclsLoaded) { assert(0 && "declaration ID out-of-range for AST file"); Error("declaration ID out-of-range for AST file"); return nullptr; } - if (!DeclsLoaded[Index]) { + if (DeclsLoaded.find(Index) == DeclsLoaded.end()) { ReadDeclRecord(ID); if (DeserializationListener) - DeserializationListener->DeclRead(ID, DeclsLoaded[Index]); + DeserializationListener->DeclRead(ID, DeclsLoaded.find(Index)->second); } - return DeclsLoaded[Index]; + return DeclsLoaded.find(Index)->second; } DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, @@ -7386,20 +7391,16 @@ void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) { void ASTReader::PrintStats() { std::fprintf(stderr, "*** AST File Statistics:\n"); - unsigned NumTypesLoaded - = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(), - QualType()); - unsigned NumDeclsLoaded - = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(), - (Decl *)nullptr); + unsigned NumTypesLoaded = TypesLoaded.size(); + + unsigned NumDeclsLoaded = DeclsLoaded.size(); + unsigned NumIdentifiersLoaded = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(), IdentifiersLoaded.end(), (IdentifierInfo *)nullptr); unsigned NumMacrosLoaded - = MacrosLoaded.size() - std::count(MacrosLoaded.begin(), - MacrosLoaded.end(), - (MacroInfo *)nullptr); + = MacrosLoaded.size(); unsigned NumSelectorsLoaded = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(), SelectorsLoaded.end(), @@ -8181,26 +8182,30 @@ MacroInfo *ASTReader::getMacro(MacroID ID) { if (ID == 0) return nullptr; - if (MacrosLoaded.empty()) { + if (!NumMacrosLoaded) { Error("no macro table in AST file"); return nullptr; } ID -= NUM_PREDEF_MACRO_IDS; - if (!MacrosLoaded[ID]) { + auto FindRes = MacrosLoaded.find(ID); + if (FindRes == MacrosLoaded.end()) { GlobalMacroMapType::iterator I = GlobalMacroMap.find(ID + NUM_PREDEF_MACRO_IDS); assert(I != GlobalMacroMap.end() && "Corrupted global macro map"); ModuleFile *M = I->second; unsigned Index = ID - M->BaseMacroID; - MacrosLoaded[ID] = ReadMacroRecord(*M, M->MacroOffsets[Index]); + MacroInfo *MI = ReadMacroRecord(*M, M->MacroOffsets[Index]); + MacrosLoaded.insert({ID, MI}); if (DeserializationListener) - DeserializationListener->MacroRead(ID + NUM_PREDEF_MACRO_IDS, - MacrosLoaded[ID]); + DeserializationListener->MacroRead(ID + NUM_PREDEF_MACRO_IDS, MI); } - return MacrosLoaded[ID]; + FindRes = MacrosLoaded.find(ID); + if (FindRes == MacrosLoaded.end()) + return nullptr; + return FindRes->second; } MacroID ASTReader::getGlobalMacroID(ModuleFile &M, unsigned LocalID) { diff --git a/interpreter/llvm/src/tools/clang/lib/Serialization/ASTReaderDecl.cpp b/interpreter/llvm/src/tools/clang/lib/Serialization/ASTReaderDecl.cpp index 7c2baaca15d..b105dc01a70 100644 --- a/interpreter/llvm/src/tools/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/interpreter/llvm/src/tools/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2560,8 +2560,9 @@ void ASTReader::ReadAttributes(ASTRecordReader &Record, AttrVec &Attrs) { /// so that future GetDecl calls will return this declaration rather /// than trying to load a new declaration. inline void ASTReader::LoadedDecl(unsigned Index, Decl *D) { - assert(!DeclsLoaded[Index] && "Decl loaded twice?"); - DeclsLoaded[Index] = D; + assert((DeclsLoaded.find(Index) == DeclsLoaded.end()) && + "Decl loaded twice?"); + DeclsLoaded.insert({Index, D}); } -- GitLab