1f61d1028SMehdi Amini //===- Pass.cpp - MLIR pass registration generator ------------------------===// 2f61d1028SMehdi Amini // 3f61d1028SMehdi Amini // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4f61d1028SMehdi Amini // See https://llvm.org/LICENSE.txt for license information. 5f61d1028SMehdi Amini // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6f61d1028SMehdi Amini // 7f61d1028SMehdi Amini //===----------------------------------------------------------------------===// 8f61d1028SMehdi Amini // 9f61d1028SMehdi Amini // PassCAPIGen uses the description of passes to generate C API for the passes. 10f61d1028SMehdi Amini // 11f61d1028SMehdi Amini //===----------------------------------------------------------------------===// 12f61d1028SMehdi Amini 13f61d1028SMehdi Amini #include "mlir/TableGen/GenInfo.h" 14f61d1028SMehdi Amini #include "mlir/TableGen/Pass.h" 15f61d1028SMehdi Amini #include "llvm/ADT/StringExtras.h" 16f61d1028SMehdi Amini #include "llvm/Support/CommandLine.h" 17f61d1028SMehdi Amini #include "llvm/Support/FormatVariadic.h" 18f61d1028SMehdi Amini #include "llvm/TableGen/Error.h" 19f61d1028SMehdi Amini #include "llvm/TableGen/Record.h" 20f61d1028SMehdi Amini 21f61d1028SMehdi Amini using namespace mlir; 22f61d1028SMehdi Amini using namespace mlir::tblgen; 23*bccd37f6SRahul Joshi using llvm::formatv; 24*bccd37f6SRahul Joshi using llvm::RecordKeeper; 25f61d1028SMehdi Amini 26f61d1028SMehdi Amini static llvm::cl::OptionCategory 27f61d1028SMehdi Amini passGenCat("Options for -gen-pass-capi-header and -gen-pass-capi-impl"); 28f61d1028SMehdi Amini static llvm::cl::opt<std::string> 29f61d1028SMehdi Amini groupName("prefix", 30f61d1028SMehdi Amini llvm::cl::desc("The prefix to use for this group of passes. The " 31f61d1028SMehdi Amini "form will be mlirCreate<prefix><passname>, the " 32f61d1028SMehdi Amini "prefix can avoid conflicts across libraries."), 33f61d1028SMehdi Amini llvm::cl::cat(passGenCat)); 34f61d1028SMehdi Amini 35f61d1028SMehdi Amini const char *const passDecl = R"( 36f61d1028SMehdi Amini /* Create {0} Pass. */ 375d91f79fSTom Eccles MLIR_CAPI_EXPORTED MlirPass mlirCreate{0}{1}(void); 385d91f79fSTom Eccles MLIR_CAPI_EXPORTED void mlirRegister{0}{1}(void); 39f61d1028SMehdi Amini 40f61d1028SMehdi Amini )"; 41f61d1028SMehdi Amini 42f61d1028SMehdi Amini const char *const fileHeader = R"( 43f61d1028SMehdi Amini /* Autogenerated by mlir-tblgen; don't manually edit. */ 44f61d1028SMehdi Amini 45f61d1028SMehdi Amini #include "mlir-c/Pass.h" 46f61d1028SMehdi Amini 47f61d1028SMehdi Amini #ifdef __cplusplus 48f61d1028SMehdi Amini extern "C" { 49f61d1028SMehdi Amini #endif 50f61d1028SMehdi Amini 51f61d1028SMehdi Amini )"; 52f61d1028SMehdi Amini 53f61d1028SMehdi Amini const char *const fileFooter = R"( 54f61d1028SMehdi Amini 55f61d1028SMehdi Amini #ifdef __cplusplus 56f61d1028SMehdi Amini } 57f61d1028SMehdi Amini #endif 58f61d1028SMehdi Amini )"; 59f61d1028SMehdi Amini 60f61d1028SMehdi Amini /// Emit TODO 61*bccd37f6SRahul Joshi static bool emitCAPIHeader(const RecordKeeper &records, raw_ostream &os) { 62f61d1028SMehdi Amini os << fileHeader; 63dc43f785SMehdi Amini os << "// Registration for the entire group\n"; 645d91f79fSTom Eccles os << "MLIR_CAPI_EXPORTED void mlirRegister" << groupName 655d91f79fSTom Eccles << "Passes(void);\n\n"; 66f61d1028SMehdi Amini for (const auto *def : records.getAllDerivedDefinitions("PassBase")) { 67f61d1028SMehdi Amini Pass pass(def); 68f61d1028SMehdi Amini StringRef defName = pass.getDef()->getName(); 69*bccd37f6SRahul Joshi os << formatv(passDecl, groupName, defName); 70f61d1028SMehdi Amini } 71f61d1028SMehdi Amini os << fileFooter; 72f61d1028SMehdi Amini return false; 73f61d1028SMehdi Amini } 74f61d1028SMehdi Amini 75f61d1028SMehdi Amini const char *const passCreateDef = R"( 765d91f79fSTom Eccles MlirPass mlirCreate{0}{1}(void) { 77f61d1028SMehdi Amini return wrap({2}.release()); 78f61d1028SMehdi Amini } 795d91f79fSTom Eccles void mlirRegister{0}{1}(void) { 8067d0d7acSMichele Scuttari register{1}(); 81aeb4b1a9SMehdi Amini } 82f61d1028SMehdi Amini 83f61d1028SMehdi Amini )"; 84f61d1028SMehdi Amini 85dc43f785SMehdi Amini /// {0}: The name of the pass group. 86dc43f785SMehdi Amini const char *const passGroupRegistrationCode = R"( 87dc43f785SMehdi Amini //===----------------------------------------------------------------------===// 88dc43f785SMehdi Amini // {0} Group Registration 89dc43f785SMehdi Amini //===----------------------------------------------------------------------===// 90dc43f785SMehdi Amini 915d91f79fSTom Eccles void mlirRegister{0}Passes(void) {{ 92dc43f785SMehdi Amini register{0}Passes(); 93dc43f785SMehdi Amini } 94dc43f785SMehdi Amini )"; 95dc43f785SMehdi Amini 96*bccd37f6SRahul Joshi static bool emitCAPIImpl(const RecordKeeper &records, raw_ostream &os) { 97f61d1028SMehdi Amini os << "/* Autogenerated by mlir-tblgen; don't manually edit. */"; 98*bccd37f6SRahul Joshi os << formatv(passGroupRegistrationCode, groupName); 99dc43f785SMehdi Amini 100f61d1028SMehdi Amini for (const auto *def : records.getAllDerivedDefinitions("PassBase")) { 101f61d1028SMehdi Amini Pass pass(def); 102f61d1028SMehdi Amini StringRef defName = pass.getDef()->getName(); 10332c5578bSMichele Scuttari 10432c5578bSMichele Scuttari std::string constructorCall; 10532c5578bSMichele Scuttari if (StringRef constructor = pass.getConstructor(); !constructor.empty()) 10632c5578bSMichele Scuttari constructorCall = constructor.str(); 10732c5578bSMichele Scuttari else 108*bccd37f6SRahul Joshi constructorCall = formatv("create{0}()", pass.getDef()->getName()).str(); 10932c5578bSMichele Scuttari 110*bccd37f6SRahul Joshi os << formatv(passCreateDef, groupName, defName, constructorCall); 111f61d1028SMehdi Amini } 112f61d1028SMehdi Amini return false; 113f61d1028SMehdi Amini } 114f61d1028SMehdi Amini 115f61d1028SMehdi Amini static mlir::GenRegistration genCAPIHeader("gen-pass-capi-header", 116f61d1028SMehdi Amini "Generate pass C API header", 117f61d1028SMehdi Amini &emitCAPIHeader); 118f61d1028SMehdi Amini 119f61d1028SMehdi Amini static mlir::GenRegistration genCAPIImpl("gen-pass-capi-impl", 120f61d1028SMehdi Amini "Generate pass C API implementation", 121f61d1028SMehdi Amini &emitCAPIImpl); 122