summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp4
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp4
-rw-r--r--utils/TableGen/Record.cpp54
-rw-r--r--utils/TableGen/Record.h63
-rw-r--r--utils/TableGen/TGParser.cpp46
-rw-r--r--utils/TableGen/TGParser.h2
6 files changed, 123 insertions, 50 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 072893fe5a..16585f7a91 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<BitsInit*>(TheInit)) {
// Turn this into an IntInit.
- Init *II = BI->convertInitializerTo(new IntRecTy());
+ Init *II = BI->convertInitializerTo(IntRecTy::get());
if (II == 0 || !dynamic_cast<IntInit*>(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 1acf3a85b6..d7816c2c28 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 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<BitsRecTy*> 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<RecordRecTy&>(*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<IntInit*>(LHS->convertInitializerTo(new IntRecTy()));
+ dynamic_cast<IntInit*>(LHS->convertInitializerTo(IntRecTy::get()));
IntInit* R =
- dynamic_cast<IntInit*>(RHS->convertInitializerTo(new IntRecTy()));
+ dynamic_cast<IntInit*>(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<IntInit*>(LHS);
- if (Init *I = LHS->convertInitializerTo(new IntRecTy()))
+ if (Init *I = LHS->convertInitializerTo(IntRecTy::get()))
LHSi = dynamic_cast<IntInit*>(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<IntInit*>(lhs);
- if (Init *I = lhs->convertInitializerTo(new IntRecTy()))
+ if (Init *I = lhs->convertInitializerTo(IntRecTy::get()))
Value = dynamic_cast<IntInit*>(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 2f4080bbfd..f4d091723d 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<this>.
+ 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<Init*>::const_iterator const_iterator;
explicit ListInit(std::vector<Init*> &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<std::pair<Init*, std::string> > &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<Init*> &args,
const std::vector<std::string> &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<std::string> &getTemplateArgs() const {
return TemplateArgs;
}
diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp
index 59097f986f..1b916b44c7 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<unsigned> &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<BitInit*>(MHS);
BitInit *RHSbit = dynamic_cast<BitInit*>(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 dce7e1dec9..8b56b8a329 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;