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
This commit is contained in:
David Greene 2011-10-07 18:25:05 +00:00
parent 67370ef903
commit a1b1b79be1
10 changed files with 12 additions and 302 deletions

View File

@ -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&lt;int i&gt; {
int value = i;
}
<b>multiclass</b> Multi&lt;list&lt;int&gt; values&gt; {
<b>def</b> ONE : Base&lt;values[0]&gt;;
<b>def</b> TWO : Base&lt;values[1]&gt;;
<b>multidef</b> COUNT&lt;values, int v, 2&gt; : Base&lt;v&gt;;
}
<b>defm</b> List : Multi&lt;[1, 2, 3, 4, 5, 6]&lt;;
...
<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 &lt;&gt; 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>

View File

@ -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) :

View File

@ -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)

View File

@ -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.

View File

@ -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();

View File

@ -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();

View File

@ -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

View File

@ -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))]

View File

@ -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))

View File

@ -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\+\>/