summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-01-05 22:27:05 +0000
committerDouglas Gregor <dgregor@apple.com>2012-01-05 22:27:05 +0000
commit64af53c364bcc20d18210432dbaa6d94186858ff (patch)
tree2c03835cca08077dd592fc50b0849a5042be05ca /clang
parentf740db31e20e18c02ef29e02f1a61900f2be8403 (diff)
downloadbcm5719-llvm-64af53c364bcc20d18210432dbaa6d94186858ff.tar.gz
bcm5719-llvm-64af53c364bcc20d18210432dbaa6d94186858ff.zip
When we deserialize a declaration from a module file, allocate extra
storage for the global declaration ID. Declarations that are parsed (rather than deserialized) are unaffected, so the number of declarations that pay this cost tends to be relatively small (since relatively few declarations are ever deserialized). This replaces a largish DenseMap within the AST reader. It's not strictly a win in terms of memory use---not every declaration was added to that DenseMap in the first place---but it's cleaner to have this information available for every deserialized declaration, so that future clients can rely on it. llvm-svn: 147617
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/DeclBase.h8
-rw-r--r--clang/include/clang/Serialization/ASTReader.h7
-rw-r--r--clang/lib/AST/DeclBase.cpp15
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp20
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp2
5 files changed, 24 insertions, 28 deletions
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index 12f37e53e98..09e1fdcd63a 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -532,6 +532,14 @@ public:
/// a precompiled header or module) rather than having been parsed.
bool isFromASTFile() const { return FromASTFile; }
+ /// \brief Retrieve the global declaration ID associated with this
+ /// declaration, which specifies where in the
+ unsigned getGlobalID() const {
+ if (isFromASTFile())
+ return *((const unsigned*)this - 1);
+ return 0;
+ }
+
unsigned getIdentifierNamespace() const {
return IdentifierNamespace;
}
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index f808b962e11..4a704d0c35c 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -675,13 +675,6 @@ private:
/// \brief Keeps track of the elements added to PendingDeclChains.
llvm::SmallSet<serialization::DeclID, 16> PendingDeclChainsKnown;
- /// \brief Reverse mapping from declarations to their global declaration IDs.
- ///
- /// FIXME: This data structure is currently only used for ObjCInterfaceDecls
- /// and ObjCProtocolDecls to support declaration merging. If we must have
- /// this for other declarations, allocate it along with the Decl itself.
- llvm::DenseMap<Decl *, serialization::GlobalDeclID> DeclToID;
-
typedef llvm::DenseMap<Decl *, llvm::SmallVector<serialization::DeclID, 2> >
MergedDeclsMap;
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 55484188c86..f4e5d43ee6c 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -44,7 +44,20 @@ static bool StatSwitch = false;
void *Decl::AllocateDeserializedDecl(const ASTContext &Context,
unsigned ID,
unsigned Size) {
- return Context.Allocate(Size);
+ // Allocate an extra pointer's worth of storage, which ensures that
+ // (1) We have enough storage to stash the global declaration ID, and
+ // (2) We maintain pointer alignment.
+ //
+ // Note that this wastes 4 bytes on x86-64, which we'll undoubtedly end up
+ // finding a use for later.
+ void *Start = Context.Allocate(Size + sizeof(void*));
+ void *Result = (char*)Start + sizeof(void*);
+
+ // Store the global declaration ID
+ unsigned *IDPtr = (unsigned*)Result - 1;
+ *IDPtr = ID;
+
+ return Result;
}
const char *Decl::getDeclKindName() const {
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index cff8667f4b5..0672129f1e8 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -402,9 +402,6 @@ void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) {
}
void ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) {
- // Record the declaration -> global ID mapping.
- Reader.DeclToID[TD] = ThisDeclID;
-
RedeclarableResult Redecl = VisitRedeclarable(TD);
VisitTypeDecl(TD);
@@ -421,9 +418,6 @@ void ASTDeclReader::VisitTypeAliasDecl(TypeAliasDecl *TD) {
}
void ASTDeclReader::VisitTagDecl(TagDecl *TD) {
- // Record the declaration -> global ID mapping.
- Reader.DeclToID[TD] = ThisDeclID;
-
RedeclarableResult Redecl = VisitRedeclarable(TD);
VisitTypeDecl(TD);
@@ -490,9 +484,6 @@ void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) {
}
void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
- // Record the declaration -> global ID mapping.
- Reader.DeclToID[FD] = ThisDeclID;
-
RedeclarableResult Redecl = VisitRedeclarable(FD);
VisitDeclaratorDecl(FD);
@@ -673,9 +664,6 @@ void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
}
void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
- // Record the declaration -> global ID mapping.
- Reader.DeclToID[ID] = ThisDeclID;
-
RedeclarableResult Redecl = VisitRedeclarable(ID);
VisitObjCContainerDecl(ID);
TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]);
@@ -746,9 +734,6 @@ void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {
}
void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
- // Record the declaration -> global ID mapping.
- Reader.DeclToID[PD] = ThisDeclID;
-
RedeclarableResult Redecl = VisitRedeclarable(PD);
VisitObjCContainerDecl(PD);
mergeRedeclarable(PD, Redecl);
@@ -880,9 +865,6 @@ void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) {
}
void ASTDeclReader::VisitVarDecl(VarDecl *VD) {
- // Record the declaration -> global ID mapping.
- Reader.DeclToID[VD] = ThisDeclID;
-
RedeclarableResult Redecl = VisitRedeclarable(VD);
VisitDeclaratorDecl(VD);
@@ -1561,7 +1543,7 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *D,
// Introduce ExistingCanon into the set of pending declaration chains,
// if in fact it came from a module file.
if (ExistingCanon->isFromASTFile()) {
- GlobalDeclID ExistingCanonID = Reader.DeclToID[ExistingCanon];
+ GlobalDeclID ExistingCanonID = ExistingCanon->getGlobalID();
assert(ExistingCanonID && "Unrecorded canonical declaration ID?");
if (Reader.PendingDeclChainsKnown.insert(ExistingCanonID))
Reader.PendingDeclChains.push_back(ExistingCanonID);
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 1317525c27d..52578599ea9 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -2914,7 +2914,7 @@ void ASTWriter::WriteMergedDecls() {
for (ASTReader::MergedDeclsMap::iterator I = Chain->MergedDecls.begin(),
IEnd = Chain->MergedDecls.end();
I != IEnd; ++I) {
- DeclID CanonID = I->first->isFromASTFile()? Chain->DeclToID[I->first]
+ DeclID CanonID = I->first->isFromASTFile()? I->first->getGlobalID()
: getDeclID(I->first);
assert(CanonID && "Merged declaration not known?");
OpenPOWER on IntegriCloud