Teach the table generated emitPseudoExpansionLowering function to not emit a switch...
authorAaron Ballman <aaron@aaronballman.com>
Fri, 23 May 2014 15:33:39 +0000 (15:33 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Fri, 23 May 2014 15:33:39 +0000 (15:33 +0000)
llvm-svn: 209521

llvm/utils/TableGen/PseudoLoweringEmitter.cpp

index 70b677f..3b74ac4 100644 (file)
@@ -200,70 +200,74 @@ void PseudoLoweringEmitter::emitLoweringEmitter(raw_ostream &o) {
 
   o << "bool " << Target.getName() + "AsmPrinter" << "::\n"
     << "emitPseudoExpansionLowering(MCStreamer &OutStreamer,\n"
-    << "                            const MachineInstr *MI) {\n"
-    << "  switch (MI->getOpcode()) {\n"
-    << "    default: return false;\n";
-  for (unsigned i = 0, e = Expansions.size(); i != e; ++i) {
-    PseudoExpansion &Expansion = Expansions[i];
-    CodeGenInstruction &Source = Expansion.Source;
-    CodeGenInstruction &Dest = Expansion.Dest;
-    o << "    case " << Source.Namespace << "::"
-      << Source.TheDef->getName() << ": {\n"
-      << "      MCInst TmpInst;\n"
-      << "      MCOperand MCOp;\n"
-      << "      TmpInst.setOpcode(" << Dest.Namespace << "::"
-      << Dest.TheDef->getName() << ");\n";
-
-    // Copy the operands from the source instruction.
-    // FIXME: Instruction operands with defaults values (predicates and cc_out
-    //        in ARM, for example shouldn't need explicit values in the
-    //        expansion DAG.
-    unsigned MIOpNo = 0;
-    for (unsigned OpNo = 0, E = Dest.Operands.size(); OpNo != E;
-         ++OpNo) {
-      o << "      // Operand: " << Dest.Operands[OpNo].Name << "\n";
-      for (unsigned i = 0, e = Dest.Operands[OpNo].MINumOperands;
-           i != e; ++i) {
-        switch (Expansion.OperandMap[MIOpNo + i].Kind) {
-        case OpData::Operand:
-          o << "      lowerOperand(MI->getOperand("
-            << Source.Operands[Expansion.OperandMap[MIOpNo].Data
-                .Operand].MIOperandNo + i
-            << "), MCOp);\n"
-            << "      TmpInst.addOperand(MCOp);\n";
-          break;
-        case OpData::Imm:
-          o << "      TmpInst.addOperand(MCOperand::CreateImm("
-            << Expansion.OperandMap[MIOpNo + i].Data.Imm << "));\n";
-          break;
-        case OpData::Reg: {
-          Record *Reg = Expansion.OperandMap[MIOpNo + i].Data.Reg;
-          o << "      TmpInst.addOperand(MCOperand::CreateReg(";
-          // "zero_reg" is special.
-          if (Reg->getName() == "zero_reg")
-            o << "0";
-          else
-            o << Reg->getValueAsString("Namespace") << "::" << Reg->getName();
-          o << "));\n";
-          break;
-        }
+    << "                            const MachineInstr *MI) {\n";
+
+  if (!Expansions.empty()) {
+    o << "  switch (MI->getOpcode()) {\n"
+      << "    default: return false;\n";
+    for (auto &Expansion : Expansions) {
+      CodeGenInstruction &Source = Expansion.Source;
+      CodeGenInstruction &Dest = Expansion.Dest;
+      o << "    case " << Source.Namespace << "::"
+        << Source.TheDef->getName() << ": {\n"
+        << "      MCInst TmpInst;\n"
+        << "      MCOperand MCOp;\n"
+        << "      TmpInst.setOpcode(" << Dest.Namespace << "::"
+        << Dest.TheDef->getName() << ");\n";
+
+      // Copy the operands from the source instruction.
+      // FIXME: Instruction operands with defaults values (predicates and cc_out
+      //        in ARM, for example shouldn't need explicit values in the
+      //        expansion DAG.
+      unsigned MIOpNo = 0;
+      for (const auto &DestOperand : Dest.Operands) {
+        o << "      // Operand: " << DestOperand.Name << "\n";
+        for (unsigned i = 0, e = DestOperand.MINumOperands; i != e; ++i) {
+          switch (Expansion.OperandMap[MIOpNo + i].Kind) {
+            case OpData::Operand:
+            o << "      lowerOperand(MI->getOperand("
+              << Source.Operands[Expansion.OperandMap[MIOpNo].Data
+              .Operand].MIOperandNo + i
+              << "), MCOp);\n"
+              << "      TmpInst.addOperand(MCOp);\n";
+            break;
+            case OpData::Imm:
+            o << "      TmpInst.addOperand(MCOperand::CreateImm("
+              << Expansion.OperandMap[MIOpNo + i].Data.Imm << "));\n";
+            break;
+            case OpData::Reg: {
+              Record *Reg = Expansion.OperandMap[MIOpNo + i].Data.Reg;
+              o << "      TmpInst.addOperand(MCOperand::CreateReg(";
+              // "zero_reg" is special.
+              if (Reg->getName() == "zero_reg")
+                o << "0";
+              else
+                o << Reg->getValueAsString("Namespace") << "::"
+                  << Reg->getName();
+              o << "));\n";
+              break;
+            }
+          }
         }
+        MIOpNo += DestOperand.MINumOperands;
       }
-      MIOpNo += Dest.Operands[OpNo].MINumOperands;
-    }
-    if (Dest.Operands.isVariadic) {
-      MIOpNo = Source.Operands.size() + 1;
-      o << "      // variable_ops\n";
-      o << "      for (unsigned i = " << MIOpNo
-        << ", e = MI->getNumOperands(); i != e; ++i)\n"
-        << "        if (lowerOperand(MI->getOperand(i), MCOp))\n"
-        << "          TmpInst.addOperand(MCOp);\n";
+      if (Dest.Operands.isVariadic) {
+        MIOpNo = Source.Operands.size() + 1;
+        o << "      // variable_ops\n";
+        o << "      for (unsigned i = " << MIOpNo
+          << ", e = MI->getNumOperands(); i != e; ++i)\n"
+          << "        if (lowerOperand(MI->getOperand(i), MCOp))\n"
+          << "          TmpInst.addOperand(MCOp);\n";
+      }
+      o << "      EmitToStreamer(OutStreamer, TmpInst);\n"
+        << "      break;\n"
+        << "    }\n";
     }
-    o << "      EmitToStreamer(OutStreamer, TmpInst);\n"
-      << "      break;\n"
-      << "    }\n";
-  }
-  o << "  }\n  return true;\n}\n\n";
+    o << "  }\n  return true;";
+  } else
+    o << "  return false;";
+
+  o << "\n}\n\n";
 }
 
 void PseudoLoweringEmitter::run(raw_ostream &o) {