//===- offload-tblgen/APIGen.cpp - Tablegen backend for Offload functions -===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This is a Tablegen backend that handles generation of various small files // pertaining to the API functions. // //===----------------------------------------------------------------------===// #include "llvm/Support/FormatVariadic.h" #include "llvm/TableGen/Record.h" #include "GenCommon.hpp" #include "RecordTypes.hpp" using namespace llvm; using namespace offload::tblgen; // Emit a list of just the API function names void EmitOffloadFuncNames(const RecordKeeper &Records, raw_ostream &OS) { OS << GenericHeader; OS << R"( #ifndef OFFLOAD_FUNC #error Please define the macro OFFLOAD_FUNC(Function) #endif )"; for (auto *R : Records.getAllDerivedDefinitions("Function")) { FunctionRec FR{R}; OS << formatv("OFFLOAD_FUNC({0})", FR.getName()) << "\n"; } for (auto *R : Records.getAllDerivedDefinitions("Function")) { FunctionRec FR{R}; OS << formatv("OFFLOAD_FUNC({0}WithCodeLoc)", FR.getName()) << "\n"; } OS << "\n#undef OFFLOAD_FUNC\n"; } void EmitOffloadExports(const RecordKeeper &Records, raw_ostream &OS) { OS << "VERS1.0 {\n"; OS << TAB_1 "global:\n"; for (auto *R : Records.getAllDerivedDefinitions("Function")) { OS << formatv(TAB_2 "{0};\n", FunctionRec(R).getName()); } for (auto *R : Records.getAllDerivedDefinitions("Function")) { OS << formatv(TAB_2 "{0}WithCodeLoc;\n", FunctionRec(R).getName()); } OS << TAB_1 "local:\n"; OS << TAB_2 "*;\n"; OS << "};\n"; } // Emit declarations for every implementation function void EmitOffloadImplFuncDecls(const RecordKeeper &Records, raw_ostream &OS) { OS << GenericHeader; for (auto *R : Records.getAllDerivedDefinitions("Function")) { FunctionRec F{R}; OS << formatv("Error {0}_impl(", F.getName()); auto Params = F.getParams(); for (auto &Param : Params) { OS << Param.getType() << " " << Param.getName(); if (Param != Params.back()) { OS << ", "; } } OS << ");\n\n"; } } // Emit macro calls for each error enum void EmitOffloadErrcodes(const RecordKeeper &Records, raw_ostream &OS) { OS << GenericHeader; OS << R"( #ifndef OFFLOAD_ERRC #error Please define the macro OFFLOAD_ERRCODE(Name, Desc, Value) #endif // Error codes are shared between PluginInterface and liboffload. // To add new error codes, add them to offload/liboffload/API/Common.td. )"; auto ErrorCodeEnum = EnumRec{Records.getDef("ol_errc_t")}; uint32_t EtorVal = 0; for (const auto &EnumVal : ErrorCodeEnum.getValues()) { OS << formatv(TAB_1 "OFFLOAD_ERRC({0}, \"{1}\", {2})\n", EnumVal.getName(), EnumVal.getDesc(), EtorVal++); } } // Emit macro calls for each info void EmitOffloadInfo(const RecordKeeper &Records, raw_ostream &OS) { OS << GenericHeader; OS << R"( #ifndef OFFLOAD_DEVINFO #error Please define the macro OFFLOAD_DEVINFO(Name, Desc, Value) #endif // Device info codes are shared between PluginInterface and liboffload. // To add new error codes, add them to offload/liboffload/API/Device.td. )"; auto Enum = EnumRec{Records.getDef("ol_device_info_t")}; // Bitfields start from 1, other enums from 0 uint32_t EtorVal = Enum.isBitField(); for (const auto &EnumVal : Enum.getValues()) { OS << formatv(TAB_1 "OFFLOAD_DEVINFO({0}, \"{1}\", {2})\n", EnumVal.getName(), EnumVal.getDesc(), EtorVal); if (Enum.isBitField()) { EtorVal <<= 1u; } else { ++EtorVal; } } }