Skip to content

Commit

Permalink
Remove Multidefs
Browse files Browse the repository at this point in the history
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
  • Loading branch information
greened committed Oct 7, 2011
1 parent 67370ef commit a1b1b79
Show file tree
Hide file tree
Showing 10 changed files with 13 additions and 303 deletions.
59 changes: 0 additions & 59 deletions docs/TableGenFundamentals.html
Original file line number Diff line number Diff line change
Expand Up @@ -769,65 +769,6 @@ <h4>
</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>
Expand Down
17 changes: 0 additions & 17 deletions include/llvm/TableGen/Record.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) :
Expand Down
1 change: 0 additions & 1 deletion lib/TableGen/TGLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion lib/TableGen/TGLexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
176 changes: 1 addition & 175 deletions lib/TableGen/TGParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 ','.
Expand Down Expand Up @@ -2327,7 +2155,6 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
/// ParseObject
/// Object ::= ClassInst
/// Object ::= DefInst
/// Object ::= MultiDefInst
/// Object ::= MultiClassInst
/// Object ::= DefMInst
/// Object ::= LETCommand '{' ObjectList '}'
Expand All @@ -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();
Expand Down
1 change: 0 additions & 1 deletion lib/TableGen/TGParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ class TGParser {
SMLoc DefmPrefixLoc);
bool ParseDefm(MultiClass *CurMultiClass);
bool ParseDef(MultiClass *CurMultiClass);
bool ParseMultiDef(MultiClass *CurMultiClass);
bool ParseTopLevelLet(MultiClass *CurMultiClass);
std::vector<LetRecord> ParseLetList();

Expand Down
18 changes: 0 additions & 18 deletions test/TableGen/MultiDef.td

This file was deleted.

Loading

0 comments on commit a1b1b79

Please sign in to comment.