]> granicus.if.org Git - llvm/commitdiff
[TableGen] Emit OperandType enums for RegisterOperands/RegisterClasses
authorAditya Nandakumar <aditya_nandakumar@apple.com>
Mon, 23 Sep 2019 18:51:00 +0000 (18:51 +0000)
committerAditya Nandakumar <aditya_nandakumar@apple.com>
Mon, 23 Sep 2019 18:51:00 +0000 (18:51 +0000)
https://reviews.llvm.org/D66773

The OpTypes::OperandType was creating an enum for all records that
inherit from Operand, but in reality there are operands for instructions
that inherit from other types too. In particular, RegisterOperand and
RegisterClass. This commit adds those types to the list of operand types
that are tracked by the OperandType enum.

Patch by: nlguillemot

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@372641 91177308-0d34-0410-b5e6-96231b3b80d8

test/TableGen/get-operand-type.td
utils/TableGen/InstrInfoEmitter.cpp

index 69bcde38c7ef282097e0441192cd738ee59292dc..27607f57a8d48572178ea885150ea50e639a6c82 100644 (file)
@@ -16,6 +16,8 @@ def RegClass : RegisterClass<"foo", [i32], 0, (add Reg)>;
 def OpA : Operand<i32>;
 def OpB : Operand<i32>;
 
+def RegOp : RegisterOperand<RegClass>;
+
 def InstA : Instruction {
   let Size = 1;
   let OutOperandList = (outs OpA:$a);
@@ -34,7 +36,17 @@ def InstB : Instruction {
   let Namespace = "MyNamespace";
 }
 
+def InstC : Instruction {
+  let Size = 1;
+  let OutOperandList = (outs RegClass:$d);
+  let InOperandList = (ins RegOp:$x);
+  field bits<8> Inst;
+  field bits<8> SoftFail = 0;
+  let Namespace = "MyNamespace";
+}
+
 // CHECK: #ifdef GET_INSTRINFO_OPERAND_TYPE
 // CHECK:        OpTypes::OpA, OpTypes::OpB, OpTypes::i32imm,
 // CHECK-NEXT:   OpTypes::i32imm, -1,
-// CHECK: #endif //GET_INSTRINFO_OPERAND_TYPE
+// CHECK-NEXT:   OpTypes::RegClass, OpTypes::RegOp,
+// CHECK: #endif // GET_INSTRINFO_OPERAND_TYPE
index ae48d383cdf7264f5654051490f7391701c470cd..b7961efbf96366f23b564a1538b5f1e1a8c1d17b 100644 (file)
@@ -332,6 +332,10 @@ void InstrInfoEmitter::emitOperandTypeMappings(
 
   StringRef Namespace = Target.getInstNamespace();
   std::vector<Record *> Operands = Records.getAllDerivedDefinitions("Operand");
+  std::vector<Record *> RegisterOperands =
+      Records.getAllDerivedDefinitions("RegisterOperand");
+  std::vector<Record *> RegisterClasses =
+      Records.getAllDerivedDefinitions("RegisterClass");
 
   OS << "#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
   OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
@@ -341,10 +345,13 @@ void InstrInfoEmitter::emitOperandTypeMappings(
   OS << "enum OperandType {\n";
 
   unsigned EnumVal = 0;
-  for (const Record *Op : Operands) {
-    if (!Op->isAnonymous())
-      OS << "  " << Op->getName() << " = " << EnumVal << ",\n";
-    ++EnumVal;
+  for (const std::vector<Record *> *RecordsToAdd :
+       {&Operands, &RegisterOperands, &RegisterClasses}) {
+    for (const Record *Op : *RecordsToAdd) {
+      if (!Op->isAnonymous())
+        OS << "  " << Op->getName() << " = " << EnumVal << ",\n";
+      ++EnumVal;
+    }
   }
 
   OS << "  OPERAND_TYPE_LIST_END" << "\n};\n";
@@ -358,7 +365,8 @@ void InstrInfoEmitter::emitOperandTypeMappings(
   OS << "namespace llvm {\n";
   OS << "namespace " << Namespace << " {\n";
   OS << "LLVM_READONLY\n";
-  OS << "int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n";
+  OS << "static int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n";
+  // TODO: Factor out instructions with same operands to compress the tables.
   if (!NumberedInstructions.empty()) {
     std::vector<int> OperandOffsets;
     std::vector<Record *> OperandRecords;
@@ -399,7 +407,10 @@ void InstrInfoEmitter::emitOperandTypeMappings(
           OS << "/**/\n    ";
       }
       Record *OpR = OperandRecords[I];
-      if (OpR->isSubClassOf("Operand") && !OpR->isAnonymous())
+      if ((OpR->isSubClassOf("Operand") ||
+           OpR->isSubClassOf("RegisterOperand") ||
+           OpR->isSubClassOf("RegisterClass")) &&
+          !OpR->isAnonymous())
         OS << "OpTypes::" << OpR->getName();
       else
         OS << -1;
@@ -414,7 +425,7 @@ void InstrInfoEmitter::emitOperandTypeMappings(
   OS << "}\n";
   OS << "} // end namespace " << Namespace << "\n";
   OS << "} // end namespace llvm\n";
-  OS << "#endif //GET_INSTRINFO_OPERAND_TYPE\n\n";
+  OS << "#endif // GET_INSTRINFO_OPERAND_TYPE\n\n";
 }
 
 void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,