summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTReaderDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2015-07-12 23:43:21 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2015-07-12 23:43:21 +0000
commit5fc18a9a1f8930dbf44b2c1b8f53e14f3142659c (patch)
treeadcee4ad93be7bb63dbdfc7b34c4fdd6d220e36e /clang/lib/Serialization/ASTReaderDecl.cpp
parenta2275910a75457abacf024c9baf9f250b86439ed (diff)
downloadbcm5719-llvm-5fc18a9a1f8930dbf44b2c1b8f53e14f3142659c.tar.gz
bcm5719-llvm-5fc18a9a1f8930dbf44b2c1b8f53e14f3142659c.zip
[modules] Improve performance when there is a local declaration of an entity
before the first imported declaration. We don't need to track all formerly-canonical declarations of an entity; it's sufficient to track those ones for which no other formerly-canonical declaration was imported into the same module. We call those ones "key declarations", and use them as our starting points for collecting redeclarations and performing namespace lookups. llvm-svn: 241999
Diffstat (limited to 'clang/lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp44
1 files changed, 27 insertions, 17 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 52019fcd328..0c59ba83706 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -128,20 +128,22 @@ namespace clang {
GlobalDeclID FirstID;
Decl *MergeWith;
mutable bool Owning;
+ bool IsKeyDecl;
Decl::Kind DeclKind;
void operator=(RedeclarableResult &) = delete;
public:
RedeclarableResult(ASTReader &Reader, GlobalDeclID FirstID,
- Decl *MergeWith, Decl::Kind DeclKind)
+ Decl *MergeWith, Decl::Kind DeclKind,
+ bool IsKeyDecl)
: Reader(Reader), FirstID(FirstID), MergeWith(MergeWith),
- Owning(true), DeclKind(DeclKind) {}
+ Owning(true), IsKeyDecl(IsKeyDecl), DeclKind(DeclKind) {}
RedeclarableResult(RedeclarableResult &&Other)
: Reader(Other.Reader), FirstID(Other.FirstID),
MergeWith(Other.MergeWith), Owning(Other.Owning),
- DeclKind(Other.DeclKind) {
+ IsKeyDecl(Other.IsKeyDecl), DeclKind(Other.DeclKind) {
Other.Owning = false;
}
@@ -156,6 +158,9 @@ namespace clang {
/// \brief Retrieve the first ID.
GlobalDeclID getFirstID() const { return FirstID; }
+ /// \brief Is this declaration the key declaration?
+ bool isKeyDecl() const { return IsKeyDecl; }
+
/// \brief Get a known declaration that this should be merged with, if
/// any.
Decl *getKnownMergeTarget() const { return MergeWith; }
@@ -348,7 +353,7 @@ namespace clang {
void mergeTemplatePattern(RedeclarableTemplateDecl *D,
RedeclarableTemplateDecl *Existing,
- DeclID DsID);
+ DeclID DsID, bool IsKeyDecl);
ObjCTypeParamList *ReadObjCTypeParamList();
@@ -2173,12 +2178,16 @@ ASTDeclReader::RedeclarableResult
ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
DeclID FirstDeclID = ReadDeclID(Record, Idx);
Decl *MergeWith = nullptr;
+ bool IsKeyDecl = ThisDeclID == FirstDeclID;
// 0 indicates that this declaration was the only declaration of its entity,
// and is used for space optimization.
- if (FirstDeclID == 0)
+ if (FirstDeclID == 0) {
FirstDeclID = ThisDeclID;
- else if (unsigned N = Record[Idx++]) {
+ IsKeyDecl = true;
+ } else if (unsigned N = Record[Idx++]) {
+ IsKeyDecl = false;
+
// We have some declarations that must be before us in our redeclaration
// chain. Read them now, and remember that we ought to merge with one of
// them.
@@ -2204,7 +2213,7 @@ 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, MergeWith,
- static_cast<T *>(D)->getKind());
+ static_cast<T *>(D)->getKind(), IsKeyDecl);
}
/// \brief Attempts to merge the given declaration (D) with another declaration
@@ -2243,11 +2252,12 @@ template<typename T> static T assert_cast(...) {
/// declarations.
void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D,
RedeclarableTemplateDecl *Existing,
- DeclID DsID) {
+ DeclID DsID, bool IsKeyDecl) {
auto *DPattern = D->getTemplatedDecl();
auto *ExistingPattern = Existing->getTemplatedDecl();
RedeclarableResult Result(Reader, DPattern->getCanonicalDecl()->getGlobalID(),
- /*MergeWith*/ExistingPattern, DPattern->getKind());
+ /*MergeWith*/ExistingPattern, DPattern->getKind(),
+ IsKeyDecl);
if (auto *DClass = dyn_cast<CXXRecordDecl>(DPattern)) {
// Merge with any existing definition.
@@ -2310,11 +2320,11 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing,
if (auto *DTemplate = dyn_cast<RedeclarableTemplateDecl>(D))
mergeTemplatePattern(
DTemplate, assert_cast<RedeclarableTemplateDecl*>(ExistingCanon),
- TemplatePatternID);
+ TemplatePatternID, Redecl.isKeyDecl());
- // If this declaration was the canonical declaration, make a note of that.
- if (DCanon == D) {
- Reader.MergedDecls[ExistingCanon].push_back(Redecl.getFirstID());
+ // If this declaration is a key declaration, make a note of that.
+ if (Redecl.isKeyDecl()) {
+ Reader.KeyDecls[ExistingCanon].push_back(Redecl.getFirstID());
if (Reader.PendingDeclChainsKnown.insert(ExistingCanon).second)
Reader.PendingDeclChains.push_back(ExistingCanon);
}
@@ -3468,7 +3478,7 @@ namespace {
return;
}
-
+
// Dig out all of the redeclarations.
unsigned Offset = Result->Offset;
unsigned N = M.RedeclarationChains[Offset];
@@ -3531,9 +3541,9 @@ void ASTReader::loadPendingDeclChain(Decl *CanonDecl) {
GlobalDeclID CanonID = CanonDecl->getGlobalID();
if (CanonID)
SearchDecls.push_back(CanonDecl->getGlobalID()); // Always first.
- MergedDeclsMap::iterator MergedPos = MergedDecls.find(CanonDecl);
- if (MergedPos != MergedDecls.end())
- SearchDecls.append(MergedPos->second.begin(), MergedPos->second.end());
+ KeyDeclsMap::iterator KeyPos = KeyDecls.find(CanonDecl);
+ if (KeyPos != KeyDecls.end())
+ SearchDecls.append(KeyPos->second.begin(), KeyPos->second.end());
// Build up the list of redeclarations.
RedeclChainVisitor Visitor(*this, SearchDecls, RedeclsDeserialized, CanonID);
OpenPOWER on IntegriCloud