From 77f8274c7d4bfb5e2a449eb49dc78dcae37e5457 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Mon, 18 Jul 2011 17:02:57 +0000 Subject: Intern all RecTy subclass instances to avoid duplicates. Make all of the RecTy constructors private, and use get() factory methods instead. Return singleton instances when it makes sense. ListTy instance pointers are stored in the element RecTy instance. BitsRecTy instance pointers, one per length, are stored in a static vector. Also unique DefInit instances. A Record has a unique DefInit which has a unique RecordRecTy instance. This saves some 200k-300k RecTy allocations when parsing ARM.td. It reduces TableGen's heap usage by almost 50%. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135399 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/Record.cpp | 54 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 9 deletions(-) (limited to 'utils/TableGen/Record.cpp') diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp index 730eca1b3c..3aaaa87989 100644 --- a/utils/TableGen/Record.cpp +++ b/utils/TableGen/Record.cpp @@ -23,8 +23,20 @@ using namespace llvm; // Type implementations //===----------------------------------------------------------------------===// +BitRecTy BitRecTy::Shared; +IntRecTy IntRecTy::Shared; +StringRecTy StringRecTy::Shared; +CodeRecTy CodeRecTy::Shared; +DagRecTy DagRecTy::Shared; + void RecTy::dump() const { print(errs()); } +ListRecTy *RecTy::getListTy() { + if (!ListTy) + ListTy = new ListRecTy(this); + return ListTy; +} + Init *BitRecTy::convertValue(BitsInit *BI) { if (BI->getNumBits() != 1) return 0; // Only accept if just one bit! return BI->getBit(0); @@ -47,6 +59,16 @@ Init *BitRecTy::convertValue(TypedInit *VI) { return 0; } +BitsRecTy *BitsRecTy::get(unsigned Sz) { + static std::vector Shared; + if (Sz >= Shared.size()) + Shared.resize(Sz + 1); + BitsRecTy *&Ty = Shared[Sz]; + if (!Ty) + Ty = new BitsRecTy(Sz); + return Ty; +} + std::string BitsRecTy::getAsString() const { return "bits<" + utostr(Size) + ">"; } @@ -231,7 +253,7 @@ Init *ListRecTy::convertValue(ListInit *LI) { return 0; } - return new ListInit(Elements, new ListRecTy(Ty)); + return new ListInit(Elements, this); } Init *ListRecTy::convertValue(TypedInit *TI) { @@ -277,6 +299,10 @@ Init *DagRecTy::convertValue(BinOpInit *BO) { return 0; } +RecordRecTy *RecordRecTy::get(Record *R) { + return &dynamic_cast(*R->getDefInit()->getType()); +} + std::string RecordRecTy::getAsString() const { return Rec->getName(); } @@ -326,7 +352,7 @@ RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) { iend = T1SuperClasses.end(); i != iend; ++i) { - RecordRecTy *SuperRecTy1 = new RecordRecTy(*i); + RecordRecTy *SuperRecTy1 = RecordRecTy::get(*i); RecTy *NewType1 = resolveTypes(SuperRecTy1, T2); if (NewType1 != 0) { if (NewType1 != SuperRecTy1) { @@ -345,7 +371,7 @@ RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) { iend = T2SuperClasses.end(); i != iend; ++i) { - RecordRecTy *SuperRecTy2 = new RecordRecTy(*i); + RecordRecTy *SuperRecTy2 = RecordRecTy::get(*i); RecTy *NewType2 = resolveTypes(T1, SuperRecTy2); if (NewType2 != 0) { if (NewType2 != SuperRecTy2) { @@ -577,7 +603,7 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { } if (Record *D = (CurRec->getRecords()).getDef(Name)) - return new DefInit(D); + return DefInit::get(D); throw TGError(CurRec->getLoc(), "Undefined reference:'" + Name + "'\n"); } @@ -687,9 +713,9 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { // try to fold eq comparison for 'bit' and 'int', otherwise fallback // to string objects. IntInit* L = - dynamic_cast(LHS->convertInitializerTo(new IntRecTy())); + dynamic_cast(LHS->convertInitializerTo(IntRecTy::get())); IntInit* R = - dynamic_cast(RHS->convertInitializerTo(new IntRecTy())); + dynamic_cast(RHS->convertInitializerTo(IntRecTy::get())); if (L && R) return new IntInit(L->getValue() == R->getValue()); @@ -902,7 +928,7 @@ Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { if (LHSd->getAsString() == RHSd->getAsString()) { Val = MHSd->getDef(); } - return new DefInit(Val); + return DefInit::get(Val); } if (RHSv) { std::string Val = RHSv->getName(); @@ -941,7 +967,7 @@ Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { case IF: { IntInit *LHSi = dynamic_cast(LHS); - if (Init *I = LHS->convertInitializerTo(new IntRecTy())) + if (Init *I = LHS->convertInitializerTo(IntRecTy::get())) LHSi = dynamic_cast(I); if (LHSi) { if (LHSi->getValue()) { @@ -962,7 +988,7 @@ Init *TernOpInit::resolveReferences(Record &R, const RecordVal *RV) { if (Opc == IF && lhs != LHS) { IntInit *Value = dynamic_cast(lhs); - if (Init *I = lhs->convertInitializerTo(new IntRecTy())) + if (Init *I = lhs->convertInitializerTo(IntRecTy::get())) Value = dynamic_cast(I); if (Value != 0) { // Short-circuit @@ -1156,6 +1182,10 @@ resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt) { return 0; } +DefInit *DefInit::get(Record *R) { + return R->getDefInit(); +} + RecTy *DefInit::getFieldType(const std::string &FieldName) const { if (const RecordVal *RV = Def->getValue(FieldName)) return RV->getType(); @@ -1270,6 +1300,12 @@ void RecordVal::print(raw_ostream &OS, bool PrintSem) const { unsigned Record::LastID = 0; +DefInit *Record::getDefInit() { + if (!TheInit) + TheInit = new DefInit(this, new RecordRecTy(this)); + return TheInit; +} + void Record::setName(const std::string &Name) { if (TrackedRecords.getDef(getName()) == this) { TrackedRecords.removeDef(getName()); -- cgit v1.2.3-70-g09d2