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

David Greene greened at obbligato.org
Wed Apr 22 15:17:51 PDT 2009


Author: greened
Date: Wed Apr 22 17:17:51 2009
New Revision: 69832

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

Allow defm to inherit from multiple multiclasses.

Added:
    llvm/trunk/test/TableGen/DefmInherit.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=69832&r1=69831&r2=69832&view=diff

==============================================================================
--- llvm/trunk/docs/TableGenFundamentals.html (original)
+++ llvm/trunk/docs/TableGenFundamentals.html Wed Apr 22 17:17:51 2009
@@ -632,9 +632,10 @@
 
 <p>The name of the resultant definitions has the multidef fragment names
    appended to them, so this defines <tt>ADD_rr</tt>, <tt>ADD_ri</tt>,
-   <tt>SUB_rr</tt>, etc.  Using a multiclass this way is exactly
-   equivalent to instantiating the classes multiple times yourself,
-   e.g. by writing:</p>
+   <tt>SUB_rr</tt>, etc.  A defm may inherit from multiple multiclasses,
+   instantiating definitions from each multiclass.  Using a multiclass
+   this way is exactly equivalent to instantiating the classes multiple
+   times yourself, e.g. by writing:</p>
 
 <div class="doc_code">
 <pre>

Added: llvm/trunk/test/TableGen/DefmInherit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/DefmInherit.td?rev=69832&view=auto

==============================================================================
--- llvm/trunk/test/TableGen/DefmInherit.td (added)
+++ llvm/trunk/test/TableGen/DefmInherit.td Wed Apr 22 17:17:51 2009
@@ -0,0 +1,32 @@
+// RUN: tblgen %s | grep {zing = 4} | count 4
+
+class C1<int A, string B> { 
+  int bar = A;
+  string thestr = B;
+  int zing;
+}
+
+def T : C1<4, "blah">;
+
+multiclass t<int a> {
+  def S1 : C1<a, "foo"> {
+    int foo = 4;
+    let bar = 1;
+  }
+  def S2 : C1<a, "bar">;
+}
+
+multiclass s<int a> {
+  def S3 : C1<a, "moo"> {
+    int moo = 3;
+    let bar = 1;
+  }
+  def S4 : C1<a, "baz">;
+}
+
+defm FOO : t<42>, s<24>;
+
+def T4 : C1<6, "foo">;
+
+let zing = 4 in
+  defm BAZ : t<3>, s<4>;

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

==============================================================================
--- llvm/trunk/utils/TableGen/TGParser.cpp (original)
+++ llvm/trunk/utils/TableGen/TGParser.cpp Wed Apr 22 17:17:51 2009
@@ -1482,77 +1482,85 @@
 
   TGLoc SubClassLoc = Lex.getLoc();
   SubClassReference Ref = ParseSubClassReference(0, true);
