From ae3329d59779756146d052d35669584f111f23bd Mon Sep 17 00:00:00 2001 From: David Greene Date: Fri, 7 Oct 2011 18:25:05 +0000 Subject: [PATCH] Remove Multidefs Multidefs are a bit unwieldy and incomplete. Remove them in favor of another mechanism, probably for loops. Revert "Make Test More Thorough" Revert "Fix a typo." Revert "Vim Support for Multidefs" Revert "Emacs Support for Multidefs" Revert "Document Multidefs" Revert "Add a Multidef Test" Revert "Update Test for Multidefs" Revert "Process Multidefs" Revert "Parser Multidef Support" Revert "Lexer Support for Multidefs" Revert "Add Multidef Data Structures" llvm-svn: 141378 --- docs/TableGenFundamentals.html | 59 ----------- include/llvm/TableGen/Record.h | 17 ---- lib/TableGen/TGLexer.cpp | 1 - lib/TableGen/TGLexer.h | 2 +- lib/TableGen/TGParser.cpp | 176 +-------------------------------- lib/TableGen/TGParser.h | 1 - test/TableGen/MultiDef.td | 18 ---- test/TableGen/MultiPat.td | 36 ++----- utils/emacs/tablegen-mode.el | 2 +- utils/vim/tablegen.vim | 2 +- 10 files changed, 12 insertions(+), 302 deletions(-) delete mode 100644 test/TableGen/MultiDef.td diff --git a/docs/TableGenFundamentals.html b/docs/TableGenFundamentals.html index f5b7e4ab577..e8fca325130 100644 --- a/docs/TableGenFundamentals.html +++ b/docs/TableGenFundamentals.html @@ -769,65 +769,6 @@ before them. -

-A special "multidef" may be used inside a multiclass to generate -several defs given a list of values. -

- -
-
-class Base<int i> {
-  int value = i;
-}
-
-multiclass Multi<list<int> values> {
-  def ONE : Base<values[0]>;
-  def TWO : Base<values[1]>;
-
-  multidef COUNT<values, int v, 2> : Base<v>;
-}
-
-defm List : Multi<[1, 2, 3, 4, 5, 6]<;
-...
-
-// Results
-def ListCOUNT {
-  int v = ?;
-  int value = v;
-  list Multi::values = [1, 2, 3, 4, 5, 6];
-}
-def ListONE {
-  int value = 1;
-}
-def ListTWO {
-  int value = 2;
-}
-def MD2.ListCOUNT {
-  int value = 3;
-}
-def MD3.ListCOUNT {
-  int value = 4;
-}
-def MD4.ListCOUNT {
-  int value = 5;
-}
-def MD5.ListCOUNT {
-  int value = 6;
-}
-
-
- -

-A multidef takes three "arguments" in the <> notation after the multidef -name. The first is a list of items to process. The second is a declaration. -This declaration creates a temporary name used as an iterator. It picks up the -value of each processed list item as TableGen generates defs from the multidef. -This temporary may be named and passed into the multidef body as shown in the -example above. This provides a powerful way to generate defs with various -values from a single multidef. The final "argument" is an integer value -indicating where in the list to begin processing. In the above example we -chose to begin list processing with the third item (index 2). -

diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h index 0fc50c5a3bc..afce7609986 100644 --- a/include/llvm/TableGen/Record.h +++ b/include/llvm/TableGen/Record.h @@ -1568,23 +1568,6 @@ struct MultiClass { typedef std::vector RecordVector; RecordVector DefPrototypes; - struct MultiDef { - Record *Rec; // The base record for all defs generated. - // This serves as the multiclass def prototype. - TypedInit *List; // A list of values to process. - // Each one generates a new def. - IntInit *Start; // This specified the list index from which to start - // processing. - std::string ItemName; // The name of a temporary iterator value to - // track the current list item being processed. - - MultiDef(Record *R, TypedInit *L, IntInit *S, const std::string &I) - : Rec(R), List(L), Start(S), ItemName(I) {}; - }; - - typedef std::vector MultiDefVector; - MultiDefVector MultiDefPrototypes; - void dump() const; MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) : diff --git a/lib/TableGen/TGLexer.cpp b/lib/TableGen/TGLexer.cpp index 5a6c8aa8a5b..8c1b4290548 100644 --- a/lib/TableGen/TGLexer.cpp +++ b/lib/TableGen/TGLexer.cpp @@ -232,7 +232,6 @@ tgtok::TokKind TGLexer::LexIdentifier() { .Case("dag", tgtok::Dag) .Case("class", tgtok::Class) .Case("def", tgtok::Def) - .Case("multidef", tgtok::MultiDef) .Case("defm", tgtok::Defm) .Case("multiclass", tgtok::MultiClass) .Case("field", tgtok::Field) diff --git a/lib/TableGen/TGLexer.h b/lib/TableGen/TGLexer.h index 7e222875aa8..84d328b12d9 100644 --- a/lib/TableGen/TGLexer.h +++ b/lib/TableGen/TGLexer.h @@ -41,7 +41,7 @@ namespace tgtok { equal, question, // = ? // Keywords. - Bit, Bits, Class, Code, Dag, Def, MultiDef, Defm, Field, In, Int, Let, List, + Bit, Bits, Class, Code, Dag, Def, Defm, Field, In, Int, Let, List, MultiClass, String, // !keywords. diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp index 97240481fcb..e7f00baf493 100644 --- a/lib/TableGen/TGParser.cpp +++ b/lib/TableGen/TGParser.cpp @@ -1720,90 +1720,6 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) { return false; } - -/// ParseMultiDef - Parse and return a multiclass multidef, return the record -/// corresponding to it. This returns null on error. -/// -/// MultiDefInst ::= MULTIDEF ObjectName '<' Value ',' Declaration ',' -/// Value '>' ObjectBody -/// -bool TGParser::ParseMultiDef(MultiClass *CurMultiClass) { - assert(CurMultiClass && "No multiclass for multidef!"); - - SMLoc DefLoc = Lex.getLoc(); - assert(Lex.getCode() == tgtok::MultiDef && "Unknown tok"); - Lex.Lex(); // Eat the 'multidef' token. - - // Parse ObjectName and make a record for it. - Record *CurRec = new Record(ParseObjectName(), DefLoc, Records); - - if (Lex.getCode() != tgtok::less) - return TokError("multidef init requires a non-empty list of values"); - Lex.Lex(); // Eat the '<' - - Init *ListI = ParseValue(CurRec, 0); - if (ListI == 0) - return TokError("First multidef init must be of list type"); - - if (Lex.getCode() != tgtok::comma) - return TokError("expected comma in multidef"); - Lex.Lex(); // Eat the comma - - std::string ItemName = ParseDeclaration(CurRec, false/*Not a template arg*/); - if (ItemName.empty()) - return TokError("expected declaration in multidef"); - - if (Lex.getCode() != tgtok::comma) - return TokError("expected comma in multidef"); - Lex.Lex(); // Eat the comma - - Init *IntI = ParseValue(CurRec, 0); - if (IntI == 0) - return TokError("expected integer value in multidef"); - - if (Lex.getCode() != tgtok::greater) - return TokError("multidef init requires a non-empty list of values"); - Lex.Lex(); // Eat the '>' - - TypedInit *List = dynamic_cast(ListI); - if (dynamic_cast(List->getType()) == 0) - return TokError("First multidef init must be of list type"); - - IntInit *Int = dynamic_cast(IntI); - if (Int == 0) - return TokError("Second multidef init must be a constant integer"); - - // Add it to the multiclass. - for (unsigned i = 0, e = CurMultiClass->MultiDefPrototypes.size(); - i != e; ++i) - if (CurMultiClass->MultiDefPrototypes[i].Rec->getName() - == CurRec->getName()) - return Error(DefLoc, "multidef '" + CurRec->getName() + - "' already defined in this multiclass!"); - - CurMultiClass->MultiDefPrototypes.push_back( - MultiClass::MultiDef(CurRec, List, Int, ItemName)); - - if (ParseObjectBody(CurRec)) - return true; - - // If ObjectBody has template arguments, it's an error. - assert(CurRec->getTemplateArgs().empty() && "How'd this get template args?"); - - // Copy the template arguments for the multiclass into the - // multidef. - const std::vector &TArgs = CurMultiClass->Rec.getTemplateArgs(); - - for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { - const RecordVal *RV = CurMultiClass->Rec.getValue(TArgs[i]); - assert(RV && "Template arg doesn't exist?"); - CurRec->addValue(*RV); - } - - return false; -} - - /// ParseClass - Parse a tblgen class definition. /// /// ClassInst ::= CLASS ID TemplateArgList? ObjectBody @@ -1989,12 +1905,10 @@ bool TGParser::ParseMultiClass() { while (Lex.getCode() != tgtok::r_brace) { switch (Lex.getCode()) { default: - return TokError("expected 'let', 'def', 'defm' or 'multidef'" - "in multiclass body"); + return TokError("expected 'let', 'def' or 'defm' in multiclass body"); case tgtok::Let: case tgtok::Def: case tgtok::Defm: - case tgtok::MultiDef: if (ParseObject(CurMultiClass)) return true; break; @@ -2177,92 +2091,6 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) { NewRecDefs.push_back(CurRec); } - // Loop over multidefs, instantiating them. - for (unsigned i = 0, e = MC->MultiDefPrototypes.size(); i != e; ++i) { - // Each multidef generates a set of defs, one per item in the - // given list. - - // Resolve the list now. This record serves as a base class for - // the individual records created below. - - Record *DefProto = MC->MultiDefPrototypes[i].Rec; - TypedInit *List = MC->MultiDefPrototypes[i].List; - IntInit *Start = MC->MultiDefPrototypes[i].Start; - - // This is the name of the second item in the multidef <> list. - // It is a temporary iterator that holds the current value of - // the list element being processed. - std::string &ItemName = MC->MultiDefPrototypes[i].ItemName; - - Record *BaseRec = InstantiateMulticlassDef(*MC, DefProto, DefmPrefix, - DefmPrefixLoc); - - // Make the list a member of the base record. - RecordVal ListV("__MDListInit__", List->getType(), 0); - ListV.setValue(List); - BaseRec->addValue(ListV); - - // Resolve the base multidef record to template args. This - // should resolve the list. We don't delete the arguments - // values because we want the created defs to inherit them. - // Each list item needs to be resolved against these values. - // They will be deleted when we do final processing of the - // instantiated def. - if (ResolveMulticlassDefArgs(*MC, BaseRec, DefmPrefixLoc, - SubClassLoc, TArgs, TemplateVals, - false/*Do not delete args*/)) - return Error(SubClassLoc, "could not instantiate def"); - - RecordVal *ListVP = BaseRec->getValue("__MDListInit__"); - ListInit *ListIn = dynamic_cast(ListVP->getValue()); - if (ListIn == 0) - return Error(SubClassLoc, "multidef init must be of list type"); - - // Remove the temporary list since we've resolve it and don't - // need it to be part of the defs. - BaseRec->removeValue("__MDListInit__"); - - // For each item in the list, create a def. - for(int64_t it = Start->getValue(); it < ListIn->getSize(); ++it) { - std::stringstream id; - id << it; - - // Create a record prefixed with MD., where is an - // incrementing value. This guarantees that defs created via - // multidefs are named uniquely. - Record *CurRec = InstantiateMulticlassDef(*MC, BaseRec, - "MD" + id.str() + ".", - DefmPrefixLoc); - - // Get the list item and resolve it. - Init *ItemVal = ListIn->resolveListElementReference(*CurRec, 0, it); - - if (!ItemVal) - return Error(SubClassLoc, "invalid list item"); - - // Set the temporary item (iterator) value now. - if (SetValue(CurRec, SubClassLoc, ItemName, std::vector(), ItemVal)) { - Error(DefmPrefixLoc, "when instantiating this defm"); - return true; - } - - // Resolve it next. - CurRec->resolveReferencesTo(CurRec->getValue(ItemName)); - - // Remove it. - CurRec->removeValue(ItemName); - - // Now instantiate the def as if it had been declared directly - // as part of the multicass. - if (ResolveMulticlassDefArgs(*MC, CurRec, DefmPrefixLoc, - SubClassLoc, TArgs, TemplateVals, - true/*Delete args*/)) - return Error(SubClassLoc, "could not instantiate def"); - - if (ResolveMulticlassDef(*MC, CurRec, DefProto, DefmPrefixLoc)) - return Error(SubClassLoc, "could not instantiate def"); - } - } if (Lex.getCode() != tgtok::comma) break; Lex.Lex(); // eat ','. @@ -2327,7 +2155,6 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) { /// ParseObject /// Object ::= ClassInst /// Object ::= DefInst -/// Object ::= MultiDefInst /// Object ::= MultiClassInst /// Object ::= DefMInst /// Object ::= LETCommand '{' ObjectList '}' @@ -2338,7 +2165,6 @@ bool TGParser::ParseObject(MultiClass *MC) { return TokError("Expected class, def, defm, multiclass or let definition"); case tgtok::Let: return ParseTopLevelLet(MC); case tgtok::Def: return ParseDef(MC); - case tgtok::MultiDef: return ParseMultiDef(MC); case tgtok::Defm: return ParseDefm(MC); case tgtok::Class: return ParseClass(); case tgtok::MultiClass: return ParseMultiClass(); diff --git a/lib/TableGen/TGParser.h b/lib/TableGen/TGParser.h index d4998d9147b..db8a6202974 100644 --- a/lib/TableGen/TGParser.h +++ b/lib/TableGen/TGParser.h @@ -100,7 +100,6 @@ private: // Parser methods. SMLoc DefmPrefixLoc); bool ParseDefm(MultiClass *CurMultiClass); bool ParseDef(MultiClass *CurMultiClass); - bool ParseMultiDef(MultiClass *CurMultiClass); bool ParseTopLevelLet(MultiClass *CurMultiClass); std::vector ParseLetList(); diff --git a/test/TableGen/MultiDef.td b/test/TableGen/MultiDef.td deleted file mode 100644 index f4527ac6f26..00000000000 --- a/test/TableGen/MultiDef.td +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: llvm-tblgen %s | FileCheck %s -// RUN: llvm-tblgen %s | FileCheck %s - -class Base { - int value = i; -} - -multiclass Multi values> { - def ONE : Base; - def TWO : Base; - - multidef COUNT : Base; -} - -defm List : Multi<[1, 2, 3, 4, 5, 6]>; - -// CHECK: MD4.ListCOUNT -// CHECK: int value = 6 diff --git a/test/TableGen/MultiPat.td b/test/TableGen/MultiPat.td index 91767dcbd61..b49b06c24ca 100644 --- a/test/TableGen/MultiPat.td +++ b/test/TableGen/MultiPat.td @@ -83,21 +83,10 @@ def Decls : decls; // Define intrinsics def int_x86_sse2_add_ps : Intrinsic<"addps">; def int_x86_sse2_add_pd : Intrinsic<"addpd">; -def int_x86_sse2_sub_ps : Intrinsic<"subps">; -def int_x86_sse2_sub_pd : Intrinsic<"subpd">; def INTRINSIC : Intrinsic<"Dummy">; def bitconvert; -def add; -def sub; -class MakePatImpl patterns> : Pat; -class MakePat patterns, - string suffix, - string intr> : MakePatImpl(!subst("SUFFIX", suffix, intr)), - !subst(REGCLASS, VR128, - !subst(MNEMONIC, set, Decls.operand)))))>; +class MakePat patterns> : Pat; class Base opcode, dag opnds, dag iopnds, string asmstr, Intrinsic intr, list> patterns> @@ -106,7 +95,12 @@ class Base opcode, dag opnds, dag iopnds, string asmstr, Intrinsic intr, !foreach(Decls.operand, Decls.pattern, !subst(INTRINSIC, intr, !subst(REGCLASS, VR128, - !subst(MNEMONIC, set, Decls.operand)))))>; + !subst(MNEMONIC, set, Decls.operand)))))>, + MakePat; multiclass arith opcode, string asmstr, string intr, list> patterns> { def PS : Base opcode, string asmstr, string intr, list> pat def PD : Base(!subst("SUFFIX", "_pd", intr)), patterns>; - - multidef pats, 1> : MakePat; - multidef pats, 1> : MakePat; } defm ADD : arith<0x58, "add", "int_x86_sse2_addSUFFIX", // rr Patterns [[(set REGCLASS:$dst, (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))], [(set REGCLASS:$dst, (bitconvert (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))), - (MNEMONIC REGCLASS:$dst, REGCLASS:$src)], - [(set REGCLASS:$dst, (add (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))), - (MNEMONIC (add REGCLASS:$dst, REGCLASS:$src))]]>; + (MNEMONIC REGCLASS:$dst, REGCLASS:$src)]]>; // CHECK: [(set VR128:$dst, (int_x86_sse2_add_pd VR128:$src1, VR128:$src2))] // CHECK: [(set VR128:$dst, (int_x86_sse2_add_ps VR128:$src1, VR128:$src2))] -// CHECK: (set VR128:$dst, (add (int_x86_sse2_add_ps VR128:$src1, VR128:$src2))) -// CHECK: (set VR128:$dst, (add (int_x86_sse2_add_pd VR128:$src1, VR128:$src2))) - -defm SUB : arith<0x59, "sub", "int_x86_sse2_subSUFFIX", - // rr Patterns - [[(set REGCLASS:$dst, (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))]]>; - -// CHECK: [(set VR128:$dst, (int_x86_sse2_sub_pd VR128:$src1, VR128:$src2))] -// CHECK: [(set VR128:$dst, (int_x86_sse2_sub_ps VR128:$src1, VR128:$src2))] diff --git a/utils/emacs/tablegen-mode.el b/utils/emacs/tablegen-mode.el index 51e1e14859d..3853ce66a28 100644 --- a/utils/emacs/tablegen-mode.el +++ b/utils/emacs/tablegen-mode.el @@ -13,7 +13,7 @@ (defvar tablegen-font-lock-keywords (let ((kw (regexp-opt '("class" "defm" "def" "field" "include" "in" - "let" "multiclass" "multidef") + "let" "multiclass") 'words)) (type-kw (regexp-opt '("bit" "bits" "code" "dag" "int" "list" "string") 'words)) diff --git a/utils/vim/tablegen.vim b/utils/vim/tablegen.vim index 0d6d3d473e0..30434899bc0 100644 --- a/utils/vim/tablegen.vim +++ b/utils/vim/tablegen.vim @@ -14,7 +14,7 @@ syntax sync minlines=100 syn case match -syn keyword tgKeyword def let in code dag field include defm multidef +syn keyword tgKeyword def let in code dag field include defm syn keyword tgType class int string list bit bits multiclass syn match tgNumber /\<\d\+\>/