diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-08-22 20:13:39 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-08-22 20:13:39 +0000 |
commit | d61d4acd703630b62e29b2541574a1842b35d7f2 (patch) | |
tree | 5cc143367055d61ff90985ec1caadc920d130619 /clang/lib/Serialization/ASTReaderDecl.cpp | |
parent | b17bb06914abe652c5aa30cb94382907f3f78962 (diff) | |
download | bcm5719-llvm-d61d4acd703630b62e29b2541574a1842b35d7f2.tar.gz bcm5719-llvm-d61d4acd703630b62e29b2541574a1842b35d7f2.zip |
[modules] Further simplification and speedup of redeclaration chain loading.
Instead of eagerly deserializing a list of DeclIDs when we load a module file
and doing a binary search to find the redeclarations of a decl, store a list of
redeclarations of each chain before the first declaration and load it directly.
llvm-svn: 245789
Diffstat (limited to 'clang/lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 69 |
1 files changed, 35 insertions, 34 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index f4f39a8506b..00785aa1d05 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2156,6 +2156,8 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { bool IsKeyDecl = ThisDeclID == FirstDeclID; bool IsFirstLocalDecl = false; + uint64_t RedeclOffset = 0; + // 0 indicates that this declaration was the only declaration of its entity, // and is used for space optimization. if (FirstDeclID == 0) { @@ -2175,6 +2177,8 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { // declaration. for (unsigned I = 0; I != N - 1; ++I) MergeWith = ReadDecl(Record, Idx/*, MergeWith*/); + + RedeclOffset = Record[Idx++]; } else { // This declaration was not the first local declaration. Read the first // local declaration now, to trigger the import of other redeclarations. @@ -2198,7 +2202,7 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { // above; this ensures that the redeclaration chain is built in the correct // order. if (IsFirstLocalDecl) - Reader.PendingDeclChains.push_back(DAsT); + Reader.PendingDeclChains.push_back(std::make_pair(DAsT, RedeclOffset)); return RedeclarableResult(FirstDeclID, MergeWith, IsKeyDecl); } @@ -3393,43 +3397,40 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) { } } -void ASTReader::loadPendingDeclChain(Decl *FirstLocal) { - ModuleFile &M = *getOwningModuleFile(FirstLocal); - DeclID LocalID = - mapGlobalIDToModuleFileGlobalID(M, FirstLocal->getGlobalID()); - assert(LocalID && "looking for redecl chain in wrong module file"); - - // Perform a binary search to find the local redeclarations for this - // declaration (if any). - // FIXME: Just store an offset with the first declaration. - const LocalRedeclarationsInfo Compare = {LocalID, 0}; - const LocalRedeclarationsInfo *Result = std::lower_bound( - M.RedeclarationsMap, - M.RedeclarationsMap + M.LocalNumRedeclarationsInMap, Compare); +void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) { + // Attach FirstLocal to the end of the decl chain. + Decl *CanonDecl = FirstLocal->getCanonicalDecl(); + if (FirstLocal != CanonDecl) { + Decl *PrevMostRecent = ASTDeclReader::getMostRecentDecl(CanonDecl); + ASTDeclReader::attachPreviousDecl( + *this, FirstLocal, PrevMostRecent ? PrevMostRecent : CanonDecl, + CanonDecl); + } - // Pull out the list of redeclarations. - SmallVector<Decl*, 4> Chain; - if (Result != M.RedeclarationsMap + M.LocalNumRedeclarationsInMap && - Result->FirstID == LocalID) { - unsigned Offset = Result->Offset; - unsigned N = M.RedeclarationChains[Offset++]; - for (unsigned I = 0; I != N; ++I) - Chain.push_back(GetLocalDecl(M, M.RedeclarationChains[Offset++])); + if (!LocalOffset) { + ASTDeclReader::attachLatestDecl(CanonDecl, FirstLocal); + return; } - Chain.push_back(FirstLocal); - // Hook up the chain. - // - // FIXME: We have three different dispatches on decl kind here; maybe + // Load the list of other redeclarations from this module file. + ModuleFile *M = getOwningModuleFile(FirstLocal); + assert(M && "imported decl from no module file"); + + llvm::BitstreamCursor &Cursor = M->DeclsCursor; + SavedStreamPosition SavedPosition(Cursor); + Cursor.JumpToBit(LocalOffset); + + RecordData Record; + unsigned Code = Cursor.ReadCode(); + unsigned RecCode = Cursor.readRecord(Code, Record); + (void)RecCode; + assert(RecCode == LOCAL_REDECLARATIONS && "expected LOCAL_REDECLARATIONS record!"); + + // FIXME: We have several different dispatches on decl kind here; maybe // we should instead generate one loop per kind and dispatch up-front? - Decl *CanonDecl = FirstLocal->getCanonicalDecl(); - Decl *MostRecent = ASTDeclReader::getMostRecentDecl(CanonDecl); - if (!MostRecent) - MostRecent = CanonDecl; - for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - auto *D = Chain[N - I - 1]; - if (D == CanonDecl) - continue; + Decl *MostRecent = FirstLocal; + for (unsigned I = 0, N = Record.size(); I != N; ++I) { + auto *D = GetLocalDecl(*M, Record[N - I - 1]); ASTDeclReader::attachPreviousDecl(*this, D, MostRecent, CanonDecl); MostRecent = D; } |