[NFC] Refactor TableGen for attributes
authorTyker <tyker1@outlook.com>
Sun, 2 Feb 2020 13:46:50 +0000 (14:46 +0100)
committerTyker <tyker1@outlook.com>
Sun, 2 Feb 2020 13:50:31 +0000 (14:50 +0100)
Summary:
this patch makes tablegen generate llvm attributes in a more generic and simpler (at least to me).

changes:  make tablegen generate
...
ATTRIBUTE_ENUM(Alignment,align)
ATTRIBUTE_ENUM(AllocSize,allocsize)
...
which can be used to generate most of what was previously used and more.

Tablegen was also generating attributes from 2 identical files leading to identical output. so I removed one of them and made user use the other.

Reviewers: jdoerfert, thakis, aaron.ballman

Reviewed By: aaron.ballman

Subscribers: mgorny, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D72455

llvm/include/llvm/IR/Attributes.h
llvm/lib/IR/Attributes.cpp
llvm/lib/IR/AttributesCompatFunc.td [deleted file]
llvm/lib/IR/CMakeLists.txt
llvm/lib/IR/Core.cpp
llvm/utils/TableGen/Attributes.cpp

index 619c1f0..cb4b5b7 100644 (file)
@@ -70,7 +70,8 @@ public:
   enum AttrKind {
     // IR-Level Attributes
     None,                  ///< No attributes have been set
-    #define GET_ATTR_ENUM
+    #define GET_ATTR_NAMES
+    #define ATTRIBUTE_ENUM(ENUM_NAME, OTHER) ENUM_NAME,
     #include "llvm/IR/Attributes.inc"
     EndAttrKinds           ///< Sentinal value useful for loops
   };
index efc7168..b184aca 100644 (file)
@@ -1850,8 +1850,49 @@ adjustNullPointerValidAttr(Function &Caller, const Function &Callee) {
   }
 }
 
+struct EnumAttr {
+  static bool isSet(const Function &Fn,
+                    Attribute::AttrKind Kind) {
+    return Fn.hasFnAttribute(Kind);
+  }
+
+  static void set(Function &Fn,
+                  Attribute::AttrKind Kind, bool Val) {
+    if (Val)
+      Fn.addFnAttr(Kind);
+    else
+      Fn.removeFnAttr(Kind);
+  }
+};
+
+struct StrBoolAttr {
+  static bool isSet(const Function &Fn,
+                    StringRef Kind) {
+    auto A = Fn.getFnAttribute(Kind);
+    return A.getValueAsString().equals("true");
+  }
+
+  static void set(Function &Fn,
+                  StringRef Kind, bool Val) {
+    Fn.addFnAttr(Kind, Val ? "true" : "false");
+  }
+};
+
+#define GET_ATTR_NAMES
+#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME)                                \
+  struct ENUM_NAME##Attr : EnumAttr {                                          \
+    static enum Attribute::AttrKind getKind() {                                \
+      return llvm::Attribute::ENUM_NAME;                                       \
+    }                                                                          \
+  };
+#define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME)                             \
+  struct ENUM_NAME##Attr : StrBoolAttr {                                       \
+    static StringRef getKind() { return #DISPLAY_NAME; }                       \
+  };
+#include "llvm/IR/Attributes.inc"
+
 #define GET_ATTR_COMPAT_FUNC
