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

source code of mlir/tools/mlir-tblgen/PassCAPIGen.cpp