IR.h
19.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
/*===-- mlir-c/IR.h - C API to Core MLIR IR classes ---------------*- C -*-===*\
|* *|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|* Exceptions. *|
|* See https://llvm.org/LICENSE.txt for license information. *|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This header declares the C interface to MLIR core IR classes. *|
|* *|
|* Many exotic languages can interoperate with C code but have a harder time *|
|* with C++ due to name mangling. So in addition to C, this interface enables *|
|* tools written in such languages. *|
|* *|
\*===----------------------------------------------------------------------===*/
#ifndef MLIR_C_IR_H
#define MLIR_C_IR_H
#include <stdint.h>
#include "mlir-c/Support.h"
#ifdef __cplusplus
extern "C" {
#endif
/*============================================================================*/
/** Opaque type declarations.
*
* Types are exposed to C bindings as structs containing opaque pointers. They
* are not supposed to be inspected from C. This allows the underlying
* representation to change without affecting the API users. The use of structs
* instead of typedefs enables some type safety as structs are not implicitly
* convertible to each other.
*
* Instances of these types may or may not own the underlying object (most often
* only point to an IR fragment without owning it). The ownership semantics is
* defined by how an instance of the type was obtained.
*/
/*============================================================================*/
#define DEFINE_C_API_STRUCT(name, storage) \
struct name { \
storage *ptr; \
}; \
typedef struct name name
DEFINE_C_API_STRUCT(MlirContext, void);
DEFINE_C_API_STRUCT(MlirDialect, void);
DEFINE_C_API_STRUCT(MlirOperation, void);
DEFINE_C_API_STRUCT(MlirBlock, void);
DEFINE_C_API_STRUCT(MlirRegion, void);
DEFINE_C_API_STRUCT(MlirValue, const void);
DEFINE_C_API_STRUCT(MlirAttribute, const void);
DEFINE_C_API_STRUCT(MlirType, const void);
DEFINE_C_API_STRUCT(MlirLocation, const void);
DEFINE_C_API_STRUCT(MlirModule, const void);
/** Named MLIR attribute.
*
* A named attribute is essentially a (name, attribute) pair where the name is
* a string.
*/
struct MlirNamedAttribute {
const char *name;
MlirAttribute attribute;
};
typedef struct MlirNamedAttribute MlirNamedAttribute;
/** A callback for returning string references.
*
* This function is called back by the functions that need to return a reference
* to the portion of the string with the following arguments:
* - a pointer to the beginning of a string;
* - the length of the string (the pointer may point to a larger buffer, not
* necessarily null-terminated);
* - a pointer to user data forwarded from the printing call.
*/
typedef void (*MlirStringCallback)(const char *, intptr_t, void *);
/*============================================================================*/
/* Context API. */
/*============================================================================*/
/** Creates an MLIR context and transfers its ownership to the caller. */
MlirContext mlirContextCreate();
/** Checks if two contexts are equal. */
int mlirContextEqual(MlirContext ctx1, MlirContext ctx2);
/** Checks whether a context is null. */
inline int mlirContextIsNull(MlirContext context) { return !context.ptr; }
/** Takes an MLIR context owned by the caller and destroys it. */
void mlirContextDestroy(MlirContext context);
/** Sets whether unregistered dialects are allowed in this context. */
void mlirContextSetAllowUnregisteredDialects(MlirContext context, int allow);
/** Returns whether the context allows unregistered dialects. */
int mlirContextGetAllowUnregisteredDialects(MlirContext context);
/** Returns the number of dialects registered with the given context. A
* registered dialect will be loaded if needed by the parser. */
intptr_t mlirContextGetNumRegisteredDialects(MlirContext context);
/** Returns the number of dialects loaded by the context.
*/
intptr_t mlirContextGetNumLoadedDialects(MlirContext context);
/** Gets the dialect instance owned by the given context using the dialect
* namespace to identify it, loads (i.e., constructs the instance of) the
* dialect if necessary. If the dialect is not registered with the context,
* returns null. Use mlirContextLoad<Name>Dialect to load an unregistered
* dialect. */
MlirDialect mlirContextGetOrLoadDialect(MlirContext context,
MlirStringRef name);
/*============================================================================*/
/* Dialect API. */
/*============================================================================*/
/** Returns the context that owns the dialect. */
MlirContext mlirDialectGetContext(MlirDialect dialect);
/** Checks if the dialect is null. */
int mlirDialectIsNull(MlirDialect dialect);
/** Checks if two dialects that belong to the same context are equal. Dialects
* from different contexts will not compare equal. */
int mlirDialectEqual(MlirDialect dialect1, MlirDialect dialect2);
/** Returns the namespace of the given dialect. */
MlirStringRef mlirDialectGetNamespace(MlirDialect dialect);
/*============================================================================*/
/* Location API. */
/*============================================================================*/
/** Creates an File/Line/Column location owned by the given context. */
MlirLocation mlirLocationFileLineColGet(MlirContext context,
const char *filename, unsigned line,
unsigned col);
/** Creates a location with unknown position owned by the given context. */
MlirLocation mlirLocationUnknownGet(MlirContext context);
/** Gets the context that a location was created with. */
MlirContext mlirLocationGetContext(MlirLocation location);
/** Prints a location by sending chunks of the string representation and
* forwarding `userData to `callback`. Note that the callback may be called
* several times with consecutive chunks of the string. */
void mlirLocationPrint(MlirLocation location, MlirStringCallback callback,
void *userData);
/*============================================================================*/
/* Module API. */
/*============================================================================*/
/** Creates a new, empty module and transfers ownership to the caller. */
MlirModule mlirModuleCreateEmpty(MlirLocation location);
/** Parses a module from the string and transfers ownership to the caller. */
MlirModule mlirModuleCreateParse(MlirContext context, const char *module);
/** Gets the context that a module was created with. */
MlirContext mlirModuleGetContext(MlirModule module);
/** Checks whether a module is null. */
inline int mlirModuleIsNull(MlirModule module) { return !module.ptr; }
/** Takes a module owned by the caller and deletes it. */
void mlirModuleDestroy(MlirModule module);
/** Views the module as a generic operation. */
MlirOperation mlirModuleGetOperation(MlirModule module);
/*============================================================================*/
/* Operation state. */
/*============================================================================*/
/** An auxiliary class for constructing operations.
*
* This class contains all the information necessary to construct the operation.
* It owns the MlirRegions it has pointers to and does not own anything else.
* By default, the state can be constructed from a name and location, the latter
* being also used to access the context, and has no other components. These
* components can be added progressively until the operation is constructed.
* Users are not expected to rely on the internals of this class and should use
* mlirOperationState* functions instead.
*/
struct MlirOperationState {
const char *name;
MlirLocation location;
intptr_t nResults;
MlirType *results;
intptr_t nOperands;
MlirValue *operands;
intptr_t nRegions;
MlirRegion *regions;
intptr_t nSuccessors;
MlirBlock *successors;
intptr_t nAttributes;
MlirNamedAttribute *attributes;
};
typedef struct MlirOperationState MlirOperationState;
/** Constructs an operation state from a name and a location. */
MlirOperationState mlirOperationStateGet(const char *name, MlirLocation loc);
/** Adds a list of components to the operation state. */
void mlirOperationStateAddResults(MlirOperationState *state, intptr_t n,
MlirType *results);
void mlirOperationStateAddOperands(MlirOperationState *state, intptr_t n,
MlirValue *operands);
void mlirOperationStateAddOwnedRegions(MlirOperationState *state, intptr_t n,
MlirRegion *regions);
void mlirOperationStateAddSuccessors(MlirOperationState *state, intptr_t n,
MlirBlock *successors);
void mlirOperationStateAddAttributes(MlirOperationState *state, intptr_t n,
MlirNamedAttribute *attributes);
/*============================================================================*/
/* Operation API. */
/*============================================================================*/
/** Creates an operation and transfers ownership to the caller. */
MlirOperation mlirOperationCreate(const MlirOperationState *state);
/** Takes an operation owned by the caller and destroys it. */
void mlirOperationDestroy(MlirOperation op);
/** Checks whether the underlying operation is null. */
int mlirOperationIsNull(MlirOperation op);
/** Returns the number of regions attached to the given operation. */
intptr_t mlirOperationGetNumRegions(MlirOperation op);
/** Returns `pos`-th region attached to the operation. */
MlirRegion mlirOperationGetRegion(MlirOperation op, intptr_t pos);
/** Returns an operation immediately following the given operation it its
* enclosing block. */
MlirOperation mlirOperationGetNextInBlock(MlirOperation op);
/** Returns the number of operands of the operation. */
intptr_t mlirOperationGetNumOperands(MlirOperation op);
/** Returns `pos`-th operand of the operation. */
MlirValue mlirOperationGetOperand(MlirOperation op, intptr_t pos);
/** Returns the number of results of the operation. */
intptr_t mlirOperationGetNumResults(MlirOperation op);
/** Returns `pos`-th result of the operation. */
MlirValue mlirOperationGetResult(MlirOperation op, intptr_t pos);
/** Returns the number of successor blocks of the operation. */
intptr_t mlirOperationGetNumSuccessors(MlirOperation op);
/** Returns `pos`-th successor of the operation. */
MlirBlock mlirOperationGetSuccessor(MlirOperation op, intptr_t pos);
/** Returns the number of attributes attached to the operation. */
intptr_t mlirOperationGetNumAttributes(MlirOperation op);
/** Return `pos`-th attribute of the operation. */
MlirNamedAttribute mlirOperationGetAttribute(MlirOperation op, intptr_t pos);
/** Returns an attribute attached to the operation given its name. */
MlirAttribute mlirOperationGetAttributeByName(MlirOperation op,
const char *name);
/** Prints an operation by sending chunks of the string representation and
* forwarding `userData to `callback`. Note that the callback may be called
* several times with consecutive chunks of the string. */
void mlirOperationPrint(MlirOperation op, MlirStringCallback callback,
void *userData);
/** Prints an operation to stderr. */
void mlirOperationDump(MlirOperation op);
/*============================================================================*/
/* Region API. */
/*============================================================================*/
/** Creates a new empty region and transfers ownership to the caller. */
MlirRegion mlirRegionCreate();
/** Takes a region owned by the caller and destroys it. */
void mlirRegionDestroy(MlirRegion region);
/** Checks whether a region is null. */
int mlirRegionIsNull(MlirRegion region);
/** Gets the first block in the region. */
MlirBlock mlirRegionGetFirstBlock(MlirRegion region);
/** Takes a block owned by the caller and appends it to the given region. */
void mlirRegionAppendOwnedBlock(MlirRegion region, MlirBlock block);
/** Takes a block owned by the caller and inserts it at `pos` to the given
* region. This is an expensive operation that linearly scans the region, prefer
* insertAfter/Before instead. */
void mlirRegionInsertOwnedBlock(MlirRegion region, intptr_t pos,
MlirBlock block);
/** Takes a block owned by the caller and inserts it after the (non-owned)
* reference block in the given region. The reference block must belong to the
* region. If the reference block is null, prepends the block to the region. */
void mlirRegionInsertOwnedBlockAfter(MlirRegion region, MlirBlock reference,
MlirBlock block);
/** Takes a block owned by the caller and inserts it before the (non-owned)
* reference block in the given region. The reference block must belong to the
* region. If the reference block is null, appends the block to the region. */
void mlirRegionInsertOwnedBlockBefore(MlirRegion region, MlirBlock reference,
MlirBlock block);
/*============================================================================*/
/* Block API. */
/*============================================================================*/
/** Creates a new empty block with the given argument types and transfers
* ownership to the caller. */
MlirBlock mlirBlockCreate(intptr_t nArgs, MlirType *args);
/** Takes a block owned by the caller and destroys it. */
void mlirBlockDestroy(MlirBlock block);
/** Checks whether a block is null. */
int mlirBlockIsNull(MlirBlock block);
/** Returns the block immediately following the given block in its parent
* region. */
MlirBlock mlirBlockGetNextInRegion(MlirBlock block);
/** Returns the first operation in the block. */
MlirOperation mlirBlockGetFirstOperation(MlirBlock block);
/** Takes an operation owned by the caller and appends it to the block. */
void mlirBlockAppendOwnedOperation(MlirBlock block, MlirOperation operation);
/** Takes an operation owned by the caller and inserts it as `pos` to the block.
This is an expensive operation that scans the block linearly, prefer
insertBefore/After instead. */
void mlirBlockInsertOwnedOperation(MlirBlock block, intptr_t pos,
MlirOperation operation);
/** Takes an operation owned by the caller and inserts it after the (non-owned)
* reference operation in the given block. If the reference is null, prepends
* the operation. Otherwise, the reference must belong to the block. */
void mlirBlockInsertOwnedOperationAfter(MlirBlock block,
MlirOperation reference,
MlirOperation operation);
/** Takes an operation owned by the caller and inserts it before the (non-owned)
* reference operation in the given block. If the reference is null, appends the
* operation. Otherwise, the reference must belong to the block. */
void mlirBlockInsertOwnedOperationBefore(MlirBlock block,
MlirOperation reference,
MlirOperation operation);
/** Returns the number of arguments of the block. */
intptr_t mlirBlockGetNumArguments(MlirBlock block);
/** Returns `pos`-th argument of the block. */
MlirValue mlirBlockGetArgument(MlirBlock block, intptr_t pos);
/** Prints a block by sending chunks of the string representation and
* forwarding `userData to `callback`. Note that the callback may be called
* several times with consecutive chunks of the string. */
void mlirBlockPrint(MlirBlock block, MlirStringCallback callback,
void *userData);
/*============================================================================*/
/* Value API. */
/*============================================================================*/
/** Returns the type of the value. */
MlirType mlirValueGetType(MlirValue value);
/** Prints a value by sending chunks of the string representation and
* forwarding `userData to `callback`. Note that the callback may be called
* several times with consecutive chunks of the string. */
void mlirValuePrint(MlirValue value, MlirStringCallback callback,
void *userData);
/*============================================================================*/
/* Type API. */
/*============================================================================*/
/** Parses a type. The type is owned by the context. */
MlirType mlirTypeParseGet(MlirContext context, const char *type);
/** Gets the context that a type was created with. */
MlirContext mlirTypeGetContext(MlirType type);
/** Checks whether a type is null. */
inline int mlirTypeIsNull(MlirType type) { return !type.ptr; }
/** Checks if two types are equal. */
int mlirTypeEqual(MlirType t1, MlirType t2);
/** Prints a location by sending chunks of the string representation and
* forwarding `userData to `callback`. Note that the callback may be called
* several times with consecutive chunks of the string. */
void mlirTypePrint(MlirType type, MlirStringCallback callback, void *userData);
/** Prints the type to the standard error stream. */
void mlirTypeDump(MlirType type);
/*============================================================================*/
/* Attribute API. */
/*============================================================================*/
/** Parses an attribute. The attribute is owned by the context. */
MlirAttribute mlirAttributeParseGet(MlirContext context, const char *attr);
/** Gets the context that an attribute was created with. */
MlirContext mlirAttributeGetContext(MlirAttribute attribute);
/** Checks whether an attribute is null. */
inline int mlirAttributeIsNull(MlirAttribute attr) { return !attr.ptr; }
/** Checks if two attributes are equal. */
int mlirAttributeEqual(MlirAttribute a1, MlirAttribute a2);
/** Prints an attribute by sending chunks of the string representation and
* forwarding `userData to `callback`. Note that the callback may be called
* several times with consecutive chunks of the string. */
void mlirAttributePrint(MlirAttribute attr, MlirStringCallback callback,
void *userData);
/** Prints the attribute to the standard error stream. */
void mlirAttributeDump(MlirAttribute attr);
/** Associates an attribute with the name. Takes ownership of neither. */
MlirNamedAttribute mlirNamedAttributeGet(const char *name, MlirAttribute attr);
#ifdef __cplusplus
}
#endif
#endif // MLIR_C_IR_H