Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/Basic/Attributes.cpp
213799 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/Error.h"9#include "llvm/TableGen/Record.h"10#include "llvm/TableGen/TableGenBackend.h"11using namespace llvm;1213#define DEBUG_TYPE "attr-enum"1415namespace {1617class Attributes {18public:19Attributes(const 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);2627const RecordKeeper &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";8687for (const Record *Rule : Records.getAllDerivedDefinitions("CompatRule")) {88StringRef FuncName = Rule->getValueAsString("CompatFunc");89OS << " Ret &= " << FuncName << "(Caller, Callee";90StringRef AttrName = Rule->getValueAsString("AttrName");91if (!AttrName.empty())92OS << ", \"" << AttrName << "\"";93OS << ");\n";94}9596OS << "\n";97OS << " return Ret;\n";98OS << "}\n\n";99100OS << "static inline void mergeFnAttrs(Function &Caller,\n"101<< " const Function &Callee) {\n";102103for (const Record *Rule : Records.getAllDerivedDefinitions("MergeRule")) {104StringRef FuncName = Rule->getValueAsString("MergeFunc");105OS << " " << FuncName << "(Caller, Callee);\n";106}107108OS << "}\n\n";109110OS << "#endif\n";111}112113void Attributes::emitAttributeProperties(raw_ostream &OS) {114OS << "#ifdef GET_ATTR_PROP_TABLE\n";115OS << "#undef GET_ATTR_PROP_TABLE\n";116OS << "static const uint8_t AttrPropTable[] = {\n";117for (StringRef KindName : {"EnumAttr", "TypeAttr", "IntAttr",118"ConstantRangeAttr", "ConstantRangeListAttr"}) {119bool AllowIntersectAnd = KindName == "EnumAttr";120bool AllowIntersectMin = KindName == "IntAttr";121for (auto *A : Records.getAllDerivedDefinitions(KindName)) {122OS << "0";123for (const Init *P : *A->getValueAsListInit("Properties")) {124if (!AllowIntersectAnd &&125cast<DefInit>(P)->getDef()->getName() == "IntersectAnd")126PrintFatalError("'IntersectAnd' only compatible with 'EnumAttr'");127if (!AllowIntersectMin &&128cast<DefInit>(P)->getDef()->getName() == "IntersectMin")129PrintFatalError("'IntersectMin' only compatible with 'IntAttr'");130131OS << " | AttributeProperty::" << cast<DefInit>(P)->getDef()->getName();132}133OS << ",\n";134}135}136OS << "};\n";137OS << "#endif\n";138}139140void Attributes::run(raw_ostream &OS) {141emitTargetIndependentNames(OS);142emitFnAttrCompatCheck(OS, false);143emitAttributeProperties(OS);144}145146static TableGen::Emitter::OptClass<Attributes> X("gen-attrs",147"Generate attributes");148149150