[llvm-commits] [llvm] r106305 - in /llvm/trunk: docs/TableGenFundamentals.html test/TableGen/defmclass.td utils/TableGen/TGParser.cpp

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Fri Jun 18 12:53:41 PDT 2010


Author: bruno
Date: Fri Jun 18 14:53:41 2010
New Revision: 106305

URL: http://llvm.org/viewvc/llvm-project?rev=106305&view=rev
Log:
Teach tablegen how to inherit from classes in 'defm' definitions.
The rule is simple: only inherit from a class list if they come
in the end, after the last multiclass.


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

Modified: llvm/trunk/docs/TableGenFundamentals.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/TableGenFundamentals.html?rev=106305&r1=106304&r2=106305&view=diff
==============================================================================
--- llvm/trunk/docs/TableGenFundamentals.html (original)
+++ llvm/trunk/docs/TableGenFundamentals.html Fri Jun 18 14:53:41 2010
@@ -732,6 +732,47 @@
 </pre>
 </div>
 
+<p>
+defm declarations can inherit from classes too, the
+rule to follow is that the class list must start after the
+last multiclass, and there must be at least one multiclass
+before them.
+</p>
+
+<div class="doc_code">
+<pre>
+<b>class</b> XD { bits<4> Prefix = 11; }
+<b>class</b> XS { bits<4> Prefix = 12; }
+
+<b>class</b> I<bits<4> op> {
+  bits<4> opcode = op;
+}
+
+<b>multiclass</b> R {
+  <b>def</b> rr : I<4>;
+  <b>def</b> rm : I<2>;
+}
+
+<b>multiclass</b> Y {
+  <b>defm</b> SS : R, XD;
+  <b>defm</b> SD : R, XS;
+}
+
+<b>defm</b> Instr : Y;
+
+<i>// Results</i>
+<b>def</b> InstrSDrm {
+  bits<4> opcode = { 0, 0, 1, 0 };
+  bits<4> Prefix = { 1, 1, 0, 0 };
+}
+...
+<b>def</b> InstrSSrr {
+  bits<4> opcode = { 0, 1, 0, 0 };
+  bits<4> Prefix = { 1, 0, 1, 1 };
+}
+</pre>
+</div>
+
 </div>
 
 <!-- ======================================================================= -->

Added: llvm/trunk/test/TableGen/defmclass.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/defmclass.td?rev=106305&view=auto
==============================================================================
--- llvm/trunk/test/TableGen/defmclass.td (added)
+++ llvm/trunk/test/TableGen/defmclass.td Fri Jun 18 14:53:41 2010
@@ -0,0 +1,36 @@
+// RUN: tblgen %s | FileCheck %s
+// XFAIL: vg_leak
+
+class XD { bits<4> Prefix = 11; }
+// CHECK: Prefix = { 1, 1, 0, 0 };
+class XS { bits<4> Prefix = 12; }
+class VEX { bit hasVEX_4VPrefix = 1; }
+
+def xd : XD;
+
+class BaseI {
+  bits<4> Prefix = 0;
+  bit hasVEX_4VPrefix = 0;
+}
+
+class I<bits<4> op> : BaseI {
+  bits<4> opcode = op;
+  int val = !if(!eq(Prefix, xd.Prefix), 7, 21);
+}
+
+multiclass R {
+  def rr : I<4>;
+}
+
+multiclass M {
+  def rm : I<2>;
+}
+
+multiclass Y {
+  defm SS : R, M, XD;
+// CHECK: Prefix = { 1, 1, 0, 0 };
+// CHECK: Prefix = { 1, 1, 0, 0 };
+  defm SD : R, M, XS;
+}
+
+defm Instr : Y, VEX;

Modified: llvm/trunk/utils/TableGen/TGParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.cpp?rev=106305&r1=106304&r2=106305&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/TGParser.cpp (original)
+++ llvm/trunk/utils/TableGen/TGParser.cpp Fri Jun 18 14:53:41 2010
@@ -1907,6 +1907,12 @@
   if (Lex.Lex() != tgtok::colon)
     return TokError("expected ':' after defm identifier");
 
+  // Keep track of the new generated record definitions.
+  std::vector<Record*> NewRecDefs;
+
+  // This record also inherits from a regular class (non-multiclass)?
+  bool InheritFromClass = false;
+
   // eat the colon.
   Lex.Lex();
 
@@ -2016,15 +2022,59 @@
         Records.addDef(CurRec);
         CurRec->resolveReferences();
       }
+
+      NewRecDefs.push_back(CurRec);
     }
 
     if (Lex.getCode() != tgtok::comma) break;
     Lex.Lex(); // eat ','.
 
     SubClassLoc = Lex.getLoc();
+
+    // A defm can inherit from regular classes (non-multiclass) as
+    // long as they come in the end of the inheritance list.
+    InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != 0);
+
+    if (InheritFromClass)
+      break;
+
     Ref = ParseSubClassReference(0, true);
   }
 
+  if (InheritFromClass) {
+    // Process all the classes to inherit as if they were part of a
+    // regular 'def' and inherit all record values.
+    SubClassReference SubClass = ParseSubClassReference(0, false);
+    while (1) {
+      // Check for error.
+      if (SubClass.Rec == 0) return true;
+
+      // Get the expanded definition prototypes and teach them about
+      // the record values the current class to inherit has
+      for (unsigned i = 0, e = NewRecDefs.size(); i != e; ++i) {
+        Record *CurRec = NewRecDefs[i];
+
+        // Add it.
+        if (AddSubClass(CurRec, SubClass))
+          return true;
+
+        // Process any variables on the let stack.
+        for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
+          for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
+            if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
+                         LetStack[i][j].Bits, LetStack[i][j].Value))
+              return true;
+
+        if (!CurMultiClass)
+          CurRec->resolveReferences();
+      }
+
+      if (Lex.getCode() != tgtok::comma) break;
+      Lex.Lex(); // eat ','.
+      SubClass = ParseSubClassReference(0, false);
+    }
+  }
+
   if (Lex.getCode() != tgtok::semi)
     return TokError("expected ';' at end of defm");
   Lex.Lex();





More information about the llvm-commits mailing list