[cfe-commits] r65103 - /cfe/trunk/lib/AST/DeclBase.cpp
steve naroff
snaroff at apple.com
Thu Feb 19 18:02:47 PST 2009
On Feb 19, 2009, at 8:44 PM, Chris Lattner wrote:
> Author: lattner
> Date: Thu Feb 19 19:44:05 2009
> New Revision: 65103
>
> URL: http://llvm.org/viewvc/llvm-project?rev=65103&view=rev
> Log:
> optimize the 'StoredDeclsMap' for the common case where there is
> exactly one decl with a specific name in a specific context. This
> avoids a bunch of malloc traffic and shrinks StoredDeclsMap to hold
> one pointer instead of 3 words (for a std::vector).
>
> This speeds up -fsyntax-only on cocoa.h with PTH by ~7.3%.
>
Wow. I'm impressed:-)
snaroff
> Modified:
> cfe/trunk/lib/AST/DeclBase.cpp
>
> Modified: cfe/trunk/lib/AST/DeclBase.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=65103&r1=65102&r2=65103&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/AST/DeclBase.cpp (original)
> +++ cfe/trunk/lib/AST/DeclBase.cpp Thu Feb 19 19:44:05 2009
> @@ -268,15 +268,119 @@
> }
> }
>
> -// FIXME: We really want to use a DenseSet here to eliminate the
> -// redundant storage of the declaration names, but (1) it doesn't
> give
> -// us the ability to search based on DeclarationName, (2) we really
> -// need something more like a DenseMultiSet, and (3) it's
> -// implemented in terms of DenseMap anyway. However, this data
> -// structure is really space-inefficient, so we'll have to do
> -// something.
> -typedef llvm::DenseMap<DeclarationName, std::vector<NamedDecl*> >
> - StoredDeclsMap;
> +/// StoredDeclsList - This is an array of decls optimized a common
> case of only
> +/// containing one entry.
> +struct StoredDeclsList {
> + /// Data - If the integer is 0, then the pointer is a
> NamedDecl*. If the
> + /// integer is 1, then it is a VectorTy;
> + llvm::PointerIntPair<void*, 1, bool> Data;
> +
> + /// VectorTy - When in vector form, this is what the Data pointer
> points to.
> + typedef llvm::SmallVector<NamedDecl*, 4> VectorTy;
> +public:
> + StoredDeclsList() {}
> + StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) {
> + if (isVector())
> + Data.setPointer(new VectorTy(getVector()));
> + }
> +
> + ~StoredDeclsList() {
> + // If this is a vector-form, free the vector.
> + if (isVector())
> + delete &getVector();
> + }
> +
> + bool isVector() const { return Data.getInt() != 0; }
> + bool isInline() const { return Data.getInt() == 0; }
> + bool isNull() const { return Data.getPointer() == 0; }
> +
> + void setOnlyValue(NamedDecl *ND) {
> + assert(isInline() && "Not inline");
> + Data.setPointer(ND);
> + }
> +
> + /// getLookupResult - Return an array of all the decls that this
> list
> + /// represents.
> + DeclContext::lookup_result getLookupResult() {
> + // If we have a single inline unit, return it.
> + if (isInline()) {
> + assert(!isNull() && "Empty list isn't allowed");
> +
> + // Data is a raw pointer to a NamedDecl*, return it.
> + void *Ptr = &Data;
> + return DeclContext::lookup_result((NamedDecl**)Ptr,
> (NamedDecl**)Ptr+1);
> + }
> +
> + // Otherwise, we have a range result.
> + VectorTy &V = getVector();
> + return DeclContext::lookup_result(&V[0], &V[0]+V.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(NamedDecl *D) {
> + // Most decls only have one entry in their list, special case it.
> + if (isInline()) {
> + if (!D->declarationReplaces(getInlineValue()))
> + return false;
> + setOnlyValue(D);
> + return true;
> + }
> +
> + // Determine if this declaration is actually a redeclaration.
> + VectorTy &Vec = getVector();
> + VectorTy::iterator RDI
> + = std::find_if(Vec.begin(), Vec.end(),
> +
> std::bind1st(std::mem_fun(&NamedDecl::declarationReplaces),
> + D));
> + if (RDI == Vec.end())
> + return false;
> + *RDI = D;
> + return true;
> + }
> +
> + /// AddSubsequentDecl - This is called on the second and later
> decl when it is
> + /// not a redeclaration to merge it into the appropriate place in
> our list.
> + ///
> + void AddSubsequentDecl(NamedDecl *D) {
> + // If this is the second decl added to the list, convert this
> to vector
> + // form.
> + if (isInline()) {
> + NamedDecl *OldD = getInlineValue();
> + Data.setInt(1);
> + VectorTy *VT = new VectorTy();
> + VT->push_back(OldD);
> + Data.setPointer(VT);
> + }
> +
> + VectorTy &Vec = getVector();
> + if (isa<UsingDirectiveDecl>(D) ||
> + D->getIdentifierNamespace() == Decl::IDNS_Tag)
> + Vec.push_back(D);
> + else if (Vec.back()->getIdentifierNamespace() ==
> Decl::IDNS_Tag) {
> + NamedDecl *TagD = Vec.back();
> + Vec.back() = D;
> + Vec.push_back(TagD);
> + } else
> + Vec.push_back(D);
> + }
> +
> +
> +private:
> + VectorTy &getVector() const {
> + assert(isVector() && "Not in vector form");
> + return *static_cast<VectorTy*>(Data.getPointer());
> + }
> +
> + NamedDecl *getInlineValue() const {
> + assert(isInline() && "Not in inline form");
> + return (NamedDecl*)Data.getPointer();
> + }
> +};
> +
> +
> +
> +typedef llvm::DenseMap<DeclarationName, StoredDeclsList>
> StoredDeclsMap;
>
> DeclContext::~DeclContext() {
> unsigned Size = LookupPtr.getInt();
> @@ -412,9 +516,7 @@
> StoredDeclsMap::iterator Pos = Map->find(Name);
> if (Pos == Map->end())
> return lookup_result(0, 0);
> -
> - return lookup_result(&Pos->second.front(),
> - &Pos->second.front() + Pos->second.size());
> + return Pos->second.getLookupResult();
> }
>
> // We have a small array. Look into it.
> @@ -559,46 +661,21 @@
> }
>
> // Insert this declaration into the map.
> - StoredDeclsMap *Map =
> static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
> - std::vector<NamedDecl *> &DeclNameEntries = (*Map)[D-
> >getDeclName()];
> - if (DeclNameEntries.empty()) {
> - DeclNameEntries.push_back(D);
> + StoredDeclsMap &Map =
> *static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
> + StoredDeclsList &DeclNameEntries = Map[D->getDeclName()];
> + if (DeclNameEntries.isNull()) {
> + DeclNameEntries.setOnlyValue(D);
> return;
> }
>
> // 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 (MayBeRedeclaration) {
> - // Most decls only have one entry in their list, special case it.
> - if (DeclNameEntries.size() == 1) {
> - if (D->declarationReplaces(DeclNameEntries[0])) {
> - DeclNameEntries[0] = D;
> - return;
> - }
> - } else {
> - // Determine if this declaration is actually a redeclaration.
> - std::vector<NamedDecl *>::iterator Redecl
> - = std::find_if(DeclNameEntries.begin(),
> DeclNameEntries.end(),
> -
> std::bind1st(std::mem_fun(&NamedDecl::declarationReplaces),
> - D));
> - if (Redecl != DeclNameEntries.end()) {
> - *Redecl = D;
> - return;
> - }
> - }
> - }
> + if (MayBeRedeclaration && DeclNameEntries.HandleRedeclaration(D))
> + return;
>
> // Put this declaration into the appropriate slot.
> - if (isa<UsingDirectiveDecl>(D) ||
> - D->getIdentifierNamespace() == Decl::IDNS_Tag)
> - DeclNameEntries.push_back(D);
> - else if (DeclNameEntries.back()->getIdentifierNamespace() ==
> Decl::IDNS_Tag) {
> - NamedDecl *TagD = DeclNameEntries.back();
> - DeclNameEntries.back() = D;
> - DeclNameEntries.push_back(TagD);
> - } else
> - DeclNameEntries.push_back(D);
> + DeclNameEntries.AddSubsequentDecl(D);
> }
>
> /// Returns iterator range [First, Last) of UsingDirectiveDecls
> stored within
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list