diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 072893fe5ab..16585f7a919 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -1771,7 +1771,7 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ if (BitsInit *BI = dynamic_cast(TheInit)) { // Turn this into an IntInit. - Init *II = BI->convertInitializerTo(new IntRecTy()); + Init *II = BI->convertInitializerTo(IntRecTy::get()); if (II == 0 || !dynamic_cast(II)) error("Bits value must be constants!"); return ParseTreePattern(II, OpName); @@ -2180,7 +2180,7 @@ void CodeGenDAGPatterns::ParseDefaultOperands() { // Find some SDNode. assert(!SDNodes.empty() && "No SDNodes parsed?"); - Init *SomeSDNode = new DefInit(SDNodes.begin()->first); + Init *SomeSDNode = DefInit::get(SDNodes.begin()->first); for (unsigned iter = 0; iter != 2; ++iter) { for (unsigned i = 0, e = DefaultOps[iter].size(); i != e; ++i) { diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 1acf3a85b60..d7816c2c281 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -182,7 +182,7 @@ struct TupleExpander : SetTheory::Expander { // Precompute some types. Record *RegisterCl = Def->getRecords().getClass("Register"); - RecTy *RegisterRecTy = new RecordRecTy(RegisterCl); + RecTy *RegisterRecTy = RecordRecTy::get(RegisterCl); StringInit *BlankName = new StringInit(""); // Zip them up. @@ -195,7 +195,7 @@ struct TupleExpander : SetTheory::Expander { Record *Reg = Lists[i][n]; if (i) Name += '_'; Name += Reg->getName(); - Tuple.push_back(new DefInit(Reg)); + Tuple.push_back(DefInit::get(Reg)); CostPerUse = std::max(CostPerUse, unsigned(Reg->getValueAsInt("CostPerUse"))); } diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp index 730eca1b3ca..3aaaa879899 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()); diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h index 2f4080bbfd9..f4d091723dd 100644 --- a/utils/TableGen/Record.h +++ b/utils/TableGen/Record.h @@ -63,7 +63,10 @@ class RecordKeeper; // Type Classes //===----------------------------------------------------------------------===// -struct RecTy { +class RecTy { + ListRecTy *ListTy; +public: + RecTy() : ListTy(0) {} virtual ~RecTy() {} virtual std::string getAsString() const = 0; @@ -74,6 +77,9 @@ struct RecTy { /// converted to the specified type. virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0; + /// getListTy - Returns the type representing list. + ListRecTy *getListTy(); + public: // These methods should only be called from subclasses of Init virtual Init *convertValue( UnsetInit *UI) { return 0; } virtual Init *convertValue( BitInit *BI) { return 0; } @@ -124,7 +130,11 @@ inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) { /// BitRecTy - 'bit' - Represent a single bit /// class BitRecTy : public RecTy { + static BitRecTy Shared; + BitRecTy() {} public: + static BitRecTy *get() { return &Shared; } + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } virtual Init *convertValue( BitInit *BI) { return (Init*)BI; } virtual Init *convertValue( BitsInit *BI); @@ -164,8 +174,9 @@ public: /// class BitsRecTy : public RecTy { unsigned Size; -public: explicit BitsRecTy(unsigned Sz) : Size(Sz) {} +public: + static BitsRecTy *get(unsigned Sz); unsigned getNumBits() const { return Size; } @@ -208,7 +219,11 @@ public: /// IntRecTy - 'int' - Represent an integer value of no particular size /// class IntRecTy : public RecTy { + static IntRecTy Shared; + IntRecTy() {} public: + static IntRecTy *get() { return &Shared; } + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } virtual Init *convertValue( BitInit *BI); virtual Init *convertValue( BitsInit *BI); @@ -246,7 +261,11 @@ public: /// StringRecTy - 'string' - Represent an string value /// class StringRecTy : public RecTy { + static StringRecTy Shared; + StringRecTy() {} public: + static StringRecTy *get() { return &Shared; } + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } virtual Init *convertValue( BitInit *BI) { return 0; } virtual Init *convertValue( BitsInit *BI) { return 0; } @@ -288,9 +307,10 @@ public: /// class ListRecTy : public RecTy { RecTy *Ty; -public: explicit ListRecTy(RecTy *T) : Ty(T) {} - + friend ListRecTy *RecTy::getListTy(); +public: + static ListRecTy *get(RecTy *T) { return T->getListTy(); } RecTy *getElementType() const { return Ty; } virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } @@ -331,7 +351,11 @@ public: /// CodeRecTy - 'code' - Represent an code fragment, function or method. /// class CodeRecTy : public RecTy { + static CodeRecTy Shared; + CodeRecTy() {} public: + static CodeRecTy *get() { return &Shared; } + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } virtual Init *convertValue( BitInit *BI) { return 0; } virtual Init *convertValue( BitsInit *BI) { return 0; } @@ -367,7 +391,11 @@ public: /// DagRecTy - 'dag' - Represent a dag fragment /// class DagRecTy : public RecTy { + static DagRecTy Shared; + DagRecTy() {} public: + static DagRecTy *get() { return &Shared; } + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } virtual Init *convertValue( BitInit *BI) { return 0; } virtual Init *convertValue( BitsInit *BI) { return 0; } @@ -407,8 +435,10 @@ public: /// class RecordRecTy : public RecTy { Record *Rec; -public: explicit RecordRecTy(Record *R) : Rec(R) {} + friend class Record; +public: + static RecordRecTy *get(Record *R); Record *getRecord() const { return Rec; } @@ -633,7 +663,7 @@ public: class IntInit : public TypedInit { int64_t Value; public: - explicit IntInit(int64_t V) : TypedInit(new IntRecTy), Value(V) {} + explicit IntInit(int64_t V) : TypedInit(IntRecTy::get()), Value(V) {} int64_t getValue() const { return Value; } @@ -671,7 +701,7 @@ class StringInit : public TypedInit { std::string Value; public: explicit StringInit(const std::string &V) - : TypedInit(new StringRecTy), Value(V) {} + : TypedInit(StringRecTy::get()), Value(V) {} const std::string &getValue() const { return Value; } @@ -726,11 +756,11 @@ public: typedef std::vector::const_iterator const_iterator; explicit ListInit(std::vector &Vs, RecTy *EltTy) - : TypedInit(new ListRecTy(EltTy)) { + : TypedInit(ListRecTy::get(EltTy)) { Values.swap(Vs); } explicit ListInit(iterator Start, iterator End, RecTy *EltTy) - : TypedInit(new ListRecTy(EltTy)), Values(Start, End) {} + : TypedInit(ListRecTy::get(EltTy)), Values(Start, End) {} unsigned getSize() const { return Values.size(); } Init *getElement(unsigned i) const { @@ -1034,8 +1064,10 @@ public: /// class DefInit : public TypedInit { Record *Def; + DefInit(Record *D, RecordRecTy *T) : TypedInit(T), Def(D) {} + friend class Record; public: - explicit DefInit(Record *D) : TypedInit(new RecordRecTy(D)), Def(D) {} + static DefInit *get(Record*); virtual Init *convertInitializerTo(RecTy *Ty) { return Ty->convertValue(this); @@ -1111,7 +1143,7 @@ class DagInit : public TypedInit { public: DagInit(Init *V, std::string VN, const std::vector > &args) - : TypedInit(new DagRecTy), Val(V), ValName(VN) { + : TypedInit(DagRecTy::get()), Val(V), ValName(VN) { Args.reserve(args.size()); ArgNames.reserve(args.size()); for (unsigned i = 0, e = args.size(); i != e; ++i) { @@ -1121,7 +1153,7 @@ public: } DagInit(Init *V, std::string VN, const std::vector &args, const std::vector &argNames) - : TypedInit(new DagRecTy), Val(V), ValName(VN), Args(args), + : TypedInit(DagRecTy::get()), Val(V), ValName(VN), Args(args), ArgNames(argNames) { } virtual Init *convertInitializerTo(RecTy *Ty) { @@ -1235,11 +1267,13 @@ class Record { // Tracks Record instances. Not owned by Record. RecordKeeper &TrackedRecords; + DefInit *TheInit; + public: // Constructs a record. explicit Record(const std::string &N, SMLoc loc, RecordKeeper &records) : - ID(LastID++), Name(N), Loc(loc), TrackedRecords(records) {} + ID(LastID++), Name(N), Loc(loc), TrackedRecords(records), TheInit(0) {} ~Record() {} @@ -1253,6 +1287,9 @@ public: SMLoc getLoc() const { return Loc; } + /// get the corresponding DefInit. + DefInit *getDefInit(); + const std::vector &getTemplateArgs() const { return TemplateArgs; } diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp index 59097f986f7..1b916b44c74 100644 --- a/utils/TableGen/TGParser.cpp +++ b/utils/TableGen/TGParser.cpp @@ -106,9 +106,9 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const std::string &ValName, return Error(Loc, "Value '" + ValName + "' is not a bits type"); // Convert the incoming value to a bits type of the appropriate size... - Init *BI = V->convertInitializerTo(new BitsRecTy(BitList.size())); + Init *BI = V->convertInitializerTo(BitsRecTy::get(BitList.size())); if (BI == 0) { - V->convertInitializerTo(new BitsRecTy(BitList.size())); + V->convertInitializerTo(BitsRecTy::get(BitList.size())); return Error(Loc, "Initializer is not compatible with bit range"); } @@ -581,13 +581,13 @@ bool TGParser::ParseOptionalBitList(std::vector &Ranges) { RecTy *TGParser::ParseType() { switch (Lex.getCode()) { default: TokError("Unknown token when expecting a type"); return 0; - case tgtok::String: Lex.Lex(); return new StringRecTy(); - case tgtok::Bit: Lex.Lex(); return new BitRecTy(); - case tgtok::Int: Lex.Lex(); return new IntRecTy(); - case tgtok::Code: Lex.Lex(); return new CodeRecTy(); - case tgtok::Dag: Lex.Lex(); return new DagRecTy(); + case tgtok::String: Lex.Lex(); return StringRecTy::get(); + case tgtok::Bit: Lex.Lex(); return BitRecTy::get(); + case tgtok::Int: Lex.Lex(); return IntRecTy::get(); + case tgtok::Code: Lex.Lex(); return CodeRecTy::get(); + case tgtok::Dag: Lex.Lex(); return DagRecTy::get(); case tgtok::Id: - if (Record *R = ParseClassID()) return new RecordRecTy(R); + if (Record *R = ParseClassID()) return RecordRecTy::get(R); return 0; case tgtok::Bits: { if (Lex.Lex() != tgtok::less) { // Eat 'bits' @@ -604,7 +604,7 @@ RecTy *TGParser::ParseType() { return 0; } Lex.Lex(); // Eat '>' - return new BitsRecTy(Val); + return BitsRecTy::get(Val); } case tgtok::List: { if (Lex.Lex() != tgtok::less) { // Eat 'bits' @@ -620,7 +620,7 @@ RecTy *TGParser::ParseType() { return 0; } Lex.Lex(); // Eat '>' - return new ListRecTy(SubType); + return ListRecTy::get(SubType); } } } @@ -667,7 +667,7 @@ Init *TGParser::ParseIDValue(Record *CurRec, } if (Record *D = Records.getDef(Name)) - return new DefInit(D); + return DefInit::get(D); Error(NameLoc, "Variable not defined: '" + Name + "'"); return 0; @@ -715,7 +715,7 @@ Init *TGParser::ParseOperation(Record *CurRec) { case tgtok::XEmpty: Lex.Lex(); // eat the operation Code = UnOpInit::EMPTY; - Type = new IntRecTy; + Type = IntRecTy::get(); break; } if (Lex.getCode() != tgtok::l_paren) { @@ -767,7 +767,7 @@ Init *TGParser::ParseOperation(Record *CurRec) { if (Code == UnOpInit::HEAD) { Type = Itemt->getType(); } else { - Type = new ListRecTy(Itemt->getType()); + Type = ListRecTy::get(Itemt->getType()); } } else { assert(LHSt && "expected list type argument in unary operator"); @@ -808,14 +808,14 @@ Init *TGParser::ParseOperation(Record *CurRec) { switch (OpTok) { default: assert(0 && "Unhandled code!"); - case tgtok::XConcat: Code = BinOpInit::CONCAT; Type = new DagRecTy(); break; - case tgtok::XSRA: Code = BinOpInit::SRA; Type = new IntRecTy(); break; - case tgtok::XSRL: Code = BinOpInit::SRL; Type = new IntRecTy(); break; - case tgtok::XSHL: Code = BinOpInit::SHL; Type = new IntRecTy(); break; - case tgtok::XEq: Code = BinOpInit::EQ; Type = new BitRecTy(); break; + case tgtok::XConcat: Code = BinOpInit::CONCAT;Type = DagRecTy::get(); break; + case tgtok::XSRA: Code = BinOpInit::SRA; Type = IntRecTy::get(); break; + case tgtok::XSRL: Code = BinOpInit::SRL; Type = IntRecTy::get(); break; + case tgtok::XSHL: Code = BinOpInit::SHL; Type = IntRecTy::get(); break; + case tgtok::XEq: Code = BinOpInit::EQ; Type = BitRecTy::get(); break; case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; - Type = new StringRecTy(); + Type = StringRecTy::get(); break; } @@ -932,14 +932,14 @@ Init *TGParser::ParseOperation(Record *CurRec) { if (MHSbits && RHSbits && MHSbits->getNumBits() == RHSbits->getNumBits()) { - Type = new BitRecTy(); + Type = BitRecTy::get(); break; } else { BitInit *MHSbit = dynamic_cast(MHS); BitInit *RHSbit = dynamic_cast(RHS); if (MHSbit && RHSbit) { - Type = new BitRecTy(); + Type = BitRecTy::get(); break; } } @@ -1110,7 +1110,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) { Records.addDef(NewRec); // The result of the expression is a reference to the new record. - return new DefInit(NewRec); + return DefInit::get(NewRec); } case tgtok::l_brace: { // Value ::= '{' ValueList '}' SMLoc BraceLoc = Lex.getLoc(); @@ -1129,7 +1129,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) { BitsInit *Result = new BitsInit(Vals.size()); for (unsigned i = 0, e = Vals.size(); i != e; ++i) { - Init *Bit = Vals[i]->convertInitializerTo(new BitRecTy()); + Init *Bit = Vals[i]->convertInitializerTo(BitRecTy::get()); if (Bit == 0) { Error(BraceLoc, "Element #" + utostr(i) + " (" + Vals[i]->getAsString()+ ") is not convertable to a bit"); diff --git a/utils/TableGen/TGParser.h b/utils/TableGen/TGParser.h index dce7e1dec94..8b56b8a3290 100644 --- a/utils/TableGen/TGParser.h +++ b/utils/TableGen/TGParser.h @@ -24,7 +24,7 @@ namespace llvm { class Record; class RecordVal; class RecordKeeper; - struct RecTy; + class RecTy; class Init; struct MultiClass; struct SubClassReference;