diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2015-11-12 20:59:43 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2015-11-12 20:59:43 +0000 |
commit | d68ad56b3f52878be32ce60b8a6f9c8dce94c34b (patch) | |
tree | 407c8b5cc21c4aba2f1fa01120c9d736298d1af0 /utils | |
parent | 22e911c8dd6b653bae6f24a5f86204ab8419a203 (diff) |
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252949 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/Attributes.cpp | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/utils/TableGen/Attributes.cpp b/utils/TableGen/Attributes.cpp index 385a244d74d..df986a5fb56 100644 --- a/utils/TableGen/Attributes.cpp +++ b/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,97 @@ 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"; + + const 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"; + + const 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 << " constexpr static const enum Attribute::AttrKind Kind = "; + OS << "Attribute::" << R->getName() << ";\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 << " constexpr static const char * const Kind = \""; + OS << R->getValueAsString("AttrString") << "\";\n"; + OS << "};\n"; + } + OS << "\n"; +} + void Attributes::emit(raw_ostream &OS) { emitTargetIndependentEnums(OS); + emitFnAttrCompatCheck(OS, false); } namespace llvm { |