Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/Attributes.cpp
35258 views
//===- Attributes.cpp - Generate attributes -------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/TableGen/Record.h"9#include "llvm/TableGen/TableGenBackend.h"10#include <vector>11using namespace llvm;1213#define DEBUG_TYPE "attr-enum"1415namespace {1617class Attributes {18public:19Attributes(RecordKeeper &R) : Records(R) {}20void run(raw_ostream &OS);2122private:23void emitTargetIndependentNames(raw_ostream &OS);24void emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr);25void emitAttributeProperties(raw_ostream &OF);2627RecordKeeper &Records;28};2930} // End anonymous namespace.3132void Attributes::emitTargetIndependentNames(raw_ostream &OS) {33OS << "#ifdef GET_ATTR_NAMES\n";34OS << "#undef GET_ATTR_NAMES\n";3536OS << "#ifndef ATTRIBUTE_ALL\n";37OS << "#define ATTRIBUTE_ALL(FIRST, SECOND)\n";38OS << "#endif\n\n";3940auto Emit = [&](ArrayRef<StringRef> KindNames, StringRef MacroName) {41OS << "#ifndef " << MacroName << "\n";42OS << "#define " << MacroName43<< "(FIRST, SECOND) ATTRIBUTE_ALL(FIRST, SECOND)\n";44OS << "#endif\n\n";45for (StringRef KindName : KindNames) {46for (auto *A : Records.getAllDerivedDefinitions(KindName)) {47OS << MacroName << "(" << A->getName() << ","48<< A->getValueAsString("AttrString") << ")\n";49}50}51OS << "#undef " << MacroName << "\n\n";52};5354// Emit attribute enums in the same order llvm::Attribute::operator< expects.55Emit({"EnumAttr", "TypeAttr", "IntAttr", "ConstantRangeAttr",56"ConstantRangeListAttr"},57"ATTRIBUTE_ENUM");58Emit({"StrBoolAttr"}, "ATTRIBUTE_STRBOOL");59Emit({"ComplexStrAttr"}, "ATTRIBUTE_COMPLEXSTR");6061OS << "#undef ATTRIBUTE_ALL\n";62OS << "#endif\n\n";6364OS << "#ifdef GET_ATTR_ENUM\n";65OS << "#undef GET_ATTR_ENUM\n";66unsigned Value = 1; // Leave zero for AttrKind::None.67for (StringRef KindName : {"EnumAttr", "TypeAttr", "IntAttr",68"ConstantRangeAttr", "ConstantRangeListAttr"}) {69OS << "First" << KindName << " = " << Value << ",\n";70for (auto *A : Records.getAllDerivedDefinitions(KindName)) {71OS << A->getName() << " = " << Value << ",\n";72Value++;73}74OS << "Last" << KindName << " = " << (Value - 1) << ",\n";75}76OS << "#endif\n\n";77}7879void Attributes::emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr) {80OS << "#ifdef GET_ATTR_COMPAT_FUNC\n";81OS << "#undef GET_ATTR_COMPAT_FUNC\n";8283OS << "static inline bool hasCompatibleFnAttrs(const Function &Caller,\n"84<< " const Function &Callee) {\n";85OS << " bool Ret = true;\n\n";8687std::vector<Record *> CompatRules =88Records.getAllDerivedDefinitions("CompatRule");8990for (auto *Rule : CompatRules) {91StringRef FuncName = Rule->getValueAsString("CompatFunc");92OS << " Ret &= " << FuncName << "(Caller, Callee";93StringRef AttrName = Rule->getValueAsString("AttrName");94if (!AttrName.empty())95OS << ", \"" << AttrName << "\"";96OS << ");\n";97}9899OS << "\n";100OS << " return Ret;\n";101OS << "}\n\n";102103std::vector<Record *> MergeRules =104Records.getAllDerivedDefinitions("MergeRule");105OS << "static inline void mergeFnAttrs(Function &Caller,\n"106<< " const Function &Callee) {\n";107108for (auto *Rule : MergeRules) {109StringRef FuncName = Rule->getValueAsString("MergeFunc");110OS << " " << FuncName << "(Caller, Callee);\n";111}112113OS << "}\n\n";114115OS << "#endif\n";116}117118void Attributes::emitAttributeProperties(raw_ostream &OS) {119OS << "#ifdef GET_ATTR_PROP_TABLE\n";120OS << "#undef GET_ATTR_PROP_TABLE\n";121OS << "static const uint8_t AttrPropTable[] = {\n";122for (StringRef KindName : {"EnumAttr", "TypeAttr", "IntAttr",123"ConstantRangeAttr", "ConstantRangeListAttr"}) {124for (auto *A : Records.getAllDerivedDefinitions(KindName)) {125OS << "0";126for (Init *P : *A->getValueAsListInit("Properties"))127OS << " | AttributeProperty::" << cast<DefInit>(P)->getDef()->getName();128OS << ",\n";129}130}131OS << "};\n";132OS << "#endif\n";133}134135void Attributes::run(raw_ostream &OS) {136emitTargetIndependentNames(OS);137emitFnAttrCompatCheck(OS, false);138emitAttributeProperties(OS);139}140141static TableGen::Emitter::OptClass<Attributes> X("gen-attrs",142"Generate attributes");143144145