[llvm-commits] [llvm] r141229 - in /llvm/trunk/lib/TableGen: TGParser.cpp TGParser.h

David Greene greened at obbligato.org
Wed Oct 5 15:42:07 PDT 2011


Author: greened
Date: Wed Oct  5 17:42:07 2011
New Revision: 141229

URL: http://llvm.org/viewvc/llvm-project?rev=141229&view=rev
Log:
Refactor Multiclass Def Processing

Move the code to instantiate a multiclass def, bind its arguments and
resolve its members into three helper functions.  These will be reused
to support a new kind of multiclass def: a multidef.

Modified:
    llvm/trunk/lib/TableGen/TGParser.cpp
    llvm/trunk/lib/TableGen/TGParser.h

Modified: llvm/trunk/lib/TableGen/TGParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGParser.cpp?rev=141229&r1=141228&r2=141229&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGParser.cpp (original)
+++ llvm/trunk/lib/TableGen/TGParser.cpp Wed Oct  5 17:42:07 2011
@@ -1919,6 +1919,115 @@
   return false;
 }
 
+Record *TGParser::
+InstantiateMulticlassDef(MultiClass &MC,
+                         Record *DefProto,
+                         const std::string &DefmPrefix,
+                         SMLoc DefmPrefixLoc) {
+  // Add in the defm name.  If the defm prefix is empty, give each
+  // instantiated def a unique name.  Otherwise, if "#NAME#" exists in the
+  // name, substitute the prefix for #NAME#.  Otherwise, use the defm name
+  // as a prefix.
+  std::string DefName = DefProto->getName();
+  if (DefmPrefix.empty()) {
+    DefName = GetNewAnonymousName();
+  } else {
+    std::string::size_type idx = DefName.find("#NAME#");
+    if (idx != std::string::npos) {
+      DefName.replace(idx, 6, DefmPrefix);
+    } else {
+      // Add the suffix to the defm name to get the new name.
+      DefName = DefmPrefix + DefName;
+    }
+  }
+
+  Record *CurRec = new Record(DefName, DefmPrefixLoc, Records);
+
+  SubClassReference Ref;
+  Ref.RefLoc = DefmPrefixLoc;
+  Ref.Rec = DefProto;
+  AddSubClass(CurRec, Ref);
+
+  return CurRec;
+}
+
+bool TGParser::ResolveMulticlassDefArgs(MultiClass &MC,
+                                        Record *CurRec,
+                                        SMLoc DefmPrefixLoc,
+                                        SMLoc SubClassLoc,
+                                        const std::vector<std::string> &TArgs,
+                                        std::vector<Init *> &TemplateVals,
+                                        bool DeleteArgs) {
+  // 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) {
+    // Check if a value is specified for this temp-arg.
+    if (i < TemplateVals.size()) {
+      // 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]));
+
+      if (DeleteArgs)
+        // 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() + "'");
+    }
+  }
+  return false;
+}
+
+bool TGParser::ResolveMulticlassDef(MultiClass &MC,
+                                    Record *CurRec,
+                                    Record *DefProto,
+                                    SMLoc DefmPrefixLoc) {
+  // 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))
+        return Error(DefmPrefixLoc, "when instantiating this defm");
+
+  // Ensure redefinition doesn't happen.
+  if (Records.getDef(CurRec->getName()))
+    return Error(DefmPrefixLoc, "def '" + CurRec->getName() + 
+                 "' already defined, instantiating defm with subdef '" + 
+                 DefProto->getName() + "'");
+
+  // 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())
+        return Error(DefmPrefixLoc, "defm '" + CurRec->getName() +
+                     "' already defined in this multiclass!");
+    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);
+  }
+
+  return false;
+}
+
 /// ParseDefm - Parse the instantiation of a multiclass.
 ///
 ///   DefMInst ::= DEFM ID ':' DefmSubClassRef ';'
@@ -1968,99 +2077,19 @@
     for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) {
       Record *DefProto = MC->DefPrototypes[i];
 
-      // Add in the defm name.  If the defm prefix is empty, give each
-      // instantiated def a unique name.  Otherwise, if "#NAME#" exists in the
-      // name, substitute the prefix for #NAME#.  Otherwise, use the defm name
-      // as a prefix.
-      std::string DefName = DefProto->getName();
-      if (DefmPrefix.empty()) {
-        DefName = GetNewAnonymousName();
-      } else {
-        std::string::size_type idx = DefName.find("#NAME#");
-        if (idx != std::string::npos) {
-          DefName.replace(idx, 6, DefmPrefix);
-        } else {
-          // Add the suffix to the defm name to get the new name.
-          DefName = DefmPrefix + DefName;
-        }
-      }
+      Record *CurRec = InstantiateMulticlassDef(*MC, DefProto, DefmPrefix, DefmPrefixLoc);
 
-      Record *CurRec = new Record(DefName, DefmPrefixLoc, Records);
+      if (ResolveMulticlassDefArgs(*MC, CurRec, DefmPrefixLoc, SubClassLoc,
+                                   TArgs, TemplateVals, true/*Delete args*/))
+        return Error(SubClassLoc, "could not instantiate def");
 
-      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) {
-        // Check if a value is specified for this temp-arg.
-        if (i < TemplateVals.size()) {
-          // 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() + "'");
-
-      // 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);
-      }
+      if (ResolveMulticlassDef(*MC, CurRec, DefProto, DefmPrefixLoc))
+        return Error(SubClassLoc, "could not instantiate def");
 
       NewRecDefs.push_back(CurRec);
     }
 
+
     if (Lex.getCode() != tgtok::comma) break;
     Lex.Lex(); // eat ','.
 

Modified: llvm/trunk/lib/TableGen/TGParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGParser.h?rev=141229&r1=141228&r2=141229&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGParser.h (original)
+++ llvm/trunk/lib/TableGen/TGParser.h Wed Oct  5 17:42:07 2011
@@ -83,6 +83,21 @@
   bool ParseObject(MultiClass *MC);
   bool ParseClass();
   bool ParseMultiClass();
+  Record *InstantiateMulticlassDef(MultiClass &MC,
+                                   Record *DefProto,
+                                   const std::string &DefmPrefix,
+                                   SMLoc DefmPrefixLoc);
+  bool ResolveMulticlassDefArgs(MultiClass &MC,
+                                Record *DefProto,
+                                SMLoc DefmPrefixLoc,
+                                SMLoc SubClassLoc,
+                                const std::vector<std::string> &TArgs,
+                                std::vector<Init *> &TemplateVals,
+                                bool DeleteArgs);
+  bool ResolveMulticlassDef(MultiClass &MC,
+                            Record *CurRec,
+                            Record *DefProto,
+                            SMLoc DefmPrefixLoc);
   bool ParseDefm(MultiClass *CurMultiClass);
   bool ParseDef(MultiClass *CurMultiClass);
   bool ParseTopLevelLet(MultiClass *CurMultiClass);





More information about the llvm-commits mailing list