That is an awesome win. On Aug 20, 2010, at 9:04 AM, Argyrios Kyrtzidis <[email protected]> wrote:
> Author: akirtzidis > Date: Fri Aug 20 11:04:35 2010 > New Revision: 111636 > > URL: http://llvm.org/viewvc/llvm-project?rev=111636&view=rev > Log: > Use the AST on-disk hash table for name lookup inside a DeclContext. > > *Huge* improvement over the amount of deserializing that we do for C++ lookup. > e.g, if he have the Carbon header precompiled and include it on a file > containing this: > > int x; > > these are the before/after stats: > > BEFORE: > > *** AST File Statistics: > 578 stat cache hits > 4 stat cache misses > 548/30654 source location entries read (1.787695%) > 15907/16501 types read (96.400223%) > 53525/59955 declarations read (89.275291%) > 33993/43525 identifiers read (78.099945%) > 41516/51891 statements read (80.006165%) > 77/5317 macros read (1.448185%) > 0/6335 lexical declcontexts read (0.000000%) > 1/5424 visible declcontexts read (0.018437%) > > AFTER using the on-disk table: > > *** AST File Statistics: > 578 stat cache hits > 4 stat cache misses > 548/30654 source location entries read (1.787695%) > 10/16501 types read (0.060602%) > 9/59955 declarations read (0.015011%) > 161/43525 identifiers read (0.369902%) > 20/51891 statements read (0.038542%) > 6/5317 macros read (0.112846%) > 0/6335 lexical declcontexts read (0.000000%) > 2/5424 visible declcontexts read (0.036873%) > > There's only one issue affecting mostly the precompiled preambles which I > will address soon. > > Modified: > cfe/trunk/include/clang/AST/DeclContextInternals.h > cfe/trunk/include/clang/AST/ExternalASTSource.h > cfe/trunk/include/clang/Serialization/ASTReader.h > cfe/trunk/include/clang/Serialization/ASTWriter.h > cfe/trunk/lib/AST/DeclBase.cpp > cfe/trunk/lib/Serialization/ASTReader.cpp > cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > cfe/trunk/lib/Serialization/ASTWriter.cpp > cfe/trunk/lib/Serialization/ASTWriterDecl.cpp > > Modified: cfe/trunk/include/clang/AST/DeclContextInternals.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclContextInternals.h?rev=111636&r1=111635&r2=111636&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/DeclContextInternals.h (original) > +++ cfe/trunk/include/clang/AST/DeclContextInternals.h Fri Aug 20 11:04:35 > 2010 > @@ -29,108 +29,54 @@ > /// StoredDeclsList - This is an array of decls optimized a common case of > only > /// containing one entry. > struct StoredDeclsList { > - /// The kind of data encoded in this list. > - enum DataKind { > - /// \brief The data is a NamedDecl*. > - DK_Decl = 0, > - /// \brief The data is a declaration ID (an unsigned value), > - /// shifted left by 2 bits. > - DK_DeclID = 1, > - /// \brief The data is a pointer to a vector (of type VectorTy) > - /// that contains declarations. > - DK_Decl_Vector = 2, > - /// \brief The data is a pointer to a vector (of type VectorTy) > - /// that contains declaration ID. > - DK_ID_Vector = 3 > - }; > - > - /// VectorTy - When in vector form, this is what the Data pointer points > to. > - typedef llvm::SmallVector<uintptr_t, 4> VectorTy; > - > - /// \brief The stored data, which will be either a declaration ID, a > - /// pointer to a NamedDecl, or a pointer to a vector. > - uintptr_t Data; > + > + /// DeclsTy - When in vector form, this is what the Data pointer points to. > + typedef llvm::SmallVector<NamedDecl *, 4> DeclsTy; > + > + /// \brief The stored data, which will be either a pointer to a NamedDecl, > + /// or a pointer to a vector. > + llvm::PointerUnion<NamedDecl *, DeclsTy *> Data; > > public: > - StoredDeclsList() : Data(0) {} > + StoredDeclsList() {} > > StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) { > - if (VectorTy *RHSVec = RHS.getAsVector()) { > - VectorTy *New = new VectorTy(*RHSVec); > - Data = reinterpret_cast<uintptr_t>(New) | (Data & 0x03); > - } > + if (DeclsTy *RHSVec = RHS.getAsVector()) > + Data = new DeclsTy(*RHSVec); > } > > ~StoredDeclsList() { > // If this is a vector-form, free the vector. > - if (VectorTy *Vector = getAsVector()) > + if (DeclsTy *Vector = getAsVector()) > delete Vector; > } > > StoredDeclsList &operator=(const StoredDeclsList &RHS) { > - if (VectorTy *Vector = getAsVector()) > + if (DeclsTy *Vector = getAsVector()) > delete Vector; > Data = RHS.Data; > - if (VectorTy *RHSVec = RHS.getAsVector()) { > - VectorTy *New = new VectorTy(*RHSVec); > - Data = reinterpret_cast<uintptr_t>(New) | (Data & 0x03); > - } > + if (DeclsTy *RHSVec = RHS.getAsVector()) > + Data = new DeclsTy(*RHSVec); > return *this; > } > > - bool isNull() const { return (Data & ~0x03) == 0; } > + bool isNull() const { return Data.isNull(); } > > NamedDecl *getAsDecl() const { > - if ((Data & 0x03) != DK_Decl) > - return 0; > - > - return reinterpret_cast<NamedDecl *>(Data & ~0x03); > + return Data.dyn_cast<NamedDecl *>(); > } > > - VectorTy *getAsVector() const { > - if ((Data & 0x03) != DK_ID_Vector && (Data & 0x03) != DK_Decl_Vector) > - return 0; > - > - return reinterpret_cast<VectorTy *>(Data & ~0x03); > + DeclsTy *getAsVector() const { > + return Data.dyn_cast<DeclsTy *>(); > } > > void setOnlyValue(NamedDecl *ND) { > assert(!getAsVector() && "Not inline"); > - Data = reinterpret_cast<uintptr_t>(ND); > - } > - > - void setFromDeclIDs(const llvm::SmallVectorImpl<unsigned> &Vec) { > - if (Vec.size() > 1) { > - VectorTy *Vector = getAsVector(); > - if (!Vector) { > - Vector = new VectorTy; > - Data = reinterpret_cast<uintptr_t>(Vector) | DK_ID_Vector; > - } > - > - Vector->resize(Vec.size()); > - std::copy(Vec.begin(), Vec.end(), Vector->begin()); > - return; > - } > - > - if (VectorTy *Vector = getAsVector()) > - delete Vector; > - > - if (Vec.empty()) > - Data = 0; > - else > - Data = (Vec[0] << 2) | DK_DeclID; > - } > - > - /// \brief Force the stored declarations list to contain actual > - /// declarations. > - /// > - /// This routine will resolve any declaration IDs for declarations > - /// that may not yet have been loaded from external storage. > - void materializeDecls(ASTContext &Context); > - > - bool hasDeclarationIDs() const { > - DataKind DK = (DataKind)(Data & 0x03); > - return DK == DK_DeclID || DK == DK_ID_Vector; > + Data = ND; > + // Make sure that Data is a plain NamedDecl* so we can use its address > + // at getLookupResult. > + assert(*(NamedDecl **)&Data == ND && > + "PointerUnion mangles the NamedDecl pointer!"); > } > > void remove(NamedDecl *D) { > @@ -138,30 +84,26 @@ > if (NamedDecl *Singleton = getAsDecl()) { > assert(Singleton == D && "list is different singleton"); > (void)Singleton; > - Data = 0; > + Data = (NamedDecl *)0; > return; > } > > - VectorTy &Vec = *getAsVector(); > - VectorTy::iterator I = std::find(Vec.begin(), Vec.end(), > - reinterpret_cast<uintptr_t>(D)); > + DeclsTy &Vec = *getAsVector(); > + DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D); > assert(I != Vec.end() && "list does not contain decl"); > Vec.erase(I); > > - assert(std::find(Vec.begin(), Vec.end(), reinterpret_cast<uintptr_t>(D)) > + assert(std::find(Vec.begin(), Vec.end(), D) > == Vec.end() && "list still contains decl"); > } > > /// getLookupResult - Return an array of all the decls that this list > /// represents. > - DeclContext::lookup_result getLookupResult(ASTContext &Context) { > + DeclContext::lookup_result getLookupResult() { > if (isNull()) > return DeclContext::lookup_result(DeclContext::lookup_iterator(0), > DeclContext::lookup_iterator(0)); > > - if (hasDeclarationIDs()) > - materializeDecls(Context); > - > // If we have a single NamedDecl, return it. > if (getAsDecl()) { > assert(!isNull() && "Empty list isn't allowed"); > @@ -172,19 +114,15 @@ > } > > assert(getAsVector() && "Must have a vector at this point"); > - VectorTy &Vector = *getAsVector(); > + DeclsTy &Vector = *getAsVector(); > > // Otherwise, we have a range result. > - return DeclContext::lookup_result((NamedDecl **)&Vector[0], > - (NamedDecl > **)&Vector[0]+Vector.size()); > + return DeclContext::lookup_result(&Vector[0], &Vector[0]+Vector.size()); > } > > /// HandleRedeclaration - If this is a redeclaration of an existing decl, > /// replace the old one with D and return true. Otherwise return false. > - bool HandleRedeclaration(ASTContext &Context, NamedDecl *D) { > - if (hasDeclarationIDs()) > - materializeDecls(Context); > - > + bool HandleRedeclaration(NamedDecl *D) { > // Most decls only have one entry in their list, special case it. > if (NamedDecl *OldD = getAsDecl()) { > if (!D->declarationReplaces(OldD)) > @@ -194,12 +132,12 @@ > } > > // Determine if this declaration is actually a redeclaration. > - VectorTy &Vec = *getAsVector(); > - for (VectorTy::iterator OD = Vec.begin(), ODEnd = Vec.end(); > + DeclsTy &Vec = *getAsVector(); > + for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end(); > OD != ODEnd; ++OD) { > - NamedDecl *OldD = reinterpret_cast<NamedDecl *>(*OD); > + NamedDecl *OldD = *OD; > if (D->declarationReplaces(OldD)) { > - *OD = reinterpret_cast<uintptr_t>(D); > + *OD = D; > return true; > } > } > @@ -211,17 +149,15 @@ > /// not a redeclaration to merge it into the appropriate place in our list. > /// > void AddSubsequentDecl(NamedDecl *D) { > - assert(!hasDeclarationIDs() && "Must materialize before adding decls"); > - > // If this is the second decl added to the list, convert this to vector > // form. > if (NamedDecl *OldD = getAsDecl()) { > - VectorTy *VT = new VectorTy(); > - VT->push_back(reinterpret_cast<uintptr_t>(OldD)); > - Data = reinterpret_cast<uintptr_t>(VT) | DK_Decl_Vector; > + DeclsTy *VT = new DeclsTy(); > + VT->push_back(OldD); > + Data = VT; > } > > - VectorTy &Vec = *getAsVector(); > + DeclsTy &Vec = *getAsVector(); > > // Using directives end up in a special entry which contains only > // other using directives, so all this logic is wasted for them. > @@ -232,32 +168,30 @@ > // iterator which points at the first tag will start a span of > // decls that only contains tags. > if (D->hasTagIdentifierNamespace()) > - Vec.push_back(reinterpret_cast<uintptr_t>(D)); > + Vec.push_back(D); > > // Resolved using declarations go at the front of the list so that > // they won't show up in other lookup results. Unresolved using > // declarations (which are always in IDNS_Using | IDNS_Ordinary) > // follow that so that the using declarations will be contiguous. > else if (D->getIdentifierNamespace() & Decl::IDNS_Using) { > - VectorTy::iterator I = Vec.begin(); > + DeclsTy::iterator I = Vec.begin(); > if (D->getIdentifierNamespace() != Decl::IDNS_Using) { > while (I != Vec.end() && > - reinterpret_cast<NamedDecl *>(*I) > - ->getIdentifierNamespace() == Decl::IDNS_Using) > + (*I)->getIdentifierNamespace() == Decl::IDNS_Using) > ++I; > } > - Vec.insert(I, reinterpret_cast<uintptr_t>(D)); > + Vec.insert(I, D); > > // All other declarations go at the end of the list, but before any > // tag declarations. But we can be clever about tag declarations > // because there can only ever be one in a scope. > - } else if (reinterpret_cast<NamedDecl *>(Vec.back()) > - ->hasTagIdentifierNamespace()) { > - uintptr_t TagD = Vec.back(); > - Vec.back() = reinterpret_cast<uintptr_t>(D); > + } else if (Vec.back()->hasTagIdentifierNamespace()) { > + NamedDecl *TagD = Vec.back(); > + Vec.back() = D; > Vec.push_back(TagD); > } else > - Vec.push_back(reinterpret_cast<uintptr_t>(D)); > + Vec.push_back(D); > } > }; > > > Modified: cfe/trunk/include/clang/AST/ExternalASTSource.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExternalASTSource.h?rev=111636&r1=111635&r2=111636&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/ExternalASTSource.h (original) > +++ cfe/trunk/include/clang/AST/ExternalASTSource.h Fri Aug 20 11:04:35 2010 > @@ -27,18 +27,6 @@ > class ExternalSemaSource; // layering violation required for downcasting > class Stmt; > > -/// \brief The deserialized representation of a set of declarations > -/// with the same name that are visible in a given context. > -struct VisibleDeclaration { > - /// \brief The name of the declarations. > - DeclarationName Name; > - > - /// \brief The ID numbers of all of the declarations with this name. > - /// > - /// These declarations have not necessarily been de-serialized. > - llvm::SmallVector<unsigned, 4> Declarations; > -}; > - > /// \brief Abstract interface for external sources of AST nodes. > /// > /// External AST sources provide AST nodes constructed from some > @@ -140,22 +128,6 @@ > virtual void PrintStats(); > > protected: > - /// \brief Initialize the context's lookup map with the given decls. > - /// It is assumed that none of the declarations are redeclarations of > - /// each other. > - static void SetExternalVisibleDecls(const DeclContext *DC, > - const llvm::SmallVectorImpl<VisibleDeclaration> &Decls); > - > - /// \brief Initialize the context's lookup map with the given decls. > - /// It is assumed that none of the declarations are redeclarations of > - /// each other. > - static void SetExternalVisibleDecls(const DeclContext *DC, > - const llvm::SmallVectorImpl<NamedDecl*> > &Decls); > - > - static DeclContext::lookup_result > - SetExternalVisibleDeclsForName(const DeclContext *DC, > - const VisibleDeclaration &VD); > - > static DeclContext::lookup_result > SetExternalVisibleDeclsForName(const DeclContext *DC, > DeclarationName Name, > > Modified: cfe/trunk/include/clang/Serialization/ASTReader.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=111636&r1=111635&r2=111636&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Serialization/ASTReader.h (original) > +++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri Aug 20 11:04:35 2010 > @@ -339,8 +339,7 @@ > > /// \brief Information about the contents of a DeclContext. > struct DeclContextInfo { > - llvm::BitstreamCursor *Stream; > - uint64_t OffsetToVisibleDecls; > + void *NameLookupTableData; // a ASTDeclContextNameLookupTable. > const serialization::DeclID *LexicalDecls; > unsigned NumLexicalDecls; > }; > > Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=111636&r1=111635&r2=111636&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Serialization/ASTWriter.h (original) > +++ cfe/trunk/include/clang/Serialization/ASTWriter.h Fri Aug 20 11:04:35 2010 > @@ -268,6 +268,7 @@ > > unsigned ParmVarDeclAbbrev; > unsigned DeclContextLexicalAbbrev; > + unsigned DeclContextVisibleLookupAbbrev; > void WriteDeclsBlockAbbrevs(); > void WriteDecl(ASTContext &Context, Decl *D); > > > Modified: cfe/trunk/lib/AST/DeclBase.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=111636&r1=111635&r2=111636&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/DeclBase.cpp (original) > +++ cfe/trunk/lib/AST/DeclBase.cpp Fri Aug 20 11:04:35 2010 > @@ -648,19 +648,6 @@ > > DeclContext::lookup_result > ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC, > - const VisibleDeclaration &VD) { > - ASTContext &Context = DC->getParentASTContext(); > - StoredDeclsMap *Map; > - if (!(Map = DC->LookupPtr)) > - Map = DC->CreateStoredDeclsMap(Context); > - > - StoredDeclsList &List = (*Map)[VD.Name]; > - List.setFromDeclIDs(VD.Declarations); > - return List.getLookupResult(Context); > -} > - > -DeclContext::lookup_result > -ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC, > DeclarationName Name, > llvm::SmallVectorImpl<NamedDecl*> &Decls) > { > ASTContext &Context = DC->getParentASTContext();; > @@ -677,35 +664,7 @@ > List.AddSubsequentDecl(Decls[I]); > } > > - return List.getLookupResult(Context); > -} > - > -void ExternalASTSource::SetExternalVisibleDecls(const DeclContext *DC, > - const llvm::SmallVectorImpl<VisibleDeclaration> &Decls) { > - // There is no longer any visible storage in this context. > - DC->ExternalVisibleStorage = false; > - > - assert(!DC->LookupPtr && "Have a lookup map before de-serialization?"); > - StoredDeclsMap *Map = DC->CreateStoredDeclsMap(DC->getParentASTContext()); > - for (unsigned I = 0, N = Decls.size(); I != N; ++I) { > - (*Map)[Decls[I].Name].setFromDeclIDs(Decls[I].Declarations); > - } > -} > - > -void ExternalASTSource::SetExternalVisibleDecls(const DeclContext *DC, > - const llvm::SmallVectorImpl<NamedDecl*> &Decls) { > - // There is no longer any visible storage in this context. > - DC->ExternalVisibleStorage = false; > - > - assert(!DC->LookupPtr && "Have a lookup map before de-serialization?"); > - StoredDeclsMap &Map = *DC->CreateStoredDeclsMap(DC->getParentASTContext()); > - for (unsigned I = 0, N = Decls.size(); I != N; ++I) { > - StoredDeclsList &List = Map[Decls[I]->getDeclName()]; > - if (List.isNull()) > - List.setOnlyValue(Decls[I]); > - else > - List.AddSubsequentDecl(Decls[I]); > - } > + return List.getLookupResult(); > } > > DeclContext::decl_iterator DeclContext::noload_decls_begin() const { > @@ -841,7 +800,7 @@ > if (LookupPtr) { > StoredDeclsMap::iterator I = LookupPtr->find(Name); > if (I != LookupPtr->end()) > - return I->second.getLookupResult(getParentASTContext()); > + return I->second.getLookupResult(); > } > > ExternalASTSource *Source = getParentASTContext().getExternalSource(); > @@ -861,7 +820,7 @@ > StoredDeclsMap::iterator Pos = LookupPtr->find(Name); > if (Pos == LookupPtr->end()) > return lookup_result(lookup_iterator(0), lookup_iterator(0)); > - return Pos->second.getLookupResult(getParentASTContext()); > + return Pos->second.getLookupResult(); > } > > DeclContext::lookup_const_result > @@ -925,18 +884,21 @@ > if (isa<ClassTemplateSpecializationDecl>(D)) > return; > > - // If there is an external AST source, load any declarations it knows about > - // with this declaration's name. > - if (ExternalASTSource *Source = getParentASTContext().getExternalSource()) > - if (hasExternalVisibleStorage()) > - Source->FindExternalVisibleDeclsByName(this, D->getDeclName()); > - > ASTContext *C = 0; > if (!LookupPtr) { > C = &getParentASTContext(); > CreateStoredDeclsMap(*C); > } > > + // If there is an external AST source, load any declarations it knows about > + // with this declaration's name. > + // If the lookup table contains an entry about this name it means that we > + // have already checked the external source. > + if (ExternalASTSource *Source = getParentASTContext().getExternalSource()) > + if (hasExternalVisibleStorage() && > + LookupPtr->find(D->getDeclName()) == LookupPtr->end()) > + Source->FindExternalVisibleDeclsByName(this, D->getDeclName()); > + > // Insert this declaration into the map. > StoredDeclsList &DeclNameEntries = (*LookupPtr)[D->getDeclName()]; > if (DeclNameEntries.isNull()) { > @@ -947,10 +909,7 @@ > // If it is possible that this is a redeclaration, check to see if there is > // already a decl for which declarationReplaces returns true. If there is > // one, just replace it and return. > - if (!C) > - C = &getParentASTContext(); > - > - if (DeclNameEntries.HandleRedeclaration(*C, D)) > + if (DeclNameEntries.HandleRedeclaration(D)) > return; > > // Put this declaration into the appropriate slot. > @@ -966,43 +925,6 @@ > reinterpret_cast<udir_iterator>(Result.second)); > } > > -void StoredDeclsList::materializeDecls(ASTContext &Context) { > - if (isNull()) > - return; > - > - switch ((DataKind)(Data & 0x03)) { > - case DK_Decl: > - case DK_Decl_Vector: > - break; > - > - case DK_DeclID: { > - // Resolve this declaration ID to an actual declaration by > - // querying the external AST source. > - unsigned DeclID = Data >> 2; > - > - ExternalASTSource *Source = Context.getExternalSource(); > - assert(Source && "No external AST source available!"); > - > - Data = reinterpret_cast<uintptr_t>(Source->GetExternalDecl(DeclID)); > - break; > - } > - > - case DK_ID_Vector: { > - // We have a vector of declaration IDs. Resolve all of them to > - // actual declarations. > - VectorTy &Vector = *getAsVector(); > - ExternalASTSource *Source = Context.getExternalSource(); > - assert(Source && "No external AST source available!"); > - > - for (unsigned I = 0, N = Vector.size(); I != N; ++I) > - Vector[I] = > reinterpret_cast<uintptr_t>(Source->GetExternalDecl(Vector[I])); > - > - Data = (Data & ~0x03) | DK_Decl_Vector; > - break; > - } > - } > -} > - > //===----------------------------------------------------------------------===// > // Creation and Destruction of StoredDeclsMaps. > // > //===----------------------------------------------------------------------===// > > Modified: cfe/trunk/lib/Serialization/ASTReader.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=111636&r1=111635&r2=111636&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Aug 20 11:04:35 2010 > @@ -846,6 +846,54 @@ > typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait> > ASTDeclContextNameLookupTable; > > +bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor, > + const std::pair<uint64_t, uint64_t> > &Offsets, > + DeclContextInfo &Info) { > + SavedStreamPosition SavedPosition(Cursor); > + // First the lexical decls. > + if (Offsets.first != 0) { > + Cursor.JumpToBit(Offsets.first); > + > + RecordData Record; > + const char *Blob; > + unsigned BlobLen; > + unsigned Code = Cursor.ReadCode(); > + unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen); > + if (RecCode != DECL_CONTEXT_LEXICAL) { > + Error("Expected lexical block"); > + return true; > + } > + > + Info.LexicalDecls = reinterpret_cast<const DeclID*>(Blob); > + Info.NumLexicalDecls = BlobLen / sizeof(DeclID); > + } else { > + Info.LexicalDecls = 0; > + Info.NumLexicalDecls = 0; > + } > + > + // Now the lookup table. > + if (Offsets.second != 0) { > + Cursor.JumpToBit(Offsets.second); > + > + RecordData Record; > + const char *Blob; > + unsigned BlobLen; > + unsigned Code = Cursor.ReadCode(); > + unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen); > + if (RecCode != DECL_CONTEXT_VISIBLE) { > + Error("Expected visible lookup table block"); > + return true; > + } > + Info.NameLookupTableData > + = ASTDeclContextNameLookupTable::Create( > + (const unsigned char *)Blob + Record[0], > + (const unsigned char *)Blob, > + ASTDeclContextNameLookupTrait(*this)); > + } > + > + return false; > +} > + > void ASTReader::Error(const char *Msg) { > Diag(diag::err_fe_pch_malformed) << Msg; > } > @@ -1674,7 +1722,7 @@ > > case TU_UPDATE_LEXICAL: { > DeclContextInfo Info = { > - /* No visible information */ 0, 0, > + /* No visible information */ 0, > reinterpret_cast<const DeclID *>(BlobStart), > BlobLen / sizeof(DeclID) > }; > @@ -3119,54 +3167,33 @@ > DeclarationName Name) { > assert(DC->hasExternalVisibleStorage() && > "DeclContext has no visible decls in storage"); > + if (!Name) > + return DeclContext::lookup_result(DeclContext::lookup_iterator(0), > + DeclContext::lookup_iterator(0)); > > - llvm::SmallVector<VisibleDeclaration, 64> Decls; > + llvm::SmallVector<NamedDecl *, 64> Decls; > // There might be lexical decls in multiple parts of the chain, for the TU > // and namespaces. > DeclContextInfos &Infos = DeclContextOffsets[DC]; > for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end(); > I != E; ++I) { > - uint64_t Offset = I->OffsetToVisibleDecls; > - if (Offset == 0) > + if (!I->NameLookupTableData) > continue; > > - llvm::BitstreamCursor &DeclsCursor = *I->Stream; > - > - // Keep track of where we are in the stream, then jump back there > - // after reading this context. > - SavedStreamPosition SavedPosition(DeclsCursor); > - > - // Load the record containing all of the declarations visible in > - // this context. > - DeclsCursor.JumpToBit(Offset); > - RecordData Record; > - unsigned Code = DeclsCursor.ReadCode(); > - unsigned RecCode = DeclsCursor.ReadRecord(Code, Record); > - if (RecCode != DECL_CONTEXT_VISIBLE) { > - Error("Expected visible block"); > - return DeclContext::lookup_result(DeclContext::lookup_iterator(), > - DeclContext::lookup_iterator()); > - } > - > - if (Record.empty()) > + ASTDeclContextNameLookupTable *LookupTable = > + (ASTDeclContextNameLookupTable*)I->NameLookupTableData; > + ASTDeclContextNameLookupTable::iterator Pos = LookupTable->find(Name); > + if (Pos == LookupTable->end()) > continue; > > - unsigned Idx = 0; > - while (Idx < Record.size()) { > - Decls.push_back(VisibleDeclaration()); > - Decls.back().Name = ReadDeclarationName(Record, Idx); > - > - unsigned Size = Record[Idx++]; > - llvm::SmallVector<unsigned, 4> &LoadedDecls = > Decls.back().Declarations; > - LoadedDecls.reserve(Size); > - for (unsigned J = 0; J < Size; ++J) > - LoadedDecls.push_back(Record[Idx++]); > - } > + ASTDeclContextNameLookupTrait::data_type Data = *Pos; > + for (; Data.first != Data.second; ++Data.first) > + Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first))); > } > > ++NumVisibleDeclContextsRead; > > - SetExternalVisibleDecls(DC, Decls); > + SetExternalVisibleDeclsForName(DC, Name, Decls); > return const_cast<DeclContext*>(DC)->lookup(Name); > } > > > Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=111636&r1=111635&r2=111636&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Fri Aug 20 11:04:35 2010 > @@ -1413,35 +1413,3 @@ > > return D; > } > - > -bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor, > - const std::pair<uint64_t, uint64_t> > &Offsets, > - DeclContextInfo &Info) { > - SavedStreamPosition SavedPosition(Cursor); > - // First the lexical decls. > - if (Offsets.first != 0) { > - Cursor.JumpToBit(Offsets.first); > - > - RecordData Record; > - const char *Blob; > - unsigned BlobLen; > - unsigned Code = Cursor.ReadCode(); > - unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen); > - if (RecCode != DECL_CONTEXT_LEXICAL) { > - Error("Expected lexical block"); > - return true; > - } > - > - Info.LexicalDecls = reinterpret_cast<const DeclID*>(Blob); > - Info.NumLexicalDecls = BlobLen / sizeof(DeclID); > - } else { > - Info.LexicalDecls = 0; > - Info.NumLexicalDecls = 0; > - } > - > - // Now the visible decls. > - Info.Stream = &Cursor; > - Info.OffsetToVisibleDecls = Offsets.second; > - > - return false; > -} > > Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=111636&r1=111635&r2=111636&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Aug 20 11:04:35 2010 > @@ -1466,59 +1466,6 @@ > return Offset; > } > > -/// \brief Write the block containing all of the declaration IDs > -/// visible from the given DeclContext. > -/// > -/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the > -/// bistream, or 0 if no block was written. > -uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, > - DeclContext *DC) { > - if (DC->getPrimaryContext() != DC) > - return 0; > - > - // Since there is no name lookup into functions or methods, don't bother to > - // build a visible-declarations table for these entities. > - if (DC->isFunctionOrMethod()) > - return 0; > - > - // If not in C++, we perform name lookup for the translation unit via the > - // IdentifierInfo chains, don't bother to build a visible-declarations > table. > - // FIXME: In C++ we need the visible declarations in order to "see" the > - // friend declarations, is there a way to do this without writing the > table ? > - if (DC->isTranslationUnit() && !Context.getLangOptions().CPlusPlus) > - return 0; > - > - // Force the DeclContext to build a its name-lookup table. > - DC->lookup(DeclarationName()); > - > - // Serialize the contents of the mapping used for lookup. Note that, > - // although we have two very different code paths, the serialized > - // representation is the same for both cases: a declaration name, > - // followed by a size, followed by references to the visible > - // declarations that have that name. > - uint64_t Offset = Stream.GetCurrentBitNo(); > - RecordData Record; > - StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr()); > - if (!Map) > - return 0; > - > - for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end(); > - D != DEnd; ++D) { > - AddDeclarationName(D->first, Record); > - DeclContext::lookup_result Result = D->second.getLookupResult(Context); > - Record.push_back(Result.second - Result.first); > - for (; Result.first != Result.second; ++Result.first) > - AddDeclRef(*Result.first, Record); > - } > - > - if (Record.size() == 0) > - return 0; > - > - Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record); > - ++NumVisibleDeclContexts; > - return Offset; > -} > - > void ASTWriter::WriteTypeDeclOffsets() { > using namespace llvm; > RecordData Record; > @@ -2062,6 +2009,74 @@ > }; > } // end anonymous namespace > > +/// \brief Write the block containing all of the declaration IDs > +/// visible from the given DeclContext. > +/// > +/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the > +/// bistream, or 0 if no block was written. > +uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, > + DeclContext *DC) { > + if (DC->getPrimaryContext() != DC) > + return 0; > + > + // Since there is no name lookup into functions or methods, don't bother to > + // build a visible-declarations table for these entities. > + if (DC->isFunctionOrMethod()) > + return 0; > + > + // If not in C++, we perform name lookup for the translation unit via the > + // IdentifierInfo chains, don't bother to build a visible-declarations > table. > + // FIXME: In C++ we need the visible declarations in order to "see" the > + // friend declarations, is there a way to do this without writing the > table ? > + if (DC->isTranslationUnit() && !Context.getLangOptions().CPlusPlus) > + return 0; > + > + // Force the DeclContext to build a its name-lookup table. > + DC->lookup(DeclarationName()); > + > + // Serialize the contents of the mapping used for lookup. Note that, > + // although we have two very different code paths, the serialized > + // representation is the same for both cases: a declaration name, > + // followed by a size, followed by references to the visible > + // declarations that have that name. > + uint64_t Offset = Stream.GetCurrentBitNo(); > + StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr()); > + if (!Map || Map->empty()) > + return 0; > + > + OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator; > + ASTDeclContextNameLookupTrait Trait(*this); > + > + // Create the on-disk hash table representation. > + for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end(); > + D != DEnd; ++D) { > + DeclarationName Name = D->first; > + DeclContext::lookup_result Result = D->second.getLookupResult(); > + Generator.insert(Name, Result, Trait); > + } > + > + // Create the on-disk hash table in a buffer. > + llvm::SmallString<4096> LookupTable; > + uint32_t BucketOffset; > + { > + llvm::raw_svector_ostream Out(LookupTable); > + // Make sure that no bucket is at offset 0 > + clang::io::Emit32(Out, 0); > + BucketOffset = Generator.Emit(Out, Trait); > + } > + > + // Write the lookup table > + RecordData Record; > + Record.push_back(DECL_CONTEXT_VISIBLE); > + Record.push_back(BucketOffset); > + Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record, > + LookupTable.str()); > + > + Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record); > + ++NumVisibleDeclContexts; > + return Offset; > +} > + > //===----------------------------------------------------------------------===// > // General Serialization Routines > //===----------------------------------------------------------------------===// > > Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=111636&r1=111635&r2=111636&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Fri Aug 20 11:04:35 2010 > @@ -1086,6 +1086,12 @@ > Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL)); > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); > DeclContextLexicalAbbrev = Stream.EmitAbbrev(Abv); > + > + Abv = new BitCodeAbbrev(); > + Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE)); > + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); > + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); > + DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(Abv); > } > > /// isRequiredDecl - Check if this is a "required" Decl, which must be seen by > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
