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