SubtargetFeatureInfo.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
  97. StringRef TargetName, StringRef ClassName, StringRef FuncName,
  98. SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
  99. OS << "FeatureBitset " << TargetName << ClassName << "::\n"
  100. << FuncName << "(const FeatureBitset &FB) const {\n";
  101. OS << " FeatureBitset Features;\n";
  102. for (const auto &SF : SubtargetFeatures) {
  103. const SubtargetFeatureInfo &SFI = SF.second;
  104. OS << " if (";
  105. const DagInit *D = SFI.TheDef->getValueAsDag("AssemblerCondDag");
  106. std::string CombineType = D->getOperator()->getAsString();
  107. if (CombineType != "any_of" && CombineType != "all_of")
  108. PrintFatalError(SFI.TheDef->getLoc(), "Invalid AssemblerCondDag!");
  109. if (D->getNumArgs() == 0)
  110. PrintFatalError(SFI.TheDef->getLoc(), "Invalid AssemblerCondDag!");
  111. bool IsOr = CombineType == "any_of";
  112. if (IsOr)
  113. OS << "(";
  114. ListSeparator LS(IsOr ? " || " : " && ");
  115. for (auto *Arg : D->getArgs()) {
  116. OS << LS;
  117. if (auto *NotArg = dyn_cast<DagInit>(Arg)) {
  118. if (NotArg->getOperator()->getAsString() != "not" ||
  119. NotArg->getNumArgs() != 1)
  120. PrintFatalError(SFI.TheDef->getLoc(), "Invalid AssemblerCondDag!");
  121. Arg = NotArg->getArg(0);
  122. OS << "!";
  123. }
  124. if (!isa<DefInit>(Arg) ||
  125. !cast<DefInit>(Arg)->getDef()->isSubClassOf("SubtargetFeature"))
  126. PrintFatalError(SFI.TheDef->getLoc(), "Invalid AssemblerCondDag!");
  127. OS << "FB[" << TargetName << "::" << Arg->getAsString() << "]";
  128. }
  129. if (IsOr)
  130. OS << ")";
  131. OS << ")\n";
  132. OS << " Features.set(" << SFI.getEnumBitName() << ");\n";
  133. }
  134. OS << " return Features;\n";
  135. OS << "}\n\n";
  136. }