[clang] [Clang] Avoid quadratic pack-indexing instantiation (store only the selected element) (PR #213790)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 5 02:31:06 PDT 2026
================
@@ -7121,6 +7127,56 @@ TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
if (Types.empty() && !PIT->expandsToEmptyPack())
Types = llvm::ArrayRef<QualType>(&Pattern, 1);
+ // Fast path: substitute only the selected element instead of all N. A
+ // pack-indexing type inside a pack expansion (`T...[Is]...`) is transformed
+ // once per outer element, so substituting the whole pack each time is
+ // O(N^2) in time and memory.
+ if (Types.size() == 1 && Types[0]->containsUnexpandedParameterPack() &&
+ IndexExpr.isUsable() && !IndexExpr.get()->isInstantiationDependent()) {
+ QualType T = Types[0];
+ SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+ getSema().collectUnexpandedParameterPacks(T, Unexpanded);
+ bool ShouldExpand = true, RetainExpansion = false;
+ UnsignedOrNone NumExpansions = std::nullopt;
+ if (getDerived().TryExpandParameterPacks(
+ TL.getEllipsisLoc(), SourceRange(), Unexpanded,
+ /*FailOnPackProducingTemplates=*/true, ShouldExpand, RetainExpansion,
+ NumExpansions))
+ return QualType();
+ if (ShouldExpand && !RetainExpansion) {
+ llvm::APSInt Value;
+ ExprResult CCE = SemaRef.CheckConvertedConstantExpression(
+ IndexExpr.get(), SemaRef.Context.getSizeType(), Value,
+ CCEKind::PackIndex);
+ if (!CCE.isUsable() || !Value.isRepresentableByInt64())
+ return QualType();
+ uint64_t V = Value.getZExtValue();
----------------
zyn0217 wrote:
This is funny: if you look at PackIndexingType::getSelectedIndex(), it suggests that when IndexExpr is not instantiation dependent, the IndexExpr must be a ConstantExpr where you can fetch the value directly, without doing the constant evaluation dance.
Again I wonder if this is written by AI. I wish I'm not talking this PR with any of your agent.
https://github.com/llvm/llvm-project/pull/213790
More information about the cfe-commits
mailing list