When deserializing a declaration, don't look for redeclarations if its

kind indicates that it can never be redeclared. Good for a 1% speedup,
and redeclaration searching drops off the profile.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173054 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2013-01-21 16:16:40 +00:00
Родитель 5a04f9fc2b
Коммит 9cfdc03fe7
4 изменённых файлов: 82 добавлений и 16 удалений

Просмотреть файл

@ -141,5 +141,68 @@ const Decl *serialization::getDefinitiveDeclContext(const DeclContext *DC) {
}
return 0;
}
bool serialization::isRedeclarableDeclKind(unsigned Kind) {
switch (static_cast<Decl::Kind>(Kind)) {
case Decl::TranslationUnit: // Special case of a "merged" declaration.
case Decl::Namespace:
case Decl::NamespaceAlias: // FIXME: Not yet redeclarable, but will be.
case Decl::Typedef:
case Decl::TypeAlias:
case Decl::Enum:
case Decl::Record:
case Decl::CXXRecord:
case Decl::ClassTemplateSpecialization:
case Decl::ClassTemplatePartialSpecialization:
case Decl::Function:
case Decl::CXXMethod:
case Decl::CXXConstructor:
case Decl::CXXDestructor:
case Decl::CXXConversion:
case Decl::Var:
case Decl::FunctionTemplate:
case Decl::ClassTemplate:
case Decl::TypeAliasTemplate:
case Decl::ObjCProtocol:
case Decl::ObjCInterface:
return true;
// Never redeclarable.
case Decl::UsingDirective:
case Decl::Label:
case Decl::UnresolvedUsingTypename:
case Decl::TemplateTypeParm:
case Decl::EnumConstant:
case Decl::UnresolvedUsingValue:
case Decl::IndirectField:
case Decl::Field:
case Decl::ObjCIvar:
case Decl::ObjCAtDefsField:
case Decl::ImplicitParam:
case Decl::ParmVar:
case Decl::NonTypeTemplateParm:
case Decl::TemplateTemplateParm:
case Decl::Using:
case Decl::UsingShadow:
case Decl::ObjCMethod:
case Decl::ObjCCategory:
case Decl::ObjCCategoryImpl:
case Decl::ObjCImplementation:
case Decl::ObjCProperty:
case Decl::ObjCCompatibleAlias:
case Decl::LinkageSpec:
case Decl::ObjCPropertyImpl:
case Decl::FileScopeAsm:
case Decl::AccessSpec:
case Decl::Friend:
case Decl::FriendTemplate:
case Decl::StaticAssert:
case Decl::Block:
case Decl::ClassScopeFunctionSpecialization:
case Decl::Import:
return false;
}
llvm_unreachable("Unhandled declaration kind");
}

Просмотреть файл

@ -70,6 +70,9 @@ unsigned ComputeHash(Selector Sel);
/// multiple definitions.
const Decl *getDefinitiveDeclContext(const DeclContext *DC);
/// \brief Determine whether the given declaration kind is redeclarable.
bool isRedeclarableDeclKind(unsigned Kind);
} // namespace serialization
} // namespace clang

Просмотреть файл

@ -116,29 +116,25 @@ namespace clang {
ASTReader &Reader;
GlobalDeclID FirstID;
mutable bool Owning;
Decl::Kind DeclKind;
void operator=(RedeclarableResult &) LLVM_DELETED_FUNCTION;
public:
RedeclarableResult(ASTReader &Reader, GlobalDeclID FirstID)
: Reader(Reader), FirstID(FirstID), Owning(true) { }
RedeclarableResult(ASTReader &Reader, GlobalDeclID FirstID,
Decl::Kind DeclKind)
: Reader(Reader), FirstID(FirstID), Owning(true), DeclKind(DeclKind) { }
RedeclarableResult(const RedeclarableResult &Other)
: Reader(Other.Reader), FirstID(Other.FirstID), Owning(Other.Owning)
: Reader(Other.Reader), FirstID(Other.FirstID), Owning(Other.Owning) ,
DeclKind(Other.DeclKind)
{
Other.Owning = false;
}
~RedeclarableResult() {
// FIXME: We want to suppress this when the declaration is local to
// a function, since there's no reason to search other AST files
// for redeclarations (they can't exist). However, this is hard to
// do locally because the declaration hasn't necessarily loaded its
// declaration context yet. Also, local externs still have the function
// as their (semantic) declaration context, which is wrong and would
// break this optimize.
if (FirstID && Owning && Reader.PendingDeclChainsKnown.insert(FirstID))
if (FirstID && Owning && isRedeclarableDeclKind(DeclKind) &&
Reader.PendingDeclChainsKnown.insert(FirstID))
Reader.PendingDeclChains.push_back(FirstID);
}
@ -151,7 +147,7 @@ namespace clang {
Owning = false;
}
};
/// \brief Class used to capture the result of searching for an existing
/// declaration of a specific kind and name, along with the ability
/// to update the place where this result was found (the declaration
@ -1562,7 +1558,8 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
// The result structure takes care to note that we need to load the
// other declaration chains for this ID.
return RedeclarableResult(Reader, FirstDeclID);
return RedeclarableResult(Reader, FirstDeclID,
static_cast<T *>(D)->getKind());
}
/// \brief Attempts to merge the given declaration (D) with another declaration

Просмотреть файл

@ -1277,7 +1277,10 @@ template <typename T>
void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
T *First = D->getFirstDeclaration();
if (First->getMostRecentDecl() != First) {
// There is more than one declaration of this entity, so we will need to
assert(isRedeclarableDeclKind(static_cast<T *>(D)->getKind()) &&
"Not considered redeclarable?");
// There is more than one declaration of this entity, so we will need to
// write a redeclaration chain.
Writer.AddDeclRef(First, Record);
Writer.Redeclarations.insert(First);