From: David Greene
Date: Thu, 23 Apr 2009 21:25:15 +0000 (+0000)
Subject: Make BinOps typed and require a type specifier for !nameconcat. This
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e8cf21e8e3db64dd49777d6bf6c867d47e9f5407;p=oota-llvm.git
Make BinOps typed and require a type specifier for !nameconcat. This
allows binops to be used in typed contexts such as when passing
arguments to classes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69921 91177308-0d34-0410-b5e6-96231b3b80d8
---
diff --git a/docs/TableGenFundamentals.html b/docs/TableGenFundamentals.html
index c9d1fa3b3f1..a698041512a 100644
--- a/docs/TableGenFundamentals.html
+++ b/docs/TableGenFundamentals.html
@@ -398,11 +398,11 @@ supported include:
!strconcat(a, b)
A string value that is the result of concatenating the 'a' and 'b'
strings.
-!nameconcat(a, b)
+!nameconcat(a, b)
A value that is the result of concatenating the 'a' and 'b'
strings and looking up the resulting name in the symbol table. The symbol type
- determines the type of the resulting value. If the symbol is not found,
- TableGen emits an error and aborts.
+ determines the type of the resulting value. If the symbol is not found
+ or the symbol type does not match 'type,' TableGen emits an error and aborts.
Note that all of the values have rules specifying how they convert to values
diff --git a/test/TableGen/nameconcat.td b/test/TableGen/nameconcat.td
index 8dbc4b87d9e..fc865f9a464 100644
--- a/test/TableGen/nameconcat.td
+++ b/test/TableGen/nameconcat.td
@@ -1,4 +1,4 @@
-// RUN: tblgen %s | grep {add_ps} | count 2
+// RUN: tblgen %s | grep {add_ps} | count 3
class ValueType {
int Size = size;
@@ -66,11 +66,25 @@ def int_x86_sse2_add_pd : Intrinsic<"addpd">;
multiclass arith opcode, string asmstr, string Intr> {
def PS : Inst;
+ [(set VR128:$dst, (!nameconcat(Intr, "_ps") VR128:$src1, VR128:$src2))]>;
def PD : Inst;
+ [(set VR128:$dst, (!nameconcat(Intr, "_pd") VR128:$src1, VR128:$src2))]>;
}
defm ADD : arith<0x58, "add", "int_x86_sse2_add">;
+
+class IntInst opcode, string asmstr, Intrinsic Intr> :
+ Inst;
+
+
+multiclass arith_int opcode, string asmstr, string Intr> {
+ def PS_Int : IntInst(Intr, "_ps")>;
+
+ def PD_Int : IntInst(Intr, "_pd")>;
+}
+
+defm ADD : arith_int<0x58, "add", "int_x86_sse2_add">;
diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp
index b505871dee2..4650b88fd51 100644
--- a/utils/TableGen/CodeGenInstruction.cpp
+++ b/utils/TableGen/CodeGenInstruction.cpp
@@ -127,7 +127,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
OperandList.clear();
return;
}
- DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI))->Fold(R, 0);
+ DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI, new DagRecTy))->Fold(R, 0);
unsigned MIOperandNo = 0;
std::set OperandNames;
diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp
index b2442199955..9ce645de34f 100644
--- a/utils/TableGen/Record.cpp
+++ b/utils/TableGen/Record.cpp
@@ -138,10 +138,21 @@ Init *StringRecTy::convertValue(BinOpInit *BO) {
Init *R = BO->getRHS()->convertInitializerTo(this);
if (L == 0 || R == 0) return 0;
if (L != BO->getLHS() || R != BO->getRHS())
- return new BinOpInit(BinOpInit::STRCONCAT, L, R);
+ return new BinOpInit(BinOpInit::STRCONCAT, L, R, new StringRecTy);
return BO;
}
- return 0;
+ if (BO->getOpcode() == BinOpInit::NAMECONCAT) {
+ if (BO->getType()->getAsString() == getAsString()) {
+ Init *L = BO->getLHS()->convertInitializerTo(this);
+ Init *R = BO->getRHS()->convertInitializerTo(this);
+ if (L == 0 || R == 0) return 0;
+ if (L != BO->getLHS() || R != BO->getRHS())
+ return new BinOpInit(BinOpInit::NAMECONCAT, L, R, new StringRecTy);
+ return BO;
+ }
+ }
+
+ return convertValue((TypedInit*)BO);
}
@@ -195,9 +206,19 @@ Init *DagRecTy::convertValue(BinOpInit *BO) {
Init *R = BO->getRHS()->convertInitializerTo(this);
if (L == 0 || R == 0) return 0;
if (L != BO->getLHS() || R != BO->getRHS())
- return new BinOpInit(BinOpInit::CONCAT, L, R);
+ return new BinOpInit(BinOpInit::CONCAT, L, R, new DagRecTy);
return BO;
}
+ if (BO->getOpcode() == BinOpInit::NAMECONCAT) {
+ if (BO->getType()->getAsString() == getAsString()) {
+ Init *L = BO->getLHS()->convertInitializerTo(this);
+ Init *R = BO->getRHS()->convertInitializerTo(this);
+ if (L == 0 || R == 0) return 0;
+ if (L != BO->getLHS() || R != BO->getRHS())
+ return new BinOpInit(BinOpInit::CONCAT, L, R, new DagRecTy);
+ return BO;
+ }
+ }
return 0;
}
@@ -445,13 +466,22 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
// From TGParser::ParseIDValue
if (CurRec) {
- if (const RecordVal *RV = CurRec->getValue(Name))
+ if (const RecordVal *RV = CurRec->getValue(Name)) {
+ if (RV->getType() != getType()) {
+ throw "type mismatch in nameconcat";
+ }
return new VarInit(Name, RV->getType());
-
+ }
+
std::string TemplateArgName = CurRec->getName()+":"+Name;
if (CurRec->isTemplateArg(TemplateArgName)) {
const RecordVal *RV = CurRec->getValue(TemplateArgName);
assert(RV && "Template arg doesn't exist??");
+
+ if (RV->getType() != getType()) {
+ throw "type mismatch in nameconcat";
+ }
+
return new VarInit(TemplateArgName, RV->getType());
}
}
@@ -461,6 +491,11 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
if (CurMultiClass->Rec.isTemplateArg(MCName)) {
const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
assert(RV && "Template arg doesn't exist??");
+
+ if (RV->getType() != getType()) {
+ throw "type mismatch in nameconcat";
+ }
+
return new VarInit(MCName, RV->getType());
}
}
@@ -501,7 +536,7 @@ Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) {
Init *rhs = RHS->resolveReferences(R, RV);
if (LHS != lhs || RHS != rhs)
- return (new BinOpInit(getOpcode(), lhs, rhs))->Fold(&R, 0);
+ return (new BinOpInit(getOpcode(), lhs, rhs, getType()))->Fold(&R, 0);
return Fold(&R, 0);
}
@@ -513,11 +548,40 @@ std::string BinOpInit::getAsString() const {
case SRA: Result = "!sra"; break;
case SRL: Result = "!srl"; break;
case STRCONCAT: Result = "!strconcat"; break;
- case NAMECONCAT: Result = "!nameconcat"; break;
+ case NAMECONCAT:
+ Result = "!nameconcat<" + getType()->getAsString() + ">"; break;
}
return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
}
+Init *BinOpInit::resolveBitReference(Record &R, const RecordVal *IRV,
+ unsigned Bit) {
+ Init *Folded = Fold(&R, 0);
+
+ if (Folded != this) {
+ TypedInit *Typed = dynamic_cast(Folded);
+ if (Typed) {
+ return Typed->resolveBitReference(R, IRV, Bit);
+ }
+ }
+
+ return 0;
+}
+
+Init *BinOpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
+ unsigned Elt) {
+ Init *Folded = Fold(&R, 0);
+
+ if (Folded != this) {
+ TypedInit *Typed = dynamic_cast(Folded);
+ if (Typed) {
+ return Typed->resolveListElementReference(R, IRV, Elt);
+ }
+ }
+
+ return 0;
+}
+
Init *TypedInit::convertInitializerBitRange(const std::vector &Bits) {
BitsRecTy *T = dynamic_cast(getType());
if (T == 0) return 0; // Cannot subscript a non-bits variable...
diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h
index b408452f3d1..4aec3320a2a 100644
--- a/utils/TableGen/Record.h
+++ b/utils/TableGen/Record.h
@@ -77,7 +77,9 @@ public: // These methods should only be called from subclasses of Init
virtual Init *convertValue( IntInit *II) { return 0; }
virtual Init *convertValue(StringInit *SI) { return 0; }
virtual Init *convertValue( ListInit *LI) { return 0; }
- virtual Init *convertValue( BinOpInit *UI) { return 0; }
+ virtual Init *convertValue( BinOpInit *UI) {
+ return convertValue((TypedInit*)UI);
+ }
virtual Init *convertValue( CodeInit *CI) { return 0; }
virtual Init *convertValue(VarBitInit *VB) { return 0; }
virtual Init *convertValue( DefInit *DI) { return 0; }
@@ -123,7 +125,7 @@ public:
virtual Init *convertValue(VarBitInit *VB) { return (Init*)VB; }
virtual Init *convertValue( DefInit *DI) { return 0; }
virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( BinOpInit *UI) { return 0; }
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( TypedInit *TI);
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -165,7 +167,7 @@ public:
virtual Init *convertValue(VarBitInit *VB) { return 0; }
virtual Init *convertValue( DefInit *DI) { return 0; }
virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( BinOpInit *UI) { return 0; }
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( TypedInit *TI);
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -203,7 +205,7 @@ public:
virtual Init *convertValue(VarBitInit *VB) { return 0; }
virtual Init *convertValue( DefInit *DI) { return 0; }
virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( BinOpInit *UI) { return 0; }
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( TypedInit *TI);
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -282,7 +284,7 @@ public:
virtual Init *convertValue(VarBitInit *VB) { return 0; }
virtual Init *convertValue( DefInit *DI) { return 0; }
virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( BinOpInit *UI) { return 0; }
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( TypedInit *TI);
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -319,7 +321,7 @@ public:
virtual Init *convertValue(VarBitInit *VB) { return 0; }
virtual Init *convertValue( DefInit *DI) { return 0; }
virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( BinOpInit *UI) { return 0; }
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( TypedInit *TI);
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -393,7 +395,7 @@ public:
virtual Init *convertValue( ListInit *LI) { return 0; }
virtual Init *convertValue( CodeInit *CI) { return 0; }
virtual Init *convertValue(VarBitInit *VB) { return 0; }
- virtual Init *convertValue( BinOpInit *UI) { return 0; }
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( DefInit *DI);
virtual Init *convertValue( DagInit *DI) { return 0; }
virtual Init *convertValue( TypedInit *VI);
@@ -656,36 +658,6 @@ public:
inline bool empty() const { return Values.empty(); }
};
-/// BinOpInit - !op (X, Y) - Combine two inits.
-///
-class BinOpInit : public Init {
-public:
- enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT };
-private:
- BinaryOp Opc;
- Init *LHS, *RHS;
-public:
- BinOpInit(BinaryOp opc, Init *lhs, Init *rhs) : Opc(opc), LHS(lhs), RHS(rhs) {
- }
-
- BinaryOp getOpcode() const { return Opc; }
- Init *getLHS() const { return LHS; }
- Init *getRHS() const { return RHS; }
-
- // Fold - If possible, fold this to a simpler init. Return this if not
- // possible to fold.
- Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
-
- virtual Init *convertInitializerTo(RecTy *Ty) {
- return Ty->convertValue(this);
- }
-
- virtual Init *resolveReferences(Record &R, const RecordVal *RV);
-
- virtual std::string getAsString() const;
-};
-
-
/// TypedInit - This is the common super-class of types that have a specific,
/// explicit, type.
@@ -714,6 +686,43 @@ public:
unsigned Elt) = 0;
};
+
+/// BinOpInit - !op (X, Y) - Combine two inits.
+///
+class BinOpInit : public TypedInit {
+public:
+ enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT };
+private:
+ BinaryOp Opc;
+ Init *LHS, *RHS;
+public:
+ BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
+ TypedInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {
+ }
+
+ BinaryOp getOpcode() const { return Opc; }
+ Init *getLHS() const { return LHS; }
+ Init *getRHS() const { return RHS; }
+
+ // Fold - If possible, fold this to a simpler init. Return this if not
+ // possible to fold.
+ Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
+
+ virtual Init *convertInitializerTo(RecTy *Ty) {
+ return Ty->convertValue(this);
+ }
+
+ virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+ unsigned Bit);
+ virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt);
+
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
+ virtual std::string getAsString() const;
+};
+
+
/// VarInit - 'Opcode' - Represent a reference to an entire variable object.
///
class VarInit : public TypedInit {
diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp
index d7feb98d2a0..c3b17ac6039 100644
--- a/utils/TableGen/TGParser.cpp
+++ b/utils/TableGen/TGParser.cpp
@@ -784,6 +784,26 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
BinOpInit::BinaryOp Code = BinOpInit::NAMECONCAT;
Lex.Lex(); // eat the operation
+
+ if (Lex.getCode() != tgtok::less) {
+ TokError("expected type name for nameconcat");
+ return 0;
+ }
+ Lex.Lex(); // eat the <
+
+ RecTy *Type = ParseType();
+
+ if (Type == 0) {
+ TokError("expected type name for nameconcat");
+ return 0;
+ }
+
+ if (Lex.getCode() != tgtok::greater) {
+ TokError("expected type name for nameconcat");
+ return 0;
+ }
+ Lex.Lex(); // eat the >
+
if (Lex.getCode() != tgtok::l_paren) {
TokError("expected '(' after binary operator");
return 0;
@@ -807,7 +827,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
return 0;
}
Lex.Lex(); // eat the ')'
- Operator = (new BinOpInit(Code, LHS, RHS))->Fold(CurRec, CurMultiClass);
+ Operator = (new BinOpInit(Code, LHS, RHS, Type))->Fold(CurRec, CurMultiClass);
}
// If the operator name is present, parse it.
@@ -842,16 +862,59 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
case tgtok::XStrConcat:
case tgtok::XNameConcat: { // Value ::= !binop '(' Value ',' Value ')'
BinOpInit::BinaryOp Code;
+ RecTy *Type = 0;
+
+
switch (Lex.getCode()) {
default: assert(0 && "Unhandled code!");
- case tgtok::XConcat: Code = BinOpInit::CONCAT; break;
- case tgtok::XSRA: Code = BinOpInit::SRA; break;
- case tgtok::XSRL: Code = BinOpInit::SRL; break;
- case tgtok::XSHL: Code = BinOpInit::SHL; break;
- case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break;
- case tgtok::XNameConcat: Code = BinOpInit::NAMECONCAT; break;
+ case tgtok::XConcat:
+ Lex.Lex(); // eat the operation
+ Code = BinOpInit::CONCAT;
+ Type = new DagRecTy();
+ break;
+ case tgtok::XSRA:
+ Lex.Lex(); // eat the operation
+ Code = BinOpInit::SRA;
+ Type = new IntRecTy();
+ break;
+ case tgtok::XSRL:
+ Lex.Lex(); // eat the operation
+ Code = BinOpInit::SRL;
+ Type = new IntRecTy();
+ break;
+ case tgtok::XSHL:
+ Lex.Lex(); // eat the operation
+ Code = BinOpInit::SHL;
+ Type = new IntRecTy();
+ break;
+ case tgtok::XStrConcat:
+ Lex.Lex(); // eat the operation
+ Code = BinOpInit::STRCONCAT;
+ Type = new StringRecTy();
+ break;
+ case tgtok::XNameConcat:
+ Lex.Lex(); // eat the operation
+ Code = BinOpInit::NAMECONCAT;
+ if (Lex.getCode() != tgtok::less) {
+ TokError("expected type name for nameconcat");
+ return 0;
+ }
+ Lex.Lex(); // eat the <
+
+ Type = ParseType();
+
+ if (Type == 0) {
+ TokError("expected type name for nameconcat");
+ return 0;
+ }
+
+ if (Lex.getCode() != tgtok::greater) {
+ TokError("expected type name for nameconcat");
+ return 0;
+ }
+ Lex.Lex(); // eat the >
+ break;
}
- Lex.Lex(); // eat the operation
if (Lex.getCode() != tgtok::l_paren) {
TokError("expected '(' after binary operator");
return 0;
@@ -875,7 +938,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
return 0;
}
Lex.Lex(); // eat the ')'
- return (new BinOpInit(Code, LHS, RHS))->Fold(CurRec, CurMultiClass);
+ return (new BinOpInit(Code, LHS, RHS, Type))->Fold(CurRec, CurMultiClass);
}
}