1 //===-- mlir-c/IR.h - C API to Core MLIR IR classes ---------------*- 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 core IR classes.
11 //
12 // Many exotic languages can interoperate with C code but have a harder time
13 // with C++ due to name mangling. So in addition to C, this interface enables
14 // tools written in such languages.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef MLIR_C_IR_H
19 #define MLIR_C_IR_H
20 
21 #include <stdbool.h>
22 #include <stdint.h>
23 
24 #include "mlir-c/Support.h"
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 //===----------------------------------------------------------------------===//
31 /// Opaque type declarations.
32 ///
33 /// Types are exposed to C bindings as structs containing opaque pointers. They
34 /// are not supposed to be inspected from C. This allows the underlying
35 /// representation to change without affecting the API users. The use of structs
36 /// instead of typedefs enables some type safety as structs are not implicitly
37 /// convertible to each other.
38 ///
39 /// Instances of these types may or may not own the underlying object (most
40 /// often only point to an IR fragment without owning it). The ownership
41 /// semantics is defined by how an instance of the type was obtained.
42 
43 //===----------------------------------------------------------------------===//
44 
45 #define DEFINE_C_API_STRUCT(name, storage)                                     \
46   struct name {                                                                \
47     storage *ptr;                                                              \
48   };                                                                           \
49   typedef struct name name
50 
51 DEFINE_C_API_STRUCT(MlirContext, void);
52 DEFINE_C_API_STRUCT(MlirDialect, void);
53 DEFINE_C_API_STRUCT(MlirDialectRegistry, void);
54 DEFINE_C_API_STRUCT(MlirOperation, void);
55 DEFINE_C_API_STRUCT(MlirOpPrintingFlags, void);
56 DEFINE_C_API_STRUCT(MlirBlock, void);
57 DEFINE_C_API_STRUCT(MlirRegion, void);
58 DEFINE_C_API_STRUCT(MlirSymbolTable, void);
59 
60 DEFINE_C_API_STRUCT(MlirAttribute, const void);
61 DEFINE_C_API_STRUCT(MlirIdentifier, const void);
62 DEFINE_C_API_STRUCT(MlirLocation, const void);
63 DEFINE_C_API_STRUCT(MlirModule, const void);
64 DEFINE_C_API_STRUCT(MlirType, const void);
65 DEFINE_C_API_STRUCT(MlirValue, const void);
66 
67 #undef DEFINE_C_API_STRUCT
68 
69 /// Named MLIR attribute.
70 ///
71 /// A named attribute is essentially a (name, attribute) pair where the name is
72 /// a string.
73 
74 struct MlirNamedAttribute {
75   MlirIdentifier name;
76   MlirAttribute attribute;
77 };
78 typedef struct MlirNamedAttribute MlirNamedAttribute;
79 
80 //===----------------------------------------------------------------------===//
81 // Context API.
82 //===----------------------------------------------------------------------===//
83 
84 /// Creates an MLIR context and transfers its ownership to the caller.
85 MLIR_CAPI_EXPORTED MlirContext mlirContextCreate();
86 
87 /// Checks if two contexts are equal.
88 MLIR_CAPI_EXPORTED bool mlirContextEqual(MlirContext ctx1, MlirContext ctx2);
89 
90 /// Checks whether a context is null.
mlirContextIsNull(MlirContext context)91 static inline bool mlirContextIsNull(MlirContext context) {
92   return !context.ptr;
93 }
94 
95 /// Takes an MLIR context owned by the caller and destroys it.
96 MLIR_CAPI_EXPORTED void mlirContextDestroy(MlirContext context);
97 
98 /// Sets whether unregistered dialects are allowed in this context.
99 MLIR_CAPI_EXPORTED void
100 mlirContextSetAllowUnregisteredDialects(MlirContext context, bool allow);
101 
102 /// Returns whether the context allows unregistered dialects.
103 MLIR_CAPI_EXPORTED bool
104 mlirContextGetAllowUnregisteredDialects(MlirContext context);
105 
106 /// Returns the number of dialects registered with the given context. A
107 /// registered dialect will be loaded if needed by the parser.
108 MLIR_CAPI_EXPORTED intptr_t
109 mlirContextGetNumRegisteredDialects(MlirContext context);
110 
111 /// Append the contents of the given dialect registry to the registry associated
112 /// with the context.
113 MLIR_CAPI_EXPORTED void
114 mlirContextAppendDialectRegistry(MlirContext ctx, MlirDialectRegistry registry);
115 
116 /// Returns the number of dialects loaded by the context.
117 
118 MLIR_CAPI_EXPORTED intptr_t
119 mlirContextGetNumLoadedDialects(MlirContext context);
120 
121 /// Gets the dialect instance owned by the given context using the dialect
122 /// namespace to identify it, loads (i.e., constructs the instance of) the
123 /// dialect if necessary. If the dialect is not registered with the context,
124 /// returns null. Use mlirContextLoad<Name>Dialect to load an unregistered
125 /// dialect.
126 MLIR_CAPI_EXPORTED MlirDialect mlirContextGetOrLoadDialect(MlirContext context,
127                                                            MlirStringRef name);
128 
129 /// Set threading mode (must be set to false to mlir-print-ir-after-all).
130 MLIR_CAPI_EXPORTED void mlirContextEnableMultithreading(MlirContext context,
131                                                         bool enable);
132 
133 /// Eagerly loads all available dialects registered with a context, making
134 /// them available for use for IR construction.
135 MLIR_CAPI_EXPORTED void
136 mlirContextLoadAllAvailableDialects(MlirContext context);
137 
138 /// Returns whether the given fully-qualified operation (i.e.
139 /// 'dialect.operation') is registered with the context. This will return true
140 /// if the dialect is loaded and the operation is registered within the
141 /// dialect.
142 MLIR_CAPI_EXPORTED bool mlirContextIsRegisteredOperation(MlirContext context,
143                                                          MlirStringRef name);
144 
145 //===----------------------------------------------------------------------===//
146 // Dialect API.
147 //===----------------------------------------------------------------------===//
148 
149 /// Returns the context that owns the dialect.
150 MLIR_CAPI_EXPORTED MlirContext mlirDialectGetContext(MlirDialect dialect);
151 
152 /// Checks if the dialect is null.
mlirDialectIsNull(MlirDialect dialect)153 static inline bool mlirDialectIsNull(MlirDialect dialect) {
154   return !dialect.ptr;
155 }
156 
157 /// Checks if two dialects that belong to the same context are equal. Dialects
158 /// from different contexts will not compare equal.
159 MLIR_CAPI_EXPORTED bool mlirDialectEqual(MlirDialect dialect1,
160                                          MlirDialect dialect2);
161 
162 /// Returns the namespace of the given dialect.
163 MLIR_CAPI_EXPORTED MlirStringRef mlirDialectGetNamespace(MlirDialect dialect);
164 
165 //===----------------------------------------------------------------------===//
166 // DialectHandle API.
167 // Registration entry-points for each dialect are declared using the common
168 // MLIR_DECLARE_DIALECT_REGISTRATION_CAPI macro, which takes the dialect
169 // API name (i.e. "Func", "Tensor", "Linalg") and namespace (i.e. "func",
170 // "tensor", "linalg"). The following declarations are produced:
171 //
172 //   /// Gets the above hook methods in struct form for a dialect by namespace.
173 //   /// This is intended to facilitate dynamic lookup and registration of
174 //   /// dialects via a plugin facility based on shared library symbol lookup.
175 //   const MlirDialectHandle *mlirGetDialectHandle__{NAMESPACE}__();
176 //
177 // This is done via a common macro to facilitate future expansion to
178 // registration schemes.
179 //===----------------------------------------------------------------------===//
180 
181 struct MlirDialectHandle {
182   const void *ptr;
183 };
184 typedef struct MlirDialectHandle MlirDialectHandle;
185 
186 #define MLIR_DECLARE_CAPI_DIALECT_REGISTRATION(Name, Namespace)                \
187   MLIR_CAPI_EXPORTED MlirDialectHandle mlirGetDialectHandle__##Namespace##__()
188 
189 /// Returns the namespace associated with the provided dialect handle.
190 MLIR_CAPI_EXPORTED
191 MlirStringRef mlirDialectHandleGetNamespace(MlirDialectHandle);
192 
193 /// Inserts the dialect associated with the provided dialect handle into the
194 /// provided dialect registry
195 MLIR_CAPI_EXPORTED void mlirDialectHandleInsertDialect(MlirDialectHandle,
196                                                        MlirDialectRegistry);
197 
198 /// Registers the dialect associated with the provided dialect handle.
199 MLIR_CAPI_EXPORTED void mlirDialectHandleRegisterDialect(MlirDialectHandle,
200                                                          MlirContext);
201 
202 /// Loads the dialect associated with the provided dialect handle.
203 MLIR_CAPI_EXPORTED MlirDialect mlirDialectHandleLoadDialect(MlirDialectHandle,
204                                                             MlirContext);
205 
206 //===----------------------------------------------------------------------===//
207 // DialectRegistry API.
208 //===----------------------------------------------------------------------===//
209 
210 /// Creates a dialect registry and transfers its ownership to the caller.
211 MLIR_CAPI_EXPORTED MlirDialectRegistry mlirDialectRegistryCreate();
212 
213 /// Checks if the dialect registry is null.
mlirDialectRegistryIsNull(MlirDialectRegistry registry)214 static inline bool mlirDialectRegistryIsNull(MlirDialectRegistry registry) {
215   return !registry.ptr;
216 }
217 
218 /// Takes a dialect registry owned by the caller and destroys it.
219 MLIR_CAPI_EXPORTED void
220 mlirDialectRegistryDestroy(MlirDialectRegistry registry);
221 
222 //===----------------------------------------------------------------------===//
223 // Location API.
224 //===----------------------------------------------------------------------===//
225 
226 /// Creates an File/Line/Column location owned by the given context.
227 MLIR_CAPI_EXPORTED MlirLocation mlirLocationFileLineColGet(
228     MlirContext context, MlirStringRef filename, unsigned line, unsigned col);
229 
230 /// Creates a call site location with a callee and a caller.
231 MLIR_CAPI_EXPORTED MlirLocation mlirLocationCallSiteGet(MlirLocation callee,
232                                                         MlirLocation caller);
233 
234 /// Creates a fused location with an array of locations and metadata.
235 MLIR_CAPI_EXPORTED MlirLocation
236 mlirLocationFusedGet(MlirContext ctx, intptr_t nLocations,
237                      MlirLocation const *locations, MlirAttribute metadata);
238 
239 /// Creates a name location owned by the given context. Providing null location
240 /// for childLoc is allowed and if childLoc is null location, then the behavior
241 /// is the same as having unknown child location.
242 MLIR_CAPI_EXPORTED MlirLocation mlirLocationNameGet(MlirContext context,
243                                                     MlirStringRef name,
244                                                     MlirLocation childLoc);
245 
246 /// Creates a location with unknown position owned by the given context.
247 MLIR_CAPI_EXPORTED MlirLocation mlirLocationUnknownGet(MlirContext context);
248 
249 /// Gets the context that a location was created with.
250 MLIR_CAPI_EXPORTED MlirContext mlirLocationGetContext(MlirLocation location);
251 
252 /// Checks if the location is null.
mlirLocationIsNull(MlirLocation location)253 static inline bool mlirLocationIsNull(MlirLocation location) {
254   return !location.ptr;
255 }
256 
257 /// Checks if two locations are equal.
258 MLIR_CAPI_EXPORTED bool mlirLocationEqual(MlirLocation l1, MlirLocation l2);
259 
260 /// Prints a location by sending chunks of the string representation and
261 /// forwarding `userData to `callback`. Note that the callback may be called
262 /// several times with consecutive chunks of the string.
263 MLIR_CAPI_EXPORTED void mlirLocationPrint(MlirLocation location,
264                                           MlirStringCallback callback,
265                                           void *userData);
266 
267 //===----------------------------------------------------------------------===//
268 // Module API.
269 //===----------------------------------------------------------------------===//
270 
271 /// Creates a new, empty module and transfers ownership to the caller.
272 MLIR_CAPI_EXPORTED MlirModule mlirModuleCreateEmpty(MlirLocation location);
273 
274 /// Parses a module from the string and transfers ownership to the caller.
275 MLIR_CAPI_EXPORTED MlirModule mlirModuleCreateParse(MlirContext context,
276                                                     MlirStringRef module);
277 
278 /// Gets the context that a module was created with.
279 MLIR_CAPI_EXPORTED MlirContext mlirModuleGetContext(MlirModule module);
280 
281 /// Gets the body of the module, i.e. the only block it contains.
282 MLIR_CAPI_EXPORTED MlirBlock mlirModuleGetBody(MlirModule module);
283 
284 /// Checks whether a module is null.
mlirModuleIsNull(MlirModule module)285 static inline bool mlirModuleIsNull(MlirModule module) { return !module.ptr; }
286 
287 /// Takes a module owned by the caller and deletes it.
288 MLIR_CAPI_EXPORTED void mlirModuleDestroy(MlirModule module);
289 
290 /// Views the module as a generic operation.
291 MLIR_CAPI_EXPORTED MlirOperation mlirModuleGetOperation(MlirModule module);
292 
293 /// Views the generic operation as a module.
294 /// The returned module is null when the input operation was not a ModuleOp.
295 MLIR_CAPI_EXPORTED MlirModule mlirModuleFromOperation(MlirOperation op);
296 
297 //===----------------------------------------------------------------------===//
298 // Operation state.
299 //===----------------------------------------------------------------------===//
300 
301 /// An auxiliary class for constructing operations.
302 ///
303 /// This class contains all the information necessary to construct the
304 /// operation. It owns the MlirRegions it has pointers to and does not own
305 /// anything else. By default, the state can be constructed from a name and
306 /// location, the latter being also used to access the context, and has no other
307 /// components. These components can be added progressively until the operation
308 /// is constructed. Users are not expected to rely on the internals of this
309 /// class and should use mlirOperationState* functions instead.
310 
311 struct MlirOperationState {
312   MlirStringRef name;
313   MlirLocation location;
314   intptr_t nResults;
315   MlirType *results;
316   intptr_t nOperands;
317   MlirValue *operands;
318   intptr_t nRegions;
319   MlirRegion *regions;
320   intptr_t nSuccessors;
321   MlirBlock *successors;
322   intptr_t nAttributes;
323   MlirNamedAttribute *attributes;
324   bool enableResultTypeInference;
325 };
326 typedef struct MlirOperationState MlirOperationState;
327 
328 /// Constructs an operation state from a name and a location.
329 MLIR_CAPI_EXPORTED MlirOperationState mlirOperationStateGet(MlirStringRef name,
330                                                             MlirLocation loc);
331 
332 /// Adds a list of components to the operation state.
333 MLIR_CAPI_EXPORTED void mlirOperationStateAddResults(MlirOperationState *state,
334                                                      intptr_t n,
335                                                      MlirType const *results);
336 MLIR_CAPI_EXPORTED void
337 mlirOperationStateAddOperands(MlirOperationState *state, intptr_t n,
338                               MlirValue const *operands);
339 MLIR_CAPI_EXPORTED void
340 mlirOperationStateAddOwnedRegions(MlirOperationState *state, intptr_t n,
341                                   MlirRegion const *regions);
342 MLIR_CAPI_EXPORTED void
343 mlirOperationStateAddSuccessors(MlirOperationState *state, intptr_t n,
344                                 MlirBlock const *successors);
345 MLIR_CAPI_EXPORTED void
346 mlirOperationStateAddAttributes(MlirOperationState *state, intptr_t n,
347                                 MlirNamedAttribute const *attributes);
348 
349 /// Enables result type inference for the operation under construction. If
350 /// enabled, then the caller must not have called
351 /// mlirOperationStateAddResults(). Note that if enabled, the
352 /// mlirOperationCreate() call is failable: it will return a null operation
353 /// on inference failure and will emit diagnostics.
354 MLIR_CAPI_EXPORTED void
355 mlirOperationStateEnableResultTypeInference(MlirOperationState *state);
356 
357 //===----------------------------------------------------------------------===//
358 // Op Printing flags API.
359 // While many of these are simple settings that could be represented in a
360 // struct, they are wrapped in a heap allocated object and accessed via
361 // functions to maximize the possibility of compatibility over time.
362 //===----------------------------------------------------------------------===//
363 
364 /// Creates new printing flags with defaults, intended for customization.
365 /// Must be freed with a call to mlirOpPrintingFlagsDestroy().
366 MLIR_CAPI_EXPORTED MlirOpPrintingFlags mlirOpPrintingFlagsCreate();
367 
368 /// Destroys printing flags created with mlirOpPrintingFlagsCreate.
369 MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsDestroy(MlirOpPrintingFlags flags);
370 
371 /// Enables the elision of large elements attributes by printing a lexically
372 /// valid but otherwise meaningless form instead of the element data. The
373 /// `largeElementLimit` is used to configure what is considered to be a "large"
374 /// ElementsAttr by providing an upper limit to the number of elements.
375 MLIR_CAPI_EXPORTED void
376 mlirOpPrintingFlagsElideLargeElementsAttrs(MlirOpPrintingFlags flags,
377                                            intptr_t largeElementLimit);
378 
379 /// Enable printing of debug information. If 'prettyForm' is set to true,
380 /// debug information is printed in a more readable 'pretty' form. Note: The
381 /// IR generated with 'prettyForm' is not parsable.
382 MLIR_CAPI_EXPORTED void
383 mlirOpPrintingFlagsEnableDebugInfo(MlirOpPrintingFlags flags, bool prettyForm);
384 
385 /// Always print operations in the generic form.
386 MLIR_CAPI_EXPORTED void
387 mlirOpPrintingFlagsPrintGenericOpForm(MlirOpPrintingFlags flags);
388 
389 /// Use local scope when printing the operation. This allows for using the
390 /// printer in a more localized and thread-safe setting, but may not
391 /// necessarily be identical to what the IR will look like when dumping
392 /// the full module.
393 MLIR_CAPI_EXPORTED void
394 mlirOpPrintingFlagsUseLocalScope(MlirOpPrintingFlags flags);
395 
396 //===----------------------------------------------------------------------===//
397 // Operation API.
398 //===----------------------------------------------------------------------===//
399 
400 /// Creates an operation and transfers ownership to the caller.
401 /// Note that caller owned child objects are transferred in this call and must
402 /// not be further used. Particularly, this applies to any regions added to
403 /// the state (the implementation may invalidate any such pointers).
404 ///
405 /// This call can fail under the following conditions, in which case, it will
406 /// return a null operation and emit diagnostics:
407 ///   - Result type inference is enabled and cannot be performed.
408 MLIR_CAPI_EXPORTED MlirOperation mlirOperationCreate(MlirOperationState *state);
409 
410 /// Creates a deep copy of an operation. The operation is not inserted and
411 /// ownership is transferred to the caller.
412 MLIR_CAPI_EXPORTED MlirOperation mlirOperationClone(MlirOperation op);
413 
414 /// Takes an operation owned by the caller and destroys it.
415 MLIR_CAPI_EXPORTED void mlirOperationDestroy(MlirOperation op);
416 
417 /// Removes the given operation from its parent block. The operation is not
418 /// destroyed. The ownership of the operation is transferred to the caller.
419 MLIR_CAPI_EXPORTED void mlirOperationRemoveFromParent(MlirOperation op);
420 
421 /// Checks whether the underlying operation is null.
mlirOperationIsNull(MlirOperation op)422 static inline bool mlirOperationIsNull(MlirOperation op) { return !op.ptr; }
423 
424 /// Checks whether two operation handles point to the same operation. This does
425 /// not perform deep comparison.
426 MLIR_CAPI_EXPORTED bool mlirOperationEqual(MlirOperation op,
427                                            MlirOperation other);
428 
429 /// Gets the context this operation is associated with
430 MLIR_CAPI_EXPORTED MlirContext mlirOperationGetContext(MlirOperation op);
431 
432 /// Gets the location of the operation.
433 MLIR_CAPI_EXPORTED MlirLocation mlirOperationGetLocation(MlirOperation op);
434 
435 /// Gets the type id of the operation.
436 /// Returns null if the operation does not have a registered operation
437 /// description.
438 MLIR_CAPI_EXPORTED MlirTypeID mlirOperationGetTypeID(MlirOperation op);
439 
440 /// Gets the name of the operation as an identifier.
441 MLIR_CAPI_EXPORTED MlirIdentifier mlirOperationGetName(MlirOperation op);
442 
443 /// Gets the block that owns this operation, returning null if the operation is
444 /// not owned.
445 MLIR_CAPI_EXPORTED MlirBlock mlirOperationGetBlock(MlirOperation op);
446 
447 /// Gets the operation that owns this operation, returning null if the operation
448 /// is not owned.
449 MLIR_CAPI_EXPORTED MlirOperation
450 mlirOperationGetParentOperation(MlirOperation op);
451 
452 /// Returns the number of regions attached to the given operation.
453 MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumRegions(MlirOperation op);
454 
455 /// Returns `pos`-th region attached to the operation.
456 MLIR_CAPI_EXPORTED MlirRegion mlirOperationGetRegion(MlirOperation op,
457                                                      intptr_t pos);
458 
459 /// Returns an operation immediately following the given operation it its
460 /// enclosing block.
461 MLIR_CAPI_EXPORTED MlirOperation mlirOperationGetNextInBlock(MlirOperation op);
462 
463 /// Returns the number of operands of the operation.
464 MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumOperands(MlirOperation op);
465 
466 /// Returns `pos`-th operand of the operation.
467 MLIR_CAPI_EXPORTED MlirValue mlirOperationGetOperand(MlirOperation op,
468                                                      intptr_t pos);
469 
470 /// Sets the `pos`-th operand of the operation.
471 MLIR_CAPI_EXPORTED void mlirOperationSetOperand(MlirOperation op, intptr_t pos,
472                                                 MlirValue newValue);
473 
474 /// Returns the number of results of the operation.
475 MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumResults(MlirOperation op);
476 
477 /// Returns `pos`-th result of the operation.
478 MLIR_CAPI_EXPORTED MlirValue mlirOperationGetResult(MlirOperation op,
479                                                     intptr_t pos);
480 
481 /// Returns the number of successor blocks of the operation.
482 MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumSuccessors(MlirOperation op);
483 
484 /// Returns `pos`-th successor of the operation.
485 MLIR_CAPI_EXPORTED MlirBlock mlirOperationGetSuccessor(MlirOperation op,
486                                                        intptr_t pos);
487 
488 /// Returns the number of attributes attached to the operation.
489 MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumAttributes(MlirOperation op);
490 
491 /// Return `pos`-th attribute of the operation.
492 MLIR_CAPI_EXPORTED MlirNamedAttribute
493 mlirOperationGetAttribute(MlirOperation op, intptr_t pos);
494 
495 /// Returns an attribute attached to the operation given its name.
496 MLIR_CAPI_EXPORTED MlirAttribute
497 mlirOperationGetAttributeByName(MlirOperation op, MlirStringRef name);
498 
499 /// Sets an attribute by name, replacing the existing if it exists or
500 /// adding a new one otherwise.
501 MLIR_CAPI_EXPORTED void mlirOperationSetAttributeByName(MlirOperation op,
502                                                         MlirStringRef name,
503                                                         MlirAttribute attr);
504 
505 /// Removes an attribute by name. Returns false if the attribute was not found
506 /// and true if removed.
507 MLIR_CAPI_EXPORTED bool mlirOperationRemoveAttributeByName(MlirOperation op,
508                                                            MlirStringRef name);
509 
510 /// Prints an operation by sending chunks of the string representation and
511 /// forwarding `userData to `callback`. Note that the callback may be called
512 /// several times with consecutive chunks of the string.
513 MLIR_CAPI_EXPORTED void mlirOperationPrint(MlirOperation op,
514                                            MlirStringCallback callback,
515                                            void *userData);
516 
517 /// Same as mlirOperationPrint but accepts flags controlling the printing
518 /// behavior.
519 MLIR_CAPI_EXPORTED void mlirOperationPrintWithFlags(MlirOperation op,
520                                                     MlirOpPrintingFlags flags,
521                                                     MlirStringCallback callback,
522                                                     void *userData);
523 
524 /// Prints an operation to stderr.
525 MLIR_CAPI_EXPORTED void mlirOperationDump(MlirOperation op);
526 
527 /// Verify the operation and return true if it passes, false if it fails.
528 MLIR_CAPI_EXPORTED bool mlirOperationVerify(MlirOperation op);
529 
530 /// Moves the given operation immediately after the other operation in its
531 /// parent block. The given operation may be owned by the caller or by its
532 /// current block. The other operation must belong to a block. In any case, the
533 /// ownership is transferred to the block of the other operation.
534 MLIR_CAPI_EXPORTED void mlirOperationMoveAfter(MlirOperation op,
535                                                MlirOperation other);
536 
537 /// Moves the given operation immediately before the other operation in its
538 /// parent block. The given operation may be owner by the caller or by its
539 /// current block. The other operation must belong to a block. In any case, the
540 /// ownership is transferred to the block of the other operation.
541 MLIR_CAPI_EXPORTED void mlirOperationMoveBefore(MlirOperation op,
542                                                 MlirOperation other);
543 //===----------------------------------------------------------------------===//
544 // Region API.
545 //===----------------------------------------------------------------------===//
546 
547 /// Creates a new empty region and transfers ownership to the caller.
548 MLIR_CAPI_EXPORTED MlirRegion mlirRegionCreate();
549 
550 /// Takes a region owned by the caller and destroys it.
551 MLIR_CAPI_EXPORTED void mlirRegionDestroy(MlirRegion region);
552 
553 /// Checks whether a region is null.
mlirRegionIsNull(MlirRegion region)554 static inline bool mlirRegionIsNull(MlirRegion region) { return !region.ptr; }
555 
556 /// Checks whether two region handles point to the same region. This does not
557 /// perform deep comparison.
558 MLIR_CAPI_EXPORTED bool mlirRegionEqual(MlirRegion region, MlirRegion other);
559 
560 /// Gets the first block in the region.
561 MLIR_CAPI_EXPORTED MlirBlock mlirRegionGetFirstBlock(MlirRegion region);
562 
563 /// Takes a block owned by the caller and appends it to the given region.
564 MLIR_CAPI_EXPORTED void mlirRegionAppendOwnedBlock(MlirRegion region,
565                                                    MlirBlock block);
566 
567 /// Takes a block owned by the caller and inserts it at `pos` to the given
568 /// region. This is an expensive operation that linearly scans the region,
569 /// prefer insertAfter/Before instead.
570 MLIR_CAPI_EXPORTED void
571 mlirRegionInsertOwnedBlock(MlirRegion region, intptr_t pos, MlirBlock block);
572 
573 /// Takes a block owned by the caller and inserts it after the (non-owned)
574 /// reference block in the given region. The reference block must belong to the
575 /// region. If the reference block is null, prepends the block to the region.
576 MLIR_CAPI_EXPORTED void mlirRegionInsertOwnedBlockAfter(MlirRegion region,
577                                                         MlirBlock reference,
578                                                         MlirBlock block);
579 
580 /// Takes a block owned by the caller and inserts it before the (non-owned)
581 /// reference block in the given region. The reference block must belong to the
582 /// region. If the reference block is null, appends the block to the region.
583 MLIR_CAPI_EXPORTED void mlirRegionInsertOwnedBlockBefore(MlirRegion region,
584                                                          MlirBlock reference,
585                                                          MlirBlock block);
586 
587 /// Returns first region attached to the operation.
588 MLIR_CAPI_EXPORTED MlirRegion mlirOperationGetFirstRegion(MlirOperation op);
589 
590 /// Returns the region immediately following the given region in its parent
591 /// operation.
592 MLIR_CAPI_EXPORTED MlirRegion mlirRegionGetNextInOperation(MlirRegion region);
593 
594 //===----------------------------------------------------------------------===//
595 // Block API.
596 //===----------------------------------------------------------------------===//
597 
598 /// Creates a new empty block with the given argument types and transfers
599 /// ownership to the caller.
600 MLIR_CAPI_EXPORTED MlirBlock mlirBlockCreate(intptr_t nArgs,
601                                              MlirType const *args,
602                                              MlirLocation const *locs);
603 
604 /// Takes a block owned by the caller and destroys it.
605 MLIR_CAPI_EXPORTED void mlirBlockDestroy(MlirBlock block);
606 
607 /// Detach a block from the owning region and assume ownership.
608 MLIR_CAPI_EXPORTED void mlirBlockDetach(MlirBlock block);
609 
610 /// Checks whether a block is null.
mlirBlockIsNull(MlirBlock block)611 static inline bool mlirBlockIsNull(MlirBlock block) { return !block.ptr; }
612 
613 /// Checks whether two blocks handles point to the same block. This does not
614 /// perform deep comparison.
615 MLIR_CAPI_EXPORTED bool mlirBlockEqual(MlirBlock block, MlirBlock other);
616 
617 /// Returns the closest surrounding operation that contains this block.
618 MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetParentOperation(MlirBlock);
619 
620 /// Returns the region that contains this block.
621 MLIR_CAPI_EXPORTED MlirRegion mlirBlockGetParentRegion(MlirBlock block);
622 
623 /// Returns the block immediately following the given block in its parent
624 /// region.
625 MLIR_CAPI_EXPORTED MlirBlock mlirBlockGetNextInRegion(MlirBlock block);
626 
627 /// Returns the first operation in the block.
628 MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetFirstOperation(MlirBlock block);
629 
630 /// Returns the terminator operation in the block or null if no terminator.
631 MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetTerminator(MlirBlock block);
632 
633 /// Takes an operation owned by the caller and appends it to the block.
634 MLIR_CAPI_EXPORTED void mlirBlockAppendOwnedOperation(MlirBlock block,
635                                                       MlirOperation operation);
636 
637 /// Takes an operation owned by the caller and inserts it as `pos` to the block.
638 /// This is an expensive operation that scans the block linearly, prefer
639 /// insertBefore/After instead.
640 MLIR_CAPI_EXPORTED void mlirBlockInsertOwnedOperation(MlirBlock block,
641                                                       intptr_t pos,
642                                                       MlirOperation operation);
643 
644 /// Takes an operation owned by the caller and inserts it after the (non-owned)
645 /// reference operation in the given block. If the reference is null, prepends
646 /// the operation. Otherwise, the reference must belong to the block.
647 MLIR_CAPI_EXPORTED void
648 mlirBlockInsertOwnedOperationAfter(MlirBlock block, MlirOperation reference,
649                                    MlirOperation operation);
650 
651 /// Takes an operation owned by the caller and inserts it before the (non-owned)
652 /// reference operation in the given block. If the reference is null, appends
653 /// the operation. Otherwise, the reference must belong to the block.
654 MLIR_CAPI_EXPORTED void
655 mlirBlockInsertOwnedOperationBefore(MlirBlock block, MlirOperation reference,
656                                     MlirOperation operation);
657 
658 /// Returns the number of arguments of the block.
659 MLIR_CAPI_EXPORTED intptr_t mlirBlockGetNumArguments(MlirBlock block);
660 
661 /// Appends an argument of the specified type to the block. Returns the newly
662 /// added argument.
663 MLIR_CAPI_EXPORTED MlirValue mlirBlockAddArgument(MlirBlock block,
664                                                   MlirType type,
665                                                   MlirLocation loc);
666 
667 /// Returns `pos`-th argument of the block.
668 MLIR_CAPI_EXPORTED MlirValue mlirBlockGetArgument(MlirBlock block,
669                                                   intptr_t pos);
670 
671 /// Prints a block by sending chunks of the string representation and
672 /// forwarding `userData to `callback`. Note that the callback may be called
673 /// several times with consecutive chunks of the string.
674 MLIR_CAPI_EXPORTED void
675 mlirBlockPrint(MlirBlock block, MlirStringCallback callback, void *userData);
676 
677 //===----------------------------------------------------------------------===//
678 // Value API.
679 //===----------------------------------------------------------------------===//
680 
681 /// Returns whether the value is null.
mlirValueIsNull(MlirValue value)682 static inline bool mlirValueIsNull(MlirValue value) { return !value.ptr; }
683 
684 /// Returns 1 if two values are equal, 0 otherwise.
685 MLIR_CAPI_EXPORTED bool mlirValueEqual(MlirValue value1, MlirValue value2);
686 
687 /// Returns 1 if the value is a block argument, 0 otherwise.
688 MLIR_CAPI_EXPORTED bool mlirValueIsABlockArgument(MlirValue value);
689 
690 /// Returns 1 if the value is an operation result, 0 otherwise.
691 MLIR_CAPI_EXPORTED bool mlirValueIsAOpResult(MlirValue value);
692 
693 /// Returns the block in which this value is defined as an argument. Asserts if
694 /// the value is not a block argument.
695 MLIR_CAPI_EXPORTED MlirBlock mlirBlockArgumentGetOwner(MlirValue value);
696 
697 /// Returns the position of the value in the argument list of its block.
698 MLIR_CAPI_EXPORTED intptr_t mlirBlockArgumentGetArgNumber(MlirValue value);
699 
700 /// Sets the type of the block argument to the given type.
701 MLIR_CAPI_EXPORTED void mlirBlockArgumentSetType(MlirValue value,
702                                                  MlirType type);
703 
704 /// Returns an operation that produced this value as its result. Asserts if the
705 /// value is not an op result.
706 MLIR_CAPI_EXPORTED MlirOperation mlirOpResultGetOwner(MlirValue value);
707 
708 /// Returns the position of the value in the list of results of the operation
709 /// that produced it.
710 MLIR_CAPI_EXPORTED intptr_t mlirOpResultGetResultNumber(MlirValue value);
711 
712 /// Returns the type of the value.
713 MLIR_CAPI_EXPORTED MlirType mlirValueGetType(MlirValue value);
714 
715 /// Prints the value to the standard error stream.
716 MLIR_CAPI_EXPORTED void mlirValueDump(MlirValue value);
717 
718 /// Prints a value by sending chunks of the string representation and
719 /// forwarding `userData to `callback`. Note that the callback may be called
720 /// several times with consecutive chunks of the string.
721 MLIR_CAPI_EXPORTED void
722 mlirValuePrint(MlirValue value, MlirStringCallback callback, void *userData);
723 
724 //===----------------------------------------------------------------------===//
725 // Type API.
726 //===----------------------------------------------------------------------===//
727 
728 /// Parses a type. The type is owned by the context.
729 MLIR_CAPI_EXPORTED MlirType mlirTypeParseGet(MlirContext context,
730                                              MlirStringRef type);
731 
732 /// Gets the context that a type was created with.
733 MLIR_CAPI_EXPORTED MlirContext mlirTypeGetContext(MlirType type);
734 
735 /// Gets the type ID of the type.
736 MLIR_CAPI_EXPORTED MlirTypeID mlirTypeGetTypeID(MlirType type);
737 
738 /// Checks whether a type is null.
mlirTypeIsNull(MlirType type)739 static inline bool mlirTypeIsNull(MlirType type) { return !type.ptr; }
740 
741 /// Checks if two types are equal.
742 MLIR_CAPI_EXPORTED bool mlirTypeEqual(MlirType t1, MlirType t2);
743 
744 /// Prints a location by sending chunks of the string representation and
745 /// forwarding `userData to `callback`. Note that the callback may be called
746 /// several times with consecutive chunks of the string.
747 MLIR_CAPI_EXPORTED void
748 mlirTypePrint(MlirType type, MlirStringCallback callback, void *userData);
749 
750 /// Prints the type to the standard error stream.
751 MLIR_CAPI_EXPORTED void mlirTypeDump(MlirType type);
752 
753 //===----------------------------------------------------------------------===//
754 // Attribute API.
755 //===----------------------------------------------------------------------===//
756 
757 /// Parses an attribute. The attribute is owned by the context.
758 MLIR_CAPI_EXPORTED MlirAttribute mlirAttributeParseGet(MlirContext context,
759                                                        MlirStringRef attr);
760 
761 /// Gets the context that an attribute was created with.
762 MLIR_CAPI_EXPORTED MlirContext mlirAttributeGetContext(MlirAttribute attribute);
763 
764 /// Gets the type of this attribute.
765 MLIR_CAPI_EXPORTED MlirType mlirAttributeGetType(MlirAttribute attribute);
766 
767 /// Gets the type id of the attribute.
768 MLIR_CAPI_EXPORTED MlirTypeID mlirAttributeGetTypeID(MlirAttribute attribute);
769 
770 /// Checks whether an attribute is null.
mlirAttributeIsNull(MlirAttribute attr)771 static inline bool mlirAttributeIsNull(MlirAttribute attr) { return !attr.ptr; }
772 
773 /// Checks if two attributes are equal.
774 MLIR_CAPI_EXPORTED bool mlirAttributeEqual(MlirAttribute a1, MlirAttribute a2);
775 
776 /// Prints an attribute by sending chunks of the string representation and
777 /// forwarding `userData to `callback`. Note that the callback may be called
778 /// several times with consecutive chunks of the string.
779 MLIR_CAPI_EXPORTED void mlirAttributePrint(MlirAttribute attr,
780                                            MlirStringCallback callback,
781                                            void *userData);
782 
783 /// Prints the attribute to the standard error stream.
784 MLIR_CAPI_EXPORTED void mlirAttributeDump(MlirAttribute attr);
785 
786 /// Associates an attribute with the name. Takes ownership of neither.
787 MLIR_CAPI_EXPORTED MlirNamedAttribute mlirNamedAttributeGet(MlirIdentifier name,
788                                                             MlirAttribute attr);
789 
790 //===----------------------------------------------------------------------===//
791 // Identifier API.
792 //===----------------------------------------------------------------------===//
793 
794 /// Gets an identifier with the given string value.
795 MLIR_CAPI_EXPORTED MlirIdentifier mlirIdentifierGet(MlirContext context,
796                                                     MlirStringRef str);
797 
798 /// Returns the context associated with this identifier
799 MLIR_CAPI_EXPORTED MlirContext mlirIdentifierGetContext(MlirIdentifier);
800 
801 /// Checks whether two identifiers are the same.
802 MLIR_CAPI_EXPORTED bool mlirIdentifierEqual(MlirIdentifier ident,
803                                             MlirIdentifier other);
804 
805 /// Gets the string value of the identifier.
806 MLIR_CAPI_EXPORTED MlirStringRef mlirIdentifierStr(MlirIdentifier ident);
807 
808 //===----------------------------------------------------------------------===//
809 // Symbol and SymbolTable API.
810 //===----------------------------------------------------------------------===//
811 
812 /// Returns the name of the attribute used to store symbol names compatible with
813 /// symbol tables.
814 MLIR_CAPI_EXPORTED MlirStringRef mlirSymbolTableGetSymbolAttributeName();
815 
816 /// Returns the name of the attribute used to store symbol visibility.
817 MLIR_CAPI_EXPORTED MlirStringRef mlirSymbolTableGetVisibilityAttributeName();
818 
819 /// Creates a symbol table for the given operation. If the operation does not
820 /// have the SymbolTable trait, returns a null symbol table.
821 MLIR_CAPI_EXPORTED MlirSymbolTable
822 mlirSymbolTableCreate(MlirOperation operation);
823 
824 /// Returns true if the symbol table is null.
mlirSymbolTableIsNull(MlirSymbolTable symbolTable)825 static inline bool mlirSymbolTableIsNull(MlirSymbolTable symbolTable) {
826   return !symbolTable.ptr;
827 }
828 
829 /// Destroys the symbol table created with mlirSymbolTableCreate. This does not
830 /// affect the operations in the table.
831 MLIR_CAPI_EXPORTED void mlirSymbolTableDestroy(MlirSymbolTable symbolTable);
832 
833 /// Looks up a symbol with the given name in the given symbol table and returns
834 /// the operation that corresponds to the symbol. If the symbol cannot be found,
835 /// returns a null operation.
836 MLIR_CAPI_EXPORTED MlirOperation
837 mlirSymbolTableLookup(MlirSymbolTable symbolTable, MlirStringRef name);
838 
839 /// Inserts the given operation into the given symbol table. The operation must
840 /// have the symbol trait. If the symbol table already has a symbol with the
841 /// same name, renames the symbol being inserted to ensure name uniqueness. Note
842 /// that this does not move the operation itself into the block of the symbol
843 /// table operation, this should be done separately. Returns the name of the
844 /// symbol after insertion.
845 MLIR_CAPI_EXPORTED MlirAttribute
846 mlirSymbolTableInsert(MlirSymbolTable symbolTable, MlirOperation operation);
847 
848 /// Removes the given operation from the symbol table and erases it.
849 MLIR_CAPI_EXPORTED void mlirSymbolTableErase(MlirSymbolTable symbolTable,
850                                              MlirOperation operation);
851 
852 /// Attempt to replace all uses that are nested within the given operation
853 /// of the given symbol 'oldSymbol' with the provided 'newSymbol'. This does
854 /// not traverse into nested symbol tables. Will fail atomically if there are
855 /// any unknown operations that may be potential symbol tables.
856 MLIR_CAPI_EXPORTED MlirLogicalResult mlirSymbolTableReplaceAllSymbolUses(
857     MlirStringRef oldSymbol, MlirStringRef newSymbol, MlirOperation from);
858 
859 /// Walks all symbol table operations nested within, and including, `op`. For
860 /// each symbol table operation, the provided callback is invoked with the op
861 /// and a boolean signifying if the symbols within that symbol table can be
862 /// treated as if all uses within the IR are visible to the caller.
863 /// `allSymUsesVisible` identifies whether all of the symbol uses of symbols
864 /// within `op` are visible.
865 MLIR_CAPI_EXPORTED void mlirSymbolTableWalkSymbolTables(
866     MlirOperation from, bool allSymUsesVisible,
867     void (*callback)(MlirOperation, bool, void *userData), void *userData);
868 
869 #ifdef __cplusplus
870 }
871 #endif
872 
873 #endif // MLIR_C_IR_H
874