Files
llvm-project/mlir/include/mlir-c/Interfaces.h
Rolf Morel a1d7cda1d7 [MLIR][Python] Impl XOpInterface(s) from Python, with X=Transform and X=MemoryEffects (#176920)
Provides the infrastructure for implementing and late-binding
OpInterfaces from Python.

* On the mlir-c API declaration side, each `XOpInterface` has a callback
struct, with a callback for each method and a userdata member (provided
as an arg to each method), and a
`mlirXOpInterfaceAttachFallbackModel(ctx, op_name, callbacks)` func.
* This CAPI is implemented by defining a subclass of
`XOpInterface::FallbackModel` that holds the callback struct and has
each method call the corresponding callback (with userdata as an arg).
Given a callback struct, a new `FallbackModel` is created and attached,
i.e. late bound, to the named op. (MLIR's interface infrastructure is
such that the thus registered `FallbackModel` will be returned in case
the op gets cast to the `XOpInterface`.)
* On the Python side, we expose a stand-in `XOpInterface` base class
which has one (class)method: `XOpInterface.attach(cls, op_name, ctx)`.
Python users subclass this class (`class MyInterfaceImpl(XOpInterface):
...`) and implement the interface's methods (with the right names and
signatures). The user calls `attach` on the subclass
(`MyInterfaceImpl.attach("my_dialect.my_op", ctx)`) which prepares the
callbacks struct _with userdata set to the subclass_ (as we use it to
lookup methods). These callbacks (and userdata) are then registered as
an `XOpInterface::FallbackModel` by
`mlirXOpInterfaceAttachFallbackModel(...)`. From then on the Python
methods will be used to respond to calls to the interface methods
(originating in C++).

This PR enables implementing the TransformOpInterface and the
MemoryEffectsOpInterface, both of which are required for making an op
into a transform op.

Everything besides the above linked code is there to facilitate exposing
the interfaces: the right types for the arguments of the methods are
exposed as are functions/methods for manipulating these arguments (e.g.
specifying side effects on `OpOperand`s and `OpResult`s and being able
to access and set the transform handles associated with args and
results).
2026-02-12 14:07:10 +00:00

130 lines
5.8 KiB
C

//===-- mlir-c/Interfaces.h - C API to Core MLIR IR interfaces ----*- 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 interface classes. It is
// intended to contain interfaces defined in lib/Interfaces.
//
//===----------------------------------------------------------------------===//
#ifndef MLIR_C_INTERFACES_H
#define MLIR_C_INTERFACES_H
#include "mlir-c/IR.h"
#include "mlir-c/Support.h"
#ifdef __cplusplus
extern "C" {
#endif
#define DEFINE_C_API_STRUCT(name, storage) \
struct name { \
storage *ptr; \
}; \
typedef struct name name
DEFINE_C_API_STRUCT(MlirMemoryEffectInstancesList, void);
#undef DEFINE_C_API_STRUCT
/// Returns `true` if the given operation implements an interface identified by
/// its TypeID.
MLIR_CAPI_EXPORTED bool
mlirOperationImplementsInterface(MlirOperation operation,
MlirTypeID interfaceTypeID);
/// Returns `true` if the operation identified by its canonical string name
/// implements the interface identified by its TypeID in the given context.
/// Note that interfaces may be attached to operations in some contexts and not
/// others.
MLIR_CAPI_EXPORTED bool
mlirOperationImplementsInterfaceStatic(MlirStringRef operationName,
MlirContext context,
MlirTypeID interfaceTypeID);
//===----------------------------------------------------------------------===//
// InferTypeOpInterface.
//===----------------------------------------------------------------------===//
/// Returns the interface TypeID of the InferTypeOpInterface.
MLIR_CAPI_EXPORTED MlirTypeID mlirInferTypeOpInterfaceTypeID(void);
/// These callbacks are used to return multiple types from functions while
/// transferring ownership to the caller. The first argument is the number of
/// consecutive elements pointed to by the second argument. The third argument
/// is an opaque pointer forwarded to the callback by the caller.
typedef void (*MlirTypesCallback)(intptr_t, MlirType *, void *);
/// Infers the return types of the operation identified by its canonical given
/// the arguments that will be supplied to its generic builder. Calls `callback`
/// with the types of inferred arguments, potentially several times, on success.
/// Returns failure otherwise.
MLIR_CAPI_EXPORTED MlirLogicalResult mlirInferTypeOpInterfaceInferReturnTypes(
MlirStringRef opName, MlirContext context, MlirLocation location,
intptr_t nOperands, MlirValue *operands, MlirAttribute attributes,
void *properties, intptr_t nRegions, MlirRegion *regions,
MlirTypesCallback callback, void *userData);
//===----------------------------------------------------------------------===//
// InferShapedTypeOpInterface.
//===----------------------------------------------------------------------===//
/// Returns the interface TypeID of the InferShapedTypeOpInterface.
MLIR_CAPI_EXPORTED MlirTypeID mlirInferShapedTypeOpInterfaceTypeID(void);
/// These callbacks are used to return multiple shaped type components from
/// functions while transferring ownership to the caller. The first argument is
/// the has rank boolean followed by the the rank and a pointer to the shape
/// (if applicable). The next argument is the element type, then the attribute.
/// The last argument is an opaque pointer forwarded to the callback by the
/// caller. This callback will be called potentially multiple times for each
/// shaped type components.
typedef void (*MlirShapedTypeComponentsCallback)(bool, intptr_t,
const int64_t *, MlirType,
MlirAttribute, void *);
/// Infers the return shaped type components of the operation. Calls `callback`
/// with the types of inferred arguments on success. Returns failure otherwise.
MLIR_CAPI_EXPORTED MlirLogicalResult
mlirInferShapedTypeOpInterfaceInferReturnTypes(
MlirStringRef opName, MlirContext context, MlirLocation location,
intptr_t nOperands, MlirValue *operands, MlirAttribute attributes,
void *properties, intptr_t nRegions, MlirRegion *regions,
MlirShapedTypeComponentsCallback callback, void *userData);
//===---------------------------------------------------------------------===//
// MemoryEffectsOpInterface
//===---------------------------------------------------------------------===//
/// Returns the interface TypeID of the MemoryEffectsOpInterface.
MLIR_CAPI_EXPORTED MlirTypeID mlirMemoryEffectsOpInterfaceTypeID(void);
/// Callbacks for implementing MemoryEffectsOpInterface from external code.
typedef struct {
/// Optional constructor for user data. Set to nullptr to disable it.
void (*construct)(void *userData);
/// Optional destructor for user data. Set to nullptr to disable it.
void (*destruct)(void *userData);
/// Get memory effects callback.
void (*getEffects)(MlirOperation op, MlirMemoryEffectInstancesList effects,
void *userData);
void *userData;
} MlirMemoryEffectsOpInterfaceCallbacks;
/// Attach a new FallbackModel for the MemoryEffectsOpInterface to the named
/// operation. The FallbackModel will call the provided callbacks.
MLIR_CAPI_EXPORTED void mlirMemoryEffectsOpInterfaceAttachFallbackModel(
MlirContext ctx, MlirStringRef opName,
MlirMemoryEffectsOpInterfaceCallbacks callbacks);
#ifdef __cplusplus
}
#endif
#endif // MLIR_C_INTERFACES_H