diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h --- a/llvm/include/llvm/TableGen/Record.h +++ b/llvm/include/llvm/TableGen/Record.h @@ -39,7 +39,7 @@ namespace llvm { namespace detail { -struct RecordContext; +struct RecordKeeperImpl; } // namespace detail class ListRecTy; @@ -69,15 +69,20 @@ private: RecTyKind Kind; + /// The RecordKeeper that uniqued this Type. + RecordKeeper &RK; /// ListRecTy of the list that has elements of this type. ListRecTy *ListTy = nullptr; public: - RecTy(RecTyKind K) : Kind(K) {} + RecTy(RecTyKind K, RecordKeeper &RK) : Kind(K), RK(RK) {} virtual ~RecTy() = default; RecTyKind getRecTyKind() const { return Kind; } + /// Return the RecordKeeper that uniqued this Type. + RecordKeeper &getRecordKeeper() const { return RK; } + virtual std::string getAsString() const = 0; void print(raw_ostream &OS) const { OS << getAsString(); } void dump() const; @@ -101,16 +106,16 @@ /// 'bit' - Represent a single bit class BitRecTy : public RecTy { - friend detail::RecordContext; + friend detail::RecordKeeperImpl; - BitRecTy() : RecTy(BitRecTyKind) {} + BitRecTy(RecordKeeper &RK) : RecTy(BitRecTyKind, RK) {} public: static bool classof(const RecTy *RT) { return RT->getRecTyKind() == BitRecTyKind; } - static BitRecTy *get(); + static BitRecTy *get(RecordKeeper &RK); std::string getAsString() const override { return "bit"; } @@ -121,14 +126,15 @@ class BitsRecTy : public RecTy { unsigned Size; - explicit BitsRecTy(unsigned Sz) : RecTy(BitsRecTyKind), Size(Sz) {} + explicit BitsRecTy(RecordKeeper &RK, unsigned Sz) + : RecTy(BitsRecTyKind, RK), Size(Sz) {} public: static bool classof(const RecTy *RT) { return RT->getRecTyKind() == BitsRecTyKind; } - static BitsRecTy *get(unsigned Sz); + static BitsRecTy *get(RecordKeeper &RK, unsigned Sz); unsigned getNumBits() const { return Size; } @@ -141,16 +147,16 @@ /// 'int' - Represent an integer value of no particular size class IntRecTy : public RecTy { - friend detail::RecordContext; + friend detail::RecordKeeperImpl; - IntRecTy() : RecTy(IntRecTyKind) {} + IntRecTy(RecordKeeper &RK) : RecTy(IntRecTyKind, RK) {} public: static bool classof(const RecTy *RT) { return RT->getRecTyKind() == IntRecTyKind; } - static IntRecTy *get(); + static IntRecTy *get(RecordKeeper &RK); std::string getAsString() const override { return "int"; } @@ -159,16 +165,16 @@ /// 'string' - Represent an string value class StringRecTy : public RecTy { - friend detail::RecordContext; + friend detail::RecordKeeperImpl; - StringRecTy() : RecTy(StringRecTyKind) {} + StringRecTy(RecordKeeper &RK) : RecTy(StringRecTyKind, RK) {} public: static bool classof(const RecTy *RT) { return RT->getRecTyKind() == StringRecTyKind; } - static StringRecTy *get(); + static StringRecTy *get(RecordKeeper &RK); std::string getAsString() const override; @@ -182,7 +188,8 @@ RecTy *ElementTy; - explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), ElementTy(T) {} + explicit ListRecTy(RecTy *T) + : RecTy(ListRecTyKind, T->getRecordKeeper()), ElementTy(T) {} public: static bool classof(const RecTy *RT) { @@ -201,16 +208,16 @@ /// 'dag' - Represent a dag fragment class DagRecTy : public RecTy { - friend detail::RecordContext; + friend detail::RecordKeeperImpl; - DagRecTy() : RecTy(DagRecTyKind) {} + DagRecTy(RecordKeeper &RK) : RecTy(DagRecTyKind, RK) {} public: static bool classof(const RecTy *RT) { return RT->getRecTyKind() == DagRecTyKind; } - static DagRecTy *get(); + static DagRecTy *get(RecordKeeper &RK); std::string getAsString() const override; }; @@ -222,12 +229,12 @@ class RecordRecTy final : public RecTy, public FoldingSetNode, public TrailingObjects { friend class Record; - friend detail::RecordContext; + friend detail::RecordKeeperImpl; unsigned NumClasses; - explicit RecordRecTy(unsigned Num) - : RecTy(RecordRecTyKind), NumClasses(Num) {} + explicit RecordRecTy(RecordKeeper &RK, unsigned Num) + : RecTy(RecordRecTyKind, RK), NumClasses(Num) {} public: RecordRecTy(const RecordRecTy &) = delete; @@ -241,7 +248,8 @@ } /// Get the record type with the given non-redundant list of superclasses. - static RecordRecTy *get(ArrayRef Classes); + static RecordRecTy *get(RecordKeeper &RK, ArrayRef Classes); + static RecordRecTy *get(Record *Class); void Profile(FoldingSetNodeID &ID) const; @@ -326,6 +334,9 @@ /// Get the kind (type) of the value. InitKind getKind() const { return Kind; } + /// Get the record keeper that initialized this Init. + RecordKeeper &getRecordKeeper() const; + protected: explicit Init(InitKind K, uint8_t Opc = 0) : Kind(K), Opc(Opc) {} @@ -425,6 +436,9 @@ /// Get the type of the Init as a RecTy. RecTy *getType() const { return ValueTy; } + /// Get the record keeper that initialized this Init. + RecordKeeper &getRecordKeeper() const { return ValueTy->getRecordKeeper(); } + Init *getCastTo(RecTy *Ty) const override; Init *convertInitializerTo(RecTy *Ty) const override; @@ -439,9 +453,12 @@ /// '?' - Represents an uninitialized value. class UnsetInit : public Init { - friend detail::RecordContext; + friend detail::RecordKeeperImpl; - UnsetInit() : Init(IK_UnsetInit) {} + /// The record keeper that initialized this Init. + RecordKeeper &RK; + + UnsetInit(RecordKeeper &RK) : Init(IK_UnsetInit), RK(RK) {} public: UnsetInit(const UnsetInit &) = delete; @@ -452,7 +469,10 @@ } /// Get the singleton unset Init. - static UnsetInit *get(); + static UnsetInit *get(RecordKeeper &RK); + + /// Get the record keeper that initialized this Init. + RecordKeeper &getRecordKeeper() const { return RK; } Init *getCastTo(RecTy *Ty) const override; Init *convertInitializerTo(RecTy *Ty) const override; @@ -472,7 +492,7 @@ /// 'true'/'false' - Represent a concrete initializer for a bit. class BitInit final : public TypedInit { - friend detail::RecordContext; + friend detail::RecordKeeperImpl; bool Value; @@ -486,7 +506,7 @@ return I->getKind() == IK_BitInit; } - static BitInit *get(bool V); + static BitInit *get(RecordKeeper &RK, bool V); bool getValue() const { return Value; } @@ -507,8 +527,8 @@ public TrailingObjects { unsigned NumBits; - BitsInit(unsigned N) - : TypedInit(IK_BitsInit, BitsRecTy::get(N)), NumBits(N) {} + BitsInit(RecordKeeper &RK, unsigned N) + : TypedInit(IK_BitsInit, BitsRecTy::get(RK, N)), NumBits(N) {} public: BitsInit(const BitsInit &) = delete; @@ -521,7 +541,7 @@ return I->getKind() == IK_BitsInit; } - static BitsInit *get(ArrayRef Range); + static BitsInit *get(RecordKeeper &RK, ArrayRef Range); void Profile(FoldingSetNodeID &ID) const; @@ -557,8 +577,8 @@ class IntInit : public TypedInit { int64_t Value; - explicit IntInit(int64_t V) - : TypedInit(IK_IntInit, IntRecTy::get()), Value(V) {} + explicit IntInit(RecordKeeper &RK, int64_t V) + : TypedInit(IK_IntInit, IntRecTy::get(RK)), Value(V) {} public: IntInit(const IntInit &) = delete; @@ -568,7 +588,7 @@ return I->getKind() == IK_IntInit; } - static IntInit *get(int64_t V); + static IntInit *get(RecordKeeper &RK, int64_t V); int64_t getValue() const { return Value; } @@ -579,7 +599,7 @@ std::string getAsString() const override; Init *getBit(unsigned Bit) const override { - return BitInit::get((Value & (1ULL << Bit)) != 0); + return BitInit::get(getRecordKeeper(), (Value & (1ULL << Bit)) != 0); } }; @@ -587,8 +607,8 @@ class AnonymousNameInit : public TypedInit { unsigned Value; - explicit AnonymousNameInit(unsigned V) - : TypedInit(IK_AnonymousNameInit, StringRecTy::get()), Value(V) {} + explicit AnonymousNameInit(RecordKeeper &RK, unsigned V) + : TypedInit(IK_AnonymousNameInit, StringRecTy::get(RK)), Value(V) {} public: AnonymousNameInit(const AnonymousNameInit &) = delete; @@ -598,7 +618,7 @@ return I->getKind() == IK_AnonymousNameInit; } - static AnonymousNameInit *get(unsigned); + static AnonymousNameInit *get(RecordKeeper &RK, unsigned); unsigned getValue() const { return Value; } @@ -625,8 +645,8 @@ StringRef Value; StringFormat Format; - explicit StringInit(StringRef V, StringFormat Fmt) - : TypedInit(IK_StringInit, StringRecTy::get()), Value(V), Format(Fmt) {} + explicit StringInit(RecordKeeper &RK, StringRef V, StringFormat Fmt) + : TypedInit(IK_StringInit, StringRecTy::get(RK)), Value(V), Format(Fmt) {} public: StringInit(const StringInit &) = delete; @@ -636,7 +656,8 @@ return I->getKind() == IK_StringInit; } - static StringInit *get(StringRef, StringFormat Fmt = SF_String); + static StringInit *get(RecordKeeper &RK, StringRef, + StringFormat Fmt = SF_String); static StringFormat determineFormat(StringFormat Fmt1, StringFormat Fmt2) { return (Fmt1 == SF_Code || Fmt2 == SF_Code) ? SF_Code : SF_String; @@ -677,7 +698,7 @@ private: explicit ListInit(unsigned N, RecTy *EltTy) - : TypedInit(IK_ListInit, ListRecTy::get(EltTy)), NumValues(N) {} + : TypedInit(IK_ListInit, ListRecTy::get(EltTy)), NumValues(N) {} public: ListInit(const ListInit &) = delete; @@ -1048,8 +1069,8 @@ Init *Expr; IsAOpInit(RecTy *CheckType, Init *Expr) - : TypedInit(IK_IsAOpInit, IntRecTy::get()), CheckType(CheckType), - Expr(Expr) {} + : TypedInit(IK_IsAOpInit, IntRecTy::get(CheckType->getRecordKeeper())), + CheckType(CheckType), Expr(Expr) {} public: IsAOpInit(const IsAOpInit &) = delete; @@ -1117,7 +1138,8 @@ unsigned Bit; VarBitInit(TypedInit *T, unsigned B) - : TypedInit(IK_VarBitInit, BitRecTy::get()), TI(T), Bit(B) { + : TypedInit(IK_VarBitInit, BitRecTy::get(T->getRecordKeeper())), TI(T), + Bit(B) { assert(T->getType() && (isa(T->getType()) || (isa(T->getType()) && @@ -1222,8 +1244,7 @@ DefInit *Def = nullptr; // after instantiation unsigned NumArgs; - explicit VarDefInit(Record *Class, unsigned N) - : TypedInit(IK_VarDefInit, RecordRecTy::get(Class)), Class(Class), NumArgs(N) {} + explicit VarDefInit(Record *Class, unsigned N); DefInit *instantiate(); @@ -1320,8 +1341,8 @@ unsigned NumArgNames; DagInit(Init *V, StringInit *VN, unsigned NumArgs, unsigned NumArgNames) - : TypedInit(IK_DagInit, DagRecTy::get()), Val(V), ValName(VN), - NumArgs(NumArgs), NumArgNames(NumArgNames) {} + : TypedInit(IK_DagInit, DagRecTy::get(V->getRecordKeeper())), Val(V), + ValName(VN), NumArgs(NumArgs), NumArgNames(NumArgNames) {} size_t numTrailingObjects(OverloadToken) const { return NumArgs; } @@ -1426,6 +1447,9 @@ RecordVal(Init *N, RecTy *T, FieldKind K); RecordVal(Init *N, SMLoc Loc, RecTy *T, FieldKind K); + /// Get the record keeper used to unique this value. + RecordKeeper &getRecordKeeper() const { return Name->getRecordKeeper(); } + /// Get the name of the field as a StringRef. StringRef getName() const; @@ -1526,13 +1550,14 @@ explicit Record(Init *N, ArrayRef locs, RecordKeeper &records, bool Anonymous = false, bool Class = false) : Name(N), Locs(locs.begin(), locs.end()), TrackedRecords(records), - ID(getNewUID()), IsAnonymous(Anonymous), IsClass(Class) { + ID(getNewUID(N->getRecordKeeper())), IsAnonymous(Anonymous), + IsClass(Class) { checkName(); } explicit Record(StringRef N, ArrayRef locs, RecordKeeper &records, bool Class = false) - : Record(StringInit::get(N), locs, records, false, Class) {} + : Record(StringInit::get(records, N), locs, records, false, Class) {} // When copy-constructing a Record, we must still guarantee a globally unique // ID number. Don't copy CorrespondingDefInit either, since it's owned by the @@ -1541,9 +1566,10 @@ : Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs), Values(O.Values), Assertions(O.Assertions), SuperClasses(O.SuperClasses), TrackedRecords(O.TrackedRecords), - ID(getNewUID()), IsAnonymous(O.IsAnonymous), IsClass(O.IsClass) {} + ID(getNewUID(O.getRecords())), IsAnonymous(O.IsAnonymous), + IsClass(O.IsClass) {} - static unsigned getNewUID(); + static unsigned getNewUID(RecordKeeper &RK); unsigned getID() const { return ID; } @@ -1599,7 +1625,7 @@ } const RecordVal *getValue(StringRef Name) const { - return getValue(StringInit::get(Name)); + return getValue(StringInit::get(getRecords(), Name)); } RecordVal *getValue(const Init *Name) { @@ -1630,7 +1656,7 @@ } void removeValue(StringRef Name) { - removeValue(StringInit::get(Name)); + removeValue(StringInit::get(getRecords(), Name)); } void addAssertion(SMLoc Loc, Init *Condition, Init *Message) { @@ -1779,26 +1805,16 @@ raw_ostream &operator<<(raw_ostream &OS, const Record &R); class RecordKeeper { - friend class RecordRecTy; - using RecordMap = std::map, std::less<>>; using GlobalMap = std::map>; - std::string InputFilename; - RecordMap Classes, Defs; - mutable StringMap> ClassRecordsMap; - FoldingSet RecordTypePool; - std::map> ExtraGlobals; - unsigned AnonCounter = 0; +public: + RecordKeeper(); + ~RecordKeeper(); - // These members are for the phase timing feature. We need a timer group, - // the last timer started, and a flag to say whether the last timer - // is the special "backend overall timer." - TimerGroup *TimingGroup = nullptr; - Timer *LastTimer = nullptr; - bool BackendTimer = false; + /// Return the internal implementation of the RecordKeeper. + detail::RecordKeeperImpl &getImpl() { return *Impl; } -public: /// Get the main TableGen input file's name. const std::string getInputFilename() const { return InputFilename; } @@ -1900,6 +1916,27 @@ getAllDerivedDefinitionsIfDefined(StringRef ClassName) const; void dump() const; + +private: + RecordKeeper(RecordKeeper &&) = delete; + RecordKeeper(const RecordKeeper &) = delete; + RecordKeeper &operator=(RecordKeeper &&) = delete; + RecordKeeper &operator=(const RecordKeeper &) = delete; + + std::string InputFilename; + RecordMap Classes, Defs; + mutable StringMap> ClassRecordsMap; + GlobalMap ExtraGlobals; + + // These members are for the phase timing feature. We need a timer group, + // the last timer started, and a flag to say whether the last timer + // is the special "backend overall timer." + TimerGroup *TimingGroup = nullptr; + Timer *LastTimer = nullptr; + bool BackendTimer = false; + + /// The internal uniquer implementation of the RecordKeeper. + std::unique_ptr Impl; }; /// Sorting predicate to sort record pointers by name. diff --git a/llvm/lib/TableGen/Error.cpp b/llvm/lib/TableGen/Error.cpp --- a/llvm/lib/TableGen/Error.cpp +++ b/llvm/lib/TableGen/Error.cpp @@ -157,8 +157,8 @@ // Check an assertion: Obtain the condition value and be sure it is true. // If not, print a nonfatal error along with the message. void CheckAssert(SMLoc Loc, Init *Condition, Init *Message) { - auto *CondValue = dyn_cast_or_null( - Condition->convertInitializerTo(IntRecTy::get())); + auto *CondValue = dyn_cast_or_null(Condition->convertInitializerTo( + IntRecTy::get(Condition->getRecordKeeper()))); if (!CondValue) PrintError(Loc, "assert condition must of type bit, bits, or int."); else if (!CondValue->getValue()) { diff --git a/llvm/lib/TableGen/Parser.cpp b/llvm/lib/TableGen/Parser.cpp --- a/llvm/lib/TableGen/Parser.cpp +++ b/llvm/lib/TableGen/Parser.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "llvm/TableGen/Parser.h" -#include "RecordContext.h" #include "TGParser.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/TableGen/Error.h" @@ -33,7 +32,6 @@ return true; // After parsing, reset the tablegen data. - detail::resetTablegenRecordContext(); SrcMgr = SourceMgr(); return false; } diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -11,7 +11,6 @@ //===----------------------------------------------------------------------===// #include "llvm/TableGen/Record.h" -#include "RecordContext.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" @@ -47,14 +46,17 @@ namespace llvm { namespace detail { -/// This class contains all of the contextual static state of the Record -/// classes. This allows for better lifetime management and control of the used -/// static data. -struct RecordContext { - RecordContext() - : AnyRecord(0), TrueBitInit(true, &SharedBitRecTy), +/// This class represents the internal implementation of the RecordKeeper. +/// It contains all of the contextual static state of the Record classes. It is +/// kept out-of-line to simplify dependencies, and also make it easier for +/// internal classes to access the uniquer state of the keeper. +struct RecordKeeperImpl { + RecordKeeperImpl(RecordKeeper &RK) + : SharedBitRecTy(RK), SharedIntRecTy(RK), SharedStringRecTy(RK), + SharedDagRecTy(RK), AnyRecord(RK, 0), TheUnsetInit(RK), + TrueBitInit(true, &SharedBitRecTy), FalseBitInit(false, &SharedBitRecTy), StringInitStringPool(Allocator), - StringInitCodePool(Allocator), LastRecordID(0) {} + StringInitCodePool(Allocator), AnonCounter(0), LastRecordID(0) {} BumpPtrAllocator Allocator; std::vector SharedBitsRecTys; @@ -86,16 +88,14 @@ DenseMap, FieldInit *> TheFieldInitPool; FoldingSet TheCondOpInitPool; FoldingSet TheDagInitPool; + FoldingSet RecordTypePool; + unsigned AnonCounter; unsigned LastRecordID; }; } // namespace detail } // namespace llvm -ManagedStatic Context; - -void llvm::detail::resetTablegenRecordContext() { Context.destroy(); } - //===----------------------------------------------------------------------===// // Type implementations //===----------------------------------------------------------------------===// @@ -106,7 +106,7 @@ ListRecTy *RecTy::getListTy() { if (!ListTy) - ListTy = new(Context->Allocator) ListRecTy(this); + ListTy = new (RK.getImpl().Allocator) ListRecTy(this); return ListTy; } @@ -117,7 +117,9 @@ bool RecTy::typeIsA(const RecTy *RHS) const { return this == RHS; } -BitRecTy *BitRecTy::get() { return &Context->SharedBitRecTy; } +BitRecTy *BitRecTy::get(RecordKeeper &RK) { + return &RK.getImpl().SharedBitRecTy; +} bool BitRecTy::typeIsConvertibleTo(const RecTy *RHS) const{ if (RecTy::typeIsConvertibleTo(RHS) || RHS->getRecTyKind() == IntRecTyKind) @@ -127,12 +129,13 @@ return false; } -BitsRecTy *BitsRecTy::get(unsigned Sz) { - if (Sz >= Context->SharedBitsRecTys.size()) - Context->SharedBitsRecTys.resize(Sz + 1); - BitsRecTy *&Ty = Context->SharedBitsRecTys[Sz]; +BitsRecTy *BitsRecTy::get(RecordKeeper &RK, unsigned Sz) { + detail::RecordKeeperImpl &RKImpl = RK.getImpl(); + if (Sz >= RKImpl.SharedBitsRecTys.size()) + RKImpl.SharedBitsRecTys.resize(Sz + 1); + BitsRecTy *&Ty = RKImpl.SharedBitsRecTys[Sz]; if (!Ty) - Ty = new (Context->Allocator) BitsRecTy(Sz); + Ty = new (RKImpl.Allocator) BitsRecTy(RK, Sz); return Ty; } @@ -153,14 +156,18 @@ return false; } -IntRecTy *IntRecTy::get() { return &Context->SharedIntRecTy; } +IntRecTy *IntRecTy::get(RecordKeeper &RK) { + return &RK.getImpl().SharedIntRecTy; +} bool IntRecTy::typeIsConvertibleTo(const RecTy *RHS) const { RecTyKind kind = RHS->getRecTyKind(); return kind==BitRecTyKind || kind==BitsRecTyKind || kind==IntRecTyKind; } -StringRecTy *StringRecTy::get() { return &Context->SharedStringRecTy; } +StringRecTy *StringRecTy::get(RecordKeeper &RK) { + return &RK.getImpl().SharedStringRecTy; +} std::string StringRecTy::getAsString() const { return "string"; @@ -187,7 +194,9 @@ return false; } -DagRecTy *DagRecTy::get() { return &Context->SharedDagRecTy; } +DagRecTy *DagRecTy::get(RecordKeeper &RK) { + return &RK.getImpl().SharedDagRecTy; +} std::string DagRecTy::getAsString() const { return "dag"; @@ -200,12 +209,13 @@ ID.AddPointer(R); } -RecordRecTy *RecordRecTy::get(ArrayRef UnsortedClasses) { +RecordRecTy *RecordRecTy::get(RecordKeeper &RK, + ArrayRef UnsortedClasses) { + detail::RecordKeeperImpl &RKImpl = RK.getImpl(); if (UnsortedClasses.empty()) - return &Context->AnyRecord; + return &RKImpl.AnyRecord; - FoldingSet &ThePool = - UnsortedClasses[0]->getRecords().RecordTypePool; + FoldingSet &ThePool = RKImpl.RecordTypePool; SmallVector Classes(UnsortedClasses.begin(), UnsortedClasses.end()); @@ -230,14 +240,18 @@ } #endif - void *Mem = Context->Allocator.Allocate( + void *Mem = RKImpl.Allocator.Allocate( totalSizeToAlloc(Classes.size()), alignof(RecordRecTy)); - RecordRecTy *Ty = new(Mem) RecordRecTy(Classes.size()); + RecordRecTy *Ty = new (Mem) RecordRecTy(RK, Classes.size()); std::uninitialized_copy(Classes.begin(), Classes.end(), Ty->getTrailingObjects()); ThePool.InsertNode(Ty, IP); return Ty; } +RecordRecTy *RecordRecTy::get(Record *Class) { + assert(Class && "unexpected null class"); + return get(Class->getRecords(), Class); +} void RecordRecTy::Profile(FoldingSetNodeID &ID) const { ProfileRecordRecTy(ID, getClasses()); @@ -297,7 +311,7 @@ } } - return RecordRecTy::get(CommonSuperClasses); + return RecordRecTy::get(T1->getRecordKeeper(), CommonSuperClasses); } RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) { @@ -336,7 +350,15 @@ LLVM_DUMP_METHOD void Init::dump() const { return print(errs()); } #endif -UnsetInit *UnsetInit::get() { return &Context->TheUnsetInit; } +RecordKeeper &Init::getRecordKeeper() const { + if (auto *TyInit = dyn_cast(this)) + return TyInit->getType()->getRecordKeeper(); + return cast(this)->getRecordKeeper(); +} + +UnsetInit *UnsetInit::get(RecordKeeper &RK) { + return &RK.getImpl().TheUnsetInit; +} Init *UnsetInit::getCastTo(RecTy *Ty) const { return const_cast(this); @@ -346,8 +368,8 @@ return const_cast(this); } -BitInit *BitInit::get(bool V) { - return V ? &Context->TrueBitInit : &Context->FalseBitInit; +BitInit *BitInit::get(RecordKeeper &RK, bool V) { + return V ? &RK.getImpl().TrueBitInit : &RK.getImpl().FalseBitInit; } Init *BitInit::convertInitializerTo(RecTy *Ty) const { @@ -355,12 +377,12 @@ return const_cast(this); if (isa(Ty)) - return IntInit::get(getValue()); + return IntInit::get(getRecordKeeper(), getValue()); if (auto *BRT = dyn_cast(Ty)) { // Can only convert single bit. if (BRT->getNumBits() == 1) - return BitsInit::get(const_cast(this)); + return BitsInit::get(getRecordKeeper(), const_cast(this)); } return nullptr; @@ -374,20 +396,21 @@ ID.AddPointer(I); } -BitsInit *BitsInit::get(ArrayRef Range) { +BitsInit *BitsInit::get(RecordKeeper &RK, ArrayRef Range) { FoldingSetNodeID ID; ProfileBitsInit(ID, Range); + detail::RecordKeeperImpl &RKImpl = RK.getImpl(); void *IP = nullptr; - if (BitsInit *I = Context->TheBitsInitPool.FindNodeOrInsertPos(ID, IP)) + if (BitsInit *I = RKImpl.TheBitsInitPool.FindNodeOrInsertPos(ID, IP)) return I; - void *Mem = Context->Allocator.Allocate( - totalSizeToAlloc(Range.size()), alignof(BitsInit)); - BitsInit *I = new(Mem) BitsInit(Range.size()); + void *Mem = RKImpl.Allocator.Allocate(totalSizeToAlloc(Range.size()), + alignof(BitsInit)); + BitsInit *I = new (Mem) BitsInit(RK, Range.size()); std::uninitialized_copy(Range.begin(), Range.end(), I->getTrailingObjects()); - Context->TheBitsInitPool.InsertNode(I, IP); + RKImpl.TheBitsInitPool.InsertNode(I, IP); return I; } @@ -415,7 +438,7 @@ Result |= static_cast(Bit->getValue()) << i; else return nullptr; - return IntInit::get(Result); + return IntInit::get(getRecordKeeper(), Result); } return nullptr; @@ -430,7 +453,7 @@ return nullptr; NewBits[i] = getBit(Bits[i]); } - return BitsInit::get(NewBits); + return BitsInit::get(getRecordKeeper(), NewBits); } bool BitsInit::isConcrete() const { @@ -485,15 +508,15 @@ } if (Changed) - return BitsInit::get(NewBits); + return BitsInit::get(getRecordKeeper(), NewBits); return const_cast(this); } -IntInit *IntInit::get(int64_t V) { - IntInit *&I = Context->TheIntInitPool[V]; +IntInit *IntInit::get(RecordKeeper &RK, int64_t V) { + IntInit *&I = RK.getImpl().TheIntInitPool[V]; if (!I) - I = new (Context->Allocator) IntInit(V); + I = new (RK.getImpl().Allocator) IntInit(RK, V); return I; } @@ -514,7 +537,7 @@ if (isa(Ty)) { int64_t Val = getValue(); if (Val != 0 && Val != 1) return nullptr; // Only accept 0 or 1 for a bit! - return BitInit::get(Val != 0); + return BitInit::get(getRecordKeeper(), Val != 0); } if (auto *BRT = dyn_cast(Ty)) { @@ -525,9 +548,10 @@ SmallVector NewBits(BRT->getNumBits()); for (unsigned i = 0; i != BRT->getNumBits(); ++i) - NewBits[i] = BitInit::get(Value & ((i < 64) ? (1LL << i) : 0)); + NewBits[i] = + BitInit::get(getRecordKeeper(), Value & ((i < 64) ? (1LL << i) : 0)); - return BitsInit::get(NewBits); + return BitsInit::get(getRecordKeeper(), NewBits); } return nullptr; @@ -541,17 +565,18 @@ if (Bits[i] >= 64) return nullptr; - NewBits[i] = BitInit::get(Value & (INT64_C(1) << Bits[i])); + NewBits[i] = + BitInit::get(getRecordKeeper(), Value & (INT64_C(1) << Bits[i])); } - return BitsInit::get(NewBits); + return BitsInit::get(getRecordKeeper(), NewBits); } -AnonymousNameInit *AnonymousNameInit::get(unsigned V) { - return new (Context->Allocator) AnonymousNameInit(V); +AnonymousNameInit *AnonymousNameInit::get(RecordKeeper &RK, unsigned V) { + return new (RK.getImpl().Allocator) AnonymousNameInit(RK, V); } StringInit *AnonymousNameInit::getNameInit() const { - return StringInit::get(getAsString()); + return StringInit::get(getRecordKeeper(), getAsString()); } std::string AnonymousNameInit::getAsString() const { @@ -568,12 +593,13 @@ return New; } -StringInit *StringInit::get(StringRef V, StringFormat Fmt) { - auto &InitMap = Fmt == SF_String ? Context->StringInitStringPool - : Context->StringInitCodePool; +StringInit *StringInit::get(RecordKeeper &RK, StringRef V, StringFormat Fmt) { + detail::RecordKeeperImpl &RKImpl = RK.getImpl(); + auto &InitMap = Fmt == SF_String ? RKImpl.StringInitStringPool + : RKImpl.StringInitCodePool; auto &Entry = *InitMap.insert(std::make_pair(V, nullptr)).first; if (!Entry.second) - Entry.second = new (Context->Allocator) StringInit(Entry.getKey(), Fmt); + Entry.second = new (RKImpl.Allocator) StringInit(RK, Entry.getKey(), Fmt); return Entry.second; } @@ -598,19 +624,20 @@ FoldingSetNodeID ID; ProfileListInit(ID, Range, EltTy); + detail::RecordKeeperImpl &RK = EltTy->getRecordKeeper().getImpl(); void *IP = nullptr; - if (ListInit *I = Context->TheListInitPool.FindNodeOrInsertPos(ID, IP)) + if (ListInit *I = RK.TheListInitPool.FindNodeOrInsertPos(ID, IP)) return I; assert(Range.empty() || !isa(Range[0]) || cast(Range[0])->getType()->typeIsConvertibleTo(EltTy)); - void *Mem = Context->Allocator.Allocate( - totalSizeToAlloc(Range.size()), alignof(ListInit)); + void *Mem = RK.Allocator.Allocate(totalSizeToAlloc(Range.size()), + alignof(ListInit)); ListInit *I = new (Mem) ListInit(Range.size(), EltTy); std::uninitialized_copy(Range.begin(), Range.end(), I->getTrailingObjects()); - Context->TheListInitPool.InsertNode(I, IP); + RK.TheListInitPool.InsertNode(I, IP); return I; } @@ -717,7 +744,7 @@ } Init *OpInit::getBit(unsigned Bit) const { - if (getType() == BitRecTy::get()) + if (getType() == BitRecTy::get(getRecordKeeper())) return const_cast(this); return VarBitInit::get(const_cast(this), Bit); } @@ -733,12 +760,13 @@ FoldingSetNodeID ID; ProfileUnOpInit(ID, Opc, LHS, Type); + detail::RecordKeeperImpl &RK = Type->getRecordKeeper().getImpl(); void *IP = nullptr; - if (UnOpInit *I = Context->TheUnOpInitPool.FindNodeOrInsertPos(ID, IP)) + if (UnOpInit *I = RK.TheUnOpInitPool.FindNodeOrInsertPos(ID, IP)) return I; - UnOpInit *I = new (Context->Allocator) UnOpInit(Opc, LHS, Type); - Context->TheUnOpInitPool.InsertNode(I, IP); + UnOpInit *I = new (RK.Allocator) UnOpInit(Opc, LHS, Type); + RK.TheUnOpInitPool.InsertNode(I, IP); return I; } @@ -747,6 +775,7 @@ } Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const { + RecordKeeper &RK = getRecordKeeper(); switch (getOpcode()) { case CAST: if (isa(getType())) { @@ -754,11 +783,11 @@ return LHSs; if (DefInit *LHSd = dyn_cast(LHS)) - return StringInit::get(LHSd->getAsString()); + return StringInit::get(RK, LHSd->getAsString()); - if (IntInit *LHSi = - dyn_cast_or_null(LHS->convertInitializerTo(IntRecTy::get()))) - return StringInit::get(LHSi->getAsString()); + if (IntInit *LHSi = dyn_cast_or_null( + LHS->convertInitializerTo(IntRecTy::get(RK)))) + return StringInit::get(RK, LHSi->getAsString()); } else if (isa(getType())) { if (StringInit *Name = dyn_cast(LHS)) { @@ -803,9 +832,9 @@ break; case NOT: - if (IntInit *LHSi = - dyn_cast_or_null(LHS->convertInitializerTo(IntRecTy::get()))) - return IntInit::get(LHSi->getValue() ? 0 : 1); + if (IntInit *LHSi = dyn_cast_or_null( + LHS->convertInitializerTo(IntRecTy::get(RK)))) + return IntInit::get(RK, LHSi->getValue() ? 0 : 1); break; case HEAD: @@ -826,20 +855,20 @@ case SIZE: if (ListInit *LHSl = dyn_cast(LHS)) - return IntInit::get(LHSl->size()); + return IntInit::get(RK, LHSl->size()); if (DagInit *LHSd = dyn_cast(LHS)) - return IntInit::get(LHSd->arg_size()); + return IntInit::get(RK, LHSd->arg_size()); if (StringInit *LHSs = dyn_cast(LHS)) - return IntInit::get(LHSs->getValue().size()); + return IntInit::get(RK, LHSs->getValue().size()); break; case EMPTY: if (ListInit *LHSl = dyn_cast(LHS)) - return IntInit::get(LHSl->empty()); + return IntInit::get(RK, LHSl->empty()); if (DagInit *LHSd = dyn_cast(LHS)) - return IntInit::get(LHSd->arg_empty()); + return IntInit::get(RK, LHSd->arg_empty()); if (StringInit *LHSs = dyn_cast(LHS)) - return IntInit::get(LHSs->getValue().empty()); + return IntInit::get(RK, LHSs->getValue().empty()); break; case GETDAGOP: @@ -896,12 +925,13 @@ FoldingSetNodeID ID; ProfileBinOpInit(ID, Opc, LHS, RHS, Type); + detail::RecordKeeperImpl &RK = LHS->getRecordKeeper().getImpl(); void *IP = nullptr; - if (BinOpInit *I = Context->TheBinOpInitPool.FindNodeOrInsertPos(ID, IP)) + if (BinOpInit *I = RK.TheBinOpInitPool.FindNodeOrInsertPos(ID, IP)) return I; - BinOpInit *I = new (Context->Allocator) BinOpInit(Opc, LHS, RHS, Type); - Context->TheBinOpInitPool.InsertNode(I, IP); + BinOpInit *I = new (RK.Allocator) BinOpInit(Opc, LHS, RHS, Type); + RK.TheBinOpInitPool.InsertNode(I, IP); return I; } @@ -913,15 +943,15 @@ const StringInit *I1) { SmallString<80> Concat(I0->getValue()); Concat.append(I1->getValue()); - return StringInit::get(Concat, - StringInit::determineFormat(I0->getFormat(), - I1->getFormat())); + return StringInit::get( + I0->getRecordKeeper(), Concat, + StringInit::determineFormat(I0->getFormat(), I1->getFormat())); } static StringInit *interleaveStringList(const ListInit *List, const StringInit *Delim) { if (List->size() == 0) - return StringInit::get(""); + return StringInit::get(List->getRecordKeeper(), ""); StringInit *Element = dyn_cast(List->getElement(0)); if (!Element) return nullptr; @@ -936,30 +966,29 @@ Result.append(Element->getValue()); Fmt = StringInit::determineFormat(Fmt, Element->getFormat()); } - return StringInit::get(Result, Fmt); + return StringInit::get(List->getRecordKeeper(), Result, Fmt); } static StringInit *interleaveIntList(const ListInit *List, const StringInit *Delim) { + RecordKeeper &RK = List->getRecordKeeper(); if (List->size() == 0) - return StringInit::get(""); - IntInit *Element = - dyn_cast_or_null(List->getElement(0) - ->convertInitializerTo(IntRecTy::get())); + return StringInit::get(RK, ""); + IntInit *Element = dyn_cast_or_null( + List->getElement(0)->convertInitializerTo(IntRecTy::get(RK))); if (!Element) return nullptr; SmallString<80> Result(Element->getAsString()); for (unsigned I = 1, E = List->size(); I < E; ++I) { Result.append(Delim->getValue()); - IntInit *Element = - dyn_cast_or_null(List->getElement(I) - ->convertInitializerTo(IntRecTy::get())); + IntInit *Element = dyn_cast_or_null( + List->getElement(I)->convertInitializerTo(IntRecTy::get(RK))); if (!Element) return nullptr; Result.append(Element->getAsString()); } - return StringInit::get(Result); + return StringInit::get(RK, Result); } Init *BinOpInit::getStrConcat(Init *I0, Init *I1) { @@ -967,7 +996,8 @@ if (const StringInit *I0s = dyn_cast(I0)) if (const StringInit *I1s = dyn_cast(I1)) return ConcatStringInits(I0s, I1s); - return BinOpInit::get(BinOpInit::STRCONCAT, I0, I1, StringRecTy::get()); + return BinOpInit::get(BinOpInit::STRCONCAT, I0, I1, + StringRecTy::get(I0->getRecordKeeper())); } static ListInit *ConcatListInits(const ListInit *LHS, @@ -1006,7 +1036,7 @@ } Init *Op = LOp ? LOp : ROp; if (!Op) - Op = UnsetInit::get(); + Op = UnsetInit::get(getRecordKeeper()); SmallVector Args; SmallVector ArgNames; @@ -1070,10 +1100,10 @@ case GE: case GT: { // First see if we have two bit, bits, or int. - IntInit *LHSi = - dyn_cast_or_null(LHS->convertInitializerTo(IntRecTy::get())); - IntInit *RHSi = - dyn_cast_or_null(RHS->convertInitializerTo(IntRecTy::get())); + IntInit *LHSi = dyn_cast_or_null( + LHS->convertInitializerTo(IntRecTy::get(getRecordKeeper()))); + IntInit *RHSi = dyn_cast_or_null( + RHS->convertInitializerTo(IntRecTy::get(getRecordKeeper()))); if (LHSi && RHSi) { bool Result; @@ -1086,7 +1116,7 @@ case GT: Result = LHSi->getValue() > RHSi->getValue(); break; default: llvm_unreachable("unhandled comparison"); } - return BitInit::get(Result); + return BitInit::get(getRecordKeeper(), Result); } // Next try strings. @@ -1104,7 +1134,7 @@ case GT: Result = LHSs->getValue() > RHSs->getValue(); break; default: llvm_unreachable("unhandled comparison"); } - return BitInit::get(Result); + return BitInit::get(getRecordKeeper(), Result); } // Finally, !eq and !ne can be used with records. @@ -1112,8 +1142,8 @@ DefInit *LHSd = dyn_cast(LHS); DefInit *RHSd = dyn_cast(RHS); if (LHSd && RHSd) - return BitInit::get((getOpcode() == EQ) ? LHSd == RHSd - : LHSd != RHSd); + return BitInit::get(getRecordKeeper(), + (getOpcode() == EQ) ? LHSd == RHSd : LHSd != RHSd); } break; @@ -1141,10 +1171,10 @@ case SHL: case SRA: case SRL: { - IntInit *LHSi = - dyn_cast_or_null(LHS->convertInitializerTo(IntRecTy::get())); - IntInit *RHSi = - dyn_cast_or_null(RHS->convertInitializerTo(IntRecTy::get())); + IntInit *LHSi = dyn_cast_or_null( + LHS->convertInitializerTo(IntRecTy::get(getRecordKeeper()))); + IntInit *RHSi = dyn_cast_or_null( + RHS->convertInitializerTo(IntRecTy::get(getRecordKeeper()))); if (LHSi && RHSi) { int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue(); int64_t Result; @@ -1160,7 +1190,7 @@ case SRA: Result = LHSv >> RHSv; break; case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break; } - return IntInit::get(Result); + return IntInit::get(getRecordKeeper(), Result); } break; } @@ -1221,12 +1251,13 @@ FoldingSetNodeID ID; ProfileTernOpInit(ID, Opc, LHS, MHS, RHS, Type); + detail::RecordKeeperImpl &RK = LHS->getRecordKeeper().getImpl(); void *IP = nullptr; - if (TernOpInit *I = Context->TheTernOpInitPool.FindNodeOrInsertPos(ID, IP)) + if (TernOpInit *I = RK.TheTernOpInitPool.FindNodeOrInsertPos(ID, IP)) return I; - TernOpInit *I = new (Context->Allocator) TernOpInit(Opc, LHS, MHS, RHS, Type); - Context->TheTernOpInitPool.InsertNode(I, IP); + TernOpInit *I = new (RK.Allocator) TernOpInit(Opc, LHS, MHS, RHS, Type); + RK.TheTernOpInitPool.InsertNode(I, IP); return I; } @@ -1299,8 +1330,9 @@ Init *Include = ItemApply(LHS, Item, RHS, CurRec); if (!Include) return nullptr; - if (IntInit *IncludeInt = dyn_cast_or_null( - Include->convertInitializerTo(IntRecTy::get()))) { + if (IntInit *IncludeInt = + dyn_cast_or_null(Include->convertInitializerTo( + IntRecTy::get(LHS->getRecordKeeper())))) { if (IncludeInt->getValue()) NewList.push_back(Item); } else { @@ -1314,6 +1346,7 @@ } Init *TernOpInit::Fold(Record *CurRec) const { + RecordKeeper &RK = getRecordKeeper(); switch (getOpcode()) { case SUBST: { DefInit *LHSd = dyn_cast(LHS); @@ -1354,7 +1387,7 @@ idx = found + MHSs->getValue().size(); } - return StringInit::get(Val); + return StringInit::get(RK, Val); } break; } @@ -1373,7 +1406,7 @@ case IF: { if (IntInit *LHSi = dyn_cast_or_null( - LHS->convertInitializerTo(IntRecTy::get()))) { + LHS->convertInitializerTo(IntRecTy::get(RK)))) { if (LHSi->getValue()) return MHS; return RHS; @@ -1394,8 +1427,8 @@ SmallVector, 8> Children; unsigned Size = MHSl ? MHSl->size() : RHSl->size(); for (unsigned i = 0; i != Size; ++i) { - Init *Node = MHSl ? MHSl->getElement(i) : UnsetInit::get(); - Init *Name = RHSl ? RHSl->getElement(i) : UnsetInit::get(); + Init *Node = MHSl ? MHSl->getElement(i) : UnsetInit::get(RK); + Init *Name = RHSl ? RHSl->getElement(i) : UnsetInit::get(RK); if (!isa(Name) && !isa(Name)) return const_cast(this); Children.emplace_back(Node, dyn_cast(Name)); @@ -1420,7 +1453,7 @@ std::to_string(Start)); if (Length < 0) PrintError(CurRec->getLoc(), "!substr length must be nonnegative"); - return StringInit::get(LHSs->getValue().substr(Start, Length), + return StringInit::get(RK, LHSs->getValue().substr(Start, Length), LHSs->getFormat()); } break; @@ -1440,8 +1473,8 @@ std::to_string(Start)); auto I = LHSs->getValue().find(MHSs->getValue(), Start); if (I == std::string::npos) - return IntInit::get(-1); - return IntInit::get(I); + return IntInit::get(RK, -1); + return IntInit::get(RK, I); } break; } @@ -1455,7 +1488,7 @@ if (getOpcode() == IF && lhs != LHS) { if (IntInit *Value = dyn_cast_or_null( - lhs->convertInitializerTo(IntRecTy::get()))) { + lhs->convertInitializerTo(IntRecTy::get(getRecordKeeper())))) { // Short-circuit if (Value->getValue()) return MHS->resolveReferences(R); @@ -1509,17 +1542,16 @@ FoldOpInit *FoldOpInit::get(Init *Start, Init *List, Init *A, Init *B, Init *Expr, RecTy *Type) { - FoldingSetNodeID ID; ProfileFoldOpInit(ID, Start, List, A, B, Expr, Type); + detail::RecordKeeperImpl &RK = Start->getRecordKeeper().getImpl(); void *IP = nullptr; - if (FoldOpInit *I = Context->TheFoldOpInitPool.FindNodeOrInsertPos(ID, IP)) + if (FoldOpInit *I = RK.TheFoldOpInitPool.FindNodeOrInsertPos(ID, IP)) return I; - FoldOpInit *I = - new (Context->Allocator) FoldOpInit(Start, List, A, B, Expr, Type); - Context->TheFoldOpInitPool.InsertNode(I, IP); + FoldOpInit *I = new (RK.Allocator) FoldOpInit(Start, List, A, B, Expr, Type); + RK.TheFoldOpInitPool.InsertNode(I, IP); return I; } @@ -1578,12 +1610,13 @@ FoldingSetNodeID ID; ProfileIsAOpInit(ID, CheckType, Expr); + detail::RecordKeeperImpl &RK = Expr->getRecordKeeper().getImpl(); void *IP = nullptr; - if (IsAOpInit *I = Context->TheIsAOpInitPool.FindNodeOrInsertPos(ID, IP)) + if (IsAOpInit *I = RK.TheIsAOpInitPool.FindNodeOrInsertPos(ID, IP)) return I; - IsAOpInit *I = new (Context->Allocator) IsAOpInit(CheckType, Expr); - Context->TheIsAOpInitPool.InsertNode(I, IP); + IsAOpInit *I = new (RK.Allocator) IsAOpInit(CheckType, Expr); + RK.TheIsAOpInitPool.InsertNode(I, IP); return I; } @@ -1595,17 +1628,17 @@ if (TypedInit *TI = dyn_cast(Expr)) { // Is the expression type known to be (a subclass of) the desired type? if (TI->getType()->typeIsConvertibleTo(CheckType)) - return IntInit::get(1); + return IntInit::get(getRecordKeeper(), 1); if (isa(CheckType)) { // If the target type is not a subclass of the expression type, or if // the expression has fully resolved to a record, we know that it can't // be of the required type. if (!CheckType->typeIsConvertibleTo(TI->getType()) || isa(Expr)) - return IntInit::get(0); + return IntInit::get(getRecordKeeper(), 0); } else { // We treat non-record types as not castable. - return IntInit::get(0); + return IntInit::get(getRecordKeeper(), 0); } } return const_cast(this); @@ -1645,7 +1678,7 @@ if (isa(getType()) && isa(Ty) && cast(Ty)->getNumBits() == 1) - return BitsInit::get({const_cast(this)}); + return BitsInit::get(getRecordKeeper(), {const_cast(this)}); return nullptr; } @@ -1663,7 +1696,7 @@ NewBits.push_back(VarBitInit::get(const_cast(this), Bit)); } - return BitsInit::get(NewBits); + return BitsInit::get(getRecordKeeper(), NewBits); } Init *TypedInit::getCastTo(RecTy *Ty) const { @@ -1701,14 +1734,15 @@ VarInit *VarInit::get(StringRef VN, RecTy *T) { - Init *Value = StringInit::get(VN); + Init *Value = StringInit::get(T->getRecordKeeper(), VN); return VarInit::get(Value, T); } VarInit *VarInit::get(Init *VN, RecTy *T) { - VarInit *&I = Context->TheVarInitPool[std::make_pair(T, VN)]; + detail::RecordKeeperImpl &RK = T->getRecordKeeper().getImpl(); + VarInit *&I = RK.TheVarInitPool[std::make_pair(T, VN)]; if (!I) - I = new (Context->Allocator) VarInit(VN, T); + I = new (RK.Allocator) VarInit(VN, T); return I; } @@ -1718,7 +1752,7 @@ } Init *VarInit::getBit(unsigned Bit) const { - if (getType() == BitRecTy::get()) + if (getType() == BitRecTy::get(getRecordKeeper())) return const_cast(this); return VarBitInit::get(const_cast(this), Bit); } @@ -1730,9 +1764,10 @@ } VarBitInit *VarBitInit::get(TypedInit *T, unsigned B) { - VarBitInit *&I = Context->TheVarBitInitPool[std::make_pair(T, B)]; + detail::RecordKeeperImpl &RK = T->getRecordKeeper().getImpl(); + VarBitInit *&I = RK.TheVarBitInitPool[std::make_pair(T, B)]; if (!I) - I = new(Context->Allocator) VarBitInit(T, B); + I = new (RK.Allocator) VarBitInit(T, B); return I; } @@ -1749,10 +1784,10 @@ } VarListElementInit *VarListElementInit::get(TypedInit *T, unsigned E) { - VarListElementInit *&I = - Context->TheVarListElementInitPool[std::make_pair(T, E)]; + detail::RecordKeeperImpl &RK = T->getRecordKeeper().getImpl(); + VarListElementInit *&I = RK.TheVarListElementInitPool[std::make_pair(T, E)]; if (!I) - I = new (Context->Allocator) VarListElementInit(T, E); + I = new (RK.Allocator) VarListElementInit(T, E); return I; } @@ -1774,7 +1809,7 @@ } Init *VarListElementInit::getBit(unsigned Bit) const { - if (getType() == BitRecTy::get()) + if (getType() == BitRecTy::get(getRecordKeeper())) return const_cast(this); return VarBitInit::get(const_cast(this), Bit); } @@ -1811,20 +1846,25 @@ ID.AddPointer(I); } +VarDefInit::VarDefInit(Record *Class, unsigned N) + : TypedInit(IK_VarDefInit, RecordRecTy::get(Class)), Class(Class), + NumArgs(N) {} + VarDefInit *VarDefInit::get(Record *Class, ArrayRef Args) { FoldingSetNodeID ID; ProfileVarDefInit(ID, Class, Args); + detail::RecordKeeperImpl &RK = Class->getRecords().getImpl(); void *IP = nullptr; - if (VarDefInit *I = Context->TheVarDefInitPool.FindNodeOrInsertPos(ID, IP)) + if (VarDefInit *I = RK.TheVarDefInitPool.FindNodeOrInsertPos(ID, IP)) return I; - void *Mem = Context->Allocator.Allocate(totalSizeToAlloc(Args.size()), - alignof(VarDefInit)); + void *Mem = RK.Allocator.Allocate(totalSizeToAlloc(Args.size()), + alignof(VarDefInit)); VarDefInit *I = new (Mem) VarDefInit(Class, Args.size()); std::uninitialized_copy(Args.begin(), Args.end(), I->getTrailingObjects()); - Context->TheVarDefInitPool.InsertNode(I, IP); + RK.TheVarDefInitPool.InsertNode(I, IP); return I; } @@ -1930,14 +1970,15 @@ } FieldInit *FieldInit::get(Init *R, StringInit *FN) { - FieldInit *&I = Context->TheFieldInitPool[std::make_pair(R, FN)]; + detail::RecordKeeperImpl &RK = R->getRecordKeeper().getImpl(); + FieldInit *&I = RK.TheFieldInitPool[std::make_pair(R, FN)]; if (!I) - I = new (Context->Allocator) FieldInit(R, FN); + I = new (RK.Allocator) FieldInit(R, FN); return I; } Init *FieldInit::getBit(unsigned Bit) const { - if (getType() == BitRecTy::get()) + if (getType() == BitRecTy::get(getRecordKeeper())) return const_cast(this); return VarBitInit::get(const_cast(this), Bit); } @@ -1995,20 +2036,20 @@ ValType); } -CondOpInit * -CondOpInit::get(ArrayRef CondRange, - ArrayRef ValRange, RecTy *Ty) { +CondOpInit *CondOpInit::get(ArrayRef CondRange, + ArrayRef ValRange, RecTy *Ty) { assert(CondRange.size() == ValRange.size() && "Number of conditions and values must match!"); FoldingSetNodeID ID; ProfileCondOpInit(ID, CondRange, ValRange, Ty); + detail::RecordKeeperImpl &RK = Ty->getRecordKeeper().getImpl(); void *IP = nullptr; - if (CondOpInit *I = Context->TheCondOpInitPool.FindNodeOrInsertPos(ID, IP)) + if (CondOpInit *I = RK.TheCondOpInitPool.FindNodeOrInsertPos(ID, IP)) return I; - void *Mem = Context->Allocator.Allocate( + void *Mem = RK.Allocator.Allocate( totalSizeToAlloc(2 * CondRange.size()), alignof(BitsInit)); CondOpInit *I = new(Mem) CondOpInit(CondRange.size(), Ty); @@ -2016,7 +2057,7 @@ I->getTrailingObjects()); std::uninitialized_copy(ValRange.begin(), ValRange.end(), I->getTrailingObjects()+CondRange.size()); - Context->TheCondOpInitPool.InsertNode(I, IP); + RK.TheCondOpInitPool.InsertNode(I, IP); return I; } @@ -2044,16 +2085,18 @@ } Init *CondOpInit::Fold(Record *CurRec) const { + RecordKeeper &RK = getRecordKeeper(); for ( unsigned i = 0; i < NumConds; ++i) { Init *Cond = getCond(i); Init *Val = getVal(i); if (IntInit *CondI = dyn_cast_or_null( - Cond->convertInitializerTo(IntRecTy::get()))) { + Cond->convertInitializerTo(IntRecTy::get(RK)))) { if (CondI->getValue()) return Val->convertInitializerTo(getValType()); - } else - return const_cast(this); + } else { + return const_cast(this); + } } PrintFatalError(CurRec->getLoc(), @@ -2123,11 +2166,12 @@ FoldingSetNodeID ID; ProfileDagInit(ID, V, VN, ArgRange, NameRange); + detail::RecordKeeperImpl &RK = V->getRecordKeeper().getImpl(); void *IP = nullptr; - if (DagInit *I = Context->TheDagInitPool.FindNodeOrInsertPos(ID, IP)) + if (DagInit *I = RK.TheDagInitPool.FindNodeOrInsertPos(ID, IP)) return I; - void *Mem = Context->Allocator.Allocate( + void *Mem = RK.Allocator.Allocate( totalSizeToAlloc(ArgRange.size(), NameRange.size()), alignof(BitsInit)); DagInit *I = new (Mem) DagInit(V, VN, ArgRange.size(), NameRange.size()); @@ -2135,7 +2179,7 @@ I->getTrailingObjects()); std::uninitialized_copy(NameRange.begin(), NameRange.end(), I->getTrailingObjects()); - Context->TheDagInitPool.InsertNode(I, IP); + RK.TheDagInitPool.InsertNode(I, IP); return I; } @@ -2212,7 +2256,7 @@ RecordVal::RecordVal(Init *N, RecTy *T, FieldKind K) : Name(N), TyAndKind(T, K) { - setValue(UnsetInit::get()); + setValue(UnsetInit::get(N->getRecordKeeper())); assert(Value && "Cannot create unset value for current type!"); } @@ -2220,7 +2264,7 @@ // a source location. RecordVal::RecordVal(Init *N, SMLoc Loc, RecTy *T, FieldKind K) : Name(N), Loc(Loc), TyAndKind(T, K) { - setValue(UnsetInit::get()); + setValue(UnsetInit::get(N->getRecordKeeper())); assert(Value && "Cannot create unset value for current type!"); } @@ -2229,7 +2273,7 @@ } std::string RecordVal::getPrintType() const { - if (getType() == StringRecTy::get()) { + if (getType() == StringRecTy::get(getRecordKeeper())) { if (auto *StrInit = dyn_cast(Value)) { if (StrInit->hasCodeFormat()) return "code"; @@ -2255,7 +2299,7 @@ Bits.reserve(BTy->getNumBits()); for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I) Bits.push_back(Value->getBit(I)); - Value = BitsInit::get(Bits); + Value = BitsInit::get(V->getRecordKeeper(), Bits); } } } @@ -2280,7 +2324,7 @@ Bits.reserve(BTy->getNumBits()); for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I) Bits.push_back(Value->getBit(I)); - Value = BitsInit::get(Bits); + Value = BitsInit::get(getRecordKeeper(), Bits); } } } @@ -2316,16 +2360,20 @@ RecordRecTy *Record::getType() { SmallVector DirectSCs; getDirectSuperClasses(DirectSCs); - return RecordRecTy::get(DirectSCs); + return RecordRecTy::get(TrackedRecords, DirectSCs); } DefInit *Record::getDefInit() { - if (!CorrespondingDefInit) - CorrespondingDefInit = new (Context->Allocator) DefInit(this); + if (!CorrespondingDefInit) { + CorrespondingDefInit = + new (TrackedRecords.getImpl().Allocator) DefInit(this); + } return CorrespondingDefInit; } -unsigned Record::getNewUID() { return Context->LastRecordID++; } +unsigned Record::getNewUID(RecordKeeper &RK) { + return RK.getImpl().LastRecordID++; +} void Record::setName(Init *NewName) { Name = NewName; @@ -2674,6 +2722,10 @@ } } +RecordKeeper::RecordKeeper() + : Impl(std::make_unique(*this)) {} +RecordKeeper::~RecordKeeper() = default; + #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void RecordKeeper::dump() const { errs() << *this; } #endif @@ -2692,7 +2744,7 @@ /// GetNewAnonymousName - Generate a unique anonymous name that can be used as /// an identifier. Init *RecordKeeper::getNewAnonymousName() { - return AnonymousNameInit::get(AnonCounter++); + return AnonymousNameInit::get(*this, getImpl().AnonCounter++); } // These functions implement the phase timing facility. Starting a timer diff --git a/llvm/lib/TableGen/RecordContext.h b/llvm/lib/TableGen/RecordContext.h deleted file mode 100644 --- a/llvm/lib/TableGen/RecordContext.h +++ /dev/null @@ -1,27 +0,0 @@ -//===- RecordContext.h - RecordContext implementation ---------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file contains functions for interacting with the tablegen record -// context. -// -//===----------------------------------------------------------------------===// - -namespace llvm { -namespace detail { - -/// Resets the Tablegen record context and all currently parsed record data. -/// Tablegen currently relies on a lot of static data to keep track of parsed -/// records, which accumulates into static fields. This method resets all of -/// that data to enable successive executions of the tablegen parser. -/// FIXME: Ideally tablegen would use a properly scoped (non-static) context, -/// which would remove any need for managing the context in this way. In that -/// case, this method could be removed. -void resetTablegenRecordContext(); - -} // end namespace detail -} // end namespace llvm diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp --- a/llvm/lib/TableGen/TGParser.cpp +++ b/llvm/lib/TableGen/TGParser.cpp @@ -112,14 +112,15 @@ /// Return an Init with a qualifier prefix referring /// to CurRec's name. -static Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass, - Init *Name, StringRef Scoper) { - Init *NewName = - BinOpInit::getStrConcat(CurRec.getNameInit(), StringInit::get(Scoper)); +static Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass, Init *Name, + StringRef Scoper) { + RecordKeeper &RK = CurRec.getRecords(); + Init *NewName = BinOpInit::getStrConcat(CurRec.getNameInit(), + StringInit::get(RK, Scoper)); NewName = BinOpInit::getStrConcat(NewName, Name); if (CurMultiClass && Scoper != "::") { Init *Prefix = BinOpInit::getStrConcat(CurMultiClass->Rec.getNameInit(), - StringInit::get("::")); + StringInit::get(RK, "::")); NewName = BinOpInit::getStrConcat(Prefix, NewName); } @@ -131,7 +132,8 @@ /// Return the qualified version of the implicit 'NAME' template argument. static Init *QualifiedNameOfImplicitName(Record &Rec, MultiClass *MC = nullptr) { - return QualifyName(Rec, MC, StringInit::get("NAME"), MC ? "::" : ":"); + return QualifyName(Rec, MC, StringInit::get(Rec.getRecords(), "NAME"), + MC ? "::" : ":"); } static Init *QualifiedNameOfImplicitName(MultiClass *MC) { @@ -187,7 +189,7 @@ "' is not a bits type"); // Convert the incoming value to a bits type of the appropriate size... - Init *BI = V->getCastTo(BitsRecTy::get(BitList.size())); + Init *BI = V->getCastTo(BitsRecTy::get(Records, BitList.size())); if (!BI) return Error(Loc, "Initializer is not compatible with bit range"); @@ -206,7 +208,7 @@ if (!NewBits[i]) NewBits[i] = CurVal->getBit(i); - V = BitsInit::get(NewBits); + V = BitsInit::get(Records, NewBits); } if (RV->setValue(V, Loc)) { @@ -262,8 +264,8 @@ Init *Name; if (CurRec->isClass()) - Name = - VarInit::get(QualifiedNameOfImplicitName(*CurRec), StringRecTy::get()); + Name = VarInit::get(QualifiedNameOfImplicitName(*CurRec), + StringRecTy::get(Records)); else Name = CurRec->getNameInit(); R.set(QualifiedNameOfImplicitName(*SC), Name); @@ -333,9 +335,9 @@ } } - TemplateArgs.emplace_back( - QualifiedNameOfImplicitName(SMC), - VarInit::get(QualifiedNameOfImplicitName(CurMC), StringRecTy::get())); + TemplateArgs.emplace_back(QualifiedNameOfImplicitName(SMC), + VarInit::get(QualifiedNameOfImplicitName(CurMC), + StringRecTy::get(Records))); // Add all of the defs in the subclass into the current multiclass. return resolve(SMC->Entries, TemplateArgs, false, &CurMC->Entries); @@ -540,7 +542,7 @@ // These are all of the tokens that can begin an object body. // Some of these can also begin values but we disallow those cases // because they are unlikely to be useful. - return UnsetInit::get(); + return UnsetInit::get(Records); default: break; } @@ -549,7 +551,7 @@ if (CurMultiClass) CurRec = &CurMultiClass->Rec; - Init *Name = ParseValue(CurRec, StringRecTy::get(), ParseNameMode); + Init *Name = ParseValue(CurRec, StringRecTy::get(Records), ParseNameMode); if (!Name) return nullptr; @@ -558,8 +560,8 @@ HasReferenceResolver R(NameStr); Name->resolveReferences(R); if (!R.found()) - Name = BinOpInit::getStrConcat(VarInit::get(NameStr, StringRecTy::get()), - Name); + Name = BinOpInit::getStrConcat( + VarInit::get(NameStr, StringRecTy::get(Records)), Name); } return Name; @@ -812,12 +814,21 @@ switch (Lex.getCode()) { default: TokError("Unknown token when expecting a type"); return nullptr; case tgtok::String: - case tgtok::Code: Lex.Lex(); return StringRecTy::get(); - case tgtok::Bit: Lex.Lex(); return BitRecTy::get(); - case tgtok::Int: Lex.Lex(); return IntRecTy::get(); - case tgtok::Dag: Lex.Lex(); return DagRecTy::get(); + case tgtok::Code: + Lex.Lex(); + return StringRecTy::get(Records); + case tgtok::Bit: + Lex.Lex(); + return BitRecTy::get(Records); + case tgtok::Int: + Lex.Lex(); + return IntRecTy::get(Records); + case tgtok::Dag: + Lex.Lex(); + return DagRecTy::get(Records); case tgtok::Id: - if (Record *R = ParseClassID()) return RecordRecTy::get(R); + if (Record *R = ParseClassID()) + return RecordRecTy::get(R); TokError("unknown class name"); return nullptr; case tgtok::Bits: { @@ -835,7 +846,7 @@ return nullptr; } Lex.Lex(); // Eat '>' - return BitsRecTy::get(Val); + return BitsRecTy::get(Records, Val); } case tgtok::List: { if (Lex.Lex() != tgtok::less) { // Eat 'bits' @@ -878,7 +889,7 @@ RV->setUsed(true); return VarInit::get(TemplateArgName, RV->getType()); } else if (Name->getValue() == "NAME") { - return VarInit::get(TemplateArgName, StringRecTy::get()); + return VarInit::get(TemplateArgName, StringRecTy::get(Records)); } } @@ -947,7 +958,7 @@ case tgtok::XNOT: Lex.Lex(); // eat the operation Code = UnOpInit::NOT; - Type = IntRecTy::get(); + Type = IntRecTy::get(Records); break; case tgtok::XHead: Lex.Lex(); // eat the operation @@ -960,12 +971,12 @@ case tgtok::XSize: Lex.Lex(); Code = UnOpInit::SIZE; - Type = IntRecTy::get(); + Type = IntRecTy::get(Records); break; case tgtok::XEmpty: Lex.Lex(); // eat the operation Code = UnOpInit::EMPTY; - Type = IntRecTy::get(); + Type = IntRecTy::get(Records); break; case tgtok::XGetDagOp: Lex.Lex(); // eat the operation @@ -985,7 +996,7 @@ // but keep parsing, to consume the operand } } else { - Type = RecordRecTy::get({}); + Type = RecordRecTy::get(Records, {}); } Code = UnOpInit::GETDAGOP; break; @@ -1143,8 +1154,8 @@ llvm_unreachable("Unhandled code!"); case tgtok::XConcat: case tgtok::XSetDagOp: - Type = DagRecTy::get(); - ArgType = DagRecTy::get(); + Type = DagRecTy::get(Records); + ArgType = DagRecTy::get(Records); break; case tgtok::XAND: case tgtok::XOR: @@ -1155,8 +1166,8 @@ case tgtok::XADD: case tgtok::XSUB: case tgtok::XMUL: - Type = IntRecTy::get(); - ArgType = IntRecTy::get(); + Type = IntRecTy::get(Records); + ArgType = IntRecTy::get(Records); break; case tgtok::XEq: case tgtok::XNe: @@ -1164,7 +1175,7 @@ case tgtok::XLt: case tgtok::XGe: case tgtok::XGt: - Type = BitRecTy::get(); + Type = BitRecTy::get(Records); // ArgType for the comparison operators is not yet known. break; case tgtok::XListConcat: @@ -1175,11 +1186,11 @@ // Can't do any typechecking until we parse the first argument. break; case tgtok::XStrConcat: - Type = StringRecTy::get(); - ArgType = StringRecTy::get(); + Type = StringRecTy::get(Records); + ArgType = StringRecTy::get(Records); break; case tgtok::XInterleave: - Type = StringRecTy::get(); + Type = StringRecTy::get(Records); // The first argument type is not yet known. } @@ -1253,9 +1264,9 @@ break; case BinOpInit::EQ: case BinOpInit::NE: - if (!ArgType->typeIsConvertibleTo(IntRecTy::get()) && - !ArgType->typeIsConvertibleTo(StringRecTy::get()) && - !ArgType->typeIsConvertibleTo(RecordRecTy::get({}))) { + if (!ArgType->typeIsConvertibleTo(IntRecTy::get(Records)) && + !ArgType->typeIsConvertibleTo(StringRecTy::get(Records)) && + !ArgType->typeIsConvertibleTo(RecordRecTy::get(Records, {}))) { Error(InitLoc, Twine("expected bit, bits, int, string, or record; " "got value of type '") + ArgType->getAsString() + "'"); @@ -1266,8 +1277,8 @@ case BinOpInit::LT: case BinOpInit::GE: case BinOpInit::GT: - if (!ArgType->typeIsConvertibleTo(IntRecTy::get()) && - !ArgType->typeIsConvertibleTo(StringRecTy::get())) { + if (!ArgType->typeIsConvertibleTo(IntRecTy::get(Records)) && + !ArgType->typeIsConvertibleTo(StringRecTy::get(Records))) { Error(InitLoc, Twine("expected bit, bits, int, or string; " "got value of type '") + ArgType->getAsString() + "'"); @@ -1277,8 +1288,9 @@ case BinOpInit::INTERLEAVE: switch (InitList.size()) { case 1: // First argument must be a list of strings or integers. - if (ArgType != StringRecTy::get()->getListTy() && - !ArgType->typeIsConvertibleTo(IntRecTy::get()->getListTy())) { + if (ArgType != StringRecTy::get(Records)->getListTy() && + !ArgType->typeIsConvertibleTo( + IntRecTy::get(Records)->getListTy())) { Error(InitLoc, Twine("expected list of string, int, bits, or bit; " "got value of type '") + ArgType->getAsString() + "'"); @@ -1323,7 +1335,7 @@ case BinOpInit::SETDAGOP: // After parsing the first dag argument, switch to expecting // a record, with no restriction on its superclasses. - ArgType = RecordRecTy::get({}); + ArgType = RecordRecTy::get(Records, {}); break; default: break; @@ -1383,7 +1395,7 @@ default: llvm_unreachable("Unhandled code!"); case tgtok::XDag: Code = TernOpInit::DAG; - Type = DagRecTy::get(); + Type = DagRecTy::get(Records); ItemType = nullptr; break; case tgtok::XIf: @@ -1445,7 +1457,7 @@ Error(RHSLoc, "could not determine type of the name list in !dag"); return nullptr; } - if (RHSt && StringRecTy::get()->getListTy() != RHSt->getType()) { + if (RHSt && StringRecTy::get(Records)->getListTy() != RHSt->getType()) { Error(RHSLoc, Twine("expected list, got type '") + RHSt->getType()->getAsString() + "'"); return nullptr; @@ -1465,16 +1477,16 @@ if (TypedInit *MHSt = dyn_cast(MHS)) MHSTy = MHSt->getType(); if (BitsInit *MHSbits = dyn_cast(MHS)) - MHSTy = BitsRecTy::get(MHSbits->getNumBits()); + MHSTy = BitsRecTy::get(Records, MHSbits->getNumBits()); if (isa(MHS)) - MHSTy = BitRecTy::get(); + MHSTy = BitRecTy::get(Records); if (TypedInit *RHSt = dyn_cast(RHS)) RHSTy = RHSt->getType(); if (BitsInit *RHSbits = dyn_cast(RHS)) - RHSTy = BitsRecTy::get(RHSbits->getNumBits()); + RHSTy = BitsRecTy::get(Records, RHSbits->getNumBits()); if (isa(RHS)) - RHSTy = BitRecTy::get(); + RHSTy = BitRecTy::get(Records); // For UnsetInit, it's typed from the other hand. if (isa(MHS)) @@ -1569,7 +1581,7 @@ return nullptr; } - Init *A = StringInit::get(Lex.getCurStrVal()); + Init *A = StringInit::get(Records, Lex.getCurStrVal()); if (CurRec && CurRec->getValue(A)) { TokError((Twine("left !foldl variable '") + A->getAsString() + "' already defined") @@ -1587,7 +1599,7 @@ return nullptr; } - Init *B = StringInit::get(Lex.getCurStrVal()); + Init *B = StringInit::get(Records, Lex.getCurStrVal()); if (CurRec && CurRec->getValue(B)) { TokError((Twine("right !foldl variable '") + B->getAsString() + "' already defined") @@ -1679,7 +1691,7 @@ /// Substr ::= !substr(string, start-int [, length-int]) => string Init *TGParser::ParseOperationSubstr(Record *CurRec, RecTy *ItemType) { TernOpInit::TernaryOp Code = TernOpInit::SUBSTR; - RecTy *Type = StringRecTy::get(); + RecTy *Type = StringRecTy::get(Records); Lex.Lex(); // eat the operation @@ -1710,7 +1722,7 @@ if (!RHS) return nullptr; } else { - RHS = IntInit::get(std::numeric_limits::max()); + RHS = IntInit::get(Records, std::numeric_limits::max()); } if (!consume(tgtok::r_paren)) { @@ -1767,7 +1779,7 @@ /// Substr ::= !find(string, string [, start-int]) => int Init *TGParser::ParseOperationFind(Record *CurRec, RecTy *ItemType) { TernOpInit::TernaryOp Code = TernOpInit::FIND; - RecTy *Type = IntRecTy::get(); + RecTy *Type = IntRecTy::get(Records); Lex.Lex(); // eat the operation @@ -1798,7 +1810,7 @@ if (!RHS) return nullptr; } else { - RHS = IntInit::get(0); + RHS = IntInit::get(Records, 0); } if (!consume(tgtok::r_paren)) { @@ -1868,7 +1880,7 @@ return nullptr; } - Init *LHS = StringInit::get(Lex.getCurStrVal()); + Init *LHS = StringInit::get(Records, Lex.getCurStrVal()); Lex.Lex(); // eat the ID. if (CurRec && CurRec->getValue(LHS)) { @@ -1908,7 +1920,7 @@ if (ListRecTy *OutListTy = dyn_cast(ItemType)) { ExprEltType = (Operation == tgtok::XForEach) ? OutListTy->getElementType() - : IntRecTy::get(); + : IntRecTy::get(Records); } else { Error(OpLoc, "expected value of type '" + @@ -2028,9 +2040,9 @@ if (TypedInit *Vt = dyn_cast(V)) VTy = Vt->getType(); if (BitsInit *Vbits = dyn_cast(V)) - VTy = BitsRecTy::get(Vbits->getNumBits()); + VTy = BitsRecTy::get(Records, Vbits->getNumBits()); if (isa(V)) - VTy = BitRecTy::get(); + VTy = BitRecTy::get(Records); if (Type == nullptr) { if (!isa(V)) @@ -2084,23 +2096,23 @@ default: TokError("Unknown or reserved token when parsing a value"); break; case tgtok::TrueVal: - R = IntInit::get(1); + R = IntInit::get(Records, 1); Lex.Lex(); break; case tgtok::FalseVal: - R = IntInit::get(0); + R = IntInit::get(Records, 0); Lex.Lex(); break; case tgtok::IntVal: - R = IntInit::get(Lex.getCurIntVal()); + R = IntInit::get(Records, Lex.getCurIntVal()); Lex.Lex(); break; case tgtok::BinaryIntVal: { auto BinaryVal = Lex.getCurBinaryIntVal(); SmallVector Bits(BinaryVal.second); for (unsigned i = 0, e = BinaryVal.second; i != e; ++i) - Bits[i] = BitInit::get(BinaryVal.first & (1LL << i)); - R = BitsInit::get(Bits); + Bits[i] = BitInit::get(Records, BinaryVal.first & (1LL << i)); + R = BitsInit::get(Records, Bits); Lex.Lex(); break; } @@ -2114,20 +2126,20 @@ Lex.Lex(); } - R = StringInit::get(Val); + R = StringInit::get(Records, Val); break; } case tgtok::CodeFragment: - R = StringInit::get(Lex.getCurStrVal(), StringInit::SF_Code); + R = StringInit::get(Records, Lex.getCurStrVal(), StringInit::SF_Code); Lex.Lex(); break; case tgtok::question: - R = UnsetInit::get(); + R = UnsetInit::get(Records); Lex.Lex(); break; case tgtok::Id: { SMLoc NameLoc = Lex.getLoc(); - StringInit *Name = StringInit::get(Lex.getCurStrVal()); + StringInit *Name = StringInit::get(Records, Lex.getCurStrVal()); if (Lex.Lex() != tgtok::less) // consume the Id. return ParseIDValue(CurRec, Name, NameLoc, Mode); // Value ::= IDValue @@ -2202,7 +2214,7 @@ // Fallthrough to try convert this to a bit. } // All other values must be convertible to just a single bit. - Init *Bit = Vals[i]->getCastTo(BitRecTy::get()); + Init *Bit = Vals[i]->getCastTo(BitRecTy::get(Records)); if (!Bit) { Error(BraceLoc, "Element #" + Twine(i) + " (" + Vals[i]->getAsString() + ") is not convertable to a bit"); @@ -2211,7 +2223,7 @@ NewBits.push_back(Bit); } std::reverse(NewBits.begin(), NewBits.end()); - return BitsInit::get(NewBits); + return BitsInit::get(Records, NewBits); } case tgtok::l_square: { // Value ::= '[' ValueList ']' Lex.Lex(); // eat the '[' @@ -2322,7 +2334,7 @@ TokError("expected variable name in dag operator"); return nullptr; } - OperatorName = StringInit::get(Lex.getCurStrVal()); + OperatorName = StringInit::get(Records, Lex.getCurStrVal()); Lex.Lex(); // eat the VarName. } @@ -2451,7 +2463,7 @@ TokError("expected field identifier after '.'"); return nullptr; } - StringInit *FieldName = StringInit::get(Lex.getCurStrVal()); + StringInit *FieldName = StringInit::get(Records, Lex.getCurStrVal()); if (!Result->getFieldType(FieldName)) { TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" + Result->getAsString() + "'"); @@ -2494,9 +2506,9 @@ // Create a !strconcat() operation, first casting each operand to // a string if necessary. - if (LHS->getType() != StringRecTy::get()) { + if (LHS->getType() != StringRecTy::get(Records)) { auto CastLHS = dyn_cast( - UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get()) + UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get(Records)) ->Fold(CurRec)); if (!CastLHS) { Error(PasteLoc, @@ -2518,7 +2530,7 @@ // because they are unlikely to be useful. // Trailing paste, concat with an empty string. - RHS = StringInit::get(""); + RHS = StringInit::get(Records, ""); break; default: @@ -2531,9 +2543,9 @@ return nullptr; } - if (RHS->getType() != StringRecTy::get()) { + if (RHS->getType() != StringRecTy::get(Records)) { auto CastRHS = dyn_cast( - UnOpInit::get(UnOpInit::CAST, RHS, StringRecTy::get()) + UnOpInit::get(UnOpInit::CAST, RHS, StringRecTy::get(Records)) ->Fold(CurRec)); if (!CastRHS) { Error(PasteLoc, @@ -2566,8 +2578,8 @@ // DagArg ::= VARNAME if (Lex.getCode() == tgtok::VarName) { // A missing value is treated like '?'. - StringInit *VarName = StringInit::get(Lex.getCurStrVal()); - Result.emplace_back(UnsetInit::get(), VarName); + StringInit *VarName = StringInit::get(Records, Lex.getCurStrVal()); + Result.emplace_back(UnsetInit::get(Records), VarName); Lex.Lex(); } else { // DagArg ::= Value (':' VARNAME)? @@ -2585,7 +2597,7 @@ Result.clear(); return; } - VarName = StringInit::get(Lex.getCurStrVal()); + VarName = StringInit::get(Records, Lex.getCurStrVal()); Lex.Lex(); // eat the VarName. } @@ -2692,7 +2704,7 @@ } SMLoc IdLoc = Lex.getLoc(); - Init *DeclName = StringInit::get(Str); + Init *DeclName = StringInit::get(Records, Str); Lex.Lex(); bool BadField; @@ -2745,7 +2757,7 @@ return nullptr; } - Init *DeclName = StringInit::get(Lex.getCurStrVal()); + Init *DeclName = StringInit::get(Records, Lex.getCurStrVal()); Lex.Lex(); // If a value is present, parse it. @@ -2799,10 +2811,10 @@ if (!Ranges.empty()) { assert(!IterType && "Type already initialized?"); - IterType = IntRecTy::get(); + IterType = IntRecTy::get(Records); std::vector Values; for (unsigned R : Ranges) - Values.push_back(IntInit::get(R)); + Values.push_back(IntInit::get(Records, R)); ForeachListValue = ListInit::get(Values, IterType); } @@ -2879,7 +2891,7 @@ return TokError("expected field identifier after let"); SMLoc IdLoc = Lex.getLoc(); - StringInit *FieldName = StringInit::get(Lex.getCurStrVal()); + StringInit *FieldName = StringInit::get(Records, Lex.getCurStrVal()); Lex.Lex(); // eat the field name. SmallVector BitList; @@ -2898,7 +2910,7 @@ if (!BitList.empty() && isa(Type)) { // When assigning to a subset of a 'bits' object, expect the RHS to have // the type of that subset instead of the type of the whole object. - Type = BitsRecTy::get(BitList.size()); + Type = BitsRecTy::get(Records, BitList.size()); } Init *Val = ParseValue(CurRec, Type); @@ -3056,7 +3068,7 @@ if (Lex.getCode() != tgtok::Id) return TokError("expected identifier"); - StringInit *DeclName = StringInit::get(Lex.getCurStrVal()); + StringInit *DeclName = StringInit::get(Records, Lex.getCurStrVal()); if (Records.getGlobal(DeclName->getValue())) return TokError("def or global variable of this name already exists"); @@ -3093,7 +3105,7 @@ if (Lex.getCode() != tgtok::Id) return TokError("expected identifier"); - StringInit *DeclName = StringInit::get(Lex.getCurStrVal()); + StringInit *DeclName = StringInit::get(Records, Lex.getCurStrVal()); if (CurLocalScope) { if (CurLocalScope->varAlreadyDefined(DeclName->getValue())) return TokError("local variable of this name already exists"); @@ -3201,10 +3213,10 @@ // loop, over a list of length 0 or 1 depending on the condition, and with no // iteration variable being assigned. - ListInit *EmptyList = ListInit::get({}, BitRecTy::get()); + ListInit *EmptyList = ListInit::get({}, BitRecTy::get(Records)); ListInit *SingletonList = - ListInit::get({BitInit::get(true)}, BitRecTy::get()); - RecTy *BitListTy = ListRecTy::get(BitRecTy::get()); + ListInit::get({BitInit::get(Records, true)}, BitRecTy::get(Records)); + RecTy *BitListTy = ListRecTy::get(BitRecTy::get(Records)); // The foreach containing the then-clause selects SingletonList if // the condition is true. @@ -3369,7 +3381,7 @@ return; } - StringInit *Name = StringInit::get(Lex.getCurStrVal()); + StringInit *Name = StringInit::get(Records, Lex.getCurStrVal()); SMLoc NameLoc = Lex.getLoc(); Lex.Lex(); // Eat the identifier. @@ -3570,7 +3582,7 @@ if (CurMultiClass) DefmName = BinOpInit::getStrConcat( VarInit::get(QualifiedNameOfImplicitName(CurMultiClass), - StringRecTy::get()), + StringRecTy::get(Records)), DefmName); } diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp --- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -2816,6 +2816,7 @@ TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName) { + RecordKeeper &RK = TheInit->getRecordKeeper(); if (DefInit *DI = dyn_cast(TheInit)) { Record *R = DI->getDef(); @@ -2854,13 +2855,13 @@ if (!OpName.empty()) error("Constant int or bit argument should not have a name!"); if (isa(TheInit)) - TheInit = TheInit->convertInitializerTo(IntRecTy::get()); + TheInit = TheInit->convertInitializerTo(IntRecTy::get(RK)); return std::make_shared(TheInit, 1); } if (BitsInit *BI = dyn_cast(TheInit)) { // Turn this into an IntInit. - Init *II = BI->convertInitializerTo(IntRecTy::get()); + Init *II = BI->convertInitializerTo(IntRecTy::get(RK)); if (!II || !isa(II)) error("Bits value must be constants!"); return ParseTreePattern(II, OpName); @@ -2959,8 +2960,8 @@ else // Otherwise, no chain. Operator = getDAGPatterns().get_intrinsic_wo_chain_sdnode(); - Children.insert(Children.begin(), - std::make_shared(IntInit::get(IID), 1)); + Children.insert(Children.begin(), std::make_shared( + IntInit::get(RK, IID), 1)); } if (Operator->isSubClassOf("ComplexPattern")) { @@ -4367,7 +4368,7 @@ PatternsToMatch.emplace_back(P.getSrcRecord(), P.getPredicates(), std::move(NewSrc), std::move(NewDst), P.getDstRegs(), P.getAddedComplexity(), - Record::getNewUID(), Mode, Check); + Record::getNewUID(Records), Mode, Check); }; for (PatternToMatch &P : Copy) { @@ -4743,7 +4744,7 @@ PatternsToMatch[i].getSrcRecord(), PatternsToMatch[i].getPredicates(), Variant, PatternsToMatch[i].getDstPatternShared(), PatternsToMatch[i].getDstRegs(), - PatternsToMatch[i].getAddedComplexity(), Record::getNewUID(), + PatternsToMatch[i].getAddedComplexity(), Record::getNewUID(Records), PatternsToMatch[i].getForceMode(), PatternsToMatch[i].getHwModeFeatures()); } diff --git a/llvm/utils/TableGen/CodeGenInstruction.cpp b/llvm/utils/TableGen/CodeGenInstruction.cpp --- a/llvm/utils/TableGen/CodeGenInstruction.cpp +++ b/llvm/utils/TableGen/CodeGenInstruction.cpp @@ -632,8 +632,8 @@ if (!BI->isComplete()) return false; // Convert the bits init to an integer and use that for the result. - IntInit *II = - dyn_cast_or_null(BI->convertInitializerTo(IntRecTy::get())); + IntInit *II = dyn_cast_or_null( + BI->convertInitializerTo(IntRecTy::get(BI->getRecordKeeper()))); if (!II) return false; ResOp = ResultOperand(II->getValue()); diff --git a/llvm/utils/TableGen/CodeGenRegisters.cpp b/llvm/utils/TableGen/CodeGenRegisters.cpp --- a/llvm/utils/TableGen/CodeGenRegisters.cpp +++ b/llvm/utils/TableGen/CodeGenRegisters.cpp @@ -638,6 +638,7 @@ Def->getValueAsListOfStrings("RegAsmNames"); // Zip them up. + RecordKeeper &RK = Def->getRecords(); for (unsigned n = 0; n != Length; ++n) { std::string Name; Record *Proto = Lists[0][n]; @@ -654,13 +655,13 @@ SmallVector CostPerUse; CostPerUse.insert(CostPerUse.end(), CostList->begin(), CostList->end()); - StringInit *AsmName = StringInit::get(""); + StringInit *AsmName = StringInit::get(RK, ""); if (!RegNames.empty()) { if (RegNames.size() <= n) PrintFatalError(Def->getLoc(), "Register tuple definition missing name for '" + Name + "'."); - AsmName = StringInit::get(RegNames[n]); + AsmName = StringInit::get(RK, RegNames[n]); } // Create a new Record representing the synthesized register. This record @@ -699,7 +700,7 @@ // Composite registers are always covered by sub-registers. if (Field == "CoveredBySubRegs") - RV.setValue(BitInit::get(true)); + RV.setValue(BitInit::get(RK, true)); // Copy fields from the RegisterTuples def. if (Field == "SubRegIndices" || diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp --- a/llvm/utils/TableGen/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/CodeGenTarget.cpp @@ -552,7 +552,7 @@ NewBits[middle] = BI->getBit(middle); } - BitsInit *NewBI = BitsInit::get(NewBits); + BitsInit *NewBI = BitsInit::get(Records, NewBits); // Update the bits in reversed order so that emitInstrOpBits will get the // correct endianness. diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -236,11 +236,11 @@ Bits.push_back(const_cast(BI)); } else { for (unsigned Idx = 0U; Idx < SI.BitWidth; ++Idx) - Bits.push_back(UnsetInit::get()); + Bits.push_back(UnsetInit::get(def.getRecords())); } } - return *BitsInit::get(Bits); + return *BitsInit::get(def.getRecords(), Bits); } // Representation of the instruction to work on. diff --git a/llvm/utils/TableGen/PseudoLoweringEmitter.cpp b/llvm/utils/TableGen/PseudoLoweringEmitter.cpp --- a/llvm/utils/TableGen/PseudoLoweringEmitter.cpp +++ b/llvm/utils/TableGen/PseudoLoweringEmitter.cpp @@ -109,7 +109,8 @@ OperandMap[BaseIdx + i].Data.Imm = II->getValue(); ++OpsAdded; } else if (auto *BI = dyn_cast(Dag->getArg(i))) { - auto *II = cast(BI->convertInitializerTo(IntRecTy::get())); + auto *II = + cast(BI->convertInitializerTo(IntRecTy::get(Records))); OperandMap[BaseIdx + i].Kind = OpData::Imm; OperandMap[BaseIdx + i].Data.Imm = II->getValue(); ++OpsAdded; diff --git a/llvm/utils/TableGen/SearchableTableEmitter.cpp b/llvm/utils/TableGen/SearchableTableEmitter.cpp --- a/llvm/utils/TableGen/SearchableTableEmitter.cpp +++ b/llvm/utils/TableGen/SearchableTableEmitter.cpp @@ -30,7 +30,9 @@ namespace { int getAsInt(Init *B) { - return cast(B->convertInitializerTo(IntRecTy::get()))->getValue(); + return cast( + B->convertInitializerTo(IntRecTy::get(B->getRecordKeeper()))) + ->getValue(); } int getInt(Record *R, StringRef Field) { return getAsInt(R->getValueInit(Field)); diff --git a/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp b/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp --- a/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp +++ b/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp @@ -37,9 +37,11 @@ if (!Def.getValue("Inst")) continue; auto &Inst = *Def.getValueAsBitsInit("Inst"); - auto Opc = static_cast( - reinterpret_cast(Inst.convertInitializerTo(IntRecTy::get())) - ->getValue()); + RecordKeeper &RK = Inst.getRecordKeeper(); + auto Opc = + static_cast(reinterpret_cast( + Inst.convertInitializerTo(IntRecTy::get(RK))) + ->getValue()); if (Opc == 0xFFFFFFFF) continue; // No opcode defined. assert(Opc <= 0xFFFFFF); @@ -55,7 +57,7 @@ // All wasm instructions have a StackBased field of type string, we only // want the instructions for which this is "true". auto StackString = - Def.getValue("StackBased")->getValue()->getCastTo(StringRecTy::get()); + Def.getValue("StackBased")->getValue()->getCastTo(StringRecTy::get(RK)); auto IsStackBased = StackString && reinterpret_cast(StackString)->getValue() == "true";