Attributes.cpp 4.2 KB

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