SubtargetFeatureInfo.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. //===- SubtargetFeatureInfo.cpp - Helpers for subtarget features ----------===//
  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. #include "SubtargetFeatureInfo.h"
  9. #include "Types.h"
  10. #include "llvm/Config/llvm-config.h"
  11. #include "llvm/TableGen/Error.h"
  12. #include "llvm/TableGen/Record.h"
  13. #include <map>
  14. using namespace llvm;
  15. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  16. LLVM_DUMP_METHOD void SubtargetFeatureInfo::dump() const {
  17. errs() << getEnumName() << " " << Index << "\n" << *TheDef;
  18. }
  19. #endif
  20. std::vector<std::pair<Record *, SubtargetFeatureInfo>>
  21. SubtargetFeatureInfo::getAll(const RecordKeeper &Records) {
  22. std::vector<std::pair<Record *, SubtargetFeatureInfo>> SubtargetFeatures;
  23. std::vector<Record *> AllPredicates =
  24. Records.getAllDerivedDefinitions("Predicate");
  25. for (Record *Pred : AllPredicates) {
  26. // Ignore predicates that are not intended for the assembler.
  27. //
  28. // The "AssemblerMatcherPredicate" string should be promoted to an argument
  29. // if we re-use the machinery for non-assembler purposes in future.
  30. if (!Pred->getValueAsBit("AssemblerMatcherPredicate"))
  31. continue;
  32. if (Pred->getName().empty())
  33. PrintFatalError(Pred->getLoc(), "Predicate has no name!");
  34. // Ignore always true predicates.
  35. if (Pred->getValueAsString("CondString").empty())
  36. continue;
  37. SubtargetFeatures.emplace_back(
  38. Pred, SubtargetFeatureInfo(Pred, SubtargetFeatures.size()));
  39. }
  40. return SubtargetFeatures;
  41. }
  42. void SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(
  43. SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
  44. OS << "// Bits for subtarget features that participate in "
  45. << "instruction matching.\n";
  46. OS << "enum SubtargetFeatureBits : "
  47. << getMinimalTypeForRange(SubtargetFeatures.size()) << " {\n";
  48. for (const auto &SF : SubtargetFeatures) {
  49. const SubtargetFeatureInfo &SFI = SF.second;
  50. OS << " " << SFI.getEnumBitName() << " = " << SFI.Index << ",\n";
  51. }
  52. OS << "};\n\n";
  53. }
  54. void SubtargetFeatureInfo::emitNameTable(
  55. SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
  56. // Need to sort the name table so that lookup by the log of the enum value
  57. // gives the proper name. More specifically, for a feature of value 1<<n,
  58. // SubtargetFeatureNames[n] should be the name of the feature.
  59. uint64_t IndexUB = 0;
  60. for (const auto &SF : SubtargetFeatures)
  61. if (IndexUB <= SF.second.Index)
  62. IndexUB = SF.second.Index+1;
  63. std::vector<std::string> Names;
  64. if (IndexUB > 0)
  65. Names.resize(IndexUB);
  66. for (const auto &SF : SubtargetFeatures)
  67. Names[SF.second.Index] = SF.second.getEnumName();
  68. OS << "static const char *SubtargetFeatureNames[] = {\n";
  69. for (uint64_t I = 0; I < IndexUB; ++I)
  70. OS << " \"" << Names[I] << "\",\n";
  71. // A small number of targets have no predicates. Null terminate the array to
  72. // avoid a zero-length array.
  73. OS << " nullptr\n"
  74. << "};\n\n";
  75. }
  76. void SubtargetFeatureInfo::emitComputeAvailableFeatures(
  77. StringRef TargetName, StringRef ClassName, StringRef FuncName,
  78. SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS,
  79. StringRef ExtraParams) {
  80. OS << "PredicateBitset " << TargetName << ClassName << "::\n"
  81. << FuncName << "(const " << TargetName << "Subtarget *Subtarget";
  82. if (!ExtraParams.empty())
  83. OS << ", " << ExtraParams;
  84. OS << ") const {\n";
  85. OS << " PredicateBitset Features;\n";
  86. for (const auto &SF : SubtargetFeatures) {
  87. const SubtargetFeatureInfo &SFI = SF.second;
  88. StringRef CondStr = SFI.TheDef->getValueAsString("CondString");
  89. assert(!CondStr.empty() && "true predicate should have been filtered");
  90. OS << " if (" << CondStr << ")\n";
  91. OS << " Features.set(" << SFI.getEnumBitName() << ");\n";
  92. }
  93. OS << " return Features;\n";
  94. OS << "}\n\n";
  95. }
  96. // If ParenIfBinOp is true, print a surrounding () if Val uses && or ||.
  97. static bool emitFeaturesAux(StringRef TargetName, const Init &Val,
  98. bool ParenIfBinOp, raw_ostream &OS) {
  99. if (auto *D = dyn_cast<DefInit>(&Val)) {
  100. if (!D->getDef()->isSubClassOf("SubtargetFeature"))
  101. return true;
  102. OS << "FB[" << TargetName << "::" << D->getAsString() << "]";
  103. return false;
  104. }
  105. if (auto *D = dyn_cast<DagInit>(&Val)) {
  106. std::string Op = D->getOperator()->getAsString();
  107. if (Op == "not" && D->getNumArgs() == 1) {
  108. OS << '!';
  109. return emitFeaturesAux(TargetName, *D->getArg(0), true, OS);
  110. }
  111. if ((Op == "any_of" || Op == "all_of") && D->getNumArgs() > 0) {
  112. bool Paren = D->getNumArgs() > 1 && std::exchange(ParenIfBinOp, true);
  113. if (Paren)
  114. OS << '(';
  115. ListSeparator LS(Op == "any_of" ? " || " : " && ");
  116. for (auto *Arg : D->getArgs()) {
  117. OS << LS;
  118. if (emitFeaturesAux(TargetName, *Arg, ParenIfBinOp, OS))
  119. return true;
  120. }
  121. if (Paren)
  122. OS << ')';
  123. return false;
  124. }
  125. }
  126. return true;
  127. }
  128. void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
  129. StringRef TargetName, StringRef ClassName, StringRef FuncName,
  130. SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
  131. OS << "FeatureBitset ";
  132. if (!ClassName.empty())
  133. OS << TargetName << ClassName << "::\n";
  134. OS << FuncName << "(const FeatureBitset &FB) ";
  135. if (!ClassName.empty())
  136. OS << "const ";
  137. OS << "{\n";
  138. OS << " FeatureBitset Features;\n";
  139. for (const auto &SF : SubtargetFeatures) {
  140. const SubtargetFeatureInfo &SFI = SF.second;
  141. OS << " if (";
  142. emitFeaturesAux(TargetName, *SFI.TheDef->getValueAsDag("AssemblerCondDag"),
  143. /*ParenIfBinOp=*/false, OS);
  144. OS << ")\n";
  145. OS << " Features.set(" << SFI.getEnumBitName() << ");\n";
  146. }
  147. OS << " return Features;\n";
  148. OS << "}\n\n";
  149. }