-#include "AttributesCompatFunc.inc"
+#include "llvm/IR/Attributes.inc"
 
 bool AttributeFuncs::areInlineCompatible(const Function &Caller,
                                          const Function &Callee) {
diff --git a/llvm/lib/IR/AttributesCompatFunc.td b/llvm/lib/IR/AttributesCompatFunc.td
deleted file mode 100644 (file)
index 7c85b3d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-include "llvm/IR/Attributes.td"
index b1fe5e1..1a36acd 100644 (file)
@@ -1,7 +1,3 @@
-set(LLVM_TARGET_DEFINITIONS AttributesCompatFunc.td)
-tablegen(LLVM AttributesCompatFunc.inc -gen-attrs)
-add_public_tablegen_target(AttributeCompatFuncTableGen)
-
 add_llvm_component_library(LLVMCore
   AbstractCallSite.cpp
   AsmWriter.cpp
index 04e34a9..11deab8 100644 (file)
@@ -127,8 +127,14 @@ unsigned LLVMGetMDKindID(const char *Name, unsigned SLen) {
   return LLVMGetMDKindIDInContext(LLVMGetGlobalContext(), Name, SLen);
 }
 
-#define GET_ATTR_KIND_FROM_NAME
-#include "AttributesCompatFunc.inc"
+static Attribute::AttrKind getAttrKindFromName(StringRef AttrName) {
+  return StringSwitch<Attribute::AttrKind>(AttrName)
+#define GET_ATTR_NAMES
+#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME)                                \
+  .Case(#DISPLAY_NAME, Attribute::ENUM_NAME)
+#include "llvm/IR/Attributes.inc"
+      .Default(Attribute::None);
+}
 
 unsigned LLVMGetEnumAttributeKindForName(const char *Name, size_t SLen) {
   return getAttrKindFromName(StringRef(Name, SLen));
index 6fbc595..b784f53 100644 (file)
@@ -23,51 +23,41 @@ public:
   void emit(raw_ostream &OS);
 
 private:
-  void emitTargetIndependentEnums(raw_ostream &OS);
-  void emitConversionFn(raw_ostream &OS);
+  void emitTargetIndependentNames(raw_ostream &OS);
   void emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr);
 
-  void printEnumAttrClasses(raw_ostream &OS,
-                            const std::vector<Record *> &Records);
-  void printStrBoolAttrClasses(raw_ostream &OS,
-                               const std::vector<Record *> &Records);
-
   RecordKeeper &Records;
 };
 
 } // End anonymous namespace.
 
-void Attributes::emitTargetIndependentEnums(raw_ostream &OS) {
-  OS << "#ifdef GET_ATTR_ENUM\n";
-  OS << "#undef GET_ATTR_ENUM\n";
+void Attributes::emitTargetIndependentNames(raw_ostream &OS) {
+  OS << "#ifdef GET_ATTR_NAMES\n";
+  OS << "#undef GET_ATTR_NAMES\n";
 
-  std::vector<Record*> Attrs =
-      Records.getAllDerivedDefinitions("EnumAttr");
+  OS << "#ifndef ATTRIBUTE_ALL\n";
+  OS << "#define ATTRIBUTE_ALL(FIRST, SECOND)\n";
+  OS << "#endif\n\n";
 
-  for (auto A : Attrs)
-    OS << A->getName() << ",\n";
+  auto Emiter = [&](StringRef KindName, StringRef MacroName) {
+    std::vector<Record *> Attrs = Records.getAllDerivedDefinitions(KindName);
 
-  OS << "#endif\n";
-}
+    OS << "#ifndef " << MacroName << "\n";
+    OS << "#define " << MacroName << "(FIRST, SECOND) ATTRIBUTE_ALL(FIRST, "
+          "SECOND)\n";
+    OS << "#endif\n\n";
 
-void Attributes::emitConversionFn(raw_ostream &OS) {
-  OS << "#ifdef GET_ATTR_KIND_FROM_NAME\n";
-  OS << "#undef GET_ATTR_KIND_FROM_NAME\n";
+    for (auto A : Attrs) {
+      OS << "" << MacroName << "(" << A->getName() << ","
+         << A->getValueAsString("AttrString") << ")\n";
+    }
+    OS << "#undef " << MacroName << "\n\n";
+  };
 
-  std::vector<Record*> Attrs =
-      Records.getAllDerivedDefinitions("EnumAttr");
-
-  OS << "static Attribute::AttrKind getAttrKindFromName(StringRef AttrName) {\n";
-  OS << "  return StringSwitch<Attribute::AttrKind>(AttrName)\n";
-
-  for (auto A : Attrs) {
-    OS << "    .Case(\"" << A->getValueAsString("AttrString");
-    OS << "\", Attribute::" << A->getName() << ")\n";
-  }
-
-  OS << "    .Default(Attribute::None);\n";
-  OS << "}\n\n";
+  Emiter("EnumAttr", "ATTRIBUTE_ENUM");
+  Emiter("StrBoolAttr", "ATTRIBUTE_STRBOOL");
 
+  OS << "#undef ATTRIBUTE_ALL\n";
   OS << "#endif\n";
 }
 
@@ -75,35 +65,6 @@ void Attributes::emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr) {
   OS << "#ifdef GET_ATTR_COMPAT_FUNC\n";
   OS << "#undef GET_ATTR_COMPAT_FUNC\n";
 
-  OS << "struct EnumAttr {\n";
-  OS << "  static bool isSet(const Function &Fn,\n";
-  OS << "                    Attribute::AttrKind Kind) {\n";
-  OS << "    return Fn.hasFnAttribute(Kind);\n";
-  OS << "  }\n\n";
-  OS << "  static void set(Function &Fn,\n";
-  OS << "                  Attribute::AttrKind Kind, bool Val) {\n";
-  OS << "    if (Val)\n";
-  OS << "      Fn.addFnAttr(Kind);\n";
-  OS << "    else\n";
-  OS << "      Fn.removeFnAttr(Kind);\n";
-  OS << "  }\n";
-  OS << "};\n\n";
-
-  OS << "struct StrBoolAttr {\n";
-  OS << "  static bool isSet(const Function &Fn,\n";
-  OS << "                    StringRef Kind) {\n";
-  OS << "    auto A = Fn.getFnAttribute(Kind);\n";
-  OS << "    return A.getValueAsString().equals(\"true\");\n";
-  OS << "  }\n\n";
-  OS << "  static void set(Function &Fn,\n";
-  OS << "                  StringRef Kind, bool Val) {\n";
-  OS << "    Fn.addFnAttr(Kind, Val ? \"true\" : \"false\");\n";
-  OS << "  }\n";
-  OS << "};\n\n";
-
-  printEnumAttrClasses(OS ,Records.getAllDerivedDefinitions("EnumAttr"));
-  printStrBoolAttrClasses(OS , Records.getAllDerivedDefinitions("StrBoolAttr"));
-
   OS << "static inline bool hasCompatibleFnAttrs(const Function &Caller,\n"
      << "                                        const Function &Callee) {\n";
   OS << "  bool Ret = true;\n\n";
@@ -135,35 +96,8 @@ void Attributes::emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr) {
   OS << "#endif\n";
 }
 
-void Attributes::printEnumAttrClasses(raw_ostream &OS,
-                                      const std::vector<Record *> &Records) {
-  OS << "// EnumAttr classes\n";
-  for (const auto *R : Records) {
-    OS << "struct " << R->getName() << "Attr : EnumAttr {\n";
-    OS << "  static enum Attribute::AttrKind getKind() {\n";
-    OS << "    return llvm::Attribute::" << R->getName() << ";\n";
-    OS << "  }\n";
-    OS << "};\n";
-  }
-  OS << "\n";
-}
-
-void Attributes::printStrBoolAttrClasses(raw_ostream &OS,
-                                         const std::vector<Record *> &Records) {
-  OS << "// StrBoolAttr classes\n";
-  for (const auto *R : Records) {
-    OS << "struct " << R->getName() << "Attr : StrBoolAttr {\n";
-    OS << "  static StringRef getKind() {\n";
-    OS << "    return \"" << R->getValueAsString("AttrString") << "\";\n";
-    OS << "  }\n";
-    OS << "};\n";
-  }
-  OS << "\n";
-}
-
 void Attributes::emit(raw_ostream &OS) {
-  emitTargetIndependentEnums(OS);
-  emitConversionFn(OS);
+  emitTargetIndependentNames(OS);
   emitFnAttrCompatCheck(OS, false);
 }