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 | |
21 | using namespace mlir; |
22 | using namespace mlir::tblgen; |
23 | |
24 | static llvm::cl::OptionCategory |
25 | passGenCat("Options for -gen-pass-capi-header and -gen-pass-capi-impl" ); |
26 | static 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 | |
33 | const char *const passDecl = R"( |
34 | /* Create {0} Pass. */ |
35 | MLIR_CAPI_EXPORTED MlirPass mlirCreate{0}{1}(void); |
36 | MLIR_CAPI_EXPORTED void mlirRegister{0}{1}(void); |
37 | |
38 | )" ; |
39 | |
40 | const char *const = R"( |
41 | /* Autogenerated by mlir-tblgen; don't manually edit. */ |
42 | |
43 | #include "mlir-c/Pass.h" |
44 | |
45 | #ifdef __cplusplus |
46 | extern "C" { |
47 | #endif |
48 | |
49 | )" ; |
50 | |
51 | const char *const = R"( |
52 | |
53 | #ifdef __cplusplus |
54 | } |
55 | #endif |
56 | )" ; |
57 | |
58 | /// Emit TODO |
59 | static bool (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 | |
73 | const char *const passCreateDef = R"( |
74 | MlirPass mlirCreate{0}{1}(void) { |
75 | return wrap({2}.release()); |
76 | } |
77 | void mlirRegister{0}{1}(void) { |
78 | register{1}(); |
79 | } |
80 | |
81 | )" ; |
82 | |
83 | /// {0}: The name of the pass group. |
84 | const char *const passGroupRegistrationCode = R"( |
85 | //===----------------------------------------------------------------------===// |
86 | // {0} Group Registration |
87 | //===----------------------------------------------------------------------===// |
88 | |
89 | void mlirRegister{0}Passes(void) {{ |
90 | register{0}Passes(); |
91 | } |
92 | )" ; |
93 | |
94 | static 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 | |
114 | static mlir::GenRegistration ("gen-pass-capi-header" , |
115 | "Generate pass C API header" , |
116 | &emitCAPIHeader); |
117 | |
118 | static mlir::GenRegistration genCAPIImpl("gen-pass-capi-impl" , |
119 | "Generate pass C API implementation" , |
120 | &emitCAPIImpl); |
121 | |