aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTWriter.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-08-20 16:04:35 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-08-20 16:04:35 +0000
commit074dcc8ef8c5df7a155c85648e8eae786bee6cab (patch)
tree5c863db01bce5193d1e028a91032e95f2b30e9fa /lib/Serialization/ASTWriter.cpp
parent5d26768e2661faa7ce0b55ffff4be8b3969fbbf5 (diff)
Use the AST on-disk hash table for name lookup inside a DeclContext.
*Huge* improvement over the amount of deserializing that we do for C++ lookup. e.g, if he have the Carbon header precompiled and include it on a file containing this: int x; these are the before/after stats: BEFORE: *** AST File Statistics: 578 stat cache hits 4 stat cache misses 548/30654 source location entries read (1.787695%) 15907/16501 types read (96.400223%) 53525/59955 declarations read (89.275291%) 33993/43525 identifiers read (78.099945%) 41516/51891 statements read (80.006165%) 77/5317 macros read (1.448185%) 0/6335 lexical declcontexts read (0.000000%) 1/5424 visible declcontexts read (0.018437%) AFTER using the on-disk table: *** AST File Statistics: 578 stat cache hits 4 stat cache misses 548/30654 source location entries read (1.787695%) 10/16501 types read (0.060602%) 9/59955 declarations read (0.015011%) 161/43525 identifiers read (0.369902%) 20/51891 statements read (0.038542%) 6/5317 macros read (0.112846%) 0/6335 lexical declcontexts read (0.000000%) 2/5424 visible declcontexts read (0.036873%) There's only one issue affecting mostly the precompiled preambles which I will address soon. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111636 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTWriter.cpp')
-rw-r--r--lib/Serialization/ASTWriter.cpp121
1 files changed, 68 insertions, 53 deletions
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 94be24ad2c..5deaf3d475 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -1466,59 +1466,6 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
return Offset;
}
-/// \brief Write the block containing all of the declaration IDs
-/// visible from the given DeclContext.
-///
-/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
-/// bistream, or 0 if no block was written.
-uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
- DeclContext *DC) {
- if (DC->getPrimaryContext() != DC)
- return 0;
-
- // Since there is no name lookup into functions or methods, don't bother to
- // build a visible-declarations table for these entities.
- if (DC->isFunctionOrMethod())
- return 0;
-
- // If not in C++, we perform name lookup for the translation unit via the
- // IdentifierInfo chains, don't bother to build a visible-declarations table.
- // FIXME: In C++ we need the visible declarations in order to "see" the
- // friend declarations, is there a way to do this without writing the table ?
- if (DC->isTranslationUnit() && !Context.getLangOptions().CPlusPlus)
- return 0;
-
- // Force the DeclContext to build a its name-lookup table.
- DC->lookup(DeclarationName());
-
- // Serialize the contents of the mapping used for lookup. Note that,
- // although we have two very different code paths, the serialized
- // representation is the same for both cases: a declaration name,
- // followed by a size, followed by references to the visible
- // declarations that have that name.
- uint64_t Offset = Stream.GetCurrentBitNo();
- RecordData Record;
- StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
- if (!Map)
- return 0;
-
- for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
- D != DEnd; ++D) {
- AddDeclarationName(D->first, Record);
- DeclContext::lookup_result Result = D->second.getLookupResult(Context);
- Record.push_back(Result.second - Result.first);
- for (; Result.first != Result.second; ++Result.first)
- AddDeclRef(*Result.first, Record);
- }
-
- if (Record.size() == 0)
- return 0;
-
- Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record);
- ++NumVisibleDeclContexts;
- return Offset;
-}
-
void ASTWriter::WriteTypeDeclOffsets() {
using namespace llvm;
RecordData Record;
@@ -2062,6 +2009,74 @@ public:
};
} // end anonymous namespace
+/// \brief Write the block containing all of the declaration IDs
+/// visible from the given DeclContext.
+///
+/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
+/// bistream, or 0 if no block was written.
+uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
+ DeclContext *DC) {
+ if (DC->getPrimaryContext() != DC)
+ return 0;
+
+ // Since there is no name lookup into functions or methods, don't bother to
+ // build a visible-declarations table for these entities.
+ if (DC->isFunctionOrMethod())
+ return 0;
+
+ // If not in C++, we perform name lookup for the translation unit via the
+ // IdentifierInfo chains, don't bother to build a visible-declarations table.
+ // FIXME: In C++ we need the visible declarations in order to "see" the
+ // friend declarations, is there a way to do this without writing the table ?
+ if (DC->isTranslationUnit() && !Context.getLangOptions().CPlusPlus)
+ return 0;
+
+ // Force the DeclContext to build a its name-lookup table.
+ DC->lookup(DeclarationName());
+
+ // Serialize the contents of the mapping used for lookup. Note that,
+ // although we have two very different code paths, the serialized
+ // representation is the same for both cases: a declaration name,
+ // followed by a size, followed by references to the visible
+ // declarations that have that name.
+ uint64_t Offset = Stream.GetCurrentBitNo();
+ StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
+ if (!Map || Map->empty())
+ return 0;
+
+ OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator;
+ ASTDeclContextNameLookupTrait Trait(*this);
+
+ // Create the on-disk hash table representation.
+ for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
+ D != DEnd; ++D) {
+ DeclarationName Name = D->first;
+ DeclContext::lookup_result Result = D->second.getLookupResult();
+ Generator.insert(Name, Result, Trait);
+ }
+
+ // Create the on-disk hash table in a buffer.
+ llvm::SmallString<4096> LookupTable;
+ uint32_t BucketOffset;
+ {
+ llvm::raw_svector_ostream Out(LookupTable);
+ // Make sure that no bucket is at offset 0
+ clang::io::Emit32(Out, 0);
+ BucketOffset = Generator.Emit(Out, Trait);
+ }
+
+ // Write the lookup table
+ RecordData Record;
+ Record.push_back(DECL_CONTEXT_VISIBLE);
+ Record.push_back(BucketOffset);
+ Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record,
+ LookupTable.str());
+
+ Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record);
+ ++NumVisibleDeclContexts;
+ return Offset;
+}
+
//===----------------------------------------------------------------------===//
// General Serialization Routines
//===----------------------------------------------------------------------===//