diff options
Diffstat (limited to 'llvm/lib/TableGen/Record.cpp')
| -rw-r--r-- | llvm/lib/TableGen/Record.cpp | 493 |
1 files changed, 314 insertions, 179 deletions
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp index 58d8c9936896..6c205104d569 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -24,7 +24,6 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/SMLoc.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TableGen/Error.h" @@ -46,14 +45,17 @@ using namespace llvm; 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<BitsRecTy *> SharedBitsRecTys; @@ -77,6 +79,7 @@ struct RecordContext { FoldingSet<TernOpInit> TheTernOpInitPool; FoldingSet<FoldOpInit> TheFoldOpInitPool; FoldingSet<IsAOpInit> TheIsAOpInitPool; + FoldingSet<ExistsOpInit> TheExistsOpInitPool; DenseMap<std::pair<RecTy *, Init *>, VarInit *> TheVarInitPool; DenseMap<std::pair<TypedInit *, unsigned>, VarBitInit *> TheVarBitInitPool; DenseMap<std::pair<TypedInit *, unsigned>, VarListElementInit *> @@ -85,14 +88,14 @@ struct RecordContext { DenseMap<std::pair<Init *, StringInit *>, FieldInit *> TheFieldInitPool; FoldingSet<CondOpInit> TheCondOpInitPool; FoldingSet<DagInit> TheDagInitPool; + FoldingSet<RecordRecTy> RecordTypePool; + unsigned AnonCounter; unsigned LastRecordID; }; } // namespace detail } // namespace llvm -ManagedStatic<detail::RecordContext> Context; - //===----------------------------------------------------------------------===// // Type implementations //===----------------------------------------------------------------------===// @@ -103,7 +106,7 @@ LLVM_DUMP_METHOD void RecTy::dump() const { print(errs()); } ListRecTy *RecTy::getListTy() { if (!ListTy) - ListTy = new(Context->Allocator) ListRecTy(this); + ListTy = new (RK.getImpl().Allocator) ListRecTy(this); return ListTy; } @@ -114,7 +117,9 @@ bool RecTy::typeIsConvertibleTo(const RecTy *RHS) const { 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) @@ -124,12 +129,13 @@ bool BitRecTy::typeIsConvertibleTo(const RecTy *RHS) const{ 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; } @@ -150,14 +156,18 @@ bool BitsRecTy::typeIsA(const RecTy *RHS) const { 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"; @@ -184,7 +194,9 @@ bool ListRecTy::typeIsA(const RecTy *RHS) const { return false; } -DagRecTy *DagRecTy::get() { return &Context->SharedDagRecTy; } +DagRecTy *DagRecTy::get(RecordKeeper &RK) { + return &RK.getImpl().SharedDagRecTy; +} std::string DagRecTy::getAsString() const { return "dag"; @@ -197,12 +209,13 @@ static void ProfileRecordRecTy(FoldingSetNodeID &ID, ID.AddPointer(R); } -RecordRecTy *RecordRecTy::get(ArrayRef<Record *> UnsortedClasses) { +RecordRecTy *RecordRecTy::get(RecordKeeper &RK, + ArrayRef<Record *> UnsortedClasses) { + detail::RecordKeeperImpl &RKImpl = RK.getImpl(); if (UnsortedClasses.empty()) - return &Context->AnyRecord; + return &RKImpl.AnyRecord; - FoldingSet<RecordRecTy> &ThePool = - UnsortedClasses[0]->getRecords().RecordTypePool; + FoldingSet<RecordRecTy> &ThePool = RKImpl.RecordTypePool; SmallVector<Record *, 4> Classes(UnsortedClasses.begin(), UnsortedClasses.end()); @@ -227,14 +240,18 @@ RecordRecTy *RecordRecTy::get(ArrayRef<Record *> UnsortedClasses) { } #endif - void *Mem = Context->Allocator.Allocate( + void *Mem = RKImpl.Allocator.Allocate( totalSizeToAlloc<Record *>(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<Record *>()); 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()); @@ -294,7 +311,7 @@ static RecordRecTy *resolveRecordTypes(RecordRecTy *T1, RecordRecTy *T2) { } } - return RecordRecTy::get(CommonSuperClasses); + return RecordRecTy::get(T1->getRecordKeeper(), CommonSuperClasses); } RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) { @@ -333,7 +350,15 @@ void Init::anchor() {} 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<TypedInit>(this)) + return TyInit->getType()->getRecordKeeper(); + return cast<UnsetInit>(this)->getRecordKeeper(); +} + +UnsetInit *UnsetInit::get(RecordKeeper &RK) { + return &RK.getImpl().TheUnsetInit; +} Init *UnsetInit::getCastTo(RecTy *Ty) const { return const_cast<UnsetInit *>(this); @@ -343,8 +368,8 @@ Init *UnsetInit::convertInitializerTo(RecTy *Ty) const { return const_cast<UnsetInit *>(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 { @@ -352,12 +377,12 @@ Init *BitInit::convertInitializerTo(RecTy *Ty) const { return const_cast<BitInit *>(this); if (isa<IntRecTy>(Ty)) - return IntInit::get(getValue()); + return IntInit::get(getRecordKeeper(), getValue()); if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) { // Can only convert single bit. if (BRT->getNumBits() == 1) - return BitsInit::get(const_cast<BitInit *>(this)); + return BitsInit::get(getRecordKeeper(), const_cast<BitInit *>(this)); } return nullptr; @@ -371,20 +396,21 @@ ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef<Init *> Range) { ID.AddPointer(I); } -BitsInit *BitsInit::get(ArrayRef<Init *> Range) { +BitsInit *BitsInit::get(RecordKeeper &RK, ArrayRef<Init *> 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<Init *>(Range.size()), alignof(BitsInit)); - BitsInit *I = new(Mem) BitsInit(Range.size()); + void *Mem = RKImpl.Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()), + alignof(BitsInit)); + BitsInit *I = new (Mem) BitsInit(RK, Range.size()); std::uninitialized_copy(Range.begin(), Range.end(), I->getTrailingObjects<Init *>()); - Context->TheBitsInitPool.InsertNode(I, IP); + RKImpl.TheBitsInitPool.InsertNode(I, IP); return I; } @@ -412,7 +438,7 @@ Init *BitsInit::convertInitializerTo(RecTy *Ty) const { Result |= static_cast<int64_t>(Bit->getValue()) << i; else return nullptr; - return IntInit::get(Result); + return IntInit::get(getRecordKeeper(), Result); } return nullptr; @@ -427,7 +453,7 @@ BitsInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const { return nullptr; NewBits[i] = getBit(Bits[i]); } - return BitsInit::get(NewBits); + return BitsInit::get(getRecordKeeper(), NewBits); } bool BitsInit::isConcrete() const { @@ -482,15 +508,15 @@ Init *BitsInit::resolveReferences(Resolver &R) const { } if (Changed) - return BitsInit::get(NewBits); + return BitsInit::get(getRecordKeeper(), NewBits); return const_cast<BitsInit *>(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; } @@ -511,7 +537,7 @@ Init *IntInit::convertInitializerTo(RecTy *Ty) const { if (isa<BitRecTy>(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<BitsRecTy>(Ty)) { @@ -522,9 +548,10 @@ Init *IntInit::convertInitializerTo(RecTy *Ty) const { SmallVector<Init *, 16> 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; @@ -538,17 +565,18 @@ IntInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const { 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 { @@ -565,12 +593,13 @@ Init *AnonymousNameInit::resolveReferences(Resolver &R) const { 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; } @@ -595,19 +624,20 @@ ListInit *ListInit::get(ArrayRef<Init *> Range, RecTy *EltTy) { 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<TypedInit>(Range[0]) || cast<TypedInit>(Range[0])->getType()->typeIsConvertibleTo(EltTy)); - void *Mem = Context->Allocator.Allocate( - totalSizeToAlloc<Init *>(Range.size()), alignof(ListInit)); + void *Mem = RK.Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()), + alignof(ListInit)); ListInit *I = new (Mem) ListInit(Range.size(), EltTy); std::uninitialized_copy(Range.begin(), Range.end(), I->getTrailingObjects<Init *>()); - Context->TheListInitPool.InsertNode(I, IP); + RK.TheListInitPool.InsertNode(I, IP); return I; } @@ -714,7 +744,7 @@ std::string ListInit::getAsString() const { } Init *OpInit::getBit(unsigned Bit) const { - if (getType() == BitRecTy::get()) + if (getType() == BitRecTy::get(getRecordKeeper())) return const_cast<OpInit*>(this); return VarBitInit::get(const_cast<OpInit*>(this), Bit); } @@ -730,12 +760,13 @@ UnOpInit *UnOpInit::get(UnaryOp Opc, Init *LHS, RecTy *Type) { 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; } @@ -744,6 +775,7 @@ void UnOpInit::Profile(FoldingSetNodeID &ID) const { } Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const { + RecordKeeper &RK = getRecordKeeper(); switch (getOpcode()) { case CAST: if (isa<StringRecTy>(getType())) { @@ -751,11 +783,11 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const { return LHSs; if (DefInit *LHSd = dyn_cast<DefInit>(LHS)) - return StringInit::get(LHSd->getAsString()); + return StringInit::get(RK, LHSd->getAsString()); - if (IntInit *LHSi = - dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get()))) - return StringInit::get(LHSi->getAsString()); + if (IntInit *LHSi = dyn_cast_or_null<IntInit>( + LHS->convertInitializerTo(IntRecTy::get(RK)))) + return StringInit::get(RK, LHSi->getAsString()); } else if (isa<RecordRecTy>(getType())) { if (StringInit *Name = dyn_cast<StringInit>(LHS)) { @@ -800,9 +832,9 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const { break; case NOT: - if (IntInit *LHSi = - dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get()))) - return IntInit::get(LHSi->getValue() ? 0 : 1); + if (IntInit *LHSi = dyn_cast_or_null<IntInit>( + LHS->convertInitializerTo(IntRecTy::get(RK)))) + return IntInit::get(RK, LHSi->getValue() ? 0 : 1); break; case HEAD: @@ -823,20 +855,20 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const { case SIZE: if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) - return IntInit::get(LHSl->size()); + return IntInit::get(RK, LHSl->size()); if (DagInit *LHSd = dyn_cast<DagInit>(LHS)) - return IntInit::get(LHSd->arg_size()); + return IntInit::get(RK, LHSd->arg_size()); if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) - return IntInit::get(LHSs->getValue().size()); + return IntInit::get(RK, LHSs->getValue().size()); break; case EMPTY: if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) - return IntInit::get(LHSl->empty()); + return IntInit::get(RK, LHSl->empty()); if (DagInit *LHSd = dyn_cast<DagInit>(LHS)) - return IntInit::get(LHSd->arg_empty()); + return IntInit::get(RK, LHSd->arg_empty()); if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) - return IntInit::get(LHSs->getValue().empty()); + return IntInit::get(RK, LHSs->getValue().empty()); break; case GETDAGOP: @@ -893,12 +925,13 @@ BinOpInit *BinOpInit::get(BinaryOp Opc, Init *LHS, Init *RHS, RecTy *Type) { 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; } @@ -910,15 +943,15 @@ static StringInit *ConcatStringInits(const StringInit *I0, 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<StringInit>(List->getElement(0)); if (!Element) return nullptr; @@ -933,30 +966,29 @@ static StringInit *interleaveStringList(const ListInit *List, 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<IntInit>(List->getElement(0) - ->convertInitializerTo(IntRecTy::get())); + return StringInit::get(RK, ""); + IntInit *Element = dyn_cast_or_null<IntInit>( + 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<IntInit>(List->getElement(I) - ->convertInitializerTo(IntRecTy::get())); + IntInit *Element = dyn_cast_or_null<IntInit>( + 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) { @@ -964,7 +996,8 @@ Init *BinOpInit::getStrConcat(Init *I0, Init *I1) { if (const StringInit *I0s = dyn_cast<StringInit>(I0)) if (const StringInit *I1s = dyn_cast<StringInit>(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, @@ -1003,7 +1036,7 @@ Init *BinOpInit::Fold(Record *CurRec) const { } Init *Op = LOp ? LOp : ROp; if (!Op) - Op = UnsetInit::get(); + Op = UnsetInit::get(getRecordKeeper()); SmallVector<Init*, 8> Args; SmallVector<StringInit*, 8> ArgNames; @@ -1067,10 +1100,10 @@ Init *BinOpInit::Fold(Record *CurRec) const { case GE: case GT: { // First see if we have two bit, bits, or int. - IntInit *LHSi = - dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get())); - IntInit *RHSi = - dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(IntRecTy::get())); + IntInit *LHSi = dyn_cast_or_null<IntInit>( + LHS->convertInitializerTo(IntRecTy::get(getRecordKeeper()))); + IntInit *RHSi = dyn_cast_or_null<IntInit>( + RHS->convertInitializerTo(IntRecTy::get(getRecordKeeper()))); if (LHSi && RHSi) { bool Result; @@ -1083,7 +1116,7 @@ Init *BinOpInit::Fold(Record *CurRec) const { 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. @@ -1101,7 +1134,7 @@ Init *BinOpInit::Fold(Record *CurRec) const { 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. @@ -1109,8 +1142,8 @@ Init *BinOpInit::Fold(Record *CurRec) const { DefInit *LHSd = dyn_cast<DefInit>(LHS); DefInit *RHSd = dyn_cast<DefInit>(RHS); if (LHSd && RHSd) - return BitInit::get((getOpcode() == EQ) ? LHSd == RHSd - : LHSd != RHSd); + return BitInit::get(getRecordKeeper(), + (getOpcode() == EQ) ? LHSd == RHSd : LHSd != RHSd); } break; @@ -1138,10 +1171,10 @@ Init *BinOpInit::Fold(Record *CurRec) const { case SHL: case SRA: case SRL: { - IntInit *LHSi = - dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get())); - IntInit *RHSi = - dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(IntRecTy::get())); + IntInit *LHSi = dyn_cast_or_null<IntInit>( + LHS->convertInitializerTo(IntRecTy::get(getRecordKeeper()))); + IntInit *RHSi = dyn_cast_or_null<IntInit>( + RHS->convertInitializerTo(IntRecTy::get(getRecordKeeper()))); if (LHSi && RHSi) { int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue(); int64_t Result; @@ -1157,7 +1190,7 @@ Init *BinOpInit::Fold(Record *CurRec) const { 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; } @@ -1218,12 +1251,13 @@ TernOpInit *TernOpInit::get(TernaryOp Opc, Init *LHS, Init *MHS, Init *RHS, 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; } @@ -1296,8 +1330,9 @@ static Init *FilterHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, Init *Include = ItemApply(LHS, Item, RHS, CurRec); if (!Include) return nullptr; - if (IntInit *IncludeInt = dyn_cast_or_null<IntInit>( - Include->convertInitializerTo(IntRecTy::get()))) { + if (IntInit *IncludeInt = + dyn_cast_or_null<IntInit>(Include->convertInitializerTo( + IntRecTy::get(LHS->getRecordKeeper())))) { if (IncludeInt->getValue()) NewList.push_back(Item); } else { @@ -1311,6 +1346,7 @@ static Init *FilterHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, } Init *TernOpInit::Fold(Record *CurRec) const { + RecordKeeper &RK = getRecordKeeper(); switch (getOpcode()) { case SUBST: { DefInit *LHSd = dyn_cast<DefInit>(LHS); @@ -1351,7 +1387,7 @@ Init *TernOpInit::Fold(Record *CurRec) const { idx = found + MHSs->getValue().size(); } - return StringInit::get(Val); + return StringInit::get(RK, Val); } break; } @@ -1370,7 +1406,7 @@ Init *TernOpInit::Fold(Record *CurRec) const { case IF: { if (IntInit *LHSi = dyn_cast_or_null<IntInit>( - LHS->convertInitializerTo(IntRecTy::get()))) { + LHS->convertInitializerTo(IntRecTy::get(RK)))) { if (LHSi->getValue()) return MHS; return RHS; @@ -1391,8 +1427,8 @@ Init *TernOpInit::Fold(Record *CurRec) const { SmallVector<std::pair<Init *, StringInit *>, 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<StringInit>(Name) && !isa<UnsetInit>(Name)) return const_cast<TernOpInit *>(this); Children.emplace_back(Node, dyn_cast<StringInit>(Name)); @@ -1417,7 +1453,7 @@ Init *TernOpInit::Fold(Record *CurRec) const { 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; @@ -1437,8 +1473,8 @@ Init *TernOpInit::Fold(Record *CurRec) const { 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; } @@ -1452,7 +1488,7 @@ Init *TernOpInit::resolveReferences(Resolver &R) const { if (getOpcode() == IF && lhs != LHS) { if (IntInit *Value = dyn_cast_or_null<IntInit>( - lhs->convertInitializerTo(IntRecTy::get()))) { + lhs->convertInitializerTo(IntRecTy::get(getRecordKeeper())))) { // Short-circuit if (Value->getValue()) return MHS->resolveReferences(R); @@ -1506,17 +1542,16 @@ static void ProfileFoldOpInit(FoldingSetNodeID &ID, Init *Start, Init *List, 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; } @@ -1575,12 +1610,13 @@ IsAOpInit *IsAOpInit::get(RecTy *CheckType, Init *Expr) { 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; } @@ -1592,17 +1628,17 @@ Init *IsAOpInit::Fold() const { if (TypedInit *TI = dyn_cast<TypedInit>(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<RecordRecTy>(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<DefInit>(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<IsAOpInit *>(this); @@ -1625,6 +1661,81 @@ std::string IsAOpInit::getAsString() const { .str(); } +static void ProfileExistsOpInit(FoldingSetNodeID &ID, RecTy *CheckType, + Init *Expr) { + ID.AddPointer(CheckType); + ID.AddPointer(Expr); +} + +ExistsOpInit *ExistsOpInit::get(RecTy *CheckType, Init *Expr) { + FoldingSetNodeID ID; + ProfileExistsOpInit(ID, CheckType, Expr); + + detail::RecordKeeperImpl &RK = Expr->getRecordKeeper().getImpl(); + void *IP = nullptr; + if (ExistsOpInit *I = RK.TheExistsOpInitPool.FindNodeOrInsertPos(ID, IP)) + return I; + + ExistsOpInit *I = new (RK.Allocator) ExistsOpInit(CheckType, Expr); + RK.TheExistsOpInitPool.InsertNode(I, IP); + return I; +} + +void ExistsOpInit::Profile(FoldingSetNodeID &ID) const { + ProfileExistsOpInit(ID, CheckType, Expr); +} + +Init *ExistsOpInit::Fold(Record *CurRec, bool IsFinal) const { + if (StringInit *Name = dyn_cast<StringInit>(Expr)) { + if (!CurRec && !IsFinal) + return const_cast<ExistsOpInit *>(this); + + // Self-references are allowed, but their resolution is delayed until + // the final resolve to ensure that we get the correct type for them. + auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->getNameInit()); + if (Name == CurRec->getNameInit() || + (Anonymous && Name == Anonymous->getNameInit())) { + if (!IsFinal) + return const_cast<ExistsOpInit *>(this); + + // No doubt that there exists a record, so we should check if types are + // compatiable. + return IntInit::get(getRecordKeeper(), + CurRec->getType()->typeIsA(CheckType)); + } + + // Look up all defined records to see if we can find one. + Record *D = CheckType->getRecordKeeper().getDef(Name->getValue()); + if (!D) { + if (IsFinal) + return IntInit::get(getRecordKeeper(), 0); + return const_cast<ExistsOpInit *>(this); + } + + // Check if types are compatiable. + return IntInit::get(getRecordKeeper(), + DefInit::get(D)->getType()->typeIsA(CheckType)); + } + return const_cast<ExistsOpInit *>(this); +} + +Init *ExistsOpInit::resolveReferences(Resolver &R) const { + Init *NewExpr = Expr->resolveReferences(R); + if (Expr != NewExpr || R.isFinal()) + return get(CheckType, NewExpr)->Fold(R.getCurrentRecord(), R.isFinal()); + return const_cast<ExistsOpInit *>(this); +} + +Init *ExistsOpInit::getBit(unsigned Bit) const { + return VarBitInit::get(const_cast<ExistsOpInit *>(this), Bit); +} + +std::string ExistsOpInit::getAsString() const { + return (Twine("!exists<") + CheckType->getAsString() + ">(" + + Expr->getAsString() + ")") + .str(); +} + RecTy *TypedInit::getFieldType(StringInit *FieldName) const { if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType())) { for (Record *Rec : RecordType->getClasses()) { @@ -1642,7 +1753,7 @@ TypedInit::convertInitializerTo(RecTy *Ty) const { if (isa<BitRecTy>(getType()) && isa<BitsRecTy>(Ty) && cast<BitsRecTy>(Ty)->getNumBits() == 1) - return BitsInit::get({const_cast<TypedInit *>(this)}); + return BitsInit::get(getRecordKeeper(), {const_cast<TypedInit *>(this)}); return nullptr; } @@ -1660,7 +1771,7 @@ Init *TypedInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const { NewBits.push_back(VarBitInit::get(const_cast<TypedInit *>(this), Bit)); } - return BitsInit::get(NewBits); + return BitsInit::get(getRecordKeeper(), NewBits); } Init *TypedInit::getCastTo(RecTy *Ty) const { @@ -1698,14 +1809,15 @@ Init *TypedInit::convertInitListSlice(ArrayRef<unsigned> Elements) const { 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; } @@ -1715,7 +1827,7 @@ StringRef VarInit::getName() const { } Init *VarInit::getBit(unsigned Bit) const { - if (getType() == BitRecTy::get()) + if (getType() == BitRecTy::get(getRecordKeeper())) return const_cast<VarInit*>(this); return VarBitInit::get(const_cast<VarInit*>(this), Bit); } @@ -1727,9 +1839,10 @@ Init *VarInit::resolveReferences(Resolver &R) const { } 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; } @@ -1746,10 +1859,10 @@ Init *VarBitInit::resolveReferences(Resolver &R) const { } 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; } @@ -1771,7 +1884,7 @@ Init *VarListElementInit::resolveReferences(Resolver &R) const { } Init *VarListElementInit::getBit(unsigned Bit) const { - if (getType() == BitRecTy::get()) + if (getType() == BitRecTy::get(getRecordKeeper())) return const_cast<VarListElementInit*>(this); return VarBitInit::get(const_cast<VarListElementInit*>(this), Bit); } @@ -1808,20 +1921,25 @@ static void ProfileVarDefInit(FoldingSetNodeID &ID, 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<Init *> 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<Init *>(Args.size()), - alignof(VarDefInit)); + void *Mem = RK.Allocator.Allocate(totalSizeToAlloc<Init *>(Args.size()), + alignof(VarDefInit)); VarDefInit *I = new (Mem) VarDefInit(Class, Args.size()); std::uninitialized_copy(Args.begin(), Args.end(), I->getTrailingObjects<Init *>()); - Context->TheVarDefInitPool.InsertNode(I, IP); + RK.TheVarDefInitPool.InsertNode(I, IP); return I; } @@ -1927,14 +2045,15 @@ std::string VarDefInit::getAsString() const { } 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<FieldInit*>(this); return VarBitInit::get(const_cast<FieldInit*>(this), Bit); } @@ -1992,20 +2111,20 @@ void CondOpInit::Profile(FoldingSetNodeID &ID) const { ValType); } -CondOpInit * -CondOpInit::get(ArrayRef<Init *> CondRange, - ArrayRef<Init *> ValRange, RecTy *Ty) { +CondOpInit *CondOpInit::get(ArrayRef<Init *> CondRange, + ArrayRef<Init *> 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<Init *>(2 * CondRange.size()), alignof(BitsInit)); CondOpInit *I = new(Mem) CondOpInit(CondRange.size(), Ty); @@ -2013,7 +2132,7 @@ CondOpInit::get(ArrayRef<Init *> CondRange, I->getTrailingObjects<Init *>()); std::uninitialized_copy(ValRange.begin(), ValRange.end(), I->getTrailingObjects<Init *>()+CondRange.size()); - Context->TheCondOpInitPool.InsertNode(I, IP); + RK.TheCondOpInitPool.InsertNode(I, IP); return I; } @@ -2041,16 +2160,18 @@ Init *CondOpInit::resolveReferences(Resolver &R) const { } 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<IntInit>( - Cond->convertInitializerTo(IntRecTy::get()))) { + Cond->convertInitializerTo(IntRecTy::get(RK)))) { if (CondI->getValue()) return Val->convertInitializerTo(getValType()); - } else - return const_cast<CondOpInit *>(this); + } else { + return const_cast<CondOpInit *>(this); + } } PrintFatalError(CurRec->getLoc(), @@ -2120,11 +2241,12 @@ DagInit *DagInit::get(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange, 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<Init *, StringInit *>(ArgRange.size(), NameRange.size()), alignof(BitsInit)); DagInit *I = new (Mem) DagInit(V, VN, ArgRange.size(), NameRange.size()); @@ -2132,7 +2254,7 @@ DagInit *DagInit::get(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange, I->getTrailingObjects<Init *>()); std::uninitialized_copy(NameRange.begin(), NameRange.end(), I->getTrailingObjects<StringInit *>()); - Context->TheDagInitPool.InsertNode(I, IP); + RK.TheDagInitPool.InsertNode(I, IP); return I; } @@ -2209,7 +2331,7 @@ std::string DagInit::getAsString() const { 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!"); } @@ -2217,7 +2339,7 @@ RecordVal::RecordVal(Init *N, RecTy *T, FieldKind K) // 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!"); } @@ -2226,7 +2348,7 @@ StringRef RecordVal::getName() const { } std::string RecordVal::getPrintType() const { - if (getType() == StringRecTy::get()) { + if (getType() == StringRecTy::get(getRecordKeeper())) { if (auto *StrInit = dyn_cast<StringInit>(Value)) { if (StrInit->hasCodeFormat()) return "code"; @@ -2252,7 +2374,7 @@ bool RecordVal::setValue(Init *V) { 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); } } } @@ -2277,7 +2399,7 @@ bool RecordVal::setValue(Init *V, SMLoc NewLoc) { 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); } } } @@ -2313,16 +2435,20 @@ void Record::checkName() { RecordRecTy *Record::getType() { SmallVector<Record *, 4> 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; @@ -2472,7 +2598,7 @@ Init *Record::getValueInit(StringRef FieldName) const { StringRef Record::getValueAsString(StringRef FieldName) const { llvm::Optional<StringRef> S = getValueAsOptionalString(FieldName); - if (!S.hasValue()) + if (!S) PrintFatalError(getLoc(), "Record `" + getName() + "' does not have a field named `" + FieldName + "'!\n"); return S.getValue(); @@ -2671,6 +2797,10 @@ void Record::checkUnusedTemplateArgs() { } } +RecordKeeper::RecordKeeper() + : Impl(std::make_unique<detail::RecordKeeperImpl>(*this)) {} +RecordKeeper::~RecordKeeper() = default; + #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void RecordKeeper::dump() const { errs() << *this; } #endif @@ -2689,7 +2819,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) { /// 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 @@ -2733,11 +2863,10 @@ void RecordKeeper::stopBackendTimer() { } } -// We cache the record vectors for single classes. Many backends request -// the same vectors multiple times. -std::vector<Record *> RecordKeeper::getAllDerivedDefinitions( - StringRef ClassName) const { - +std::vector<Record *> +RecordKeeper::getAllDerivedDefinitions(StringRef ClassName) const { + // We cache the record vectors for single classes. Many backends request + // the same vectors multiple times. auto Pair = ClassRecordsMap.try_emplace(ClassName); if (Pair.second) Pair.first->second = getAllDerivedDefinitions(makeArrayRef(ClassName)); @@ -2768,6 +2897,12 @@ std::vector<Record *> RecordKeeper::getAllDerivedDefinitions( return Defs; } +std::vector<Record *> +RecordKeeper::getAllDerivedDefinitionsIfDefined(StringRef ClassName) const { + return getClass(ClassName) ? getAllDerivedDefinitions(ClassName) + : std::vector<Record *>(); +} + Init *MapResolver::resolve(Init *VarName) { auto It = Map.find(VarName); if (It == Map.end()) |
