1d932679cSAkira Hatanaka //===- Attributes.cpp - Generate attributes -------------------------------===//
2d932679cSAkira Hatanaka //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d932679cSAkira Hatanaka //
7d932679cSAkira Hatanaka //===----------------------------------------------------------------------===//
8d932679cSAkira Hatanaka
9d932679cSAkira Hatanaka #include "llvm/TableGen/Record.h"
10d932679cSAkira Hatanaka #include <vector>
11d932679cSAkira Hatanaka using namespace llvm;
12d932679cSAkira Hatanaka
13d932679cSAkira Hatanaka #define DEBUG_TYPE "attr-enum"
14d932679cSAkira Hatanaka
15d932679cSAkira Hatanaka namespace {
16d932679cSAkira Hatanaka
17d932679cSAkira Hatanaka class Attributes {
18d932679cSAkira Hatanaka public:
Attributes(RecordKeeper & R)19d932679cSAkira Hatanaka Attributes(RecordKeeper &R) : Records(R) {}
20d932679cSAkira Hatanaka void emit(raw_ostream &OS);
21d932679cSAkira Hatanaka
22d932679cSAkira Hatanaka private:
23cfe87a4aSTyker void emitTargetIndependentNames(raw_ostream &OS);
241cb242ebSAkira Hatanaka void emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr);
25*7ed3e878SNikita Popov void emitAttributeProperties(raw_ostream &OF);
261cb242ebSAkira Hatanaka
27d932679cSAkira Hatanaka RecordKeeper &Records;
28d932679cSAkira Hatanaka };
29d932679cSAkira Hatanaka
30d932679cSAkira Hatanaka } // End anonymous namespace.
31d932679cSAkira Hatanaka
emitTargetIndependentNames(raw_ostream & OS)32cfe87a4aSTyker void Attributes::emitTargetIndependentNames(raw_ostream &OS) {
33cfe87a4aSTyker OS << "#ifdef GET_ATTR_NAMES\n";
34cfe87a4aSTyker OS << "#undef GET_ATTR_NAMES\n";
35d932679cSAkira Hatanaka
36cfe87a4aSTyker OS << "#ifndef ATTRIBUTE_ALL\n";
37cfe87a4aSTyker OS << "#define ATTRIBUTE_ALL(FIRST, SECOND)\n";
38cfe87a4aSTyker OS << "#endif\n\n";
39d932679cSAkira Hatanaka
40ed766f1bSBenjamin Kramer auto Emit = [&](ArrayRef<StringRef> KindNames, StringRef MacroName) {
41cfe87a4aSTyker OS << "#ifndef " << MacroName << "\n";
42ed766f1bSBenjamin Kramer OS << "#define " << MacroName
43ed766f1bSBenjamin Kramer << "(FIRST, SECOND) ATTRIBUTE_ALL(FIRST, SECOND)\n";
44cfe87a4aSTyker OS << "#endif\n\n";
45ed766f1bSBenjamin Kramer for (StringRef KindName : KindNames) {
46ed766f1bSBenjamin Kramer for (auto A : Records.getAllDerivedDefinitions(KindName)) {
47ed766f1bSBenjamin Kramer OS << MacroName << "(" << A->getName() << ","
48cfe87a4aSTyker << A->getValueAsString("AttrString") << ")\n";
4960b31453SAmaury Sechet }
50ed766f1bSBenjamin Kramer }
51cfe87a4aSTyker OS << "#undef " << MacroName << "\n\n";
52cfe87a4aSTyker };
5360b31453SAmaury Sechet
54ed766f1bSBenjamin Kramer // Emit attribute enums in the same order llvm::Attribute::operator< expects.
55ed766f1bSBenjamin Kramer Emit({"EnumAttr", "TypeAttr", "IntAttr"}, "ATTRIBUTE_ENUM");
56ed766f1bSBenjamin Kramer Emit({"StrBoolAttr"}, "ATTRIBUTE_STRBOOL");
5760b31453SAmaury Sechet
58cfe87a4aSTyker OS << "#undef ATTRIBUTE_ALL\n";
595d1464cbSNikita Popov OS << "#endif\n\n";
605d1464cbSNikita Popov
615d1464cbSNikita Popov OS << "#ifdef GET_ATTR_ENUM\n";
625d1464cbSNikita Popov OS << "#undef GET_ATTR_ENUM\n";
635d1464cbSNikita Popov unsigned Value = 1; // Leave zero for AttrKind::None.
645d1464cbSNikita Popov for (StringRef KindName : {"EnumAttr", "TypeAttr", "IntAttr"}) {
655d1464cbSNikita Popov OS << "First" << KindName << " = " << Value << ",\n";
665d1464cbSNikita Popov for (auto A : Records.getAllDerivedDefinitions(KindName)) {
675d1464cbSNikita Popov OS << A->getName() << " = " << Value << ",\n";
685d1464cbSNikita Popov Value++;
695d1464cbSNikita Popov }
705d1464cbSNikita Popov OS << "Last" << KindName << " = " << (Value - 1) << ",\n";
715d1464cbSNikita Popov }
725d1464cbSNikita Popov OS << "#endif\n\n";
7360b31453SAmaury Sechet }
7460b31453SAmaury Sechet
emitFnAttrCompatCheck(raw_ostream & OS,bool IsStringAttr)751cb242ebSAkira Hatanaka void Attributes::emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr) {
761cb242ebSAkira Hatanaka OS << "#ifdef GET_ATTR_COMPAT_FUNC\n";
771cb242ebSAkira Hatanaka OS << "#undef GET_ATTR_COMPAT_FUNC\n";
781cb242ebSAkira Hatanaka
791cb242ebSAkira Hatanaka OS << "static inline bool hasCompatibleFnAttrs(const Function &Caller,\n"
801cb242ebSAkira Hatanaka << " const Function &Callee) {\n";
811cb242ebSAkira Hatanaka OS << " bool Ret = true;\n\n";
821cb242ebSAkira Hatanaka
831cb242ebSAkira Hatanaka std::vector<Record *> CompatRules =
841cb242ebSAkira Hatanaka Records.getAllDerivedDefinitions("CompatRule");
851cb242ebSAkira Hatanaka
861cb242ebSAkira Hatanaka for (auto *Rule : CompatRules) {
87bcd3c37fSCraig Topper StringRef FuncName = Rule->getValueAsString("CompatFunc");
881cb242ebSAkira Hatanaka OS << " Ret &= " << FuncName << "(Caller, Callee);\n";
891cb242ebSAkira Hatanaka }
901cb242ebSAkira Hatanaka
911cb242ebSAkira Hatanaka OS << "\n";
921cb242ebSAkira Hatanaka OS << " return Ret;\n";
931cb242ebSAkira Hatanaka OS << "}\n\n";
941cb242ebSAkira Hatanaka
951cb242ebSAkira Hatanaka std::vector<Record *> MergeRules =
961cb242ebSAkira Hatanaka Records.getAllDerivedDefinitions("MergeRule");
971cb242ebSAkira Hatanaka OS << "static inline void mergeFnAttrs(Function &Caller,\n"
981cb242ebSAkira Hatanaka << " const Function &Callee) {\n";
991cb242ebSAkira Hatanaka
1001cb242ebSAkira Hatanaka for (auto *Rule : MergeRules) {
101bcd3c37fSCraig Topper StringRef FuncName = Rule->getValueAsString("MergeFunc");
1021cb242ebSAkira Hatanaka OS << " " << FuncName << "(Caller, Callee);\n";
1031cb242ebSAkira Hatanaka }
1041cb242ebSAkira Hatanaka
1051cb242ebSAkira Hatanaka OS << "}\n\n";
1061cb242ebSAkira Hatanaka
1071cb242ebSAkira Hatanaka OS << "#endif\n";
1081cb242ebSAkira Hatanaka }
1091cb242ebSAkira Hatanaka
emitAttributeProperties(raw_ostream & OS)110*7ed3e878SNikita Popov void Attributes::emitAttributeProperties(raw_ostream &OS) {
111*7ed3e878SNikita Popov OS << "#ifdef GET_ATTR_PROP_TABLE\n";
112*7ed3e878SNikita Popov OS << "#undef GET_ATTR_PROP_TABLE\n";
113*7ed3e878SNikita Popov OS << "static const uint8_t AttrPropTable[] = {\n";
114*7ed3e878SNikita Popov for (StringRef KindName : {"EnumAttr", "TypeAttr", "IntAttr"}) {
115*7ed3e878SNikita Popov for (auto A : Records.getAllDerivedDefinitions(KindName)) {
116*7ed3e878SNikita Popov OS << "0";
117*7ed3e878SNikita Popov for (Init *P : *A->getValueAsListInit("Properties"))
118*7ed3e878SNikita Popov OS << " | AttributeProperty::" << cast<DefInit>(P)->getDef()->getName();
119*7ed3e878SNikita Popov OS << ",\n";
120*7ed3e878SNikita Popov }
121*7ed3e878SNikita Popov }
122*7ed3e878SNikita Popov OS << "};\n";
123*7ed3e878SNikita Popov OS << "#endif\n";
124*7ed3e878SNikita Popov }
125*7ed3e878SNikita Popov
emit(raw_ostream & OS)126d932679cSAkira Hatanaka void Attributes::emit(raw_ostream &OS) {
127cfe87a4aSTyker emitTargetIndependentNames(OS);
1281cb242ebSAkira Hatanaka emitFnAttrCompatCheck(OS, false);
129*7ed3e878SNikita Popov emitAttributeProperties(OS);
130d932679cSAkira Hatanaka }
131d932679cSAkira Hatanaka
132d932679cSAkira Hatanaka namespace llvm {
133d932679cSAkira Hatanaka
EmitAttributes(RecordKeeper & RK,raw_ostream & OS)134d932679cSAkira Hatanaka void EmitAttributes(RecordKeeper &RK, raw_ostream &OS) {
135d932679cSAkira Hatanaka Attributes(RK).emit(OS);
136d932679cSAkira Hatanaka }
137d932679cSAkira Hatanaka
138d932679cSAkira Hatanaka } // End llvm namespace.
139