From f6270bbcd543bd38cfa2e745a612c96c900eb32a Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Tue, 25 Mar 2025 11:59:46 +0100 Subject: [PATCH] [Serialization] Remove bail-out logic in TemplateArgumentHasher While it is correct to assign a single fixed hash to all template arguments, it can reduce the effectiveness of lazy loading and is not actually needed: we are allowed to ignore parts that cannot be handled because they will be analogously ignored by all hashings. Reviewed as part of https://github.com/llvm/llvm-project/pull/133057 --- .../Serialization/TemplateArgumentHasher.cpp | 36 ++----------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/clang/lib/Serialization/TemplateArgumentHasher.cpp b/clang/lib/Serialization/TemplateArgumentHasher.cpp index da2c70ca17b7..6b598d26c309 100644 --- a/clang/lib/Serialization/TemplateArgumentHasher.cpp +++ b/clang/lib/Serialization/TemplateArgumentHasher.cpp @@ -22,17 +22,6 @@ using namespace clang; namespace { class TemplateArgumentHasher { - // If we bail out during the process of calculating hash values for - // template arguments for any reason. We're allowed to do it since - // TemplateArgumentHasher are only required to give the same hash value - // for the same template arguments, but not required to give different - // hash value for different template arguments. - // - // So in the worst case, it is still a valid implementation to give all - // inputs the same BailedOutValue as output. - bool BailedOut = false; - static constexpr unsigned BailedOutValue = 0x12345678; - llvm::FoldingSetNodeID ID; public: @@ -42,14 +31,7 @@ public: void AddInteger(unsigned V) { ID.AddInteger(V); } - unsigned getValue() { - if (BailedOut) - return BailedOutValue; - - return ID.computeStableHash(); - } - - void setBailedOut() { BailedOut = true; } + unsigned getValue() { return ID.computeStableHash(); } void AddType(const Type *T); void AddQualType(QualType T); @@ -95,8 +77,7 @@ void TemplateArgumentHasher::AddTemplateArgument(TemplateArgument TA) { case TemplateArgument::Expression: // If we meet expression in template argument, it implies // that the template is still dependent. It is meaningless - // to get a stable hash for the template. Bail out simply. - BailedOut = true; + // to get a stable hash for the template. break; case TemplateArgument::Pack: AddInteger(TA.pack_size()); @@ -113,10 +94,9 @@ void TemplateArgumentHasher::AddStructuralValue(const APValue &Value) { // 'APValue::Profile' uses pointer values to make hash for LValue and // MemberPointer, but they differ from one compiler invocation to another. - // It may be difficult to handle such cases. Bail out simply. + // It may be difficult to handle such cases. if (Kind == APValue::LValue || Kind == APValue::MemberPointer) { - BailedOut = true; return; } @@ -138,14 +118,11 @@ void TemplateArgumentHasher::AddTemplateName(TemplateName Name) { case TemplateName::DependentTemplate: case TemplateName::SubstTemplateTemplateParm: case TemplateName::SubstTemplateTemplateParmPack: - BailedOut = true; break; case TemplateName::UsingTemplate: { UsingShadowDecl *USD = Name.getAsUsingShadowDecl(); if (USD) AddDecl(USD->getTargetDecl()); - else - BailedOut = true; break; } case TemplateName::DeducedTemplate: @@ -170,7 +147,6 @@ void TemplateArgumentHasher::AddDeclarationName(DeclarationName Name) { case DeclarationName::ObjCZeroArgSelector: case DeclarationName::ObjCOneArgSelector: case DeclarationName::ObjCMultiArgSelector: - BailedOut = true; break; case DeclarationName::CXXConstructorName: case DeclarationName::CXXDestructorName: @@ -197,7 +173,6 @@ void TemplateArgumentHasher::AddDeclarationName(DeclarationName Name) { void TemplateArgumentHasher::AddDecl(const Decl *D) { const NamedDecl *ND = dyn_cast(D); if (!ND) { - BailedOut = true; return; } @@ -221,7 +196,6 @@ void TemplateArgumentHasher::AddDecl(const Decl *D) { void TemplateArgumentHasher::AddQualType(QualType T) { if (T.isNull()) { - BailedOut = true; return; } SplitQualType split = T.split(); @@ -231,7 +205,6 @@ void TemplateArgumentHasher::AddQualType(QualType T) { // Process a Type pointer. Add* methods call back into TemplateArgumentHasher // while Visit* methods process the relevant parts of the Type. -// Any unhandled type will make the hash computation bail out. class TypeVisitorHelper : public TypeVisitor { typedef TypeVisitor Inherited; llvm::FoldingSetNodeID &ID; @@ -263,9 +236,6 @@ public: void Visit(const Type *T) { Inherited::Visit(T); } - // Unhandled types. Bail out simply. - void VisitType(const Type *T) { Hash.setBailedOut(); } - void VisitAdjustedType(const AdjustedType *T) { AddQualType(T->getOriginalType()); }