[llvm] r259913 - TableGen: Add IsOptional field to AsmOperandClass

Tom Stellard via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 5 11:59:33 PST 2016


Author: tstellar
Date: Fri Feb  5 13:59:33 2016
New Revision: 259913

URL: http://llvm.org/viewvc/llvm-project?rev=259913&view=rev
Log:
TableGen: Add IsOptional field to AsmOperandClass

Summary:
This makes it possible to specify some operands as optional to the AsmMatcher.
Setting this field to true will prevent the AsmMatcher from emitting
'too few operands' errors when there are missing optional operands.

Reviewers: olista01, ab

Subscribers: nhaustov, arsenm, llvm-commits

Differential Revision: http://reviews.llvm.org/D15755

Modified:
    llvm/trunk/include/llvm/Target/Target.td
    llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp

Modified: llvm/trunk/include/llvm/Target/Target.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=259913&r1=259912&r2=259913&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/Target.td (original)
+++ llvm/trunk/include/llvm/Target/Target.td Fri Feb  5 13:59:33 2016
@@ -605,6 +605,15 @@ class AsmOperandClass {
   // match failure error message. By default, use a generic "invalid operand"
   // diagnostic. The target AsmParser maps these codes to text.
   string DiagnosticType = "";
+
+  /// Set to 1 if this operand is optional and not always required. Typically,
+  /// the AsmParser will emit an error when it finishes parsing an
+  /// instruction if it hasn't matched all the operands yet.  However, this
+  /// error will be suppressed if all of the remaining unmatched operands are
+  /// marked as IsOptional.
+  ///
+  /// Optional arguments must be at the end of the operand list.
+  bit IsOptional = 0;
 }
 
 def ImmAsmOperand : AsmOperandClass {

Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=259913&r1=259912&r2=259913&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Fri Feb  5 13:59:33 2016
@@ -200,6 +200,10 @@ struct ClassInfo {
 
   /// For custom match classes: the diagnostic kind for when the predicate fails.
   std::string DiagnosticType;
+
+  /// Is this operand optional and not always required.
+  bool IsOptional;
+
 public:
   /// isRegisterClass() - Check if this is a register class.
   bool isRegisterClass() const {
@@ -1115,6 +1119,7 @@ ClassInfo *AsmMatcherInfo::getTokenClass
     Entry->RenderMethod = "<invalid>";
     Entry->ParserMethod = "";
     Entry->DiagnosticType = "";
+    Entry->IsOptional = false;
   }
 
   return Entry;
@@ -1249,6 +1254,7 @@ buildRegisterClasses(SmallPtrSetImpl<Rec
     CI->Registers = RS;
     // FIXME: diagnostic type.
     CI->DiagnosticType = "";
+    CI->IsOptional = false;
     RegisterSetClasses.insert(std::make_pair(RS, CI));
     ++Index;
   }
@@ -1363,6 +1369,10 @@ void AsmMatcherInfo::buildOperandClasses
     if (StringInit *SI = dyn_cast<StringInit>(DiagnosticType))
       CI->DiagnosticType = SI->getValue();
 
+    Init *IsOptional = Rec->getValueInit("IsOptional");
+    if (BitInit *BI = dyn_cast<BitInit>(IsOptional))
+      CI->IsOptional = BI->getValue();
+
     ++Index;
   }
 }
@@ -2102,6 +2112,7 @@ static void emitMatchClassEnumeration(Co
      << "/// instruction matching.\n";
   OS << "enum MatchClassKind {\n";
   OS << "  InvalidMatchClass = 0,\n";
+  OS << "  OptionalMatchClass = 1,\n";
   for (const auto &CI : Infos) {
     OS << "  " << CI.Name << ", // ";
     if (CI.Kind == ClassInfo::Token) {
@@ -2188,6 +2199,8 @@ static void emitIsSubclass(CodeGenTarget
   bool EmittedSwitch = false;
   for (const auto &A : Infos) {
     std::vector<StringRef> SuperClasses;
+    if (A.IsOptional)
+      SuperClasses.push_back("OptionalMatchClass");
     for (const auto &B : Infos) {
       if (&A != &B && A.isSubsetOf(B))
         SuperClasses.push_back(B.Name);
@@ -3100,7 +3113,8 @@ void AsmMatcherEmitter::run(raw_ostream
   OS << "      auto Formal = static_cast<MatchClassKind>(it->Classes[i]);\n";
   OS << "      if (i" << (HasMnemonicFirst ? "+1" : "")
      << " >= Operands.size()) {\n";
-  OS << "        OperandsValid = (Formal == " <<"InvalidMatchClass);\n";
+  OS << "        OperandsValid = (Formal == " <<"InvalidMatchClass) || "
+                                 "isSubclass(Formal, OptionalMatchClass);\n";
   OS << "        if (!OperandsValid) ErrorInfo = i"
      << (HasMnemonicFirst ? "+1" : "") << ";\n";
   OS << "        break;\n";




More information about the llvm-commits mailing list