-  if (Ref.Rec == 0) return true;
-  
-  if (Lex.getCode() != tgtok::semi)
-    return TokError("expected ';' at end of defm");
-  Lex.Lex();
-  
-  // To instantiate a multiclass, we need to first get the multiclass, then
-  // instantiate each def contained in the multiclass with the SubClassRef
-  // template parameters.
-  MultiClass *MC = MultiClasses[Ref.Rec->getName()];
-  assert(MC && "Didn't lookup multiclass correctly?");
-  std::vector<Init*> &TemplateVals = Ref.TemplateArgs;
-  
-  // Verify that the correct number of template arguments were specified.
-  const std::vector<std::string> &TArgs = MC->Rec.getTemplateArgs();
-  if (TArgs.size() < TemplateVals.size())
-    return Error(SubClassLoc,
-                 "more template args specified than multiclass expects");
-  
-  // Loop over all the def's in the multiclass, instantiating each one.
-  for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) {
-    Record *DefProto = MC->DefPrototypes[i];
-    
-    // Add the suffix to the defm name to get the new name.
-    Record *CurRec = new Record(DefmPrefix + DefProto->getName(),DefmPrefixLoc);
-    
-    SubClassReference Ref;
-    Ref.RefLoc = DefmPrefixLoc;
-    Ref.Rec = DefProto;
-    AddSubClass(CurRec, Ref);
-    
-    // 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 = TArgs.size(); i != e; ++i) {
-      if (i < TemplateVals.size()) { // A value is specified for this temp-arg?
-        // Set it now.
-        if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], std::vector<unsigned>(),
-                     TemplateVals[i]))
-          return true;
-        
-        // Resolve it next.
-        CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
-        
-        // Now remove it.
-        CurRec->removeValue(TArgs[i]);
-        
-      } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
-        return Error(SubClassLoc, "value not specified for template argument #"+
-                     utostr(i) + " (" + TArgs[i] + ") of multiclassclass '" +
-                     MC->Rec.getName() + "'");
+
+  while (1) {
+    if (Ref.Rec == 0) return true;
+
+    // To instantiate a multiclass, we need to first get the multiclass, then
+    // instantiate each def contained in the multiclass with the SubClassRef
+    // template parameters.
+    MultiClass *MC = MultiClasses[Ref.Rec->getName()];
+    assert(MC && "Didn't lookup multiclass correctly?");
+    std::vector<Init*> &TemplateVals = Ref.TemplateArgs;   
+
+    // Verify that the correct number of template arguments were specified.
+    const std::vector<std::string> &TArgs = MC->Rec.getTemplateArgs();
+    if (TArgs.size() < TemplateVals.size())
+      return Error(SubClassLoc,
+                   "more template args specified than multiclass expects");
+
+    // Loop over all the def's in the multiclass, instantiating each one.
+    for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) {
+      Record *DefProto = MC->DefPrototypes[i];
+
+      // Add the suffix to the defm name to get the new name.
+      Record *CurRec = new Record(DefmPrefix + DefProto->getName(), DefmPrefixLoc);
+
+      SubClassReference Ref;
+      Ref.RefLoc = DefmPrefixLoc;
+      Ref.Rec = DefProto;
+      AddSubClass(CurRec, Ref);
+
+      // 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 = TArgs.size(); i != e; ++i) {
+        if (i < TemplateVals.size()) { // A value is specified for this temp-arg?
+          // Set it now.
+          if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], std::vector<unsigned>(),
+                       TemplateVals[i]))
+            return true;
+
+          // Resolve it next.
+          CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
+
+          // Now remove it.
+          CurRec->removeValue(TArgs[i]);
+
+        } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
+          return Error(SubClassLoc, "value not specified for template argument #"+
+                       utostr(i) + " (" + TArgs[i] + ") of multiclassclass '" +
+                       MC->Rec.getName() + "'");
+        }
       }
+
+      // If the mdef is inside a 'let' expression, add to each def.
+      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)) {
+            Error(DefmPrefixLoc, "when instantiating this defm");
+            return true;
+          }
+
+      // Ensure redefinition doesn't happen.
+      if (Records.getDef(CurRec->getName()))
+        return Error(DefmPrefixLoc, "def '" + CurRec->getName() + 
+                     "' already defined, instantiating defm with subdef '" + 
+                     DefProto->getName() + "'");
+      Records.addDef(CurRec);
+      CurRec->resolveReferences();
     }
-    
-    // If the mdef is inside a 'let' expression, add to each def.
-    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)) {
-          Error(DefmPrefixLoc, "when instantiating this defm");
-          return true;
-        }
-    
-    
-    // Ensure redefinition doesn't happen.
-    if (Records.getDef(CurRec->getName()))
-      return Error(DefmPrefixLoc, "def '" + CurRec->getName() + 
-                   "' already defined, instantiating defm with subdef '" + 
-                   DefProto->getName() + "'");
-    Records.addDef(CurRec);
-    CurRec->resolveReferences();
+
+    if (Lex.getCode() != tgtok::comma) break;
+    Lex.Lex(); // eat ','.
+
+    SubClassLoc = Lex.getLoc();
+    Ref = ParseSubClassReference(0, true);
   }
+
+  if (Lex.getCode() != tgtok::semi)
+    return TokError("expected ';' at end of defm");
+  Lex.Lex();
   
   return false;
 }





More information about the llvm-commits mailing list