tblgen: Twinify PrintFatalError.
[oota-llvm.git] / utils / TableGen / AsmWriterEmitter.cpp
index a6d1daf91a485f39d70025fd941df9eff00a2c0c..f9e1990d0553e8f2b22e2045960affc30cfb39ca 100644 (file)
@@ -32,10 +32,12 @@ using namespace llvm;
 namespace {
 class AsmWriterEmitter {
   RecordKeeper &Records;
+  CodeGenTarget Target;
   std::map<const CodeGenInstruction*, AsmWriterInst*> CGIAWIMap;
-  std::vector<const CodeGenInstruction*> NumberedInstructions;
+  const std::vector<const CodeGenInstruction*> *NumberedInstructions;
+  std::vector<AsmWriterInst> Instructions;
 public:
-  AsmWriterEmitter(RecordKeeper &R) : Records(R) {}
+  AsmWriterEmitter(RecordKeeper &R);
 
   void run(raw_ostream &o);
 
@@ -45,9 +47,9 @@ private:
   void EmitPrintAliasInstruction(raw_ostream &O);
 
   AsmWriterInst *getAsmWriterInstByID(unsigned ID) const {
-    assert(ID < NumberedInstructions.size());
+    assert(ID < NumberedInstructions->size());
     std::map<const CodeGenInstruction*, AsmWriterInst*>::const_iterator I =
-      CGIAWIMap.find(NumberedInstructions[ID]);
+      CGIAWIMap.find(NumberedInstructions->at(ID));
     assert(I != CGIAWIMap.end() && "Didn't find inst!");
     return I->second;
   }
@@ -139,7 +141,7 @@ void AsmWriterEmitter::
 FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
                           std::vector<unsigned> &InstIdxs,
                           std::vector<unsigned> &InstOpsUsed) const {
-  InstIdxs.assign(NumberedInstructions.size(), ~0U);
+  InstIdxs.assign(NumberedInstructions->size(), ~0U);
 
   // This vector parallels UniqueOperandCommands, keeping track of which
   // instructions each case are used for.  It is a comma separated string of
@@ -148,9 +150,10 @@ FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
   InstrsForCase.resize(UniqueOperandCommands.size());
   InstOpsUsed.assign(UniqueOperandCommands.size(), 0);
 
-  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+  for (unsigned i = 0, e = NumberedInstructions->size(); i != e; ++i) {
     const AsmWriterInst *Inst = getAsmWriterInstByID(i);
-    if (Inst == 0) continue;  // PHI, INLINEASM, PROLOG_LABEL, etc.
+    if (Inst == 0)
+      continue; // PHI, INLINEASM, CFI_INSTRUCTION, etc.
 
     std::string Command;
     if (Inst->Operands.empty())
@@ -273,41 +276,17 @@ static void UnescapeString(std::string &Str) {
 }
 
 /// EmitPrintInstruction - Generate the code for the "printInstruction" method
-/// implementation.
+/// implementation. Destroys all instances of AsmWriterInst information, by
+/// clearing the Instructions vector.
 void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
-  CodeGenTarget Target(Records);
   Record *AsmWriter = Target.getAsmWriter();
   std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
-  bool isMC = AsmWriter->getValueAsBit("isMCAsmWriter");
-  const char *MachineInstrClassName = isMC ? "MCInst" : "MachineInstr";
 
   O <<
   "/// printInstruction - This method is automatically generated by tablegen\n"
   "/// from the instruction set description.\n"
     "void " << Target.getName() << ClassName
-            << "::printInstruction(const " << MachineInstrClassName
-            << " *MI, raw_ostream &O) {\n";
-
-  std::vector<AsmWriterInst> Instructions;
-
-  for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
-         E = Target.inst_end(); I != E; ++I)
-    if (!(*I)->AsmString.empty() &&
-        (*I)->TheDef->getName() != "PHI")
-      Instructions.push_back(
-        AsmWriterInst(**I,
-                      AsmWriter->getValueAsInt("Variant"),
-                      AsmWriter->getValueAsInt("FirstOperandColumn"),
-                      AsmWriter->getValueAsInt("OperandSpacing")));
-
-  // Get the instruction numbering.
-  NumberedInstructions = Target.getInstructionsByEnumValue();
-
-  // Compute the CodeGenInstruction -> AsmWriterInst mapping.  Note that not
-  // all machine instructions are necessarily being printed, so there may be
-  // target instructions not in this map.
-  for (unsigned i = 0, e = Instructions.size(); i != e; ++i)
-    CGIAWIMap.insert(std::make_pair(Instructions[i].CGI, &Instructions[i]));
+            << "::printInstruction(const MCInst *MI, raw_ostream &O) {\n";
 
   // Build an aggregate string, and build a table of offsets into it.
   SequenceToOffsetTable<std::string> StringTable;
@@ -320,8 +299,8 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
 
   // Add all strings to the string table upfront so it can generate an optimized
   // representation.
-  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
-    AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]];
+  for (unsigned i = 0, e = NumberedInstructions->size(); i != e; ++i) {
+    AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions->at(i)];
     if (AWI != 0 &&
         AWI->Operands[0].OperandType ==
                  AsmWriterOperand::isLiteralTextOperand &&
@@ -335,8 +314,8 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
   StringTable.layout();
 
   unsigned MaxStringIdx = 0;
-  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
-    AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]];
+  for (unsigned i = 0, e = NumberedInstructions->size(); i != e; ++i) {
+    AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions->at(i)];
     unsigned Idx;
     if (AWI == 0) {
       // Something not handled by the asmwriter printer.
@@ -398,7 +377,7 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
     BitsLeft -= NumBits;
 
     // Remove the info about this operand.
-    for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+    for (unsigned i = 0, e = NumberedInstructions->size(); i != e; ++i) {
       if (AsmWriterInst *Inst = getAsmWriterInstByID(i))
         if (!Inst->Operands.empty()) {
           unsigned NumOps = NumInstOpsHandled[InstIdxs[i]];
@@ -417,9 +396,9 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
   // We always emit at least one 32-bit table. A second table is emitted if
   // more bits are needed.
   O<<"  static const uint32_t OpInfo[] = {\n";
-  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+  for (unsigned i = 0, e = NumberedInstructions->size(); i != e; ++i) {
     O << "    " << (OpcodeInfo[i] & 0xffffffff) << "U,\t// "
-      << NumberedInstructions[i]->TheDef->getName() << "\n";
+      << NumberedInstructions->at(i)->TheDef->getName() << "\n";
   }
   // Add a dummy entry so the array init doesn't end with a comma.
   O << "    0U\n";
@@ -431,9 +410,9 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
     O << "  static const uint"
       << ((BitsLeft < 16) ? "32" : (BitsLeft < 24) ? "16" : "8")
       << "_t OpInfo2[] = {\n";
-    for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+    for (unsigned i = 0, e = NumberedInstructions->size(); i != e; ++i) {
       O << "    " << (OpcodeInfo[i] >> 32) << "U,\t// "
-        << NumberedInstructions[i]->TheDef->getName() << "\n";
+        << NumberedInstructions->at(i)->TheDef->getName() << "\n";
     }
     // Add a dummy entry so the array init doesn't end with a comma.
     O << "    0U\n";
@@ -568,8 +547,8 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName,
           Reg.TheDef->getValueAsListOfStrings("AltNames");
         if (AltNames.size() <= Idx)
           PrintFatalError(Reg.TheDef->getLoc(),
-            (Twine("Register definition missing alt name for '") +
-             AltName + "'.").str());
+                          "Register definition missing alt name for '" +
+                          AltName + "'.");
         AsmName = AltNames[Idx];
       }
     }
