Skip to content

Commit 81127b7

Browse files
committed
[Index] Only hash Decl once when generating the hash value for a record
Say we are indexing the header file containing `NSArray`. Almost every declaration in here has a relation to `NSArray` (mostly child-of relations). This means that for every of those declarations we hash `NSArray` again by creating a `DeclHashVisitor` that, among others, adds the string `NSArray` to the hash builder. To avoid this, keep track of all the declarations that we have already incorporated into the hash. If we did already hash the declaration, only incorporate an integer into the hash.
1 parent 9db20e6 commit 81127b7

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

clang/lib/Index/IndexRecordHasher.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ struct IndexRecordHasher {
2828
llvm::HashBuilder<llvm::TruncatedBLAKE3<8>, llvm::endianness::little>
2929
HashBuilder;
3030

31+
/// Maps declarations that have already been hashed in this
32+
/// `IndexRecordHasher` to a unique ID that identifies this declaration.
33+
///
34+
/// The ID assigned to a declaration is consistent across multiple runs of the
35+
/// `IndexRecordHasher` on the same AST structure, even across multiple
36+
/// process runs.
37+
///
38+
/// See `hashDecl` for its use.
39+
llvm::DenseMap<const Decl *, size_t> HashedDecls;
40+
3141
explicit IndexRecordHasher(ASTContext &context) : Ctx(context) {}
3242

3343
void hashDecl(const Decl *D);
@@ -184,6 +194,19 @@ void IndexRecordHasher::hashMacro(const IdentifierInfo *name,
184194
void IndexRecordHasher::hashDecl(const Decl *D) {
185195
assert(D->isCanonicalDecl());
186196

197+
auto emplaceResult = HashedDecls.try_emplace(D, HashedDecls.size());
198+
bool inserted = emplaceResult.second;
199+
if (!inserted) {
200+
// If we have already serialized this declaration, just add the
201+
// declaration's hash to the hash builder. This is significantly
202+
// cheaper than visiting the declaration again.
203+
HashBuilder.add(emplaceResult.first->second);
204+
return;
205+
}
206+
207+
// If we haven't serialized the declaration yet,`try_emplace` will insert the
208+
// new unique ID into `HashedDecls`. We just need to hash the declaration
209+
// once.
187210
if (auto *NS = dyn_cast<NamespaceDecl>(D)) {
188211
if (NS->isAnonymousNamespace()) {
189212
HashBuilder.add("@aN");

0 commit comments

Comments
 (0)