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;
23
24static llvm::cl::OptionCategory
25 passGenCat("Options for -gen-pass-capi-header and -gen-pass-capi-impl");
26static llvm::cl::opt<std::string>
27 groupName("prefix",
28 llvm::cl::desc("The prefix to use for this group of passes. The "
29 "form will be mlirCreate<prefix><passname>, the "
30 "prefix can avoid conflicts across libraries."),
31 llvm::cl::cat(passGenCat));
32
33const char *const passDecl = R"(
34/* Create {0} Pass. */
35MLIR_CAPI_EXPORTED MlirPass mlirCreate{0}{1}(void);
36MLIR_CAPI_EXPORTED void mlirRegister{0}{1}(void);
37
38)";
39
40const char *const fileHeader = R"(
41/* Autogenerated by mlir-tblgen; don't manually edit. */
42
43#include "mlir-c/Pass.h"
44
45#ifdef __cplusplus
46extern "C" {
47#endif
48
49)";
50
51const char *const fileFooter = R"(
52
53#ifdef __cplusplus
54}
55#endif
56)";
57
58/// Emit TODO
59static bool emitCAPIHeader(const llvm::RecordKeeper &records, raw_ostream &os) {
60 os << fileHeader;
61 os << "// Registration for the entire group\n";
62 os << "MLIR_CAPI_EXPORTED void mlirRegister" << groupName
63 << "Passes(void);\n\n";
64 for (const auto *def : records.getAllDerivedDefinitions(ClassName: "PassBase")) {
65 Pass pass(def);
66 StringRef defName = pass.getDef()->getName();
67 os << llvm::formatv(Fmt: passDecl, Vals&: groupName, Vals&: defName);
68 }
69 os << fileFooter;
70 return false;
71}
72
73const char *const passCreateDef = R"(
74MlirPass mlirCreate{0}{1}(void) {
75 return wrap({2}.release());
76}
77void mlirRegister{0}{1}(void) {
78 register{1}();
79}
80
81)";
82
83/// {0}: The name of the pass group.
84const char *const passGroupRegistrationCode = R"(
85//===----------------------------------------------------------------------===//
86// {0} Group Registration
87//===----------------------------------------------------------------------===//
88
89void mlirRegister{0}Passes(void) {{
90 register{0}Passes();
91}
92)";
93
94static bool emitCAPIImpl(const llvm::RecordKeeper &records, raw_ostream &os) {
95 os << "/* Autogenerated by mlir-tblgen; don't manually edit. */";
96 os << llvm::formatv(Fmt: passGroupRegistrationCode, Vals&: groupName);
97
98 for (const auto *def : records.getAllDerivedDefinitions(ClassName: "PassBase")) {
99 Pass pass(def);
100 StringRef defName = pass.getDef()->getName();
101
102 std::string constructorCall;
103 if (StringRef constructor = pass.getConstructor(); !constructor.empty())
104 constructorCall = constructor.str();
105 else
106 constructorCall =
107 llvm::formatv(Fmt: "create{0}()", Vals: pass.getDef()->getName()).str();
108
109 os << llvm::formatv(Fmt: passCreateDef, Vals&: groupName, Vals&: defName, Vals&: constructorCall);
110 }
111 return false;
112}
113
114static mlir::GenRegistration genCAPIHeader("gen-pass-capi-header",
115 "Generate pass C API header",
116 &emitCAPIHeader);
117
118static mlir::GenRegistration genCAPIImpl("gen-pass-capi-impl",
119 "Generate pass C API implementation",
120 &emitCAPIImpl);
121

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