forked from OSchip/llvm-project
[Tablegen] Collect all global state into one managed static
Tablegen uses copious amounts of global state for uniquing various records. This was fine under the original vision where tablegen was a tool, and not a library, but there are various usages of tablegen that want to use it as a library. One concrete example is that downstream we have a kythe indexer for tablegen constructs that allows for IDEs to serve go-to-definition/references/and more. We currently (kind of hackily) keep the tablegen parts in a shared library that gets loaded/unloaded. This revision starts to remedy this by globbing all of the static state into a managed static so that they can at least be unloaded with llvm_shutdown. A better solution would be to feed in a context variable (much like how the IR in LLVM/MLIR do), but that is a more invasive change that can come later. Differential Revision: https://reviews.llvm.org/D108934
This commit is contained in:
parent
26c2afce78
commit
7480efd6f0
|
@ -39,6 +39,9 @@
|
|||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
namespace detail {
|
||||
struct RecordContext;
|
||||
} // namespace detail
|
||||
|
||||
class ListRecTy;
|
||||
struct MultiClass;
|
||||
|
@ -100,7 +103,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) {
|
|||
|
||||
/// 'bit' - Represent a single bit
|
||||
class BitRecTy : public RecTy {
|
||||
static BitRecTy Shared;
|
||||
friend detail::RecordContext;
|
||||
|
||||
BitRecTy() : RecTy(BitRecTyKind) {}
|
||||
|
||||
|
@ -109,7 +112,7 @@ public:
|
|||
return RT->getRecTyKind() == BitRecTyKind;
|
||||
}
|
||||
|
||||
static BitRecTy *get() { return &Shared; }
|
||||
static BitRecTy *get();
|
||||
|
||||
std::string getAsString() const override { return "bit"; }
|
||||
|
||||
|
@ -140,7 +143,7 @@ public:
|
|||
|
||||
/// 'int' - Represent an integer value of no particular size
|
||||
class IntRecTy : public RecTy {
|
||||
static IntRecTy Shared;
|
||||
friend detail::RecordContext;
|
||||
|
||||
IntRecTy() : RecTy(IntRecTyKind) {}
|
||||
|
||||
|
@ -149,7 +152,7 @@ public:
|
|||
return RT->getRecTyKind() == IntRecTyKind;
|
||||
}
|
||||
|
||||
static IntRecTy *get() { return &Shared; }
|
||||
static IntRecTy *get();
|
||||
|
||||
std::string getAsString() const override { return "int"; }
|
||||
|
||||
|
@ -158,7 +161,7 @@ public:
|
|||
|
||||
/// 'string' - Represent an string value
|
||||
class StringRecTy : public RecTy {
|
||||
static StringRecTy Shared;
|
||||
friend detail::RecordContext;
|
||||
|
||||
StringRecTy() : RecTy(StringRecTyKind) {}
|
||||
|
||||
|
@ -167,7 +170,7 @@ public:
|
|||
return RT->getRecTyKind() == StringRecTyKind;
|
||||
}
|
||||
|
||||
static StringRecTy *get() { return &Shared; }
|
||||
static StringRecTy *get();
|
||||
|
||||
std::string getAsString() const override;
|
||||
|
||||
|
@ -200,7 +203,7 @@ public:
|
|||
|
||||
/// 'dag' - Represent a dag fragment
|
||||
class DagRecTy : public RecTy {
|
||||
static DagRecTy Shared;
|
||||
friend detail::RecordContext;
|
||||
|
||||
DagRecTy() : RecTy(DagRecTyKind) {}
|
||||
|
||||
|
@ -209,7 +212,7 @@ public:
|
|||
return RT->getRecTyKind() == DagRecTyKind;
|
||||
}
|
||||
|
||||
static DagRecTy *get() { return &Shared; }
|
||||
static DagRecTy *get();
|
||||
|
||||
std::string getAsString() const override;
|
||||
};
|
||||
|
@ -221,6 +224,7 @@ public:
|
|||
class RecordRecTy final : public RecTy, public FoldingSetNode,
|
||||
public TrailingObjects<RecordRecTy, Record *> {
|
||||
friend class Record;
|
||||
friend detail::RecordContext;
|
||||
|
||||
unsigned NumClasses;
|
||||
|
||||
|
@ -437,6 +441,8 @@ public:
|
|||
|
||||
/// '?' - Represents an uninitialized value.
|
||||
class UnsetInit : public Init {
|
||||
friend detail::RecordContext;
|
||||
|
||||
UnsetInit() : Init(IK_UnsetInit) {}
|
||||
|
||||
public:
|
||||
|
@ -468,9 +474,11 @@ public:
|
|||
|
||||
/// 'true'/'false' - Represent a concrete initializer for a bit.
|
||||
class BitInit final : public TypedInit {
|
||||
friend detail::RecordContext;
|
||||
|
||||
bool Value;
|
||||
|
||||
explicit BitInit(bool V) : TypedInit(IK_BitInit, BitRecTy::get()), Value(V) {}
|
||||
explicit BitInit(bool V, RecTy *T) : TypedInit(IK_BitInit, T), Value(V) {}
|
||||
|
||||
public:
|
||||
BitInit(const BitInit &) = delete;
|
||||
|
@ -637,7 +645,7 @@ public:
|
|||
}
|
||||
|
||||
StringRef getValue() const { return Value; }
|
||||
StringFormat getFormat() const { return Format; }
|
||||
StringFormat getFormat() const { return Format; }
|
||||
bool hasCodeFormat() const { return Format == SF_Code; }
|
||||
|
||||
Init *convertInitializerTo(RecTy *Ty) const override;
|
||||
|
@ -1489,8 +1497,6 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
static unsigned LastID;
|
||||
|
||||
Init *Name;
|
||||
// Location where record was instantiated, followed by the location of
|
||||
// multiclass prototypes used.
|
||||
|
@ -1521,8 +1527,8 @@ public:
|
|||
// Constructs a record.
|
||||
explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records,
|
||||
bool Anonymous = false, bool Class = false)
|
||||
: Name(N), Locs(locs.begin(), locs.end()), TrackedRecords(records),
|
||||
ID(LastID++), IsAnonymous(Anonymous), IsClass(Class) {
|
||||
: Name(N), Locs(locs.begin(), locs.end()), TrackedRecords(records),
|
||||
ID(getNewUID()), IsAnonymous(Anonymous), IsClass(Class) {
|
||||
checkName();
|
||||
}
|
||||
|
||||
|
@ -1534,12 +1540,12 @@ public:
|
|||
// ID number. Don't copy CorrespondingDefInit either, since it's owned by the
|
||||
// original record. All other fields can be copied normally.
|
||||
Record(const Record &O)
|
||||
: Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs),
|
||||
Values(O.Values), Assertions(O.Assertions), SuperClasses(O.SuperClasses),
|
||||
TrackedRecords(O.TrackedRecords), ID(LastID++),
|
||||
IsAnonymous(O.IsAnonymous), IsClass(O.IsClass) { }
|
||||
: 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) {}
|
||||
|
||||
static unsigned getNewUID() { return LastID++; }
|
||||
static unsigned getNewUID();
|
||||
|
||||
unsigned getID() const { return ID; }
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#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"
|
||||
|
@ -41,24 +42,70 @@ using namespace llvm;
|
|||
|
||||
#define DEBUG_TYPE "tblgen-records"
|
||||
|
||||
static BumpPtrAllocator Allocator;
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Context
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
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),
|
||||
FalseBitInit(false, &SharedBitRecTy), StringInitStringPool(Allocator),
|
||||
StringInitCodePool(Allocator), LastRecordID(0) {}
|
||||
|
||||
BumpPtrAllocator Allocator;
|
||||
std::vector<BitsRecTy *> SharedBitsRecTys;
|
||||
BitRecTy SharedBitRecTy;
|
||||
IntRecTy SharedIntRecTy;
|
||||
StringRecTy SharedStringRecTy;
|
||||
DagRecTy SharedDagRecTy;
|
||||
|
||||
RecordRecTy AnyRecord;
|
||||
UnsetInit TheUnsetInit;
|
||||
BitInit TrueBitInit;
|
||||
BitInit FalseBitInit;
|
||||
|
||||
FoldingSet<BitsInit> TheBitsInitPool;
|
||||
std::map<int64_t, IntInit *> TheIntInitPool;
|
||||
StringMap<StringInit *, BumpPtrAllocator &> StringInitStringPool;
|
||||
StringMap<StringInit *, BumpPtrAllocator &> StringInitCodePool;
|
||||
FoldingSet<ListInit> TheListInitPool;
|
||||
FoldingSet<UnOpInit> TheUnOpInitPool;
|
||||
FoldingSet<BinOpInit> TheBinOpInitPool;
|
||||
FoldingSet<TernOpInit> TheTernOpInitPool;
|
||||
FoldingSet<FoldOpInit> TheFoldOpInitPool;
|
||||
FoldingSet<IsAOpInit> TheIsAOpInitPool;
|
||||
DenseMap<std::pair<RecTy *, Init *>, VarInit *> TheVarInitPool;
|
||||
DenseMap<std::pair<TypedInit *, unsigned>, VarBitInit *> TheVarBitInitPool;
|
||||
DenseMap<std::pair<TypedInit *, unsigned>, VarListElementInit *>
|
||||
TheVarListElementInitPool;
|
||||
FoldingSet<VarDefInit> TheVarDefInitPool;
|
||||
DenseMap<std::pair<Init *, StringInit *>, FieldInit *> TheFieldInitPool;
|
||||
FoldingSet<CondOpInit> TheCondOpInitPool;
|
||||
FoldingSet<DagInit> TheDagInitPool;
|
||||
|
||||
unsigned LastRecordID;
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace llvm
|
||||
|
||||
ManagedStatic<detail::RecordContext> Context;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Type implementations
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
BitRecTy BitRecTy::Shared;
|
||||
IntRecTy IntRecTy::Shared;
|
||||
StringRecTy StringRecTy::Shared;
|
||||
DagRecTy DagRecTy::Shared;
|
||||
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
LLVM_DUMP_METHOD void RecTy::dump() const { print(errs()); }
|
||||
#endif
|
||||
|
||||
ListRecTy *RecTy::getListTy() {
|
||||
if (!ListTy)
|
||||
ListTy = new(Allocator) ListRecTy(this);
|
||||
ListTy = new(Context->Allocator) ListRecTy(this);
|
||||
return ListTy;
|
||||
}
|
||||
|
||||
|
@ -69,6 +116,8 @@ bool RecTy::typeIsConvertibleTo(const RecTy *RHS) const {
|
|||
|
||||
bool RecTy::typeIsA(const RecTy *RHS) const { return this == RHS; }
|
||||
|
||||
BitRecTy *BitRecTy::get() { return &Context->SharedBitRecTy; }
|
||||
|
||||
bool BitRecTy::typeIsConvertibleTo(const RecTy *RHS) const{
|
||||
if (RecTy::typeIsConvertibleTo(RHS) || RHS->getRecTyKind() == IntRecTyKind)
|
||||
return true;
|
||||
|
@ -78,12 +127,11 @@ bool BitRecTy::typeIsConvertibleTo(const RecTy *RHS) const{
|
|||
}
|
||||
|
||||
BitsRecTy *BitsRecTy::get(unsigned Sz) {
|
||||
static std::vector<BitsRecTy*> Shared;
|
||||
if (Sz >= Shared.size())
|
||||
Shared.resize(Sz + 1);
|
||||
BitsRecTy *&Ty = Shared[Sz];
|
||||
if (Sz >= Context->SharedBitsRecTys.size())
|
||||
Context->SharedBitsRecTys.resize(Sz + 1);
|
||||
BitsRecTy *&Ty = Context->SharedBitsRecTys[Sz];
|
||||
if (!Ty)
|
||||
Ty = new(Allocator) BitsRecTy(Sz);
|
||||
Ty = new (Context->Allocator) BitsRecTy(Sz);
|
||||
return Ty;
|
||||
}
|
||||
|
||||
|
@ -104,11 +152,15 @@ bool BitsRecTy::typeIsA(const RecTy *RHS) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
IntRecTy *IntRecTy::get() { return &Context->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; }
|
||||
|
||||
std::string StringRecTy::getAsString() const {
|
||||
return "string";
|
||||
}
|
||||
|
@ -134,6 +186,8 @@ bool ListRecTy::typeIsA(const RecTy *RHS) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
DagRecTy *DagRecTy::get() { return &Context->SharedDagRecTy; }
|
||||
|
||||
std::string DagRecTy::getAsString() const {
|
||||
return "dag";
|
||||
}
|
||||
|
@ -146,10 +200,8 @@ static void ProfileRecordRecTy(FoldingSetNodeID &ID,
|
|||
}
|
||||
|
||||
RecordRecTy *RecordRecTy::get(ArrayRef<Record *> UnsortedClasses) {
|
||||
if (UnsortedClasses.empty()) {
|
||||
static RecordRecTy AnyRecord(0);
|
||||
return &AnyRecord;
|
||||
}
|
||||
if (UnsortedClasses.empty())
|
||||
return &Context->AnyRecord;
|
||||
|
||||
FoldingSet<RecordRecTy> &ThePool =
|
||||
UnsortedClasses[0]->getRecords().RecordTypePool;
|
||||
|
@ -177,8 +229,8 @@ RecordRecTy *RecordRecTy::get(ArrayRef<Record *> UnsortedClasses) {
|
|||
}
|
||||
#endif
|
||||
|
||||
void *Mem = Allocator.Allocate(totalSizeToAlloc<Record *>(Classes.size()),
|
||||
alignof(RecordRecTy));
|
||||
void *Mem = Context->Allocator.Allocate(
|
||||
totalSizeToAlloc<Record *>(Classes.size()), alignof(RecordRecTy));
|
||||
RecordRecTy *Ty = new(Mem) RecordRecTy(Classes.size());
|
||||
std::uninitialized_copy(Classes.begin(), Classes.end(),
|
||||
Ty->getTrailingObjects<Record *>());
|
||||
|
@ -283,10 +335,7 @@ void Init::anchor() {}
|
|||
LLVM_DUMP_METHOD void Init::dump() const { return print(errs()); }
|
||||
#endif
|
||||
|
||||
UnsetInit *UnsetInit::get() {
|
||||
static UnsetInit TheInit;
|
||||
return &TheInit;
|
||||
}
|
||||
UnsetInit *UnsetInit::get() { return &Context->TheUnsetInit; }
|
||||
|
||||
Init *UnsetInit::getCastTo(RecTy *Ty) const {
|
||||
return const_cast<UnsetInit *>(this);
|
||||
|
@ -297,10 +346,7 @@ Init *UnsetInit::convertInitializerTo(RecTy *Ty) const {
|
|||
}
|
||||
|
||||
BitInit *BitInit::get(bool V) {
|
||||
static BitInit True(true);
|
||||
static BitInit False(false);
|
||||
|
||||
return V ? &True : &False;
|
||||
return V ? &Context->TrueBitInit : &Context->FalseBitInit;
|
||||
}
|
||||
|
||||
Init *BitInit::convertInitializerTo(RecTy *Ty) const {
|
||||
|
@ -328,21 +374,19 @@ ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef<Init *> Range) {
|
|||
}
|
||||
|
||||
BitsInit *BitsInit::get(ArrayRef<Init *> Range) {
|
||||
static FoldingSet<BitsInit> ThePool;
|
||||
|
||||
FoldingSetNodeID ID;
|
||||
ProfileBitsInit(ID, Range);
|
||||
|
||||
void *IP = nullptr;
|
||||
if (BitsInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
|
||||
if (BitsInit *I = Context->TheBitsInitPool.FindNodeOrInsertPos(ID, IP))
|
||||
return I;
|
||||
|
||||
void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()),
|
||||
alignof(BitsInit));
|
||||
void *Mem = Context->Allocator.Allocate(
|
||||
totalSizeToAlloc<Init *>(Range.size()), alignof(BitsInit));
|
||||
BitsInit *I = new(Mem) BitsInit(Range.size());
|
||||
std::uninitialized_copy(Range.begin(), Range.end(),
|
||||
I->getTrailingObjects<Init *>());
|
||||
ThePool.InsertNode(I, IP);
|
||||
Context->TheBitsInitPool.InsertNode(I, IP);
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -446,10 +490,9 @@ Init *BitsInit::resolveReferences(Resolver &R) const {
|
|||
}
|
||||
|
||||
IntInit *IntInit::get(int64_t V) {
|
||||
static std::map<int64_t, IntInit*> ThePool;
|
||||
|
||||
IntInit *&I = ThePool[V];
|
||||
if (!I) I = new(Allocator) IntInit(V);
|
||||
IntInit *&I = Context->TheIntInitPool[V];
|
||||
if (!I)
|
||||
I = new (Context->Allocator) IntInit(V);
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -503,7 +546,7 @@ IntInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
|
|||
}
|
||||
|
||||
AnonymousNameInit *AnonymousNameInit::get(unsigned V) {
|
||||
return new (Allocator) AnonymousNameInit(V);
|
||||
return new (Context->Allocator) AnonymousNameInit(V);
|
||||
}
|
||||
|
||||
StringInit *AnonymousNameInit::getNameInit() const {
|
||||
|
@ -525,20 +568,12 @@ Init *AnonymousNameInit::resolveReferences(Resolver &R) const {
|
|||
}
|
||||
|
||||
StringInit *StringInit::get(StringRef V, StringFormat Fmt) {
|
||||
static StringMap<StringInit*, BumpPtrAllocator &> StringPool(Allocator);
|
||||
static StringMap<StringInit*, BumpPtrAllocator &> CodePool(Allocator);
|
||||
|
||||
if (Fmt == SF_String) {
|
||||
auto &Entry = *StringPool.insert(std::make_pair(V, nullptr)).first;
|
||||
if (!Entry.second)
|
||||
Entry.second = new (Allocator) StringInit(Entry.getKey(), Fmt);
|
||||
return Entry.second;
|
||||
} else {
|
||||
auto &Entry = *CodePool.insert(std::make_pair(V, nullptr)).first;
|
||||
if (!Entry.second)
|
||||
Entry.second = new (Allocator) StringInit(Entry.getKey(), Fmt);
|
||||
return Entry.second;
|
||||
}
|
||||
auto &InitMap = Fmt == SF_String ? Context->StringInitStringPool
|
||||
: Context->StringInitCodePool;
|
||||
auto &Entry = *InitMap.insert(std::make_pair(V, nullptr)).first;
|
||||
if (!Entry.second)
|
||||
Entry.second = new (Context->Allocator) StringInit(Entry.getKey(), Fmt);
|
||||
return Entry.second;
|
||||
}
|
||||
|
||||
Init *StringInit::convertInitializerTo(RecTy *Ty) const {
|
||||
|
@ -559,24 +594,22 @@ static void ProfileListInit(FoldingSetNodeID &ID,
|
|||
}
|
||||
|
||||
ListInit *ListInit::get(ArrayRef<Init *> Range, RecTy *EltTy) {
|
||||
static FoldingSet<ListInit> ThePool;
|
||||
|
||||
FoldingSetNodeID ID;
|
||||
ProfileListInit(ID, Range, EltTy);
|
||||
|
||||
void *IP = nullptr;
|
||||
if (ListInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
|
||||
if (ListInit *I = Context->TheListInitPool.FindNodeOrInsertPos(ID, IP))
|
||||
return I;
|
||||
|
||||
assert(Range.empty() || !isa<TypedInit>(Range[0]) ||
|
||||
cast<TypedInit>(Range[0])->getType()->typeIsConvertibleTo(EltTy));
|
||||
|
||||
void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()),
|
||||
alignof(ListInit));
|
||||
ListInit *I = new(Mem) ListInit(Range.size(), EltTy);
|
||||
void *Mem = Context->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 *>());
|
||||
ThePool.InsertNode(I, IP);
|
||||
Context->TheListInitPool.InsertNode(I, IP);
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -696,17 +729,15 @@ ProfileUnOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *Op, RecTy *Type) {
|
|||
}
|
||||
|
||||
UnOpInit *UnOpInit::get(UnaryOp Opc, Init *LHS, RecTy *Type) {
|
||||
static FoldingSet<UnOpInit> ThePool;
|
||||
|
||||
FoldingSetNodeID ID;
|
||||
ProfileUnOpInit(ID, Opc, LHS, Type);
|
||||
|
||||
void *IP = nullptr;
|
||||
if (UnOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
|
||||
if (UnOpInit *I = Context->TheUnOpInitPool.FindNodeOrInsertPos(ID, IP))
|
||||
return I;
|
||||
|
||||
UnOpInit *I = new(Allocator) UnOpInit(Opc, LHS, Type);
|
||||
ThePool.InsertNode(I, IP);
|
||||
UnOpInit *I = new (Context->Allocator) UnOpInit(Opc, LHS, Type);
|
||||
Context->TheUnOpInitPool.InsertNode(I, IP);
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -860,19 +891,16 @@ ProfileBinOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *RHS,
|
|||
ID.AddPointer(Type);
|
||||
}
|
||||
|
||||
BinOpInit *BinOpInit::get(BinaryOp Opc, Init *LHS,
|
||||
Init *RHS, RecTy *Type) {
|
||||
static FoldingSet<BinOpInit> ThePool;
|
||||
|
||||
BinOpInit *BinOpInit::get(BinaryOp Opc, Init *LHS, Init *RHS, RecTy *Type) {
|
||||
FoldingSetNodeID ID;
|
||||
ProfileBinOpInit(ID, Opc, LHS, RHS, Type);
|
||||
|
||||
void *IP = nullptr;
|
||||
if (BinOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
|
||||
if (BinOpInit *I = Context->TheBinOpInitPool.FindNodeOrInsertPos(ID, IP))
|
||||
return I;
|
||||
|
||||
BinOpInit *I = new(Allocator) BinOpInit(Opc, LHS, RHS, Type);
|
||||
ThePool.InsertNode(I, IP);
|
||||
BinOpInit *I = new (Context->Allocator) BinOpInit(Opc, LHS, RHS, Type);
|
||||
Context->TheBinOpInitPool.InsertNode(I, IP);
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -884,7 +912,7 @@ static StringInit *ConcatStringInits(const StringInit *I0,
|
|||
const StringInit *I1) {
|
||||
SmallString<80> Concat(I0->getValue());
|
||||
Concat.append(I1->getValue());
|
||||
return StringInit::get(Concat,
|
||||
return StringInit::get(Concat,
|
||||
StringInit::determineFormat(I0->getFormat(),
|
||||
I1->getFormat()));
|
||||
}
|
||||
|
@ -1189,17 +1217,15 @@ ProfileTernOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *MHS,
|
|||
|
||||
TernOpInit *TernOpInit::get(TernaryOp Opc, Init *LHS, Init *MHS, Init *RHS,
|
||||
RecTy *Type) {
|
||||
static FoldingSet<TernOpInit> ThePool;
|
||||
|
||||
FoldingSetNodeID ID;
|
||||
ProfileTernOpInit(ID, Opc, LHS, MHS, RHS, Type);
|
||||
|
||||
void *IP = nullptr;
|
||||
if (TernOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
|
||||
if (TernOpInit *I = Context->TheTernOpInitPool.FindNodeOrInsertPos(ID, IP))
|
||||
return I;
|
||||
|
||||
TernOpInit *I = new(Allocator) TernOpInit(Opc, LHS, MHS, RHS, Type);
|
||||
ThePool.InsertNode(I, IP);
|
||||
TernOpInit *I = new (Context->Allocator) TernOpInit(Opc, LHS, MHS, RHS, Type);
|
||||
Context->TheTernOpInitPool.InsertNode(I, IP);
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -1273,8 +1299,8 @@ static Init *FilterHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
|
|||
if (!Include)
|
||||
return nullptr;
|
||||
if (IntInit *IncludeInt = dyn_cast_or_null<IntInit>(
|
||||
Include->convertInitializerTo(IntRecTy::get()))) {
|
||||
if (IncludeInt->getValue())
|
||||
Include->convertInitializerTo(IntRecTy::get()))) {
|
||||
if (IncludeInt->getValue())
|
||||
NewList.push_back(Item);
|
||||
} else {
|
||||
return nullptr;
|
||||
|
@ -1482,17 +1508,17 @@ static void ProfileFoldOpInit(FoldingSetNodeID &ID, Init *Start, Init *List,
|
|||
|
||||
FoldOpInit *FoldOpInit::get(Init *Start, Init *List, Init *A, Init *B,
|
||||
Init *Expr, RecTy *Type) {
|
||||
static FoldingSet<FoldOpInit> ThePool;
|
||||
|
||||
FoldingSetNodeID ID;
|
||||
ProfileFoldOpInit(ID, Start, List, A, B, Expr, Type);
|
||||
|
||||
void *IP = nullptr;
|
||||
if (FoldOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
|
||||
if (FoldOpInit *I = Context->TheFoldOpInitPool.FindNodeOrInsertPos(ID, IP))
|
||||
return I;
|
||||
|
||||
FoldOpInit *I = new (Allocator) FoldOpInit(Start, List, A, B, Expr, Type);
|
||||
ThePool.InsertNode(I, IP);
|
||||
FoldOpInit *I =
|
||||
new (Context->Allocator) FoldOpInit(Start, List, A, B, Expr, Type);
|
||||
Context->TheFoldOpInitPool.InsertNode(I, IP);
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -1547,17 +1573,16 @@ static void ProfileIsAOpInit(FoldingSetNodeID &ID, RecTy *CheckType,
|
|||
}
|
||||
|
||||
IsAOpInit *IsAOpInit::get(RecTy *CheckType, Init *Expr) {
|
||||
static FoldingSet<IsAOpInit> ThePool;
|
||||
|
||||
FoldingSetNodeID ID;
|
||||
ProfileIsAOpInit(ID, CheckType, Expr);
|
||||
|
||||
void *IP = nullptr;
|
||||
if (IsAOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
|
||||
if (IsAOpInit *I = Context->TheIsAOpInitPool.FindNodeOrInsertPos(ID, IP))
|
||||
return I;
|
||||
|
||||
IsAOpInit *I = new (Allocator) IsAOpInit(CheckType, Expr);
|
||||
ThePool.InsertNode(I, IP);
|
||||
IsAOpInit *I = new (Context->Allocator) IsAOpInit(CheckType, Expr);
|
||||
Context->TheIsAOpInitPool.InsertNode(I, IP);
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -1680,14 +1705,9 @@ VarInit *VarInit::get(StringRef VN, RecTy *T) {
|
|||
}
|
||||
|
||||
VarInit *VarInit::get(Init *VN, RecTy *T) {
|
||||
using Key = std::pair<RecTy *, Init *>;
|
||||
static DenseMap<Key, VarInit*> ThePool;
|
||||
|
||||
Key TheKey(std::make_pair(T, VN));
|
||||
|
||||
VarInit *&I = ThePool[TheKey];
|
||||
VarInit *&I = Context->TheVarInitPool[std::make_pair(T, VN)];
|
||||
if (!I)
|
||||
I = new(Allocator) VarInit(VN, T);
|
||||
I = new (Context->Allocator) VarInit(VN, T);
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -1709,14 +1729,9 @@ Init *VarInit::resolveReferences(Resolver &R) const {
|
|||
}
|
||||
|
||||
VarBitInit *VarBitInit::get(TypedInit *T, unsigned B) {
|
||||
using Key = std::pair<TypedInit *, unsigned>;
|
||||
static DenseMap<Key, VarBitInit*> ThePool;
|
||||
|
||||
Key TheKey(std::make_pair(T, B));
|
||||
|
||||
VarBitInit *&I = ThePool[TheKey];
|
||||
VarBitInit *&I = Context->TheVarBitInitPool[std::make_pair(T, B)];
|
||||
if (!I)
|
||||
I = new(Allocator) VarBitInit(T, B);
|
||||
I = new(Context->Allocator) VarBitInit(T, B);
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -1732,15 +1747,11 @@ Init *VarBitInit::resolveReferences(Resolver &R) const {
|
|||
return const_cast<VarBitInit*>(this);
|
||||
}
|
||||
|
||||
VarListElementInit *VarListElementInit::get(TypedInit *T,
|
||||
unsigned E) {
|
||||
using Key = std::pair<TypedInit *, unsigned>;
|
||||
static DenseMap<Key, VarListElementInit*> ThePool;
|
||||
|
||||
Key TheKey(std::make_pair(T, E));
|
||||
|
||||
VarListElementInit *&I = ThePool[TheKey];
|
||||
if (!I) I = new(Allocator) VarListElementInit(T, E);
|
||||
VarListElementInit *VarListElementInit::get(TypedInit *T, unsigned E) {
|
||||
VarListElementInit *&I =
|
||||
Context->TheVarListElementInitPool[std::make_pair(T, E)];
|
||||
if (!I)
|
||||
I = new (Context->Allocator) VarListElementInit(T, E);
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -1800,21 +1811,19 @@ static void ProfileVarDefInit(FoldingSetNodeID &ID,
|
|||
}
|
||||
|
||||
VarDefInit *VarDefInit::get(Record *Class, ArrayRef<Init *> Args) {
|
||||
static FoldingSet<VarDefInit> ThePool;
|
||||
|
||||
FoldingSetNodeID ID;
|
||||
ProfileVarDefInit(ID, Class, Args);
|
||||
|
||||
void *IP = nullptr;
|
||||
if (VarDefInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
|
||||
if (VarDefInit *I = Context->TheVarDefInitPool.FindNodeOrInsertPos(ID, IP))
|
||||
return I;
|
||||
|
||||
void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *>(Args.size()),
|
||||
alignof(VarDefInit));
|
||||
VarDefInit *I = new(Mem) VarDefInit(Class, Args.size());
|
||||
void *Mem = Context->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 *>());
|
||||
ThePool.InsertNode(I, IP);
|
||||
Context->TheVarDefInitPool.InsertNode(I, IP);
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -1920,13 +1929,9 @@ std::string VarDefInit::getAsString() const {
|
|||
}
|
||||
|
||||
FieldInit *FieldInit::get(Init *R, StringInit *FN) {
|
||||
using Key = std::pair<Init *, StringInit *>;
|
||||
static DenseMap<Key, FieldInit*> ThePool;
|
||||
|
||||
Key TheKey(std::make_pair(R, FN));
|
||||
|
||||
FieldInit *&I = ThePool[TheKey];
|
||||
if (!I) I = new(Allocator) FieldInit(R, FN);
|
||||
FieldInit *&I = Context->TheFieldInitPool[std::make_pair(R, FN)];
|
||||
if (!I)
|
||||
I = new (Context->Allocator) FieldInit(R, FN);
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -1995,23 +2000,22 @@ CondOpInit::get(ArrayRef<Init *> CondRange,
|
|||
assert(CondRange.size() == ValRange.size() &&
|
||||
"Number of conditions and values must match!");
|
||||
|
||||
static FoldingSet<CondOpInit> ThePool;
|
||||
FoldingSetNodeID ID;
|
||||
ProfileCondOpInit(ID, CondRange, ValRange, Ty);
|
||||
|
||||
void *IP = nullptr;
|
||||
if (CondOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
|
||||
if (CondOpInit *I = Context->TheCondOpInitPool.FindNodeOrInsertPos(ID, IP))
|
||||
return I;
|
||||
|
||||
void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *>(2*CondRange.size()),
|
||||
alignof(BitsInit));
|
||||
void *Mem = Context->Allocator.Allocate(
|
||||
totalSizeToAlloc<Init *>(2 * CondRange.size()), alignof(BitsInit));
|
||||
CondOpInit *I = new(Mem) CondOpInit(CondRange.size(), Ty);
|
||||
|
||||
std::uninitialized_copy(CondRange.begin(), CondRange.end(),
|
||||
I->getTrailingObjects<Init *>());
|
||||
std::uninitialized_copy(ValRange.begin(), ValRange.end(),
|
||||
I->getTrailingObjects<Init *>()+CondRange.size());
|
||||
ThePool.InsertNode(I, IP);
|
||||
Context->TheCondOpInitPool.InsertNode(I, IP);
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -2113,25 +2117,24 @@ static void ProfileDagInit(FoldingSetNodeID &ID, Init *V, StringInit *VN,
|
|||
assert(Name == NameRange.end() && "Arg name overflow!");
|
||||
}
|
||||
|
||||
DagInit *
|
||||
DagInit::get(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange,
|
||||
ArrayRef<StringInit *> NameRange) {
|
||||
static FoldingSet<DagInit> ThePool;
|
||||
|
||||
DagInit *DagInit::get(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange,
|
||||
ArrayRef<StringInit *> NameRange) {
|
||||
FoldingSetNodeID ID;
|
||||
ProfileDagInit(ID, V, VN, ArgRange, NameRange);
|
||||
|
||||
void *IP = nullptr;
|
||||
if (DagInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
|
||||
if (DagInit *I = Context->TheDagInitPool.FindNodeOrInsertPos(ID, IP))
|
||||
return I;
|
||||
|
||||
void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *, StringInit *>(ArgRange.size(), NameRange.size()), alignof(BitsInit));
|
||||
DagInit *I = new(Mem) DagInit(V, VN, ArgRange.size(), NameRange.size());
|
||||
void *Mem = Context->Allocator.Allocate(
|
||||
totalSizeToAlloc<Init *, StringInit *>(ArgRange.size(), NameRange.size()),
|
||||
alignof(BitsInit));
|
||||
DagInit *I = new (Mem) DagInit(V, VN, ArgRange.size(), NameRange.size());
|
||||
std::uninitialized_copy(ArgRange.begin(), ArgRange.end(),
|
||||
I->getTrailingObjects<Init *>());
|
||||
std::uninitialized_copy(NameRange.begin(), NameRange.end(),
|
||||
I->getTrailingObjects<StringInit *>());
|
||||
ThePool.InsertNode(I, IP);
|
||||
Context->TheDagInitPool.InsertNode(I, IP);
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -2301,8 +2304,6 @@ void RecordVal::print(raw_ostream &OS, bool PrintSem) const {
|
|||
if (PrintSem) OS << ";\n";
|
||||
}
|
||||
|
||||
unsigned Record::LastID = 0;
|
||||
|
||||
void Record::checkName() {
|
||||
// Ensure the record name has string type.
|
||||
const TypedInit *TypedName = cast<const TypedInit>(Name);
|
||||
|
@ -2319,10 +2320,12 @@ RecordRecTy *Record::getType() {
|
|||
|
||||
DefInit *Record::getDefInit() {
|
||||
if (!CorrespondingDefInit)
|
||||
CorrespondingDefInit = new (Allocator) DefInit(this);
|
||||
CorrespondingDefInit = new (Context->Allocator) DefInit(this);
|
||||
return CorrespondingDefInit;
|
||||
}
|
||||
|
||||
unsigned Record::getNewUID() { return Context->LastRecordID++; }
|
||||
|
||||
void Record::setName(Init *NewName) {
|
||||
Name = NewName;
|
||||
checkName();
|
||||
|
@ -2501,7 +2504,7 @@ BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
|
|||
|
||||
if (BitsInit *BI = dyn_cast<BitsInit>(R->getValue()))
|
||||
return BI;
|
||||
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
|
||||
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
|
||||
"' exists but does not have a bits value");
|
||||
}
|
||||
|
||||
|
@ -2513,7 +2516,7 @@ ListInit *Record::getValueAsListInit(StringRef FieldName) const {
|
|||
|
||||
if (ListInit *LI = dyn_cast<ListInit>(R->getValue()))
|
||||
return LI;
|
||||
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
|
||||
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
|
||||
"' exists but does not have a list value");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue