llvm.org GIT mirror llvm / a1b1b79
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" git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141378 91177308-0d34-0410-b5e6-96231b3b80d8 David Greene 9 years ago
10 changed file(s) with 12 addition(s) and 302 deletion(s). Raw diff Collapse all Expand all
768768
769769
770770
771

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

775
776
777

                  
                
778 class Base<int i> {
779 int value = i;
780 }
781
782 multiclass Multi<list<int> values> {
783 def ONE : Base<values[0]>;
784 def TWO : Base<values[1]>;
785
786 multidef COUNT<values, int v, 2> : Base<v>;
787 }
788
789 defm List : Multi<[1, 2, 3, 4, 5, 6]<;
790 ...
791
792 // Results
793 def ListCOUNT {
794 int v = ?;
795 int value = v;
796 list Multi::values = [1, 2, 3, 4, 5, 6];
797 }
798 def ListONE {
799 int value = 1;
800 }
801 def ListTWO {
802 int value = 2;
803 }
804 def MD2.ListCOUNT {
805 int value = 3;
806 }
807 def MD3.ListCOUNT {
808 int value = 4;
809 }
810 def MD4.ListCOUNT {
811 int value = 5;
812 }
813 def MD5.ListCOUNT {
814 int value = 6;
815 }
816
817
818
819

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

830771
831772
832773
15671567 typedef std::vector RecordVector;
15681568 RecordVector DefPrototypes;
15691569
1570 struct MultiDef {
1571 Record *Rec; // The base record for all defs generated.
1572 // This serves as the multiclass def prototype.
1573 TypedInit *List; // A list of values to process.
1574 // Each one generates a new def.
1575 IntInit *Start; // This specified the list index from which to start
1576 // processing.
1577 std::string ItemName; // The name of a temporary iterator value to
1578 // track the current list item being processed.
1579
1580 MultiDef(Record *R, TypedInit *L, IntInit *S, const std::string &I)
1581 : Rec(R), List(L), Start(S), ItemName(I) {};
1582 };
1583
1584 typedef std::vector MultiDefVector;
1585 MultiDefVector MultiDefPrototypes;
1586
15871570 void dump() const;
15881571
15891572 MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) :
231231 .Case("dag", tgtok::Dag)
232232 .Case("class", tgtok::Class)
233233 .Case("def", tgtok::Def)
234 .Case("multidef", tgtok::MultiDef)
235234 .Case("defm", tgtok::Defm)
236235 .Case("multiclass", tgtok::MultiClass)
237236 .Case("field", tgtok::Field)
4040 equal, question, // = ?
4141
4242 // Keywords.
43 Bit, Bits, Class, Code, Dag, Def, MultiDef, Defm, Field, In, Int, Let, List,
43 Bit, Bits, Class, Code, Dag, Def, Defm, Field, In, Int, Let, List,
4444 MultiClass, String,
4545
4646 // !keywords.
17191719 return false;
17201720 }
17211721
1722
1723 /// ParseMultiDef - Parse and return a multiclass multidef, return the record
1724 /// corresponding to it. This returns null on error.
1725 ///
1726 /// MultiDefInst ::= MULTIDEF ObjectName '<' Value ',' Declaration ','
1727 /// Value '>' ObjectBody
1728 ///
1729 bool TGParser::ParseMultiDef(MultiClass *CurMultiClass) {
1730 assert(CurMultiClass && "No multiclass for multidef!");
1731
1732 SMLoc DefLoc = Lex.getLoc();
1733 assert(Lex.getCode() == tgtok::MultiDef && "Unknown tok");
1734 Lex.Lex(); // Eat the 'multidef' token.
1735
1736 // Parse ObjectName and make a record for it.
1737 Record *CurRec = new Record(ParseObjectName(), DefLoc, Records);
1738
1739 if (Lex.getCode() != tgtok::less)
1740 return TokError("multidef init requires a non-empty list of values");
1741 Lex.Lex(); // Eat the '<'
1742
1743 Init *ListI = ParseValue(CurRec, 0);
1744 if (ListI == 0)
1745 return TokError("First multidef init must be of list type");
1746
1747 if (Lex.getCode() != tgtok::comma)
1748 return TokError("expected comma in multidef");
1749 Lex.Lex(); // Eat the comma
1750
1751 std::string ItemName = ParseDeclaration(CurRec, false/*Not a template arg*/);
1752 if (ItemName.empty())
1753 return TokError("expected declaration in multidef");
1754
1755 if (Lex.getCode() != tgtok::comma)
1756 return TokError("expected comma in multidef");
1757 Lex.Lex(); // Eat the comma
1758
1759 Init *IntI = ParseValue(CurRec, 0);
1760 if (IntI == 0)
1761 return TokError("expected integer value in multidef");
1762
1763 if (Lex.getCode() != tgtok::greater)
1764 return TokError("multidef init requires a non-empty list of values");
1765 Lex.Lex(); // Eat the '>'
1766
1767 TypedInit *List = dynamic_cast(ListI);
1768 if (dynamic_cast(List->getType()) == 0)
1769 return TokError("First multidef init must be of list type");
1770
1771 IntInit *Int = dynamic_cast(IntI);
1772 if (Int == 0)
1773 return TokError("Second multidef init must be a constant integer");
1774
1775 // Add it to the multiclass.
1776 for (unsigned i = 0, e = CurMultiClass->MultiDefPrototypes.size();
1777 i != e; ++i)
1778 if (CurMultiClass->MultiDefPrototypes[i].Rec->getName()
1779 == CurRec->getName())
1780 return Error(DefLoc, "multidef '" + CurRec->getName() +
1781 "' already defined in this multiclass!");
1782
1783 CurMultiClass->MultiDefPrototypes.push_back(
1784 MultiClass::MultiDef(CurRec, List, Int, ItemName));
1785
1786 if (ParseObjectBody(CurRec))
1787 return true;
1788
1789 // If ObjectBody has template arguments, it's an error.
1790 assert(CurRec->getTemplateArgs().empty() && "How'd this get template args?");
1791
1792 // Copy the template arguments for the multiclass into the
1793 // multidef.
1794 const std::vector &TArgs = CurMultiClass->Rec.getTemplateArgs();
1795
1796 for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
1797 const RecordVal *RV = CurMultiClass->Rec.getValue(TArgs[i]);
1798 assert(RV && "Template arg doesn't exist?");
1799 CurRec->addValue(*RV);
1800 }
1801
1802 return false;
1803 }
1804
1805
18061722 /// ParseClass - Parse a tblgen class definition.
18071723 ///
18081724 /// ClassInst ::= CLASS ID TemplateArgList? ObjectBody
19881904 while (Lex.getCode() != tgtok::r_brace) {
19891905 switch (Lex.getCode()) {
19901906 default:
1991 return TokError("expected 'let', 'def', 'defm' or 'multidef'"
1992 "in multiclass body");
1907 return TokError("expected 'let', 'def' or 'defm' in multiclass body");
19931908 case tgtok::Let:
19941909 case tgtok::Def:
19951910 case tgtok::Defm:
1996 case tgtok::MultiDef:
19971911 if (ParseObject(CurMultiClass))
19981912 return true;
19991913 break;
21762090 NewRecDefs.push_back(CurRec);
21772091 }
21782092
2179 // Loop over multidefs, instantiating them.
2180 for (unsigned i = 0, e = MC->MultiDefPrototypes.size(); i != e; ++i) {
2181 // Each multidef generates a set of defs, one per item in the
2182 // given list.
2183
2184 // Resolve the list now. This record serves as a base class for
2185 // the individual records created below.
2186
2187 Record *DefProto = MC->MultiDefPrototypes[i].Rec;
2188 TypedInit *List = MC->MultiDefPrototypes[i].List;
2189 IntInit *Start = MC->MultiDefPrototypes[i].Start;
2190
2191 // This is the name of the second item in the multidef <> list.
2192 // It is a temporary iterator that holds the current value of
2193 // the list element being processed.
2194 std::string &ItemName = MC->MultiDefPrototypes[i].ItemName;
2195
2196 Record *BaseRec = InstantiateMulticlassDef(*MC, DefProto, DefmPrefix,
2197 DefmPrefixLoc);
2198
2199 // Make the list a member of the base record.
2200 RecordVal ListV("__MDListInit__", List->getType(), 0);
2201 ListV.setValue(List);
2202 BaseRec->addValue(ListV);
2203
2204 // Resolve the base multidef record to template args. This
2205 // should resolve the list. We don't delete the arguments
2206 // values because we want the created defs to inherit them.
2207 // Each list item needs to be resolved against these values.
2208 // They will be deleted when we do final processing of the
2209 // instantiated def.
2210 if (ResolveMulticlassDefArgs(*MC, BaseRec, DefmPrefixLoc,
2211 SubClassLoc, TArgs, TemplateVals,
2212 false/*Do not delete args*/))
2213 return Error(SubClassLoc, "could not instantiate def");
2214
2215 RecordVal *ListVP = BaseRec->getValue("__MDListInit__");
2216 ListInit *ListIn = dynamic_cast(ListVP->getValue());
2217 if (ListIn == 0)
2218 return Error(SubClassLoc, "multidef init must be of list type");
2219
2220 // Remove the temporary list since we've resolve it and don't
2221 // need it to be part of the defs.
2222 BaseRec->removeValue("__MDListInit__");
2223
2224 // For each item in the list, create a def.
2225 for(int64_t it = Start->getValue(); it < ListIn->getSize(); ++it) {
2226 std::stringstream id;
2227 id << it;
2228
2229 // Create a record prefixed with MD., where is an
2230 // incrementing value. This guarantees that defs created via
2231 // multidefs are named uniquely.
2232 Record *CurRec = InstantiateMulticlassDef(*MC, BaseRec,
2233 "MD" + id.str() + ".",
2234 DefmPrefixLoc);
2235
2236 // Get the list item and resolve it.
2237 Init *ItemVal = ListIn->resolveListElementReference(*CurRec, 0, it);
2238
2239 if (!ItemVal)
2240 return Error(SubClassLoc, "invalid list item");
2241
2242 // Set the temporary item (iterator) value now.
2243 if (SetValue(CurRec, SubClassLoc, ItemName, std::vector(), ItemVal)) {
2244 Error(DefmPrefixLoc, "when instantiating this defm");
2245 return true;
2246 }
2247
2248 // Resolve it next.
2249 CurRec->resolveReferencesTo(CurRec->getValue(ItemName));
2250
2251 // Remove it.
2252 CurRec->removeValue(ItemName);
2253
2254 // Now instantiate the def as if it had been declared directly
2255 // as part of the multicass.
2256 if (ResolveMulticlassDefArgs(*MC, CurRec, DefmPrefixLoc,
2257 SubClassLoc, TArgs, TemplateVals,
2258 true/*Delete args*/))
2259 return Error(SubClassLoc, "could not instantiate def");
2260
2261 if (ResolveMulticlassDef(*MC, CurRec, DefProto, DefmPrefixLoc))
2262 return Error(SubClassLoc, "could not instantiate def");
2263 }
2264 }
22652093
22662094 if (Lex.getCode() != tgtok::comma) break;
22672095 Lex.Lex(); // eat ','.
23262154 /// ParseObject
23272155 /// Object ::= ClassInst
23282156 /// Object ::= DefInst
2329 /// Object ::= MultiDefInst
23302157 /// Object ::= MultiClassInst
23312158 /// Object ::= DefMInst
23322159 /// Object ::= LETCommand '{' ObjectList '}'
23372164 return TokError("Expected class, def, defm, multiclass or let definition");
23382165 case tgtok::Let: return ParseTopLevelLet(MC);
23392166 case tgtok::Def: return ParseDef(MC);
2340 case tgtok::MultiDef: return ParseMultiDef(MC);
23412167 case tgtok::Defm: return ParseDefm(MC);
23422168 case tgtok::Class: return ParseClass();
23432169 case tgtok::MultiClass: return ParseMultiClass();
9999 SMLoc DefmPrefixLoc);
100100 bool ParseDefm(MultiClass *CurMultiClass);
101101 bool ParseDef(MultiClass *CurMultiClass);
102 bool ParseMultiDef(MultiClass *CurMultiClass);
103102 bool ParseTopLevelLet(MultiClass *CurMultiClass);
104103 std::vector ParseLetList();
105104
+0
-18
test/TableGen/MultiDef.td less more
None // RUN: llvm-tblgen %s | FileCheck %s
1 // RUN: llvm-tblgen %s | FileCheck %s
2
3 class Base {
4 int value = i;
5 }
6
7 multiclass Multi values> {
8 def ONE : Base;
9 def TWO : Base;
10
11 multidef COUNT : Base;
12 }
13
14 defm List : Multi<[1, 2, 3, 4, 5, 6]>;
15
16 // CHECK: MD4.ListCOUNT
17 // CHECK: int value = 6
8282 // Define intrinsics
8383 def int_x86_sse2_add_ps : Intrinsic<"addps">;
8484 def int_x86_sse2_add_pd : Intrinsic<"addpd">;
85 def int_x86_sse2_sub_ps : Intrinsic<"subps">;
86 def int_x86_sse2_sub_pd : Intrinsic<"subpd">;
8785 def INTRINSIC : Intrinsic<"Dummy">;
8886 def bitconvert;
89 def add;
90 def sub;
9187
92 class MakePatImpl patterns> : Pat;
93 class MakePat patterns,
94 string suffix,
95 string intr> : MakePatImpl
96 !foreach(Decls.operand, Decls.pattern,
97 !subst(INTRINSIC, !cast(!subst("SUFFIX", suffix, intr)),
98 !subst(REGCLASS, VR128,
99 !subst(MNEMONIC, set, Decls.operand)))))>;
88 class MakePat patterns> : Pat>;
10089
10190 class Base opcode, dag opnds, dag iopnds, string asmstr, Intrinsic intr,
10291 list> patterns>
10594 !foreach(Decls.operand, Decls.pattern,
10695 !subst(INTRINSIC, intr,
10796 !subst(REGCLASS, VR128,
108 !subst(MNEMONIC, set, Decls.operand)))))>;
97 !subst(MNEMONIC, set, Decls.operand)))))>,
98 MakePat
99 !foreach(Decls.operand, Decls.pattern,
100 !subst(INTRINSIC, intr,
101 !subst(REGCLASS, VR128,
102 !subst(MNEMONIC, set, Decls.operand)))))>;
109103
110104 multiclass arith opcode, string asmstr, string intr, list> patterns> {
111105 def PS : Base
113107
114108 def PD : Base
115109 !strconcat(asmstr, "\t$dst, $src1, $src2"), !cast(!subst("SUFFIX", "_pd", intr)), patterns>;
116
117 multidef pats, 1> : MakePat;
118 multidef pats, 1> : MakePat;
119110 }
120111
121112 defm ADD : arith<0x58, "add", "int_x86_sse2_addSUFFIX",
122113 // rr Patterns
123114 [[(set REGCLASS:$dst, (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))],
124115 [(set REGCLASS:$dst, (bitconvert (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))),
125 (MNEMONIC REGCLASS:$dst, REGCLASS:$src)],
126 [(set REGCLASS:$dst, (add (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))),
127 (MNEMONIC (add REGCLASS:$dst, REGCLASS:$src))]]>;
116 (MNEMONIC REGCLASS:$dst, REGCLASS:$src)]]>;
128117
129118 // CHECK: [(set VR128:$dst, (int_x86_sse2_add_pd VR128:$src1, VR128:$src2))]
130119 // CHECK: [(set VR128:$dst, (int_x86_sse2_add_ps VR128:$src1, VR128:$src2))]
131 // CHECK: (set VR128:$dst, (add (int_x86_sse2_add_ps VR128:$src1, VR128:$src2)))
132 // CHECK: (set VR128:$dst, (add (int_x86_sse2_add_pd VR128:$src1, VR128:$src2)))
133
134 defm SUB : arith<0x59, "sub", "int_x86_sse2_subSUFFIX",
135 // rr Patterns
136 [[(set REGCLASS:$dst, (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))]]>;
137
138 // CHECK: [(set VR128:$dst, (int_x86_sse2_sub_pd VR128:$src1, VR128:$src2))]
139 // CHECK: [(set VR128:$dst, (int_x86_sse2_sub_ps VR128:$src1, VR128:$src2))]
1212
1313 (defvar tablegen-font-lock-keywords
1414 (let ((kw (regexp-opt '("class" "defm" "def" "field" "include" "in"
15 "let" "multiclass" "multidef")
15 "let" "multiclass")
1616 'words))
1717 (type-kw (regexp-opt '("bit" "bits" "code" "dag" "int" "list" "string")
1818 'words))
1313
1414 syn case match
1515
16 syn keyword tgKeyword def let in code dag field include defm multidef
16 syn keyword tgKeyword def let in code dag field include defm
1717 syn keyword tgType class int string list bit bits multiclass
1818
1919 syn match tgNumber /\<\d\+\>/