diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2015-12-22 20:00:05 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2015-12-22 20:00:05 +0000 |
commit | a61deb249ba13fbbb80a4927e0c619f54e62ee30 (patch) | |
tree | b2a43eb3986c7b8c9b769a52d6e9401570db44ad /llvm/utils/TableGen/Attributes.cpp | |
parent | 5349d87a69dfef34a6538aff082775da19be8e88 (diff) | |
download | bcm5719-llvm-a61deb249ba13fbbb80a4927e0c619f54e62ee30.tar.gz bcm5719-llvm-a61deb249ba13fbbb80a4927e0c619f54e62ee30.zip |
Provide a way to specify inliner's attribute compatibility and merging.
This reapplies r252990 and r252949. I've added member function getKind
to the Attr classes which returns the enum or string of the attribute.
Original commit message for r252949:
Provide a way to specify inliner's attribute compatibility and merging
rules using table-gen. NFC.
This commit adds new classes CompatRule and MergeRule to Attributes.td,
which are used to generate code to check attribute compatibility and
merge attributes of the caller and callee.
rdar://problem/19836465
llvm-svn: 256277
Diffstat (limited to 'llvm/utils/TableGen/Attributes.cpp')
-rw-r--r-- | llvm/utils/TableGen/Attributes.cpp | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/llvm/utils/TableGen/Attributes.cpp b/llvm/utils/TableGen/Attributes.cpp index 385a244d74d..ffa49d0686d 100644 --- a/llvm/utils/TableGen/Attributes.cpp +++ b/llvm/utils/TableGen/Attributes.cpp @@ -27,6 +27,12 @@ public: private: void emitTargetIndependentEnums(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; }; @@ -46,8 +52,99 @@ void Attributes::emitTargetIndependentEnums(raw_ostream &OS) { OS << "#endif\n"; } +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"; + + std::vector<Record *> CompatRules = + Records.getAllDerivedDefinitions("CompatRule"); + + for (auto *Rule : CompatRules) { + StringRef FuncName = Rule->getValueAsString("CompatFunc"); + OS << " Ret &= " << FuncName << "(Caller, Callee);\n"; + } + + OS << "\n"; + OS << " return Ret;\n"; + OS << "}\n\n"; + + std::vector<Record *> MergeRules = + Records.getAllDerivedDefinitions("MergeRule"); + OS << "static inline void mergeFnAttrs(Function &Caller,\n" + << " const Function &Callee) {\n"; + + for (auto *Rule : MergeRules) { + StringRef FuncName = Rule->getValueAsString("MergeFunc"); + OS << " " << FuncName << "(Caller, Callee);\n"; + } + + OS << "}\n\n"; + + 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 const char *getKind() {\n"; + OS << " return \"" << R->getValueAsString("AttrString") << "\";\n"; + OS << " }\n"; + OS << "};\n"; + } + OS << "\n"; +} + void Attributes::emit(raw_ostream &OS) { emitTargetIndependentEnums(OS); + emitFnAttrCompatCheck(OS, false); } namespace llvm { |