xref: /llvm-project/mlir/tools/mlir-tblgen/PassCAPIGen.cpp (revision bccd37f69fdc7b5cd00d9231cabbe74bfe38f598)
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