InstrInfoEmitter.cpp revision 243830
1193323Sed//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This tablegen backend is responsible for emitting a description of the target
11193323Sed// instruction set for the code generator.
12193323Sed//
13193323Sed//===----------------------------------------------------------------------===//
14193323Sed
15239462Sdim
16239462Sdim#include "CodeGenDAGPatterns.h"
17239462Sdim#include "CodeGenSchedule.h"
18193323Sed#include "CodeGenTarget.h"
19243830Sdim#include "TableGenBackends.h"
20234353Sdim#include "SequenceToOffsetTable.h"
21239462Sdim#include "llvm/ADT/StringExtras.h"
22243830Sdim#include "llvm/TableGen/Error.h"
23226633Sdim#include "llvm/TableGen/Record.h"
24239462Sdim#include "llvm/TableGen/TableGenBackend.h"
25193323Sed#include <algorithm>
26234353Sdim#include <cstdio>
27239462Sdim#include <map>
28239462Sdim#include <vector>
29193323Sedusing namespace llvm;
30193323Sed
31239462Sdimnamespace {
32239462Sdimclass InstrInfoEmitter {
33239462Sdim  RecordKeeper &Records;
34239462Sdim  CodeGenDAGPatterns CDP;
35239462Sdim  const CodeGenSchedModels &SchedModels;
36239462Sdim
37239462Sdimpublic:
38239462Sdim  InstrInfoEmitter(RecordKeeper &R):
39239462Sdim    Records(R), CDP(R), SchedModels(CDP.getTargetInfo().getSchedModels()) {}
40239462Sdim
41239462Sdim  // run - Output the instruction set description.
42239462Sdim  void run(raw_ostream &OS);
43239462Sdim
44239462Sdimprivate:
45239462Sdim  void emitEnums(raw_ostream &OS);
46239462Sdim
47239462Sdim  typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy;
48239462Sdim  void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
49239462Sdim                  Record *InstrInfo,
50239462Sdim                  std::map<std::vector<Record*>, unsigned> &EL,
51239462Sdim                  const OperandInfoMapTy &OpInfo,
52239462Sdim                  raw_ostream &OS);
53239462Sdim
54239462Sdim  // Operand information.
55239462Sdim  void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs);
56239462Sdim  std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst);
57239462Sdim};
58239462Sdim} // End anonymous namespace
59239462Sdim
60193323Sedstatic void PrintDefList(const std::vector<Record*> &Uses,
61195340Sed                         unsigned Num, raw_ostream &OS) {
62234353Sdim  OS << "static const uint16_t ImplicitList" << Num << "[] = { ";
63193323Sed  for (unsigned i = 0, e = Uses.size(); i != e; ++i)
64193323Sed    OS << getQualifiedName(Uses[i]) << ", ";
65193323Sed  OS << "0 };\n";
66193323Sed}
67193323Sed
68193323Sed//===----------------------------------------------------------------------===//
69193323Sed// Operand Info Emission.
70193323Sed//===----------------------------------------------------------------------===//
71193323Sed
72193323Sedstd::vector<std::string>
73193323SedInstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
74193323Sed  std::vector<std::string> Result;
75224145Sdim
76218893Sdim  for (unsigned i = 0, e = Inst.Operands.size(); i != e; ++i) {
77193323Sed    // Handle aggregate operands and normal operands the same way by expanding
78193323Sed    // either case into a list of operands for this op.
79218893Sdim    std::vector<CGIOperandList::OperandInfo> OperandList;
80193323Sed
81193323Sed    // This might be a multiple operand thing.  Targets like X86 have
82193323Sed    // registers in their multi-operand operands.  It may also be an anonymous
83193323Sed    // operand, which has a single operand, but no declared class for the
84193323Sed    // operand.
85218893Sdim    DagInit *MIOI = Inst.Operands[i].MIOperandInfo;
86224145Sdim
87193323Sed    if (!MIOI || MIOI->getNumArgs() == 0) {
88193323Sed      // Single, anonymous, operand.
89218893Sdim      OperandList.push_back(Inst.Operands[i]);
90193323Sed    } else {
91218893Sdim      for (unsigned j = 0, e = Inst.Operands[i].MINumOperands; j != e; ++j) {
92218893Sdim        OperandList.push_back(Inst.Operands[i]);
93193323Sed
94243830Sdim        Record *OpR = cast<DefInit>(MIOI->getArg(j))->getDef();
95193323Sed        OperandList.back().Rec = OpR;
96193323Sed      }
97193323Sed    }
98193323Sed
99193323Sed    for (unsigned j = 0, e = OperandList.size(); j != e; ++j) {
100193323Sed      Record *OpR = OperandList[j].Rec;
101193323Sed      std::string Res;
102224145Sdim
103224145Sdim      if (OpR->isSubClassOf("RegisterOperand"))
104224145Sdim        OpR = OpR->getValueAsDef("RegClass");
105193323Sed      if (OpR->isSubClassOf("RegisterClass"))
106193323Sed        Res += getQualifiedName(OpR) + "RegClassID, ";
107198090Srdivacky      else if (OpR->isSubClassOf("PointerLikeRegClass"))
108198090Srdivacky        Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", ";
109193323Sed      else
110210299Sed        // -1 means the operand does not have a fixed register class.
111210299Sed        Res += "-1, ";
112224145Sdim
113193323Sed      // Fill in applicable flags.
114193323Sed      Res += "0";
115224145Sdim
116193323Sed      // Ptr value whose register class is resolved via callback.
117198090Srdivacky      if (OpR->isSubClassOf("PointerLikeRegClass"))
118224145Sdim        Res += "|(1<<MCOI::LookupPtrRegClass)";
119193323Sed
120193323Sed      // Predicate operands.  Check to see if the original unexpanded operand
121193323Sed      // was of type PredicateOperand.
122218893Sdim      if (Inst.Operands[i].Rec->isSubClassOf("PredicateOperand"))
123224145Sdim        Res += "|(1<<MCOI::Predicate)";
124224145Sdim
125193323Sed      // Optional def operands.  Check to see if the original unexpanded operand
126193323Sed      // was of type OptionalDefOperand.
127218893Sdim      if (Inst.Operands[i].Rec->isSubClassOf("OptionalDefOperand"))
128224145Sdim        Res += "|(1<<MCOI::OptionalDef)";
129193323Sed
130234353Sdim      // Fill in operand type.
131234353Sdim      Res += ", MCOI::";
132234353Sdim      assert(!Inst.Operands[i].OperandType.empty() && "Invalid operand type.");
133234353Sdim      Res += Inst.Operands[i].OperandType;
134234353Sdim
135193323Sed      // Fill in constraint info.
136203954Srdivacky      Res += ", ";
137224145Sdim
138218893Sdim      const CGIOperandList::ConstraintInfo &Constraint =
139218893Sdim        Inst.Operands[i].Constraints[j];
140203954Srdivacky      if (Constraint.isNone())
141203954Srdivacky        Res += "0";
142203954Srdivacky      else if (Constraint.isEarlyClobber())
143224145Sdim        Res += "(1 << MCOI::EARLY_CLOBBER)";
144203954Srdivacky      else {
145203954Srdivacky        assert(Constraint.isTied());
146203954Srdivacky        Res += "((" + utostr(Constraint.getTiedOperand()) +
147224145Sdim                    " << 16) | (1 << MCOI::TIED_TO))";
148203954Srdivacky      }
149224145Sdim
150193323Sed      Result.push_back(Res);
151193323Sed    }
152193323Sed  }
153193323Sed
154193323Sed  return Result;
155193323Sed}
156193323Sed
157224145Sdimvoid InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
158193323Sed                                       OperandInfoMapTy &OperandInfoIDs) {
159193323Sed  // ID #0 is for no operand info.
160193323Sed  unsigned OperandListNum = 0;
161193323Sed  OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum;
162224145Sdim
163193323Sed  OS << "\n";
164193323Sed  const CodeGenTarget &Target = CDP.getTargetInfo();
165193323Sed  for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
166193323Sed       E = Target.inst_end(); II != E; ++II) {
167205407Srdivacky    std::vector<std::string> OperandInfo = GetOperandInfo(**II);
168193323Sed    unsigned &N = OperandInfoIDs[OperandInfo];
169193323Sed    if (N != 0) continue;
170224145Sdim
171193323Sed    N = ++OperandListNum;
172224145Sdim    OS << "static const MCOperandInfo OperandInfo" << N << "[] = { ";
173193323Sed    for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i)
174193323Sed      OS << "{ " << OperandInfo[i] << " }, ";
175193323Sed    OS << "};\n";
176193323Sed  }
177193323Sed}
178193323Sed
179193323Sed//===----------------------------------------------------------------------===//
180193323Sed// Main Output.
181193323Sed//===----------------------------------------------------------------------===//
182193323Sed
183193323Sed// run - Emit the main instruction description records for the target...
184195340Sedvoid InstrInfoEmitter::run(raw_ostream &OS) {
185239462Sdim  emitSourceFileHeader("Target Instruction Enum Values", OS);
186224145Sdim  emitEnums(OS);
187224145Sdim
188239462Sdim  emitSourceFileHeader("Target Instruction Descriptors", OS);
189193323Sed
190224145Sdim  OS << "\n#ifdef GET_INSTRINFO_MC_DESC\n";
191224145Sdim  OS << "#undef GET_INSTRINFO_MC_DESC\n";
192224145Sdim
193193323Sed  OS << "namespace llvm {\n\n";
194193323Sed
195193323Sed  CodeGenTarget &Target = CDP.getTargetInfo();
196193323Sed  const std::string &TargetName = Target.getName();
197193323Sed  Record *InstrInfo = Target.getInstructionSet();
198193323Sed
199193323Sed  // Keep track of all of the def lists we have emitted already.
200193323Sed  std::map<std::vector<Record*>, unsigned> EmittedLists;
201193323Sed  unsigned ListNumber = 0;
202224145Sdim
203193323Sed  // Emit all of the instruction's implicit uses and defs.
204193323Sed  for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
205193323Sed         E = Target.inst_end(); II != E; ++II) {
206205407Srdivacky    Record *Inst = (*II)->TheDef;
207193323Sed    std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses");
208193323Sed    if (!Uses.empty()) {
209193323Sed      unsigned &IL = EmittedLists[Uses];
210193323Sed      if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS);
211193323Sed    }
212193323Sed    std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs");
213193323Sed    if (!Defs.empty()) {
214193323Sed      unsigned &IL = EmittedLists[Defs];
215193323Sed      if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS);
216193323Sed    }
217193323Sed  }
218193323Sed
219193323Sed  OperandInfoMapTy OperandInfoIDs;
220224145Sdim
221193323Sed  // Emit all of the operand info records.
222193323Sed  EmitOperandInfo(OS, OperandInfoIDs);
223224145Sdim
224224145Sdim  // Emit all of the MCInstrDesc records in their ENUM ordering.
225193323Sed  //
226234353Sdim  OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n";
227205407Srdivacky  const std::vector<const CodeGenInstruction*> &NumberedInstructions =
228205407Srdivacky    Target.getInstructionsByEnumValue();
229193323Sed
230193323Sed  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i)
231193323Sed    emitRecord(*NumberedInstructions[i], i, InstrInfo, EmittedLists,
232224145Sdim               OperandInfoIDs, OS);
233224145Sdim  OS << "};\n\n";
234224145Sdim
235234353Sdim  // Build an array of instruction names
236234353Sdim  SequenceToOffsetTable<std::string> InstrNames;
237234353Sdim  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
238234353Sdim    const CodeGenInstruction *Instr = NumberedInstructions[i];
239234353Sdim    InstrNames.add(Instr->TheDef->getName());
240234353Sdim  }
241234353Sdim
242234353Sdim  InstrNames.layout();
243234353Sdim  OS << "extern const char " << TargetName << "InstrNameData[] = {\n";
244234353Sdim  InstrNames.emit(OS, printChar);
245234353Sdim  OS << "};\n\n";
246234353Sdim
247234353Sdim  OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {";
248234353Sdim  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
249234353Sdim    if (i % 8 == 0)
250234353Sdim      OS << "\n    ";
251234353Sdim    const CodeGenInstruction *Instr = NumberedInstructions[i];
252234353Sdim    OS << InstrNames.get(Instr->TheDef->getName()) << "U, ";
253234353Sdim  }
254234353Sdim
255234353Sdim  OS << "\n};\n\n";
256234353Sdim
257224145Sdim  // MCInstrInfo initialization routine.
258224145Sdim  OS << "static inline void Init" << TargetName
259224145Sdim     << "MCInstrInfo(MCInstrInfo *II) {\n";
260224145Sdim  OS << "  II->InitMCInstrInfo(" << TargetName << "Insts, "
261234353Sdim     << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, "
262224145Sdim     << NumberedInstructions.size() << ");\n}\n\n";
263224145Sdim
264193323Sed  OS << "} // End llvm namespace \n";
265224145Sdim
266224145Sdim  OS << "#endif // GET_INSTRINFO_MC_DESC\n\n";
267224145Sdim
268224145Sdim  // Create a TargetInstrInfo subclass to hide the MC layer initialization.
269224145Sdim  OS << "\n#ifdef GET_INSTRINFO_HEADER\n";
270224145Sdim  OS << "#undef GET_INSTRINFO_HEADER\n";
271224145Sdim
272224145Sdim  std::string ClassName = TargetName + "GenInstrInfo";
273224145Sdim  OS << "namespace llvm {\n";
274224145Sdim  OS << "struct " << ClassName << " : public TargetInstrInfoImpl {\n"
275224145Sdim     << "  explicit " << ClassName << "(int SO = -1, int DO = -1);\n"
276224145Sdim     << "};\n";
277224145Sdim  OS << "} // End llvm namespace \n";
278224145Sdim
279224145Sdim  OS << "#endif // GET_INSTRINFO_HEADER\n\n";
280224145Sdim
281224145Sdim  OS << "\n#ifdef GET_INSTRINFO_CTOR\n";
282224145Sdim  OS << "#undef GET_INSTRINFO_CTOR\n";
283224145Sdim
284224145Sdim  OS << "namespace llvm {\n";
285234353Sdim  OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n";
286234353Sdim  OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
287234353Sdim  OS << "extern const char " << TargetName << "InstrNameData[];\n";
288224145Sdim  OS << ClassName << "::" << ClassName << "(int SO, int DO)\n"
289224145Sdim     << "  : TargetInstrInfoImpl(SO, DO) {\n"
290224145Sdim     << "  InitMCInstrInfo(" << TargetName << "Insts, "
291234353Sdim     << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, "
292224145Sdim     << NumberedInstructions.size() << ");\n}\n";
293224145Sdim  OS << "} // End llvm namespace \n";
294224145Sdim
295224145Sdim  OS << "#endif // GET_INSTRINFO_CTOR\n\n";
296193323Sed}
297193323Sed
298193323Sedvoid InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
299193323Sed                                  Record *InstrInfo,
300193323Sed                         std::map<std::vector<Record*>, unsigned> &EmittedLists,
301193323Sed                                  const OperandInfoMapTy &OpInfo,
302195340Sed                                  raw_ostream &OS) {
303193323Sed  int MinOperands = 0;
304243830Sdim  if (!Inst.Operands.empty())
305193323Sed    // Each logical operand can be multiple MI operands.
306218893Sdim    MinOperands = Inst.Operands.back().MIOperandNo +
307218893Sdim                  Inst.Operands.back().MINumOperands;
308193323Sed
309193323Sed  OS << "  { ";
310193323Sed  OS << Num << ",\t" << MinOperands << ",\t"
311224145Sdim     << Inst.Operands.NumDefs << ",\t"
312243830Sdim     << SchedModels.getSchedClassIdx(Inst) << ",\t"
313234353Sdim     << Inst.TheDef->getValueAsInt("Size") << ",\t0";
314193323Sed
315193323Sed  // Emit all of the target indepedent flags...
316226633Sdim  if (Inst.isPseudo)           OS << "|(1<<MCID::Pseudo)";
317224145Sdim  if (Inst.isReturn)           OS << "|(1<<MCID::Return)";
318224145Sdim  if (Inst.isBranch)           OS << "|(1<<MCID::Branch)";
319224145Sdim  if (Inst.isIndirectBranch)   OS << "|(1<<MCID::IndirectBranch)";
320224145Sdim  if (Inst.isCompare)          OS << "|(1<<MCID::Compare)";
321224145Sdim  if (Inst.isMoveImm)          OS << "|(1<<MCID::MoveImm)";
322224145Sdim  if (Inst.isBitcast)          OS << "|(1<<MCID::Bitcast)";
323239462Sdim  if (Inst.isSelect)           OS << "|(1<<MCID::Select)";
324224145Sdim  if (Inst.isBarrier)          OS << "|(1<<MCID::Barrier)";
325224145Sdim  if (Inst.hasDelaySlot)       OS << "|(1<<MCID::DelaySlot)";
326224145Sdim  if (Inst.isCall)             OS << "|(1<<MCID::Call)";
327224145Sdim  if (Inst.canFoldAsLoad)      OS << "|(1<<MCID::FoldableAsLoad)";
328224145Sdim  if (Inst.mayLoad)            OS << "|(1<<MCID::MayLoad)";
329224145Sdim  if (Inst.mayStore)           OS << "|(1<<MCID::MayStore)";
330224145Sdim  if (Inst.isPredicable)       OS << "|(1<<MCID::Predicable)";
331224145Sdim  if (Inst.isConvertibleToThreeAddress) OS << "|(1<<MCID::ConvertibleTo3Addr)";
332224145Sdim  if (Inst.isCommutable)       OS << "|(1<<MCID::Commutable)";
333224145Sdim  if (Inst.isTerminator)       OS << "|(1<<MCID::Terminator)";
334224145Sdim  if (Inst.isReMaterializable) OS << "|(1<<MCID::Rematerializable)";
335224145Sdim  if (Inst.isNotDuplicable)    OS << "|(1<<MCID::NotDuplicable)";
336224145Sdim  if (Inst.Operands.hasOptionalDef) OS << "|(1<<MCID::HasOptionalDef)";
337224145Sdim  if (Inst.usesCustomInserter) OS << "|(1<<MCID::UsesCustomInserter)";
338226633Sdim  if (Inst.hasPostISelHook)    OS << "|(1<<MCID::HasPostISelHook)";
339224145Sdim  if (Inst.Operands.isVariadic)OS << "|(1<<MCID::Variadic)";
340224145Sdim  if (Inst.hasSideEffects)     OS << "|(1<<MCID::UnmodeledSideEffects)";
341224145Sdim  if (Inst.isAsCheapAsAMove)   OS << "|(1<<MCID::CheapAsAMove)";
342224145Sdim  if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<MCID::ExtraSrcRegAllocReq)";
343224145Sdim  if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<MCID::ExtraDefRegAllocReq)";
344193323Sed
345193323Sed  // Emit all of the target-specific flags...
346206274Srdivacky  BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");
347243830Sdim  if (!TSF)
348243830Sdim    PrintFatalError("no TSFlags?");
349206274Srdivacky  uint64_t Value = 0;
350206274Srdivacky  for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) {
351243830Sdim    if (BitInit *Bit = dyn_cast<BitInit>(TSF->getBit(i)))
352206274Srdivacky      Value |= uint64_t(Bit->getValue()) << i;
353206274Srdivacky    else
354243830Sdim      PrintFatalError("Invalid TSFlags bit in " + Inst.TheDef->getName());
355206274Srdivacky  }
356206274Srdivacky  OS << ", 0x";
357206274Srdivacky  OS.write_hex(Value);
358210299Sed  OS << "ULL, ";
359193323Sed
360193323Sed  // Emit the implicit uses and defs lists...
361193323Sed  std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses");
362193323Sed  if (UseList.empty())
363193323Sed    OS << "NULL, ";
364193323Sed  else
365193323Sed    OS << "ImplicitList" << EmittedLists[UseList] << ", ";
366193323Sed
367193323Sed  std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs");
368193323Sed  if (DefList.empty())
369193323Sed    OS << "NULL, ";
370193323Sed  else
371193323Sed    OS << "ImplicitList" << EmittedLists[DefList] << ", ";
372193323Sed
373193323Sed  // Emit the operand info.
374193323Sed  std::vector<std::string> OperandInfo = GetOperandInfo(Inst);
375193323Sed  if (OperandInfo.empty())
376193323Sed    OS << "0";
377193323Sed  else
378193323Sed    OS << "OperandInfo" << OpInfo.find(OperandInfo)->second;
379206274Srdivacky
380193323Sed  OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
381193323Sed}
382224145Sdim
383224145Sdim// emitEnums - Print out enum values for all of the instructions.
384224145Sdimvoid InstrInfoEmitter::emitEnums(raw_ostream &OS) {
385224145Sdim
386224145Sdim  OS << "\n#ifdef GET_INSTRINFO_ENUM\n";
387224145Sdim  OS << "#undef GET_INSTRINFO_ENUM\n";
388224145Sdim
389224145Sdim  OS << "namespace llvm {\n\n";
390224145Sdim
391224145Sdim  CodeGenTarget Target(Records);
392224145Sdim
393224145Sdim  // We must emit the PHI opcode first...
394224145Sdim  std::string Namespace = Target.getInstNamespace();
395234353Sdim
396224145Sdim  if (Namespace.empty()) {
397224145Sdim    fprintf(stderr, "No instructions defined!\n");
398224145Sdim    exit(1);
399224145Sdim  }
400224145Sdim
401224145Sdim  const std::vector<const CodeGenInstruction*> &NumberedInstructions =
402224145Sdim    Target.getInstructionsByEnumValue();
403224145Sdim
404224145Sdim  OS << "namespace " << Namespace << " {\n";
405224145Sdim  OS << "  enum {\n";
406224145Sdim  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
407224145Sdim    OS << "    " << NumberedInstructions[i]->TheDef->getName()
408224145Sdim       << "\t= " << i << ",\n";
409224145Sdim  }
410224145Sdim  OS << "    INSTRUCTION_LIST_END = " << NumberedInstructions.size() << "\n";
411224145Sdim  OS << "  };\n}\n";
412224145Sdim  OS << "} // End llvm namespace \n";
413224145Sdim
414224145Sdim  OS << "#endif // GET_INSTRINFO_ENUM\n\n";
415224145Sdim}
416239462Sdim
417239462Sdimnamespace llvm {
418239462Sdim
419239462Sdimvoid EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) {
420239462Sdim  InstrInfoEmitter(RK).run(OS);
421243830Sdim  EmitMapTable(RK, OS);
422239462Sdim}
423239462Sdim
424239462Sdim} // End llvm namespace
425