| //===- ExtensibleDialect - C API for MLIR Extensible Dialect --------------===// | |
| // | |
| // 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 | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "mlir-c/ExtensibleDialect.h" | |
| #include "mlir/CAPI/IR.h" | |
| #include "mlir/CAPI/Support.h" | |
| #include "mlir/IR/ExtensibleDialect.h" | |
| #include "mlir/IR/OperationSupport.h" | |
| using namespace mlir; | |
| DEFINE_C_API_PTR_METHODS(MlirDynamicOpTrait, DynamicOpTrait) | |
| DEFINE_C_API_PTR_METHODS(MlirDynamicTypeDefinition, DynamicTypeDefinition) | |
| DEFINE_C_API_PTR_METHODS(MlirDynamicAttrDefinition, DynamicAttrDefinition) | |
| bool mlirDynamicOpTraitAttach(MlirDynamicOpTrait dynamicOpTrait, | |
| MlirStringRef opName, MlirContext context) { | |
| std::optional<RegisteredOperationName> opNameFound = | |
| RegisteredOperationName::lookup(unwrap(opName), unwrap(context)); | |
| assert(opNameFound && "operation name must be registered in the context"); | |
| // The original getImpl() is protected, so we create a small helper struct | |
| // here. | |
| struct RegisteredOperationNameWithImpl : RegisteredOperationName { | |
| Impl *getImpl() { return RegisteredOperationName::getImpl(); } | |
| }; | |
| OperationName::Impl *impl = | |
| static_cast<RegisteredOperationNameWithImpl &>(*opNameFound).getImpl(); | |
| std::unique_ptr<DynamicOpTrait> trait(unwrap(dynamicOpTrait)); | |
| // TODO: we should enable llvm-style RTTI for `OperationName::Impl` and check | |
| // whether the `impl` is a `DynamicOpDefinition` here. | |
| return static_cast<DynamicOpDefinition *>(impl)->addTrait(std::move(trait)); | |
| } | |
| MlirDynamicOpTrait mlirDynamicOpTraitIsTerminatorCreate() { | |
| return wrap(new DynamicOpTraits::IsTerminator()); | |
| } | |
| MlirTypeID mlirDynamicOpTraitIsTerminatorGetTypeID() { | |
| return wrap(DynamicOpTraits::IsTerminator::getStaticTypeID()); | |
| } | |
| MlirDynamicOpTrait mlirDynamicOpTraitNoTerminatorCreate() { | |
| return wrap(new DynamicOpTraits::NoTerminator()); | |
| } | |
| MlirTypeID mlirDynamicOpTraitNoTerminatorGetTypeID() { | |
| return wrap(DynamicOpTraits::NoTerminator::getStaticTypeID()); | |
| } | |
| namespace mlir::DynamicOpTraits { | |
| class RecursiveMemoryEffects | |
| : public DynamicOpTraitImpl<OpTrait::HasRecursiveMemoryEffects> {}; | |
| } // namespace mlir::DynamicOpTraits | |
| MlirDynamicOpTrait mlirDynamicOpTraitRecursiveMemoryEffectsCreate(void) { | |
| return wrap(new DynamicOpTraits::RecursiveMemoryEffects()); | |
| } | |
| MlirTypeID mlirDynamicOpTraitRecursiveMemoryEffectsGetTypeID(void) { | |
| return wrap(DynamicOpTraits::RecursiveMemoryEffects::getStaticTypeID()); | |
| } | |
| MlirDynamicOpTrait mlirDynamicOpTraitIsIsolatedFromAboveCreate() { | |
| return wrap(new DynamicOpTraits::IsIsolatedFromAbove()); | |
| } | |
| MlirTypeID mlirDynamicOpTraitIsIsolatedFromAboveGetTypeID() { | |
| return wrap(DynamicOpTraits::IsIsolatedFromAbove::getStaticTypeID()); | |
| } | |
| void mlirDynamicOpTraitDestroy(MlirDynamicOpTrait dynamicOpTrait) { | |
| delete unwrap(dynamicOpTrait); | |
| } | |
| namespace mlir { | |
| class ExternalDynamicOpTrait : public DynamicOpTrait { | |
| public: | |
| ExternalDynamicOpTrait(TypeID typeID, MlirDynamicOpTraitCallbacks callbacks, | |
| void *userData) | |
| : typeID(typeID), callbacks(callbacks), userData(userData) { | |
| if (callbacks.construct) | |
| callbacks.construct(userData); | |
| } | |
| ~ExternalDynamicOpTrait() { | |
| if (callbacks.destruct) | |
| callbacks.destruct(userData); | |
| } | |
| LogicalResult verifyTrait(Operation *op) const override { | |
| return unwrap(callbacks.verifyTrait(wrap(op), userData)); | |
| }; | |
| LogicalResult verifyRegionTrait(Operation *op) const override { | |
| return unwrap(callbacks.verifyRegionTrait(wrap(op), userData)); | |
| }; | |
| TypeID getTypeID() const override { return typeID; }; | |
| private: | |
| TypeID typeID; | |
| MlirDynamicOpTraitCallbacks callbacks; | |
| void *userData; | |
| }; | |
| } // namespace mlir | |
| MlirDynamicOpTrait mlirDynamicOpTraitCreate( | |
| MlirTypeID typeID, MlirDynamicOpTraitCallbacks callbacks, void *userData) { | |
| return wrap( | |
| new mlir::ExternalDynamicOpTrait(unwrap(typeID), callbacks, userData)); | |
| } | |
| bool mlirDialectIsAExtensibleDialect(MlirDialect dialect) { | |
| return llvm::isa<mlir::ExtensibleDialect>(unwrap(dialect)); | |
| } | |
| MlirDynamicTypeDefinition | |
| mlirExtensibleDialectLookupTypeDefinition(MlirDialect dialect, | |
| MlirStringRef typeName) { | |
| return wrap(llvm::cast<mlir::ExtensibleDialect>(unwrap(dialect)) | |
| ->lookupTypeDefinition(unwrap(typeName))); | |
| } | |
| bool mlirTypeIsADynamicType(MlirType type) { | |
| return llvm::isa<mlir::DynamicType>(unwrap(type)); | |
| } | |
| MlirTypeID mlirDynamicTypeGetTypeID() { | |
| return wrap(mlir::DynamicType::getTypeID()); | |
| } | |
| MlirType mlirDynamicTypeGet(MlirDynamicTypeDefinition typeDef, | |
| MlirAttribute *attrs, intptr_t numAttrs) { | |
| llvm::SmallVector<mlir::Attribute> attributes; | |
| attributes.reserve(numAttrs); | |
| for (intptr_t i = 0; i < numAttrs; ++i) | |
| attributes.push_back(unwrap(attrs[i])); | |
| return wrap(mlir::DynamicType::get(unwrap(typeDef), attributes)); | |
| } | |
| intptr_t mlirDynamicTypeGetNumParams(MlirType type) { | |
| return llvm::cast<mlir::DynamicType>(unwrap(type)).getParams().size(); | |
| } | |
| MlirAttribute mlirDynamicTypeGetParam(MlirType type, intptr_t index) { | |
| return wrap(llvm::cast<mlir::DynamicType>(unwrap(type)).getParams()[index]); | |
| } | |
| MlirDynamicTypeDefinition mlirDynamicTypeGetTypeDef(MlirType type) { | |
| return wrap(llvm::cast<mlir::DynamicType>(unwrap(type)).getTypeDef()); | |
| } | |
| MlirTypeID | |
| mlirDynamicTypeDefinitionGetTypeID(MlirDynamicTypeDefinition typeDef) { | |
| return wrap(unwrap(typeDef)->getTypeID()); | |
| } | |
| MlirStringRef | |
| mlirDynamicTypeDefinitionGetName(MlirDynamicTypeDefinition typeDef) { | |
| return wrap(unwrap(typeDef)->getName()); | |
| } | |
| MlirDialect | |
| mlirDynamicTypeDefinitionGetDialect(MlirDynamicTypeDefinition typeDef) { | |
| return wrap(unwrap(typeDef)->getDialect()); | |
| } | |
| MlirDynamicAttrDefinition | |
| mlirExtensibleDialectLookupAttrDefinition(MlirDialect dialect, | |
| MlirStringRef attrName) { | |
| return wrap(llvm::cast<mlir::ExtensibleDialect>(unwrap(dialect)) | |
| ->lookupAttrDefinition(unwrap(attrName))); | |
| } | |
| bool mlirAttributeIsADynamicAttr(MlirAttribute attr) { | |
| return llvm::isa<mlir::DynamicAttr>(unwrap(attr)); | |
| } | |
| MlirTypeID mlirDynamicAttrGetTypeID(void) { | |
| return wrap(mlir::DynamicAttr::getTypeID()); | |
| } | |
| MlirAttribute mlirDynamicAttrGet(MlirDynamicAttrDefinition attrDef, | |
| MlirAttribute *attrs, intptr_t numAttrs) { | |
| llvm::SmallVector<mlir::Attribute> attributes; | |
| attributes.reserve(numAttrs); | |
| for (intptr_t i = 0; i < numAttrs; ++i) | |
| attributes.push_back(unwrap(attrs[i])); | |
| return wrap(mlir::DynamicAttr::get(unwrap(attrDef), attributes)); | |
| } | |
| intptr_t mlirDynamicAttrGetNumParams(MlirAttribute attr) { | |
| return llvm::cast<mlir::DynamicAttr>(unwrap(attr)).getParams().size(); | |
| } | |
| MlirAttribute mlirDynamicAttrGetParam(MlirAttribute attr, intptr_t index) { | |
| return wrap(llvm::cast<mlir::DynamicAttr>(unwrap(attr)).getParams()[index]); | |
| } | |
| MlirDynamicAttrDefinition mlirDynamicAttrGetAttrDef(MlirAttribute attr) { | |
| return wrap(llvm::cast<mlir::DynamicAttr>(unwrap(attr)).getAttrDef()); | |
| } | |
| MlirTypeID | |
| mlirDynamicAttrDefinitionGetTypeID(MlirDynamicAttrDefinition attrDef) { | |
| return wrap(unwrap(attrDef)->getTypeID()); | |
| } | |
| MlirStringRef | |
| mlirDynamicAttrDefinitionGetName(MlirDynamicAttrDefinition attrDef) { | |
| return wrap(unwrap(attrDef)->getName()); | |
| } | |
| MlirDialect | |
| mlirDynamicAttrDefinitionGetDialect(MlirDynamicAttrDefinition attrDef) { | |
| return wrap(unwrap(attrDef)->getDialect()); | |
| } |