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); } }