[Mlir-commits] [mlir] [mlir][CAPI] Add C API for creating dynamic dialects, ops, types, and attrs (PR #187239)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Mar 19 08:28:01 PDT 2026


================
@@ -31,12 +31,128 @@ extern "C" {
   };                                                                           \
   typedef struct name name
 
+DEFINE_C_API_STRUCT(MlirDynamicDialect, void);
+DEFINE_C_API_STRUCT(MlirDynamicOpDefinition, void);
 DEFINE_C_API_STRUCT(MlirDynamicOpTrait, void);
 DEFINE_C_API_STRUCT(MlirDynamicTypeDefinition, void);
 DEFINE_C_API_STRUCT(MlirDynamicAttrDefinition, void);
 
 #undef DEFINE_C_API_STRUCT
 
+//===----------------------------------------------------------------------===//
+/// Dynamic dialect creation
+//===----------------------------------------------------------------------===//
+
+/// Create a new dynamic dialect with the given name and register it with the
+/// context. If a dialect with the same name already exists, returns the
+/// existing one. The context takes ownership of the dialect. The returned
+/// handle is valid as long as the context is alive and must not be freed.
+MLIR_CAPI_EXPORTED MlirDynamicDialect
+mlirDynamicDialectCreate(MlirContext ctx, MlirStringRef name);
+
+/// Get the underlying MlirDialect from a MlirDynamicDialect.
+MLIR_CAPI_EXPORTED MlirDialect
+mlirDynamicDialectGetDialect(MlirDynamicDialect dialect);
+
+//===----------------------------------------------------------------------===//
+/// Dynamic op definition creation
+//===----------------------------------------------------------------------===//
+
+/// Callback to verify a dynamic op.
+typedef MlirLogicalResult (*MlirDynamicOpVerifyFn)(MlirOperation op,
+                                                   void *userData);
+
+/// Create a dynamic op definition with the given name and verifier callbacks.
+/// The name should be the bare op name (e.g. "constant"), not the
+/// dialect-qualified name. The definition is NOT yet registered with the
+/// dialect; call mlirDynamicDialectRegisterOp to register it.
+/// Both \p verifyFn and \p verifyRegionFn may be NULL, in which case
+/// verification always succeeds. \p userData is shared between both callbacks.
+/// If the definition is not registered, it must be destroyed with
+/// mlirDynamicOpDefinitionDestroy to avoid a memory leak.
+MLIR_CAPI_EXPORTED MlirDynamicOpDefinition mlirDynamicOpDefinitionCreate(
+    MlirDynamicDialect dialect, MlirStringRef name,
+    MlirDynamicOpVerifyFn verifyFn, MlirDynamicOpVerifyFn verifyRegionFn,
+    void *userData);
----------------
PragmaTwice wrote:

I'm thinking that maybe we should define a structure with callbacks, like
```c
typedef struct {
  void (*construct)(void *userData);
  void (*destruct)(void *userData);

  MlirLogicalResult (*verify)(MlirOperation op, void *userData);
  MlirLogicalResult (*verifyRegion)(MlirOperation op, void *userData);

  // add more in the future ..
} MlirDynamicOpDefinitionCallbacks;

MLIR_CAPI_EXPORTED MlirDynamicOpDefinition mlirDynamicOpDefinitionCreate(
    MlirStringRef name,
    MlirDynamicDialect dialect, 
    MlirDynamicOpDefinitionCallbacks callbacks,
    void *userData);
```

This will make the API more extensible.

https://github.com/llvm/llvm-project/pull/187239


More information about the Mlir-commits mailing list