r362560 - msabi: Fix exponential mangling time for even more contrived inputs
Nico Weber via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 4 16:27:40 PDT 2019
Author: nico
Date: Tue Jun 4 16:27:40 2019
New Revision: 362560
URL: http://llvm.org/viewvc/llvm-project?rev=362560&view=rev
Log:
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
Modified:
cfe/trunk/lib/AST/MicrosoftMangle.cpp
cfe/trunk/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp
Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=362560&r1=362559&r2=362560&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Tue Jun 4 16:27:40 2019
@@ -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<const void *, StringRef> TemplateArgStringMap;
+ TemplateArgStringMap TemplateArgStrings;
+ llvm::StringSaver TemplateArgStringStorage;
+ llvm::BumpPtrAllocator TemplateArgStringStorageAlloc;
+
typedef std::set<std::pair<int, bool>> 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::mangleUnqu
// 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;
}
Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp?rev=362560&r1=362559&r2=362560&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp Tue Jun 4 16:27:40 2019
@@ -232,3 +232,25 @@ using B6 = Food<B5, B4, B3, B2, B1, B0,
void f(B6 a) {}
// CHECK: "?f@@YAXU?$Food at U?$Food at U?$Food at U?$Food at U?$Food at U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U2 at U2@U2 at U2@U2 at U2@U2 at U2@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@@@U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U3 at U3@U3 at U3@U3 at U3@U3 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U2 at U2@U2 at U2@U2 at U2@U2 at U2@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@@@U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U4 at U4@U4 at U4@U4 at U4@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@@@U?$Food at U?$Food at U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U2 at U2@U2 at U2@U2 at U2@U2 at U2@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@@@U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U3 at U3@U3 at U3@U3 at U3@U3 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U2 at U2@U2 at U2@U2 at U2@U2 at U2@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@@@U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U5 at U5@U5 at U5@U5 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at U?$Food at U?$Food at U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U2 at U2@U2 at U2@U2 at U2@U2 at U2@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@@@U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U3 at U3@U3 at U3@U3 at U3@U3 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U2 at U2@U2 at U2@U2 at U2@U2 at U2@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@@@U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U4 at U4@U4 at U4@U4 at U4@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@@@U?$Food at U?$Food at U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U2 at U2@U2 at U2@U2 at U2@U2 at U2@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@@@U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U3 at U3@U3 at U3@U3 at U3@U3 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U2 at U2@U2 at U2@U2 at U2@U2 at U2@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@@@U?$Food at U?$Food at HHHHHHHHHHHHHHHHHHHH@@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1@@@U?$Food at HHHHHHHHHHHHHHHHHHHH@@U6 at U6@U6 at U6@U1 at U1@U1 at U1@U1 at U1@U1 at U1@U1 at U1@@@@Z"
+
+
+// Similar to the previous case, except that the later arguments aren't
+// present in the earlier ones and hence aren't in the backref cache.
+template <class T1, class T2, class T3, class T4, class T5, class T6, class T7,
+ class T8, class T9, class T10, class T11, class T12, class T13,
+ class T14, class T15, class T16, class T17, class T18, class T19,
+ class T20>
+struct Fooe {};
+
+using C0 = Fooe<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>;
+using C1 = Fooe<C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0>;
+using C2 = Fooe<C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1>;
+using C3 = Fooe<C1, C1, C0, C0, C0, C0, C0, C0, C0, C0, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2>;
+using C4 = Fooe<C2, C2, C1, C0, C0, C0, C0, C0, C0, C0, C3, C3, C3, C3, C3, C3, C3, C3, C3, C3>;
+using C5 = Fooe<C3, C3, C2, C1, C0, C0, C0, C0, C0, C0, C4, C4, C4, C4, C4, C4, C4, C4, C4, C4>;
+using C6 = Fooe<C4, C4, C3, C2, C1, C0, C0, C0, C0, C0, C5, C5, C5, C5, C5, C5, C5, C5, C5, C5>;
+using C7 = Fooe<C5, C4, C3, C2, C1, C0, C0, C0, C0, C0, C6, C6, C6, C6, C6, C6, C6, C6, C6, C6>;
+
+// This too should take milliseconds, not minutes.
+void f(C7 a) {}
+// CHECK: "??@f23afdfb44276eaa53a5575352cf0ebc@"
More information about the cfe-commits
mailing list