Index: include/llvm/ADT/StringSet.h =================================================================== --- include/llvm/ADT/StringSet.h +++ include/llvm/ADT/StringSet.h @@ -33,6 +33,7 @@ for (StringRef X : S) insert(X); } + explicit StringSet(AllocatorTy A) : base(A) {} std::pair insert(StringRef Key) { assert(!Key.empty()); Index: include/llvm/TableGen/Record.h =================================================================== --- include/llvm/TableGen/Record.h +++ include/llvm/TableGen/Record.h @@ -623,10 +623,11 @@ class CodeInit : public TypedInit { StringRef Value; + SMLoc Loc; - explicit CodeInit(StringRef V) + explicit CodeInit(StringRef V, const SMLoc &Loc) : TypedInit(IK_CodeInit, static_cast(CodeRecTy::get())), - Value(V) {} + Value(V), Loc(Loc) {} public: CodeInit(const StringInit &) = delete; @@ -636,9 +637,10 @@ return I->getKind() == IK_CodeInit; } - static CodeInit *get(StringRef); + static CodeInit *get(StringRef, const SMLoc &Loc); StringRef getValue() const { return Value; } + const SMLoc &getLoc() const { return Loc; } Init *convertInitializerTo(RecTy *Ty) const override; Index: lib/TableGen/Record.cpp =================================================================== --- lib/TableGen/Record.cpp +++ lib/TableGen/Record.cpp @@ -15,9 +15,11 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSet.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" @@ -36,8 +38,13 @@ using namespace llvm; +#define DEBUG_TYPE "tblgen-records" + static BumpPtrAllocator Allocator; +STATISTIC(CodeInitsConstructed, + "The total number of unique CodeInits constructed"); + //===----------------------------------------------------------------------===// // Type implementations //===----------------------------------------------------------------------===// @@ -506,13 +513,20 @@ return BitsInit::get(NewBits); } -CodeInit *CodeInit::get(StringRef V) { - static StringMap ThePool(Allocator); +CodeInit *CodeInit::get(StringRef V, const SMLoc &Loc) { + static StringSet ThePool(Allocator); - auto &Entry = *ThePool.insert(std::make_pair(V, nullptr)).first; - if (!Entry.second) - Entry.second = new(Allocator) CodeInit(Entry.getKey()); - return Entry.second; + CodeInitsConstructed++; + + // Unlike StringMap, StringSet doesn't accept empty keys. + if (V.empty()) + return new (Allocator) CodeInit("", Loc); + + // Location tracking prevents us from de-duping CodeInit's as we're never + // called with the same string and same location twice. However, we can at + // least de-dupe the strings for a modest saving. + auto &Entry = *ThePool.insert(V).first; + return new(Allocator) CodeInit(Entry.getKey(), Loc); } StringInit *StringInit::get(StringRef V) { @@ -528,7 +542,7 @@ if (isa(Ty)) return const_cast(this); if (isa(Ty)) - return CodeInit::get(getValue()); + return CodeInit::get(getValue(), SMLoc()); return nullptr; } Index: lib/TableGen/TGParser.cpp =================================================================== --- lib/TableGen/TGParser.cpp +++ lib/TableGen/TGParser.cpp @@ -1744,7 +1744,7 @@ break; } case tgtok::CodeFragment: - R = CodeInit::get(Lex.getCurStrVal()); + R = CodeInit::get(Lex.getCurStrVal(), Lex.getLoc()); Lex.Lex(); break; case tgtok::question: