[llvm-commits] [llvm] r78099 - /llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp

Daniel Dunbar daniel at zuster.org
Tue Aug 4 13:36:56 PDT 2009


Author: ddunbar
Date: Tue Aug  4 15:36:45 2009
New Revision: 78099

URL: http://llvm.org/viewvc/llvm-project?rev=78099&view=rev
Log:
TableGen / AsmMatcher: Tweaks to avoid generating completely bogus match
functions.
 - Fix variant flattening when the variant embeds an operand reference.

 - Ignore instructions which reference an operand multiple times (e.g., "xorb
   $dst, $dst"), and operands which have extra flags (e.g., "$dst:subreg32").

Modified:
    llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp

Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=78099&r1=78098&r2=78099&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Tue Aug  4 15:36:45 2009
@@ -29,23 +29,40 @@
   std::string Res = "";
   
   for (;;) {
-    // Add the prefix until the next '{', and split out the contents in the
-    // braces.
-    std::pair<StringRef, StringRef> Inner, Split = Cur.split('{');
-
-    Res += Split.first;
-    if (Split.second.empty())
+    // Find the start of the next variant string.
+    size_t VariantsStart = 0;
+    for (size_t e = Cur.size(); VariantsStart != e; ++VariantsStart)
+      if (Cur[VariantsStart] == '{' && 
+          (VariantsStart == 0 || Cur[VariantsStart-1] != '$'))
+        break;
+
+    // Add the prefix to the result.
+    Res += Cur.slice(0, VariantsStart);
+    if (VariantsStart == Cur.size())
       break;
 
-    Inner = Split.second.split('}');
+    ++VariantsStart; // Skip the '{'.
+
+    // Scan to the end of the variants string.
+    size_t VariantsEnd = VariantsStart;
+    unsigned NestedBraces = 1;
+    for (size_t e = Cur.size(); VariantsEnd != e; ++VariantsEnd) {
+      if (Cur[VariantsEnd] == '}') {
+        if (--NestedBraces == 0)
+          break;
+      } else if (Cur[VariantsEnd] == '{')
+        ++NestedBraces;
+    }
 
     // Select the Nth variant (or empty).
-    StringRef Selection = Inner.first;
+    StringRef Selection = Cur.slice(VariantsStart, VariantsEnd);
     for (unsigned i = 0; i != N; ++i)
       Selection = Selection.split('|').second;
     Res += Selection.split('|').first;
 
-    Cur = Inner.second;
+    assert(VariantsEnd != Cur.size() && 
+           "Unterminated variants in assembly string!");
+    Cur = Cur.substr(VariantsEnd + 1);
   } 
 
   return Res;
@@ -128,6 +145,12 @@
       if (Form->getValue()->getAsString() == "Pseudo")
         continue;
 
+    // Ignore "PHI" node.
+    //
+    // FIXME: This is also a hack.
+    if (it->first == "PHI")
+      continue;
+
     // Ignore instructions with no .s string.
     //
     // FIXME: What are these?
@@ -138,12 +161,6 @@
     if (StringRef(CGI.AsmString).startswith("lock"))
       continue;
 
-    // FIXME: Hack.
-#if 0
-    if (1 && it->first != "SUB8mr")
-      continue;
-#endif
-
     std::string Flattened = FlattenVariants(CGI.AsmString, 0);
     SmallVector<StringRef, 8> Tokens;
 
@@ -167,9 +184,50 @@
         }
       });
 
-    // FIXME: Ignore non-literal tokens.
-    if (std::find(Tokens[0].begin(), Tokens[0].end(), '$') != Tokens[0].end())
+    // FIXME: Ignore prefixes with non-literal tokens.
+    if (std::find(Tokens[0].begin(), Tokens[0].end(), '$') != Tokens[0].end()) {
+      DEBUG({
+          errs() << "warning: '" << it->first << "': "
+                 << "ignoring non-literal token '" << Tokens[0] << "', \n";
+        });
+      continue;
+    }
+
+    // Ignore instructions with subreg specifiers, these are always fake
+    // instructions for simplifying codegen.
+    //
+    // FIXME: Is this true?
+    //
+    // Also, we ignore instructions which reference the operand multiple times;
+    // this implies a constraint we would not currently honor. These are
+    // currently always fake instructions for simplifying codegen.
+    //
+    // FIXME: Encode this assumption in the .td, so we can error out here.
+    std::set<std::string> OperandNames;
+    unsigned HasSubreg = 0, HasDuplicate = 0;
+    for (unsigned i = 1, e = Tokens.size(); i < e; ++i) {
+      if (Tokens[i][0] == '$' && 
+          std::find(Tokens[i].begin(), 
+                    Tokens[i].end(), ':') != Tokens[i].end())
+        HasSubreg = i;
+      if (Tokens[i][0] == '$' && !OperandNames.insert(Tokens[i]).second)
+        HasDuplicate = i;
+    }
+    if (HasSubreg) {
+      DEBUG({
+          errs() << "warning: '" << it->first << "': "
+                 << "ignoring instruction; operand with subreg attribute '" 
+                 << Tokens[HasSubreg] << "', \n";
+        });
       continue;
+    } else if (HasDuplicate) {
+      DEBUG({
+          errs() << "warning: '" << it->first << "': "
+                 << "ignoring instruction; tied operand '" 
+                 << Tokens[HasSubreg] << "', \n";
+        });
+      continue;
+    }
 
     std::string FnName = "Match_" + Target.getName() + "_Inst_" + it->first;
     MatchFns.push_back(FnName);





More information about the llvm-commits mailing list