@@ -592,7 +571,6 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName,
 }
 
 void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
-  CodeGenTarget Target(Records);
   Record *AsmWriter = Target.getAsmWriter();
   std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
   const std::vector<CodeGenRegister*> &Registers =
@@ -625,8 +603,8 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
       << "  switch(AltIdx) {\n"
       << "  default: llvm_unreachable(\"Invalid register alt name index!\");\n";
     for (unsigned i = 0, e = AltNameIndices.size(); i < e; ++i) {
-      StringRef Namespace = AltNameIndices[1]->getValueAsString("Namespace");
-      StringRef AltName(AltNameIndices[i]->getName());
+      std::string Namespace = AltNameIndices[1]->getValueAsString("Namespace");
+      std::string AltName(AltNameIndices[i]->getName());
       O << "  case " << Namespace << "::" << AltName
         << ":\n"
         << "    AsmStrs = AsmStrs" << AltName  << ";\n"
@@ -782,12 +760,8 @@ static unsigned CountResultNumOperands(StringRef AsmString) {
 }
 
 void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
-  CodeGenTarget Target(Records);
   Record *AsmWriter = Target.getAsmWriter();
 
-  if (!AsmWriter->getValueAsBit("isMCAsmWriter"))
-    return;
-
   O << "\n#ifdef PRINT_ALIAS_INSTR\n";
   O << "#undef PRINT_ALIAS_INSTR\n\n";
 
@@ -1000,6 +974,26 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
   O << "#endif // PRINT_ALIAS_INSTR\n";
 }
 
+AsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) {
+  Record *AsmWriter = Target.getAsmWriter();
+  for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
+                                    E = Target.inst_end();
+       I != E; ++I)
+    if (!(*I)->AsmString.empty() && (*I)->TheDef->getName() != "PHI")
+      Instructions.push_back(
+          AsmWriterInst(**I, AsmWriter->getValueAsInt("Variant"),
+                        AsmWriter->getValueAsInt("OperandSpacing")));
+
+  // Get the instruction numbering.
+  NumberedInstructions = &Target.getInstructionsByEnumValue();
+
+  // Compute the CodeGenInstruction -> AsmWriterInst mapping.  Note that not
+  // all machine instructions are necessarily being printed, so there may be
+  // target instructions not in this map.
+  for (unsigned i = 0, e = Instructions.size(); i != e; ++i)
+    CGIAWIMap.insert(std::make_pair(Instructions[i].CGI, &Instructions[i]));
+}
+
 void AsmWriterEmitter::run(raw_ostream &O) {
   EmitPrintInstruction(O);
   EmitGetRegisterName(O);