From: Nico Weber Date: Tue, 4 Jun 2019 23:27:40 +0000 (+0000) Subject: msabi: Fix exponential mangling time for even more contrived inputs X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=31328963a09f9781c9ace84b9f49ff5fdd79b6be;p=clang msabi: Fix exponential mangling time for even more contrived inputs This is a follow-up to r362293 which fixed exponential time needed for mangling certain templates. This fixes the same issue if that template pattern happens in template arguments > 10: The first ten template arguments can use back references, and r362293 added caching for back references. For latter arguments, we have to add a cache for the mangling itself instead. Fixes PR42091 even more. Differential Revision: https://reviews.llvm.org/D62780 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@362560 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index ddc6e12d1d..5e9358e24f 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -31,6 +31,7 @@ #include "llvm/Support/xxhash.h" #include "llvm/Support/MD5.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/StringSaver.h" using namespace clang; @@ -268,6 +269,11 @@ class MicrosoftCXXNameMangler { ArgBackRefMap FunArgBackReferences; ArgBackRefMap TemplateArgBackReferences; + typedef llvm::DenseMap TemplateArgStringMap; + TemplateArgStringMap TemplateArgStrings; + llvm::StringSaver TemplateArgStringStorage; + llvm::BumpPtrAllocator TemplateArgStringStorageAlloc; + typedef std::set> PassObjectSizeArgsSet; PassObjectSizeArgsSet PassObjectSizeArgs; @@ -282,18 +288,21 @@ public: MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_) : Context(C), Out(Out_), Structor(nullptr), StructorType(-1), + TemplateArgStringStorage(TemplateArgStringStorageAlloc), PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) == 64) {} MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_, const CXXConstructorDecl *D, CXXCtorType Type) : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type), + TemplateArgStringStorage(TemplateArgStringStorageAlloc), PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) == 64) {} MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_, const CXXDestructorDecl *D, CXXDtorType Type) : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type), + TemplateArgStringStorage(TemplateArgStringStorageAlloc), PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) == 64) {} @@ -809,24 +818,34 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, // TD / TemplateArg pairs. ArgBackRefMap::iterator Found = TemplateArgBackReferences.find(ND); if (Found == TemplateArgBackReferences.end()) { - // Mangle full template name into temporary buffer. - llvm::SmallString<64> TemplateMangling; - llvm::raw_svector_ostream Stream(TemplateMangling); - MicrosoftCXXNameMangler Extra(Context, Stream); - Extra.mangleTemplateInstantiationName(TD, *TemplateArgs); - - // Use the string backref vector to possibly get a back reference. - mangleSourceName(TemplateMangling); - - // Memoize back reference for this type. - BackRefVec::iterator StringFound = - llvm::find(NameBackReferences, TemplateMangling); - if (StringFound != NameBackReferences.end()) { - TemplateArgBackReferences[ND] = - StringFound - NameBackReferences.begin(); + + TemplateArgStringMap::iterator Found = TemplateArgStrings.find(ND); + if (Found == TemplateArgStrings.end()) { + // Mangle full template name into temporary buffer. + llvm::SmallString<64> TemplateMangling; + llvm::raw_svector_ostream Stream(TemplateMangling); + MicrosoftCXXNameMangler Extra(Context, Stream); + Extra.mangleTemplateInstantiationName(TD, *TemplateArgs); + + // Use the string backref vector to possibly get a back reference. + mangleSourceName(TemplateMangling); + + // Memoize back reference for this type if one exist, else memoize + // the mangling itself. + BackRefVec::iterator StringFound = + llvm::find(NameBackReferences, TemplateMangling); + if (StringFound != NameBackReferences.end()) { + TemplateArgBackReferences[ND] = + StringFound - NameBackReferences.begin(); + } else { + TemplateArgStrings[ND] = + TemplateArgStringStorage.save(TemplateMangling.str()); + } + } else { + Out << Found->second; // Outputs a StringRef. } } else { - Out << Found->second; + Out << Found->second; // Outputs a back reference (an int). } return; } diff --git a/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp b/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp index 653937917b..d810ec7080 100644 --- a/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp +++ b/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp @@ -232,3 +232,25 @@ using B6 = Food +struct Fooe {}; + +using C0 = Fooe; +using C1 = Fooe; +using C2 = Fooe; +using C3 = Fooe; +using C4 = Fooe; +using C5 = Fooe; +using C6 = Fooe; +using C7 = Fooe; + +// This too should take milliseconds, not minutes. +void f(C7 a) {} +// CHECK: "??@f23afdfb44276eaa53a5575352cf0ebc@"