================
@@ -1611,13 +1618,28 @@ namespace {
       }
       return Type;
     }
+
     // Override the default version to handle a rewrite-template-arg-pack case
     // for building a deduction guide.
     bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
                                    TemplateArgumentLoc &Output,
                                    bool Uneval = false) {
       const TemplateArgument &Arg = Input.getArgument();
       std::vector<TemplateArgument> TArgs;
+      if (auto *Cache = SemaRef.CurrentCachedTemplateArgs;
+          TemplateArgsHashValue && Cache) {
+        llvm::FoldingSetNodeID ID = *TemplateArgsHashValue;
+        ID.AddInteger(SemaRef.ArgPackSubstIndex.toInternalRepresentation());
+        Input.getArgument().Profile(ID, SemaRef.Context);
----------------
zyn0217 wrote:

To demonstrate how badly performance was impacted, consider this example (which 
is a very common pattern extracted from libc++):

```cpp
template <class Tp, class Up>
concept common_with = same_as<common_type<Tp, Up>, common_type<Up, Tp>> && 
requires { /*expressions that use Tp and Up many times*/} && 
common_reference_with<const Tp, const Up> && ...;
```

After normalization, Tp and Up are substituted with their corresponding 
template arguments within the resulting atomic expressions. So we end up 
substituting into the same Tp and Up parameters multiple times, whereas they 
technically only need to be substituted once. (The one-shot-substitution 
behavior was a natural result of the previous 
substitution-first-normalization-second approach)

Clang always struggles with avoiding template transforms, and I think this 
approach is our best effort so far to alleviate the issue without an overhaul 
of the template instantiation stuffs.

https://github.com/llvm/llvm-project/pull/188421
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to