Attributes.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //===- Attributes.cpp - Generate attributes -------------------------------===//
  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 "llvm/TableGen/Record.h"
  9. #include <vector>
  10. using namespace llvm;
  11. #define DEBUG_TYPE "attr-enum"
  12. namespace {
  13. class Attributes {
  14. public:
  15. Attributes(RecordKeeper &R) : Records(R) {}
  16. void emit(raw_ostream &OS);
  17. private:
  18. void emitTargetIndependentNames(raw_ostream &OS);
  19. void emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr);
  20. void emitAttributeProperties(raw_ostream &OF);
  21. RecordKeeper &Records;
  22. };
  23. } // End anonymous namespace.
  24. void Attributes::emitTargetIndependentNames(raw_ostream &OS) {
  25. OS << "#ifdef GET_ATTR_NAMES\n";
  26. OS << "#undef GET_ATTR_NAMES\n";
  27. OS << "#ifndef ATTRIBUTE_ALL\n";
  28. OS << "#define ATTRIBUTE_ALL(FIRST, SECOND)\n";
  29. OS << "#endif\n\n";
  30. auto Emit = [&](ArrayRef<StringRef> KindNames, StringRef MacroName) {
  31. OS << "#ifndef " << MacroName << "\n";
  32. OS << "#define " << MacroName
  33. << "(FIRST, SECOND) ATTRIBUTE_ALL(FIRST, SECOND)\n";
  34. OS << "#endif\n\n";
  35. for (StringRef KindName : KindNames) {
  36. for (auto *A : Records.getAllDerivedDefinitions(KindName)) {
  37. OS << MacroName << "(" << A->getName() << ","
  38. << A->getValueAsString("AttrString") << ")\n";
  39. }
  40. }
  41. OS << "#undef " << MacroName << "\n\n";
  42. };
  43. // Emit attribute enums in the same order llvm::Attribute::operator< expects.
  44. Emit({"EnumAttr", "TypeAttr", "IntAttr"}, "ATTRIBUTE_ENUM");
  45. Emit({"StrBoolAttr"}, "ATTRIBUTE_STRBOOL");
  46. OS << "#undef ATTRIBUTE_ALL\n";
  47. OS << "#endif\n\n";
  48. OS << "#ifdef GET_ATTR_ENUM\n";
  49. OS << "#undef GET_ATTR_ENUM\n";
  50. unsigned Value = 1; // Leave zero for AttrKind::None.
  51. for (StringRef KindName : {"EnumAttr", "TypeAttr", "IntAttr"}) {
  52. OS << "First" << KindName << " = " << Value << ",\n";
  53. for (auto *A : Records.getAllDerivedDefinitions(KindName)) {
  54. OS << A->getName() << " = " << Value << ",\n";
  55. Value++;
  56. }
  57. OS << "Last" << KindName << " = " << (Value - 1) << ",\n";
  58. }
  59. OS << "#endif\n\n";
  60. }
  61. void Attributes::emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr) {
  62. OS << "#ifdef GET_ATTR_COMPAT_FUNC\n";
  63. OS << "#undef GET_ATTR_COMPAT_FUNC\n";
  64. OS << "static inline bool hasCompatibleFnAttrs(const Function &Caller,\n"
  65. << " const Function &Callee) {\n";
  66. OS << " bool Ret = true;\n\n";
  67. std::vector<Record *> CompatRules =
  68. Records.getAllDerivedDefinitions("CompatRule");
  69. for (auto *Rule : CompatRules) {
  70. StringRef FuncName = Rule->getValueAsString("CompatFunc");
  71. OS << " Ret &= " << FuncName << "(Caller, Callee);\n";
  72. }
  73. OS << "\n";
  74. OS << " return Ret;\n";
  75. OS << "}\n\n";
  76. std::vector<Record *> MergeRules =
  77. Records.getAllDerivedDefinitions("MergeRule");
  78. OS << "static inline void mergeFnAttrs(Function &Caller,\n"
  79. << " const Function &Callee) {\n";
  80. for (auto *Rule : MergeRules) {
  81. StringRef FuncName = Rule->getValueAsString("MergeFunc");
  82. OS << " " << FuncName << "(Caller, Callee);\n";
  83. }
  84. OS << "}\n\n";
  85. OS << "#endif\n";
  86. }
  87. void Attributes::emitAttributeProperties(raw_ostream &OS) {
  88. OS << "#ifdef GET_ATTR_PROP_TABLE\n";
  89. OS << "#undef GET_ATTR_PROP_TABLE\n";
  90. OS << "static const uint8_t AttrPropTable[] = {\n";
  91. for (StringRef KindName : {"EnumAttr", "TypeAttr", "IntAttr"}) {
  92. for (auto *A : Records.getAllDerivedDefinitions(KindName)) {
  93. OS << "0";
  94. for (Init *P : *A->getValueAsListInit("Properties"))
  95. OS << " | AttributeProperty::" << cast<DefInit>(P)->getDef()->getName();
  96. OS << ",\n";
  97. }
  98. }
  99. OS << "};\n";
  100. OS << "#endif\n";
  101. }
  102. void Attributes::emit(raw_ostream &OS) {
  103. emitTargetIndependentNames(OS);
  104. emitFnAttrCompatCheck(OS, false);
  105. emitAttributeProperties(OS);
  106. }
  107. namespace llvm {
  108. void EmitAttributes(RecordKeeper &RK, raw_ostream &OS) {
  109. Attributes(RK).emit(OS);
  110. }
  111. } // End llvm namespace.