llvm-project/clang/lib/Serialization/TemplateArgumentHasher.h
Chuanqi Xu 20e9049509
[Serialization] Support loading template specializations lazily (#119333)
Reland https://github.com/llvm/llvm-project/pull/83237

---

(Original comments)

Currently all the specializations of a template (including
instantiation, specialization and partial specializations) will be
loaded at once if we want to instantiate another instance for the
template, or find instantiation for the template, or just want to
complete the redecl chain.

This means basically we need to load every specializations for the
template once the template declaration got loaded. This is bad since
when we load a specialization, we need to load all of its template
arguments. Then we have to deserialize a lot of unnecessary
declarations.

For example,

```
// M.cppm
export module M;
export template <class T>
class A {};

export class ShouldNotBeLoaded {};

export class Temp {
   A<ShouldNotBeLoaded> AS;
};

// use.cpp
import M;
A<int> a;
```

We have a specialization ` A<ShouldNotBeLoaded>` in `M.cppm` and we
instantiate the template `A` in `use.cpp`. Then we will deserialize
`ShouldNotBeLoaded` surprisingly when compiling `use.cpp`. And this
patch tries to avoid that.

Given that the templates are heavily used in C++, this is a pain point
for the performance.

This patch adds MultiOnDiskHashTable for specializations in the
ASTReader. Then we will only deserialize the specializations with the
same template arguments. We made that by using ODRHash for the template
arguments as the key of the hash table.

To review this patch, I think `ASTReaderDecl::AddLazySpecializations`
may be a good entry point.
2024-12-11 09:40:47 +08:00

35 lines
1.7 KiB
C++

//===- TemplateArgumentHasher.h - Hash Template Arguments -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "clang/AST/TemplateBase.h"
namespace clang {
namespace serialization {
/// Calculate a stable hash value for template arguments. We guarantee that
/// the same template arguments must have the same hashed values. But we don't
/// guarantee that the template arguments with the same hashed value are the
/// same template arguments.
///
/// ODR hashing may not be the best mechanism to hash the template
/// arguments. ODR hashing is (or perhaps, should be) about determining whether
/// two things are spelled the same way and have the same meaning (as required
/// by the C++ ODR), whereas what we want here is whether they have the same
/// meaning regardless of spelling. Maybe we can get away with reusing ODR
/// hashing anyway, on the basis that any canonical, non-dependent template
/// argument should have the same (invented) spelling in every translation
/// unit, but it is not sure that's true in all cases. There may still be cases
/// where the canonical type includes some aspect of "whatever we saw first",
/// in which case the ODR hash can differ across translation units for
/// non-dependent, canonical template arguments that are spelled differently
/// but have the same meaning. But it is not easy to raise examples.
unsigned StableHashForTemplateArguments(llvm::ArrayRef<TemplateArgument> Args);
} // namespace serialization
} // namespace clang