1 //===-- mlir-c/Pass.h - C API to Pass Management ------------------*- C -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM
4 // Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This header declares the C interface to MLIR pass manager.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_C_PASS_H
15 #define MLIR_C_PASS_H
16 
17 #include "mlir-c/IR.h"
18 #include "mlir-c/Support.h"
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 //===----------------------------------------------------------------------===//
25 // Opaque type declarations.
26 //
27 // Types are exposed to C bindings as structs containing opaque pointers. They
28 // are not supposed to be inspected from C. This allows the underlying
29 // representation to change without affecting the API users. The use of structs
30 // instead of typedefs enables some type safety as structs are not implicitly
31 // convertible to each other.
32 //
33 // Instances of these types may or may not own the underlying object. The
34 // ownership semantics is defined by how an instance of the type was obtained.
35 //===----------------------------------------------------------------------===//
36 
37 #define DEFINE_C_API_STRUCT(name, storage)                                     \
38   struct name {                                                                \
39     storage *ptr;                                                              \
40   };                                                                           \
41   typedef struct name name
42 
43 DEFINE_C_API_STRUCT(MlirPass, void);
44 DEFINE_C_API_STRUCT(MlirExternalPass, void);
45 DEFINE_C_API_STRUCT(MlirPassManager, void);
46 DEFINE_C_API_STRUCT(MlirOpPassManager, void);
47 
48 #undef DEFINE_C_API_STRUCT
49 
50 //===----------------------------------------------------------------------===//
51 // PassManager/OpPassManager APIs.
52 //===----------------------------------------------------------------------===//
53 
54 /// Create a new top-level PassManager.
55 MLIR_CAPI_EXPORTED MlirPassManager mlirPassManagerCreate(MlirContext ctx);
56 
57 /// Destroy the provided PassManager.
58 MLIR_CAPI_EXPORTED void mlirPassManagerDestroy(MlirPassManager passManager);
59 
60 /// Checks if a PassManager is null.
mlirPassManagerIsNull(MlirPassManager passManager)61 static inline bool mlirPassManagerIsNull(MlirPassManager passManager) {
62   return !passManager.ptr;
63 }
64 
65 /// Cast a top-level PassManager to a generic OpPassManager.
66 MLIR_CAPI_EXPORTED MlirOpPassManager
67 mlirPassManagerGetAsOpPassManager(MlirPassManager passManager);
68 
69 /// Run the provided `passManager` on the given `module`.
70 MLIR_CAPI_EXPORTED MlirLogicalResult
71 mlirPassManagerRun(MlirPassManager passManager, MlirModule module);
72 
73 /// Enable mlir-print-ir-after-all.
74 MLIR_CAPI_EXPORTED void
75 mlirPassManagerEnableIRPrinting(MlirPassManager passManager);
76 
77 /// Enable / disable verify-each.
78 MLIR_CAPI_EXPORTED void
79 mlirPassManagerEnableVerifier(MlirPassManager passManager, bool enable);
80 
81 /// Nest an OpPassManager under the top-level PassManager, the nested
82 /// passmanager will only run on operations matching the provided name.
83 /// The returned OpPassManager will be destroyed when the parent is destroyed.
84 /// To further nest more OpPassManager under the newly returned one, see
85 /// `mlirOpPassManagerNest` below.
86 MLIR_CAPI_EXPORTED MlirOpPassManager mlirPassManagerGetNestedUnder(
87     MlirPassManager passManager, MlirStringRef operationName);
88 
89 /// Nest an OpPassManager under the provided OpPassManager, the nested
90 /// passmanager will only run on operations matching the provided name.
91 /// The returned OpPassManager will be destroyed when the parent is destroyed.
92 MLIR_CAPI_EXPORTED MlirOpPassManager mlirOpPassManagerGetNestedUnder(
93     MlirOpPassManager passManager, MlirStringRef operationName);
94 
95 /// Add a pass and transfer ownership to the provided top-level mlirPassManager.
96 /// If the pass is not a generic operation pass or a ModulePass, a new
97 /// OpPassManager is implicitly nested under the provided PassManager.
98 MLIR_CAPI_EXPORTED void mlirPassManagerAddOwnedPass(MlirPassManager passManager,
99                                                     MlirPass pass);
100 
101 /// Add a pass and transfer ownership to the provided mlirOpPassManager. If the
102 /// pass is not a generic operation pass or matching the type of the provided
103 /// PassManager, a new OpPassManager is implicitly nested under the provided
104 /// PassManager.
105 MLIR_CAPI_EXPORTED void
106 mlirOpPassManagerAddOwnedPass(MlirOpPassManager passManager, MlirPass pass);
107 
108 /// Print a textual MLIR pass pipeline by sending chunks of the string
109 /// representation and forwarding `userData to `callback`. Note that the
110 /// callback may be called several times with consecutive chunks of the string.
111 MLIR_CAPI_EXPORTED void mlirPrintPassPipeline(MlirOpPassManager passManager,
112                                               MlirStringCallback callback,
113                                               void *userData);
114 
115 /// Parse a textual MLIR pass pipeline and add it to the provided OpPassManager.
116 
117 MLIR_CAPI_EXPORTED MlirLogicalResult
118 mlirParsePassPipeline(MlirOpPassManager passManager, MlirStringRef pipeline);
119 
120 //===----------------------------------------------------------------------===//
121 // External Pass API.
122 //
123 // This API allows to define passes outside of MLIR, not necessarily in
124 // C++, and register them with the MLIR pass management infrastructure.
125 //
126 //===----------------------------------------------------------------------===//
127 
128 /// Structure of external `MlirPass` callbacks.
129 /// All callbacks are required to be set unless otherwise specified.
130 struct MlirExternalPassCallbacks {
131   /// This callback is called from the pass is created.
132   /// This is analogous to a C++ pass constructor.
133   void (*construct)(void *userData);
134 
135   /// This callback is called when the pass is destroyed
136   /// This is analogous to a C++ pass destructor.
137   void (*destruct)(void *userData);
138 
139   /// This callback is optional.
140   /// The callback is called before the pass is run, allowing a chance to
141   /// initialize any complex state necessary for running the pass.
142   /// See Pass::initialize(MLIRContext *).
143   MlirLogicalResult (*initialize)(MlirContext ctx, void *userData);
144 
145   /// This callback is called when the pass is cloned.
146   /// See Pass::clonePass().
147   void *(*clone)(void *userData);
148 
149   /// This callback is called when the pass is run.
150   /// See Pass::runOnOperation().
151   void (*run)(MlirOperation op, MlirExternalPass pass, void *userData);
152 };
153 typedef struct MlirExternalPassCallbacks MlirExternalPassCallbacks;
154 
155 /// Creates an external `MlirPass` that calls the supplied `callbacks` using the
156 /// supplied `userData`. If `opName` is empty, the pass is a generic operation
157 /// pass. Otherwise it is an operation pass specific to the specified pass name.
158 MLIR_CAPI_EXPORTED MlirPass mlirCreateExternalPass(
159     MlirTypeID passID, MlirStringRef name, MlirStringRef argument,
160     MlirStringRef description, MlirStringRef opName,
161     intptr_t nDependentDialects, MlirDialectHandle *dependentDialects,
162     MlirExternalPassCallbacks callbacks, void *userData);
163 
164 /// This signals that the pass has failed. This is only valid to call during
165 /// the `run` callback of `MlirExternalPassCallbacks`.
166 /// See Pass::signalPassFailure().
167 MLIR_CAPI_EXPORTED void mlirExternalPassSignalFailure(MlirExternalPass pass);
168 
169 #ifdef __cplusplus
170 }
171 #endif
172 
173 #endif // MLIR_C_PASS_H
174