InstrDocsEmitter.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. //===- InstrDocsEmitter.cpp - Opcode Documentation Generator --------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // InstrDocsEmitter generates restructured text documentation for the opcodes
  10. // that can be used by MachineInstr. For each opcode, the documentation lists:
  11. // * Opcode name
  12. // * Assembly string
  13. // * Flags (e.g. mayLoad, isBranch, ...)
  14. // * Operands, including type and name
  15. // * Operand constraints
  16. // * Implicit register uses & defs
  17. // * Predicates
  18. //
  19. //===----------------------------------------------------------------------===//
  20. #include "CodeGenDAGPatterns.h"
  21. #include "CodeGenInstruction.h"
  22. #include "CodeGenTarget.h"
  23. #include "TableGenBackends.h"
  24. #include "llvm/TableGen/Record.h"
  25. #include <string>
  26. #include <vector>
  27. using namespace llvm;
  28. namespace llvm {
  29. void writeTitle(StringRef Str, raw_ostream &OS, char Kind = '-') {
  30. OS << std::string(Str.size(), Kind) << "\n" << Str << "\n"
  31. << std::string(Str.size(), Kind) << "\n";
  32. }
  33. void writeHeader(StringRef Str, raw_ostream &OS, char Kind = '-') {
  34. OS << Str << "\n" << std::string(Str.size(), Kind) << "\n";
  35. }
  36. std::string escapeForRST(StringRef Str) {
  37. std::string Result;
  38. Result.reserve(Str.size() + 4);
  39. for (char C : Str) {
  40. switch (C) {
  41. // We want special characters to be shown as their C escape codes.
  42. case '\n': Result += "\\n"; break;
  43. case '\t': Result += "\\t"; break;
  44. // Underscore at the end of a line has a special meaning in rst.
  45. case '_': Result += "\\_"; break;
  46. default: Result += C;
  47. }
  48. }
  49. return Result;
  50. }
  51. void EmitInstrDocs(RecordKeeper &RK, raw_ostream &OS) {
  52. CodeGenDAGPatterns CDP(RK);
  53. CodeGenTarget &Target = CDP.getTargetInfo();
  54. unsigned VariantCount = Target.getAsmParserVariantCount();
  55. // Page title.
  56. std::string Title = std::string(Target.getName());
  57. Title += " Instructions";
  58. writeTitle(Title, OS);
  59. OS << "\n";
  60. for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) {
  61. Record *Inst = II->TheDef;
  62. // Don't print the target-independent instructions.
  63. if (II->Namespace == "TargetOpcode")
  64. continue;
  65. // Heading (instruction name).
  66. writeHeader(escapeForRST(Inst->getName()), OS, '=');
  67. OS << "\n";
  68. // Assembly string(s).
  69. if (!II->AsmString.empty()) {
  70. for (unsigned VarNum = 0; VarNum < VariantCount; ++VarNum) {
  71. Record *AsmVariant = Target.getAsmParserVariant(VarNum);
  72. OS << "Assembly string";
  73. if (VariantCount != 1)
  74. OS << " (" << AsmVariant->getValueAsString("Name") << ")";
  75. std::string AsmString =
  76. CodeGenInstruction::FlattenAsmStringVariants(II->AsmString, VarNum);
  77. // We trim spaces at each end of the asm string because rst needs the
  78. // formatting backticks to be next to a non-whitespace character.
  79. OS << ": ``" << escapeForRST(StringRef(AsmString).trim(" "))
  80. << "``\n\n";
  81. }
  82. }
  83. // Boolean flags.
  84. std::vector<const char *> FlagStrings;
  85. #define xstr(s) str(s)
  86. #define str(s) #s
  87. #define FLAG(f) if (II->f) { FlagStrings.push_back(str(f)); }
  88. FLAG(isReturn)
  89. FLAG(isEHScopeReturn)
  90. FLAG(isBranch)
  91. FLAG(isIndirectBranch)
  92. FLAG(isCompare)
  93. FLAG(isMoveImm)
  94. FLAG(isBitcast)
  95. FLAG(isSelect)
  96. FLAG(isBarrier)
  97. FLAG(isCall)
  98. FLAG(isAdd)
  99. FLAG(isTrap)
  100. FLAG(canFoldAsLoad)
  101. FLAG(mayLoad)
  102. //FLAG(mayLoad_Unset) // Deliberately omitted.
  103. FLAG(mayStore)
  104. //FLAG(mayStore_Unset) // Deliberately omitted.
  105. FLAG(isPredicable)
  106. FLAG(isConvertibleToThreeAddress)
  107. FLAG(isCommutable)
  108. FLAG(isTerminator)
  109. FLAG(isReMaterializable)
  110. FLAG(hasDelaySlot)
  111. FLAG(usesCustomInserter)
  112. FLAG(hasPostISelHook)
  113. FLAG(hasCtrlDep)
  114. FLAG(isNotDuplicable)
  115. FLAG(hasSideEffects)
  116. //FLAG(hasSideEffects_Unset) // Deliberately omitted.
  117. FLAG(isAsCheapAsAMove)
  118. FLAG(hasExtraSrcRegAllocReq)
  119. FLAG(hasExtraDefRegAllocReq)
  120. FLAG(isCodeGenOnly)
  121. FLAG(isPseudo)
  122. FLAG(isRegSequence)
  123. FLAG(isExtractSubreg)
  124. FLAG(isInsertSubreg)
  125. FLAG(isConvergent)
  126. FLAG(hasNoSchedulingInfo)
  127. FLAG(variadicOpsAreDefs)
  128. FLAG(isAuthenticated)
  129. if (!FlagStrings.empty()) {
  130. OS << "Flags: ";
  131. ListSeparator LS;
  132. for (auto FlagString : FlagStrings)
  133. OS << LS << "``" << FlagString << "``";
  134. OS << "\n\n";
  135. }
  136. // Operands.
  137. for (unsigned i = 0; i < II->Operands.size(); ++i) {
  138. bool IsDef = i < II->Operands.NumDefs;
  139. auto Op = II->Operands[i];
  140. if (Op.MINumOperands > 1) {
  141. // This operand corresponds to multiple operands on the
  142. // MachineInstruction, so print all of them, showing the types and
  143. // names of both the compound operand and the basic operands it
  144. // contains.
  145. for (unsigned SubOpIdx = 0; SubOpIdx < Op.MINumOperands; ++SubOpIdx) {
  146. Record *SubRec =
  147. cast<DefInit>(Op.MIOperandInfo->getArg(SubOpIdx))->getDef();
  148. StringRef SubOpName = Op.MIOperandInfo->getArgNameStr(SubOpIdx);
  149. StringRef SubOpTypeName = SubRec->getName();
  150. OS << "* " << (IsDef ? "DEF" : "USE") << " ``" << Op.Rec->getName()
  151. << "/" << SubOpTypeName << ":$" << Op.Name << ".";
  152. // Not all sub-operands are named, make up a name for these.
  153. if (SubOpName.empty())
  154. OS << "anon" << SubOpIdx;
  155. else
  156. OS << SubOpName;
  157. OS << "``\n\n";
  158. }
  159. } else {
  160. // The operand corresponds to only one MachineInstruction operand.
  161. OS << "* " << (IsDef ? "DEF" : "USE") << " ``" << Op.Rec->getName()
  162. << ":$" << Op.Name << "``\n\n";
  163. }
  164. }
  165. // Constraints.
  166. StringRef Constraints = Inst->getValueAsString("Constraints");
  167. if (!Constraints.empty()) {
  168. OS << "Constraints: ``" << Constraints << "``\n\n";
  169. }
  170. // Implicit definitions.
  171. if (!II->ImplicitDefs.empty()) {
  172. OS << "Implicit defs: ";
  173. ListSeparator LS;
  174. for (Record *Def : II->ImplicitDefs)
  175. OS << LS << "``" << Def->getName() << "``";
  176. OS << "\n\n";
  177. }
  178. // Implicit uses.
  179. if (!II->ImplicitUses.empty()) {
  180. OS << "Implicit uses: ";
  181. ListSeparator LS;
  182. for (Record *Use : II->ImplicitUses)
  183. OS << LS << "``" << Use->getName() << "``";
  184. OS << "\n\n";
  185. }
  186. // Predicates.
  187. std::vector<Record *> Predicates =
  188. II->TheDef->getValueAsListOfDefs("Predicates");
  189. if (!Predicates.empty()) {
  190. OS << "Predicates: ";
  191. ListSeparator LS;
  192. for (Record *P : Predicates)
  193. OS << LS << "``" << P->getName() << "``";
  194. OS << "\n\n";
  195. }
  196. }
  197. }
  198. } // end namespace llvm