[llvm] r237877 - [TableGen] Resolve complex def names inside multiclasses

Hal Finkel hfinkel at anl.gov
Wed May 20 21:32:56 PDT 2015


Author: hfinkel
Date: Wed May 20 23:32:56 2015
New Revision: 237877

URL: http://llvm.org/viewvc/llvm-project?rev=237877&view=rev
Log:
[TableGen] Resolve complex def names inside multiclasses

We had not been trying hard enough to resolve def names inside multiclasses
that had complex concatenations, etc. Now we'll try harder.

Patch by Amaury Sechet!

Modified:
    llvm/trunk/lib/TableGen/TGParser.cpp
    llvm/trunk/lib/TableGen/TGParser.h
    llvm/trunk/test/TableGen/MultiClassDefName.td

Modified: llvm/trunk/lib/TableGen/TGParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGParser.cpp?rev=237877&r1=237876&r2=237877&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGParser.cpp (original)
+++ llvm/trunk/lib/TableGen/TGParser.cpp Wed May 20 23:32:56 2015
@@ -2322,7 +2322,9 @@ Record *TGParser::
 InstantiateMulticlassDef(MultiClass &MC,
                          Record *DefProto,
                          Init *&DefmPrefix,
-                         SMRange DefmPrefixRange) {
+                         SMRange DefmPrefixRange,
+                         const std::vector<Init *> &TArgs,
+                         std::vector<Init *> &TemplateVals) {
   // We need to preserve DefProto so it can be reused for later
   // instantiations, so create a new Record to inherit from it.
 
@@ -2338,7 +2340,6 @@ InstantiateMulticlassDef(MultiClass &MC,
   }
 
   Init *DefName = DefProto->getNameInit();
-
   StringInit *DefNameString = dyn_cast<StringInit>(DefName);
 
   if (DefNameString) {
@@ -2386,12 +2387,40 @@ InstantiateMulticlassDef(MultiClass &MC,
     RecordVal *DefNameRV = CurRec->getValue("NAME");
     CurRec->resolveReferencesTo(DefNameRV);
 
+    // Check if the name is a complex pattern.
+    // If so, resolve it.
+    DefName = CurRec->getNameInit();
+    DefNameString = dyn_cast<StringInit>(DefName);
+
+    // OK the pattern is more complex than simply using NAME.
+    // Let's use the heavy weaponery.
+    if (!DefNameString) {
+      ResolveMulticlassDefArgs(MC, CurRec.get(), DefmPrefixRange.Start,
+                               Lex.getLoc(), TArgs, TemplateVals,
+                               false/*Delete args*/);
+      DefName = CurRec->getNameInit();
+      DefNameString = dyn_cast<StringInit>(DefName);
+
+      if (!DefNameString)
+        DefName = DefName->convertInitializerTo(StringRecTy::get());
+
+      // We ran out of options here...
+      DefNameString = dyn_cast<StringInit>(DefName);
+      if (!DefNameString) {
+        PrintFatalError(CurRec->getLoc()[CurRec->getLoc().size() - 1],
+                        DefName->getAsUnquotedString() + " is not a string.");
+        return nullptr;
+      }
+
+      CurRec->setName(DefName);
+    }
+
     // Now that NAME references are resolved and we're at the top level of
     // any multiclass expansions, add the record to the RecordKeeper. If we are
     // currently in a multiclass, it means this defm appears inside a
     // multiclass and its name won't be fully resolvable until we see
-    // the top-level defm.  Therefore, we don't add this to the
-    // RecordKeeper at this point.  If we did we could get duplicate
+    // the top-level defm. Therefore, we don't add this to the
+    // RecordKeeper at this point. If we did we could get duplicate
     // defs as more than one probably refers to NAME or some other
     // common internal placeholder.
 
@@ -2523,12 +2552,19 @@ bool TGParser::ParseDefm(MultiClass *Cur
 
     // Loop over all the def's in the multiclass, instantiating each one.
     for (const std::unique_ptr<Record> &DefProto : MC->DefPrototypes) {
+      // The record name construction goes as follow:
+      //  - If the def name is a string, prepend the prefix.
+      //  - If the def name is a more complex pattern, use that pattern.
+      // As a result, the record is instanciated before resolving
+      // arguments, as it would make its name a string.
       Record *CurRec = InstantiateMulticlassDef(*MC, DefProto.get(), DefmPrefix,
                                                 SMRange(DefmLoc,
-                                                        DefmPrefixEndLoc));
+                                                        DefmPrefixEndLoc),
+                                                TArgs, TemplateVals);
       if (!CurRec)
         return true;
 
+      // Now that the record is instanciated, we can resolve arguments.
       if (ResolveMulticlassDefArgs(*MC, CurRec, DefmLoc, SubClassLoc,
                                    TArgs, TemplateVals, true/*Delete args*/))
         return Error(SubClassLoc, "could not instantiate def");

Modified: llvm/trunk/lib/TableGen/TGParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGParser.h?rev=237877&r1=237876&r2=237877&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGParser.h (original)
+++ llvm/trunk/lib/TableGen/TGParser.h Wed May 20 23:32:56 2015
@@ -138,7 +138,9 @@ private:  // Parser methods.
   Record *InstantiateMulticlassDef(MultiClass &MC,
                                    Record *DefProto,
                                    Init *&DefmPrefix,
-                                   SMRange DefmPrefixRange);
+                                   SMRange DefmPrefixRange,
+                                   const std::vector<Init *> &TArgs,
+                                   std::vector<Init *> &TemplateVals);
   bool ResolveMulticlassDefArgs(MultiClass &MC,
                                 Record *DefProto,
                                 SMLoc DefmPrefixLoc,

Modified: llvm/trunk/test/TableGen/MultiClassDefName.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/MultiClassDefName.td?rev=237877&r1=237876&r2=237877&view=diff
==============================================================================
--- llvm/trunk/test/TableGen/MultiClassDefName.td (original)
+++ llvm/trunk/test/TableGen/MultiClassDefName.td Wed May 20 23:32:56 2015
@@ -39,3 +39,45 @@ multiclass MC2<string name> {
 
 defm : MC2<"bar">;
 
+multiclass MC3<string s> {
+  def ZFizz#s : C<s>;
+}
+
+defm : MC3<"Buzz">;
+
+// CHECK: def ZFizzBuzz
+// CHECK: string name = "Buzz";
+// CHECK-NOT: MC3::s
+
+multiclass MC4<string s> {
+  def NAME#s : C<s>;
+}
+
+defm ZTagazok : MC4<"AToi">;
+
+// CHECK: def ZTagazokAToi
+// CHECK: string name = "AToi";
+// CHECK-NOT: MC4::s
+
+multiclass MC5<C c> {
+  def NAME#c.name : C<c.name>;
+}
+
+def CTiger : C<"Tiger">;
+defm Zebra : MC5<CTiger>;
+
+// CHECK: def ZebraTiger
+// CHECK: string name = "Tiger";
+// CHECK-NOT: MC5::c
+
+multiclass MC6<C c> {
+  def NAME#Tiger#c.name : C<c.name>;
+}
+
+def CAligator : C<"Aligator">;
+defm Zebra : MC6<CAligator>;
+
+// CHECK: def ZebraTigerAligator
+// CHECK: string name = "Aligator";
+// CHECK-NOT: MC6::c
+





More information about the llvm-commits mailing list