summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTReaderDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2015-08-22 20:13:39 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2015-08-22 20:13:39 +0000
commitd61d4acd703630b62e29b2541574a1842b35d7f2 (patch)
tree5cc143367055d61ff90985ec1caadc920d130619 /clang/lib/Serialization/ASTReaderDecl.cpp
parentb17bb06914abe652c5aa30cb94382907f3f78962 (diff)
downloadbcm5719-llvm-d61d4acd703630b62e29b2541574a1842b35d7f2.tar.gz
bcm5719-llvm-d61d4acd703630b62e29b2541574a1842b35d7f2.zip
[modules] Further simplification and speedup of redeclaration chain loading.
Instead of eagerly deserializing a list of DeclIDs when we load a module file and doing a binary search to find the redeclarations of a decl, store a list of redeclarations of each chain before the first declaration and load it directly. llvm-svn: 245789
Diffstat (limited to 'clang/lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp69
1 files changed, 35 insertions, 34 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index f4f39a8506b..00785aa1d05 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2156,6 +2156,8 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
bool IsKeyDecl = ThisDeclID == FirstDeclID;
bool IsFirstLocalDecl = false;
+ uint64_t RedeclOffset = 0;
+
// 0 indicates that this declaration was the only declaration of its entity,
// and is used for space optimization.
if (FirstDeclID == 0) {
@@ -2175,6 +2177,8 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
// declaration.
for (unsigned I = 0; I != N - 1; ++I)
MergeWith = ReadDecl(Record, Idx/*, MergeWith*/);
+
+ RedeclOffset = Record[Idx++];
} else {
// This declaration was not the first local declaration. Read the first
// local declaration now, to trigger the import of other redeclarations.
@@ -2198,7 +2202,7 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
// above; this ensures that the redeclaration chain is built in the correct
// order.
if (IsFirstLocalDecl)
- Reader.PendingDeclChains.push_back(DAsT);
+ Reader.PendingDeclChains.push_back(std::make_pair(DAsT, RedeclOffset));
return RedeclarableResult(FirstDeclID, MergeWith, IsKeyDecl);
}
@@ -3393,43 +3397,40 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
}
}
-void ASTReader::loadPendingDeclChain(Decl *FirstLocal) {
- ModuleFile &M = *getOwningModuleFile(FirstLocal);
- DeclID LocalID =
- mapGlobalIDToModuleFileGlobalID(M, FirstLocal->getGlobalID());
- assert(LocalID && "looking for redecl chain in wrong module file");
-
- // Perform a binary search to find the local redeclarations for this
- // declaration (if any).
- // FIXME: Just store an offset with the first declaration.
- const LocalRedeclarationsInfo Compare = {LocalID, 0};
- const LocalRedeclarationsInfo *Result = std::lower_bound(
- M.RedeclarationsMap,
- M.RedeclarationsMap + M.LocalNumRedeclarationsInMap, Compare);
+void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) {
+ // Attach FirstLocal to the end of the decl chain.
+ Decl *CanonDecl = FirstLocal->getCanonicalDecl();
+ if (FirstLocal != CanonDecl) {
+ Decl *PrevMostRecent = ASTDeclReader::getMostRecentDecl(CanonDecl);
+ ASTDeclReader::attachPreviousDecl(
+ *this, FirstLocal, PrevMostRecent ? PrevMostRecent : CanonDecl,
+ CanonDecl);
+ }
- // Pull out the list of redeclarations.
- SmallVector<Decl*, 4> Chain;
- if (Result != M.RedeclarationsMap + M.LocalNumRedeclarationsInMap &&
- Result->FirstID == LocalID) {
- unsigned Offset = Result->Offset;
- unsigned N = M.RedeclarationChains[Offset++];
- for (unsigned I = 0; I != N; ++I)
- Chain.push_back(GetLocalDecl(M, M.RedeclarationChains[Offset++]));
+ if (!LocalOffset) {
+ ASTDeclReader::attachLatestDecl(CanonDecl, FirstLocal);
+ return;
}
- Chain.push_back(FirstLocal);
- // Hook up the chain.
- //
- // FIXME: We have three different dispatches on decl kind here; maybe
+ // Load the list of other redeclarations from this module file.
+ ModuleFile *M = getOwningModuleFile(FirstLocal);
+ assert(M && "imported decl from no module file");
+
+ llvm::BitstreamCursor &Cursor = M->DeclsCursor;
+ SavedStreamPosition SavedPosition(Cursor);
+ Cursor.JumpToBit(LocalOffset);
+
+ RecordData Record;
+ unsigned Code = Cursor.ReadCode();
+ unsigned RecCode = Cursor.readRecord(Code, Record);
+ (void)RecCode;
+ assert(RecCode == LOCAL_REDECLARATIONS && "expected LOCAL_REDECLARATIONS record!");
+
+ // FIXME: We have several different dispatches on decl kind here; maybe
// we should instead generate one loop per kind and dispatch up-front?
- Decl *CanonDecl = FirstLocal->getCanonicalDecl();
- Decl *MostRecent = ASTDeclReader::getMostRecentDecl(CanonDecl);
- if (!MostRecent)
- MostRecent = CanonDecl;
- for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
- auto *D = Chain[N - I - 1];
- if (D == CanonDecl)
- continue;
+ Decl *MostRecent = FirstLocal;
+ for (unsigned I = 0, N = Record.size(); I != N; ++I) {
+ auto *D = GetLocalDecl(*M, Record[N - I - 1]);
ASTDeclReader::attachPreviousDecl(*this, D, MostRecent, CanonDecl);
MostRecent = D;
}
OpenPOWER on IntegriCloud