[cfe-commits] r173050 - in /cfe/trunk: include/clang/Serialization/ASTReader.h lib/Serialization/ASTCommon.cpp lib/Serialization/ASTCommon.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp
Douglas Gregor
dgregor at apple.com
Mon Jan 21 07:25:38 PST 2013
Author: dgregor
Date: Mon Jan 21 09:25:38 2013
New Revision: 173050
URL: http://llvm.org/viewvc/llvm-project?rev=173050&view=rev
Log:
Introduce a fast path for the ASTReader's name lookup within a
DeclContext. When the DeclContext is of a kind that can only be
defined once and never updated, we limit the search to the module file
that conatins the lookup table. Provides a 15% speedup in one
modules-heavy source file.
Modified:
cfe/trunk/include/clang/Serialization/ASTReader.h
cfe/trunk/lib/Serialization/ASTCommon.cpp
cfe/trunk/lib/Serialization/ASTCommon.h
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=173050&r1=173049&r2=173050&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Mon Jan 21 09:25:38 2013
@@ -1311,7 +1311,7 @@
/// \brief Retrieve the module file that owns the given declaration, or NULL
/// if the declaration is not from a module file.
- ModuleFile *getOwningModuleFile(Decl *D);
+ ModuleFile *getOwningModuleFile(const Decl *D);
/// \brief Returns the source location for the decl \p ID.
SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID);
Modified: cfe/trunk/lib/Serialization/ASTCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.cpp?rev=173050&r1=173049&r2=173050&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTCommon.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTCommon.cpp Mon Jan 21 09:25:38 2013
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "ASTCommon.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Serialization/ASTDeserializationListener.h"
#include "llvm/ADT/StringExtras.h"
@@ -85,3 +86,60 @@
R = llvm::HashString(II->getName(), R);
return R;
}
+
+const Decl *serialization::getDefinitiveDeclContext(const DeclContext *DC) {
+ switch (DC->getDeclKind()) {
+ // These entities may have multiple definitions.
+ case Decl::TranslationUnit:
+ case Decl::Namespace:
+ case Decl::LinkageSpec:
+ return 0;
+
+ // C/C++ tag types can only be defined in one place.
+ case Decl::Enum:
+ case Decl::Record:
+ if (const TagDecl *Def = cast<TagDecl>(DC)->getDefinition())
+ return Def;
+ break;
+
+ // FIXME: These can be defined in one place... except special member
+ // functions and out-of-line definitions.
+ case Decl::CXXRecord:
+ case Decl::ClassTemplateSpecialization:
+ case Decl::ClassTemplatePartialSpecialization:
+ return 0;
+
+ // Each function, method, and block declaration is its own DeclContext.
+ case Decl::Function:
+ case Decl::CXXMethod:
+ case Decl::CXXConstructor:
+ case Decl::CXXDestructor:
+ case Decl::CXXConversion:
+ case Decl::ObjCMethod:
+ case Decl::Block:
+ // Objective C categories, category implementations, and class
+ // implementations can only be defined in one place.
+ case Decl::ObjCCategory:
+ case Decl::ObjCCategoryImpl:
+ case Decl::ObjCImplementation:
+ return cast<Decl>(DC);
+
+ case Decl::ObjCProtocol:
+ if (const ObjCProtocolDecl *Def
+ = cast<ObjCProtocolDecl>(DC)->getDefinition())
+ return Def;
+ break;
+
+ // FIXME: These are defined in one place, but properties in class extensions
+ // end up being back-patched into the main interface. See
+ // Sema::HandlePropertyInClassExtension for the offending code.
+ case Decl::ObjCInterface:
+ break;
+
+ default:
+ llvm_unreachable("Unhandled DeclContext in AST reader");
+ }
+
+ return 0;
+
+}
Modified: cfe/trunk/lib/Serialization/ASTCommon.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.h?rev=173050&r1=173049&r2=173050&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTCommon.h (original)
+++ cfe/trunk/lib/Serialization/ASTCommon.h Mon Jan 21 09:25:38 2013
@@ -58,6 +58,18 @@
unsigned ComputeHash(Selector Sel);
+/// \brief Retrieve the "definitive" declaration that provides all of the
+/// visible entries for the given declaration context, if there is one.
+///
+/// The "definitive" declaration is the only place where we need to look to
+/// find information about the declarations within the given declaration
+/// context. For example, C++ and Objective-C classes, C structs/unions, and
+/// Objective-C protocols, categories, and extensions are all defined in a
+/// single place in the source code, so they have definitive declarations
+/// associated with them. C++ namespaces, on the other hand, can have
+/// multiple definitions.
+const Decl *getDefinitiveDeclContext(const DeclContext *DC);
+
} // namespace serialization
} // namespace clang
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=173050&r1=173049&r2=173050&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Jan 21 09:25:38 2013
@@ -4971,7 +4971,7 @@
return &M == I->second;
}
-ModuleFile *ASTReader::getOwningModuleFile(Decl *D) {
+ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) {
if (!D->isFromASTFile())
return 0;
GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(D->getGlobalID());
@@ -5307,6 +5307,27 @@
};
}
+/// \brief Retrieve the "definitive" module file for the definition of the
+/// given declaration context, if there is one.
+///
+/// The "definitive" module file is the only place where we need to look to
+/// find information about the declarations within the given declaration
+/// context. For example, C++ and Objective-C classes, C structs/unions, and
+/// Objective-C protocols, categories, and extensions are all defined in a
+/// single place in the source code, so they have definitive module files
+/// associated with them. C++ namespaces, on the other hand, can have
+/// definitions in multiple different module files.
+///
+/// Note: this needs to be kept in sync with ASTWriter::AddedVisibleDecl's
+/// NDEBUG checking.
+static ModuleFile *getDefinitiveModuleFileFor(const DeclContext *DC,
+ ASTReader &Reader) {
+ if (const Decl *D = getDefinitiveDeclContext(DC))
+ return Reader.getOwningModuleFile(D);
+
+ return 0;
+}
+
DeclContext::lookup_result
ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) {
@@ -5335,7 +5356,16 @@
}
DeclContextNameLookupVisitor Visitor(*this, Contexts, Name, Decls);
- ModuleMgr.visit(&DeclContextNameLookupVisitor::visit, &Visitor);
+
+ // If we can definitively determine which module file to look into,
+ // only look there. Otherwise, look in all module files.
+ ModuleFile *Definitive;
+ if (Contexts.size() == 1 &&
+ (Definitive = getDefinitiveModuleFileFor(DC, *this))) {
+ DeclContextNameLookupVisitor::visit(*Definitive, &Visitor);
+ } else {
+ ModuleMgr.visit(&DeclContextNameLookupVisitor::visit, &Visitor);
+ }
++NumVisibleDeclContextsRead;
SetExternalVisibleDeclsForName(DC, Name, Decls);
return const_cast<DeclContext*>(DC)->lookup(Name);
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=173050&r1=173049&r2=173050&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Jan 21 09:25:38 2013
@@ -4780,6 +4780,7 @@
if (!(!D->isFromASTFile() && cast<Decl>(DC)->isFromASTFile()))
return; // Not a source decl added to a DeclContext from PCH.
+ assert(!getDefinitiveDeclContext(DC) && "DeclContext not definitive!");
AddUpdatedDeclContext(DC);
UpdatingVisibleDecls.push_back(D);
}
More information about the cfe-commits
mailing list