[llvm-commits] [llvm] r105519 - in /llvm/trunk: docs/TableGenFundamentals.html test/TableGen/DefmInsideMultiClass.td utils/TableGen/TGParser.cpp utils/TableGen/TGParser.h

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Fri Jun 4 19:11:52 PDT 2010


Author: bruno
Date: Fri Jun  4 21:11:52 2010
New Revision: 105519

URL: http://llvm.org/viewvc/llvm-project?rev=105519&view=rev
Log:
Teach tablegen to support 'defm' inside multiclasses.

Added:
    llvm/trunk/test/TableGen/DefmInsideMultiClass.td
Modified:
    llvm/trunk/docs/TableGenFundamentals.html
    llvm/trunk/utils/TableGen/TGParser.cpp
    llvm/trunk/utils/TableGen/TGParser.h

Modified: llvm/trunk/docs/TableGenFundamentals.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/TableGenFundamentals.html?rev=105519&r1=105518&r2=105519&view=diff
==============================================================================
--- llvm/trunk/docs/TableGenFundamentals.html (original)
+++ llvm/trunk/docs/TableGenFundamentals.html Fri Jun  4 21:11:52 2010
@@ -687,6 +687,50 @@
 </pre>
 </div>
 
+<p>
+A defm can also be used inside a multiclass providing several levels of
+multiclass instanciations.
+</p>
+
+<div class="doc_code">
+<pre>
+<b>class</b> Instruction<bits<4> opc, string Name> {
+  bits<4> opcode = opc;
+  string name = Name;
+}
+
+<b>multiclass</b> basic_r<bits<4> opc> {
+  <b>def</b> rr : Instruction<opc, "rr">;
+  <b>def</b> rm : Instruction<opc, "rm">;
+}
+
+<b>multiclass</b> basic_s<bits<4> opc> {
+  <b>defm</b> SS : basic_r<opc>;
+  <b>defm</b> SD : basic_r<opc>;
+  <b>def</b> X : Instruction<opc, "x">;
+}
+
+<b>multiclass</b> basic_p<bits<4> opc> {
+  <b>defm</b> PS : basic_r<opc>;
+  <b>defm</b> PD : basic_r<opc>;
+  <b>def</b> Y : Instruction<opc, "y">;
+}
+
+<b>defm</b> ADD : basic_s<0xf>, basic_p<0xf>;
+...
+
+<i>// Results</i>
+<b>def</b> ADDPDrm { ...
+<b>def</b> ADDPDrr { ...
+<b>def</b> ADDPSrm { ...
+<b>def</b> ADDPSrr { ...
+<b>def</b> ADDSDrm { ...
+<b>def</b> ADDSDrr { ...
+<b>def</b> ADDY { ...
+<b>def</b> ADDX { ...
+</pre>
+</div>
+
 </div>
 
 <!-- ======================================================================= -->

Added: llvm/trunk/test/TableGen/DefmInsideMultiClass.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/DefmInsideMultiClass.td?rev=105519&view=auto
==============================================================================
--- llvm/trunk/test/TableGen/DefmInsideMultiClass.td (added)
+++ llvm/trunk/test/TableGen/DefmInsideMultiClass.td Fri Jun  4 21:11:52 2010
@@ -0,0 +1,25 @@
+// RUN: tblgen %s | grep ADDPSrr | count 1
+// XFAIL: vg_leak
+
+class Instruction<bits<4> opc, string Name> {
+  bits<4> opcode = opc;
+  string name = Name;
+}
+
+multiclass basic_r<bits<4> opc> {
+  def rr : Instruction<opc, "rr">;
+  def rm : Instruction<opc, "rm">;
+}
+
+multiclass basic_s<bits<4> opc> {
+  defm SS : basic_r<opc>;
+  defm SD : basic_r<opc>;
+}
+
+multiclass basic_p<bits<4> opc> {
+  defm PS : basic_r<opc>;
+  defm PD : basic_r<opc>;
+}
+
+defm ADD : basic_s<0xf>, basic_p<0xf>;
+defm SUB : basic_s<0xe>, basic_p<0xe>;

Modified: llvm/trunk/utils/TableGen/TGParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.cpp?rev=105519&r1=105518&r2=105519&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/TGParser.cpp (original)
+++ llvm/trunk/utils/TableGen/TGParser.cpp Fri Jun  4 21:11:52 2010
@@ -1635,7 +1635,6 @@
   return ParseBody(CurRec);
 }
 
-
 /// ParseDef - Parse and return a top level or multiclass def, return the record
 /// corresponding to it.  This returns null on error.
 ///
@@ -1807,8 +1806,6 @@
 ///  MultiClassDef ::= DefInst
 ///
 bool TGParser::ParseMultiClassDef(MultiClass *CurMC) {
-  if (Lex.getCode() != tgtok::Def)
-    return TokError("expected 'def' in multiclass body");
 
   Record *D = ParseDef(CurMC);
   if (D == 0) return true;
@@ -1885,9 +1882,18 @@
     if (Lex.Lex() == tgtok::r_brace)  // eat the '{'.
       return TokError("multiclass must contain at least one def");
 
-    while (Lex.getCode() != tgtok::r_brace)
-      if (ParseMultiClassDef(CurMultiClass))
-        return true;
+    while (Lex.getCode() != tgtok::r_brace) {
+      if (Lex.getCode() != tgtok::Defm && Lex.getCode() != tgtok::Def)
+        return TokError("expected 'def' or 'defm' in multiclass body");
+
+      if (Lex.getCode() == tgtok::Def)
+        if (ParseMultiClassDef(CurMultiClass))
+          return true;
+
+      if (Lex.getCode() == tgtok::Defm)
+        if (ParseDefm(CurMultiClass))
+          return true;
+    }
 
     Lex.Lex();  // eat the '}'.
   }
@@ -1900,7 +1906,7 @@
 ///
 ///   DefMInst ::= DEFM ID ':' DefmSubClassRef ';'
 ///
-bool TGParser::ParseDefm() {
+bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
   assert(Lex.getCode() == tgtok::Defm && "Unexpected token!");
   if (Lex.Lex() != tgtok::Id)  // eat the defm.
     return TokError("expected identifier after defm");
@@ -1991,8 +1997,34 @@
         return Error(DefmPrefixLoc, "def '" + CurRec->getName() +
                      "' already defined, instantiating defm with subdef '" +
                      DefProto->getName() + "'");
-      Records.addDef(CurRec);
-      CurRec->resolveReferences();
+
+      // Don't create a top level definition for defm inside multiclasses,
+      // instead, only update the prototypes and bind the template args
+      // with the new created definition.
+      if (CurMultiClass) {
+        for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size();
+             i != e; ++i) {
+          if (CurMultiClass->DefPrototypes[i]->getName() == CurRec->getName()) {
+            Error(DefmPrefixLoc, "defm '" + CurRec->getName() +
+                  "' already defined in this multiclass!");
+            return 0;
+          }
+        }
+        CurMultiClass->DefPrototypes.push_back(CurRec);
+
+        // Copy the template arguments for the multiclass into the new def.
+        const std::vector<std::string> &TA =
+          CurMultiClass->Rec.getTemplateArgs();
+
+        for (unsigned i = 0, e = TA.size(); i != e; ++i) {
+          const RecordVal *RV = CurMultiClass->Rec.getValue(TA[i]);
+          assert(RV && "Template arg doesn't exist?");
+          CurRec->addValue(*RV);
+        }
+      } else {
+        Records.addDef(CurRec);
+        CurRec->resolveReferences();
+      }
     }
 
     if (Lex.getCode() != tgtok::comma) break;

Modified: llvm/trunk/utils/TableGen/TGParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.h?rev=105519&r1=105518&r2=105519&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/TGParser.h (original)
+++ llvm/trunk/utils/TableGen/TGParser.h Fri Jun  4 21:11:52 2010
@@ -74,7 +74,7 @@
   bool ParseClass();
   bool ParseMultiClass();
   bool ParseMultiClassDef(MultiClass *CurMC);
-  bool ParseDefm();
+  bool ParseDefm(MultiClass *CurMultiClass = 0);
   bool ParseTopLevelLet();
   std::vector<LetRecord> ParseLetList();
 





More information about the llvm-commits mailing list