Skip to content

Commit d3744bd

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 19e6fd0 commit d3744bd

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
@@ -29,6 +29,16 @@ struct IndexRecordHasher {
2929
llvm::HashBuilder<llvm::TruncatedBLAKE3<8>, llvm::endianness::little>
3030
HashBuilder;
3131

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

3444
void hashDecl(const Decl *D);
@@ -185,6 +195,19 @@ void IndexRecordHasher::hashMacro(const IdentifierInfo *name,
185195
void IndexRecordHasher::hashDecl(const Decl *D) {
186196
assert(D->isCanonicalDecl());
187197

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

0 commit comments

Comments
 (0)