diff options
-rw-r--r-- | docs/TableGenFundamentals.html | 59 | ||||
-rw-r--r-- | include/llvm/TableGen/Record.h | 17 | ||||
-rw-r--r-- | lib/TableGen/TGLexer.cpp | 1 | ||||
-rw-r--r-- | lib/TableGen/TGLexer.h | 2 | ||||
-rw-r--r-- | lib/TableGen/TGParser.cpp | 176 | ||||
-rw-r--r-- | lib/TableGen/TGParser.h | 1 | ||||
-rw-r--r-- | test/TableGen/MultiDef.td | 18 | ||||
-rw-r--r-- | test/TableGen/MultiPat.td | 38 | ||||
-rw-r--r-- | utils/emacs/tablegen-mode.el | 2 | ||||
-rw-r--r-- | utils/vim/tablegen.vim | 2 |
10 files changed, 13 insertions, 303 deletions
diff --git a/docs/TableGenFundamentals.html b/docs/TableGenFundamentals.html index f5b7e4ab57..e8fca32513 100644 --- a/docs/TableGenFundamentals.html +++ b/docs/TableGenFundamentals.html @@ -769,65 +769,6 @@ before them. </pre> </div> -<p> -A special "multidef" may be used inside a multiclass to generate -several defs given a list of values. -</p> - -<div class="doc_code"> -<pre> -<b>class</b> Base<int i> { - int value = i; -} - -<b>multiclass</b> Multi<list<int> values> { - <b>def</b> ONE : Base<values[0]>; - <b>def</b> TWO : Base<values[1]>; - - <b>multidef</b> COUNT<values, int v, 2> : Base<v>; -} - -<b>defm</b> List : Multi<[1, 2, 3, 4, 5, 6]<; -... - -<i>// Results</i> -<b>def</b> ListCOUNT { - int v = ?; - int value = v; - list<int> Multi::values = [1, 2, 3, 4, 5, 6]; -} -<b>def</b> ListONE { - int value = 1; -} -<b>def</b> ListTWO { - int value = 2; -} -<b>def</b> MD2.ListCOUNT { - int value = 3; -} -<b>def</b> MD3.ListCOUNT { - int value = 4; -} -<b>def</b> MD4.ListCOUNT { - int value = 5; -} -<b>def</b> MD5.ListCOUNT { - int value = 6; -} -</pre> -</div> - -<p> -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). -</p> </div> </div> diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h index 0fc50c5a3b..afce760998 100644 --- a/include/llvm/TableGen/Record.h +++ b/include/llvm/TableGen/Record.h @@ -1568,23 +1568,6 @@ struct MultiClass { typedef std::vector<Record*> 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<MultiDef> 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 5a6c8aa8a5..8c1b429054 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 7e222875aa..84d328b12d 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 97240481fc..e7f00baf49 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<TypedInit *>(ListI); - if (dynamic_cast<ListRecTy *>(List->getType()) == 0) - return TokError("First multidef init must be of list type"); - - IntInit *Int = dynamic_cast<IntInit *>(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<std::string> &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<ListInit *>(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<n>., where <n> 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<unsigned>(), 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 d4998d9147..db8a620297 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<LetRecord> ParseLetList(); diff --git a/test/TableGen/MultiDef.td b/test/TableGen/MultiDef.td deleted file mode 100644 index f4527ac6f2..0000000000 --- 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 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]>; - -// CHECK: MD4.ListCOUNT -// CHECK: int value = 6 diff --git a/test/TableGen/MultiPat.td b/test/TableGen/MultiPat.td index 91767dcbd6..b49b06c24c 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<list<dag> patterns> : Pat<patterns[0], patterns[1]>; -class MakePat<list<dag> patterns, - string suffix, - string intr> : MakePatImpl<!foreach(Decls.pattern, patterns, - !foreach(Decls.operand, Decls.pattern, - !subst(INTRINSIC, !cast<Intrinsic>(!subst("SUFFIX", suffix, intr)), - !subst(REGCLASS, VR128, - !subst(MNEMONIC, set, Decls.operand)))))>; + +class MakePat<list<dag> patterns> : Pat<patterns[0], patterns[1]>; class Base<bits<8> opcode, dag opnds, dag iopnds, string asmstr, Intrinsic intr, list<list<dag>> patterns> @@ -106,7 +95,12 @@ class Base<bits<8> 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<!foreach(Decls.pattern, patterns[1], + !foreach(Decls.operand, Decls.pattern, + !subst(INTRINSIC, intr, + !subst(REGCLASS, VR128, + !subst(MNEMONIC, set, Decls.operand)))))>; multiclass arith<bits<8> opcode, string asmstr, string intr, list<list<dag>> patterns> { def PS : Base<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), @@ -114,27 +108,13 @@ multiclass arith<bits<8> opcode, string asmstr, string intr, list<list<dag>> pat def PD : Base<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), !strconcat(asmstr, "\t$dst, $src1, $src2"), !cast<Intrinsic>(!subst("SUFFIX", "_pd", intr)), patterns>; - - multidef <patterns, list<dag> pats, 1> : MakePat<pats, "_ps", intr>; - multidef <patterns, list<dag> pats, 1> : MakePat<pats, "_pd", intr>; } 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 51e1e14859..3853ce66a2 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 0d6d3d473e..30434899bc 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\+\>/ |