[llvm-commits] [llvm] r69974 - in /llvm/trunk: test/TableGen/MultiClassInherit.td utils/TableGen/Record.cpp utils/TableGen/Record.h utils/TableGen/TGParser.cpp

David Greene greened at obbligato.org
Fri Apr 24 09:55:43 PDT 2009


Author: greened
Date: Fri Apr 24 11:55:41 2009
New Revision: 69974

URL: http://llvm.org/viewvc/llvm-project?rev=69974&view=rev
Log:

Fix multiclass inheritance to limit value resolution to new defs added
by base multiclasses.  Do not attempt to alter defs from previous base
multiclasses.  This fixes multiple multiclass inheritance.

Modified:
    llvm/trunk/test/TableGen/MultiClassInherit.td
    llvm/trunk/utils/TableGen/Record.cpp
    llvm/trunk/utils/TableGen/Record.h
    llvm/trunk/utils/TableGen/TGParser.cpp

Modified: llvm/trunk/test/TableGen/MultiClassInherit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/MultiClassInherit.td?rev=69974&r1=69973&r2=69974&view=diff

==============================================================================
--- llvm/trunk/test/TableGen/MultiClassInherit.td (original)
+++ llvm/trunk/test/TableGen/MultiClassInherit.td Fri Apr 24 11:55:41 2009
@@ -1,4 +1,4 @@
-// RUN: tblgen %s | grep {zing = 4} | count 4
+// RUN: tblgen %s | grep {zing = 4} | count 28
 
 class C1<int A, string B> { 
   int bar = A;
@@ -8,25 +8,57 @@
 
 def T : C1<4, "blah">;
 
-multiclass t<int a> {
-  def S1 : C1<a, "foo"> {
+multiclass t1<int a1> {
+  def S1 : C1<a1, "foo"> {
     int foo = 4;
     let bar = 1;
   }
-  def S2 : C1<a, "bar">;
+  def S2 : C1<a1, "bar">;
 }
 
-multiclass s<int a, int b> : t<a> {
-  def S3 : C1<b, "moo"> {
+multiclass t2<int a2> {
+  def S3 : C1<a2, "foo"> {
+    int foo = 4;
+    let bar = 1;
+  }
+  def S4 : C1<a2, "bar">;
+}
+
+multiclass s1<int as1, int bs1> : t1<as1> {
+  def S5 : C1<bs1, "moo"> {
     int moo = 3;
     let bar = 1;
   }
-  def S4 : C1<b, "baz">;
+  def S6 : C1<bs1, "baz">;
 }
 
-defm FOO : s<42, 24>;
+multiclass s2<int as2> : t1<as2>, t2<as2>;
+
+multiclass s3<int as3, int bs3> : t1<as3>, t2<as3> {
+  def S7 : C1<bs3, "moo"> {
+    int moo = 3;
+    let bar = 1;
+  }
+  def S8 : C1<bs3, "baz">;
+}
+
+let zing = 4 in
+defm FOO1 : s1<42, 24>;
+
+let zing = 4 in
+defm FOO2 : s2<99>;
+
+let zing = 4 in
+defm FOO3 : s3<84, 48>;
 
 def T4 : C1<6, "foo">;
 
 let zing = 4 in
-  defm BAZ : s<3, 4>;
+  defm BAZ1 : s1<3, 4>;
+
+let zing = 4 in
+  defm BAZ2 : s2<5>;
+
+let zing = 4 in
+  defm BAZ3 : s3<6, 7>;
+

Modified: llvm/trunk/utils/TableGen/Record.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.cpp?rev=69974&r1=69973&r2=69974&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/Record.cpp (original)
+++ llvm/trunk/utils/TableGen/Record.cpp Fri Apr 24 11:55:41 2009
@@ -1060,6 +1060,20 @@
 }
 
 
+void MultiClass::dump() const {
+  cerr << "Record:\n";
+  Rec.dump();
+  
+  cerr << "Defs:\n";
+  for (RecordVector::const_iterator r = DefPrototypes.begin(),
+         rend = DefPrototypes.end();
+       r != rend;
+       ++r) {
+    (*r)->dump();
+  }
+}
+
+
 void RecordKeeper::dump() const { cerr << *this; }
 
 std::ostream &llvm::operator<<(std::ostream &OS, const RecordKeeper &RK) {

Modified: llvm/trunk/utils/TableGen/Record.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.h?rev=69974&r1=69973&r2=69974&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/Record.h (original)
+++ llvm/trunk/utils/TableGen/Record.h Fri Apr 24 11:55:41 2009
@@ -1138,7 +1138,9 @@
   Record Rec;  // Placeholder for template args and Name.
   typedef std::vector<Record*> RecordVector;
   RecordVector DefPrototypes;
-    
+
+  void dump() const;
+
   MultiClass(const std::string &Name, TGLoc Loc) : Rec(Name, Loc) {}
 };
 

Modified: llvm/trunk/utils/TableGen/TGParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.cpp?rev=69974&r1=69973&r2=69974&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TGParser.cpp (original)
+++ llvm/trunk/utils/TableGen/TGParser.cpp Fri Apr 24 11:55:41 2009
@@ -16,6 +16,7 @@
 #include "TGParser.h"
 #include "Record.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Streams.h"
 using namespace llvm;
 
 //===----------------------------------------------------------------------===//
@@ -28,7 +29,7 @@
   Record *Rec;
   std::vector<Init*> TemplateArgs;
   SubClassReference() : Rec(0) {}
-  
+
   bool isInvalid() const { return Rec == 0; }
 };
 
@@ -39,8 +40,23 @@
   SubMultiClassReference() : MC(0) {}
   
   bool isInvalid() const { return MC == 0; }
+  void dump() const;
 };
-  
+
+void SubMultiClassReference::dump() const {
+  cerr << "Multiclass:\n";
+ 
+  MC->dump();
+ 
+  cerr << "Template args:\n";
+  for (std::vector<Init *>::const_iterator i = TemplateArgs.begin(),
+         iend = TemplateArgs.end();
+       i != iend;
+       ++i) {
+    (*i)->dump();
+  }
+}
+
 } // end namespace llvm
 
 bool TGParser::AddValue(Record *CurRec, TGLoc Loc, const RecordVal &RV) {
@@ -182,7 +198,8 @@
 /// AddSubMultiClass - Add SubMultiClass as a subclass to
 /// CurMultiClass, resolving its template args as SubMultiClass's
 /// template arguments.
-bool TGParser::AddSubMultiClass(MultiClass *CurMultiClass, class SubMultiClassReference &SubMultiClass) {
+bool TGParser::AddSubMultiClass(MultiClass *CurMultiClass,
+                                class SubMultiClassReference &SubMultiClass) {
   MultiClass *SMC = SubMultiClass.MC;
   Record *CurRec = &CurMultiClass->Rec;
 
@@ -194,6 +211,8 @@
     if (AddValue(CurRec, SubMultiClass.RefLoc, SMCVals[i]))
       return true;
 
+  int newDefStart = CurMultiClass->DefPrototypes.size();
+
   // Add all of the defs in the subclass into the current multiclass.
   for (MultiClass::RecordVector::const_iterator i = SMC->DefPrototypes.begin(),
          iend = SMC->DefPrototypes.end();
@@ -212,16 +231,20 @@
   
   const std::vector<std::string> &SMCTArgs = SMC->Rec.getTemplateArgs();
 
-  // Ensure that an appropriate number of template arguments are specified.
+  // Ensure that an appropriate number of template arguments are
+  // specified.
   if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size())
-    return Error(SubMultiClass.RefLoc, "More template args specified than expected");
+    return Error(SubMultiClass.RefLoc,
+                 "More template args specified than expected");
   
   // Loop over all of the template arguments, setting them to the specified
   // value or leaving them as the default if necessary.
   for (unsigned i = 0, e = SMCTArgs.size(); i != e; ++i) {
     if (i < SubMultiClass.TemplateArgs.size()) {
-      // If a value is specified for this template arg, set it in the superclass now.
-      if (SetValue(CurRec, SubMultiClass.RefLoc, SMCTArgs[i], std::vector<unsigned>(), 
+      // If a value is specified for this template arg, set it in the
+      // superclass now.
+      if (SetValue(CurRec, SubMultiClass.RefLoc, SMCTArgs[i],
+                   std::vector<unsigned>(), 
                    SubMultiClass.TemplateArgs[i]))
         return true;
 
@@ -231,14 +254,17 @@
       // Now remove it.
       CurRec->removeValue(SMCTArgs[i]);
 
-      // If a value is specified for this template arg, set it in the defs now.
-      for (MultiClass::RecordVector::iterator j = CurMultiClass->DefPrototypes.begin(),
+      // If a value is specified for this template arg, set it in the
+      // new defs now.
+      for (MultiClass::RecordVector::iterator j =
+             CurMultiClass->DefPrototypes.begin() + newDefStart,
              jend = CurMultiClass->DefPrototypes.end();
            j != jend;
            ++j) {
         Record *Def = *j;
 
-        if (SetValue(Def, SubMultiClass.RefLoc, SMCTArgs[i], std::vector<unsigned>(), 
+        if (SetValue(Def, SubMultiClass.RefLoc, SMCTArgs[i],
+                     std::vector<unsigned>(), 
                      SubMultiClass.TemplateArgs[i]))
           return true;
 
@@ -249,7 +275,8 @@
         Def->removeValue(SMCTArgs[i]);
       }
     } else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) {
-      return Error(SubMultiClass.RefLoc,"Value not specified for template argument #"
+      return Error(SubMultiClass.RefLoc,
+                   "Value not specified for template argument #"
                    + utostr(i) + " (" + SMCTArgs[i] + ") of subclass '" + 
                    SMC->Rec.getName() + "'!");
     }
@@ -1490,8 +1517,12 @@
     if (ParseTemplateArgList(0))
       return true;
 
+  bool inherits = false;
+
   // If there are submulticlasses, parse them.
   if (Lex.getCode() == tgtok::colon) {
+    inherits = true;
+
     Lex.Lex();
     
     // Read all of the submulticlasses.
@@ -1510,17 +1541,25 @@
     }
   }
 
-  if (Lex.getCode() != tgtok::l_brace)
-    return TokError("expected '{' in multiclass definition");
-
-  if (Lex.Lex() == tgtok::r_brace)  // eat the '{'.
-    return TokError("multiclass must contain at least one def");
+  if (Lex.getCode() != tgtok::l_brace) {
+    if (!inherits)
+      return TokError("expected '{' in multiclass definition");
+    else
+      if (Lex.getCode() != tgtok::semi)
+        return TokError("expected ';' in multiclass definition");
+      else
+        Lex.Lex();  // eat the ';'.
+  }
+  else {
+    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 (ParseMultiClassDef(CurMultiClass))
+        return true;
   
-  Lex.Lex();  // eat the '}'.
+    Lex.Lex();  // eat the '}'.
+  }
   
   CurMultiClass = 0;
   return false;





More information about the llvm-commits mailing list