| //===- Rewrite.cpp - C API for Rewrite Patterns ---------------------------===// |
| // |
| // 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/Rewrite.h" |
| |
| #include "mlir-c/Support.h" |
| #include "mlir-c/Transforms.h" |
| #include "mlir/CAPI/IR.h" |
| #include "mlir/CAPI/IRMapping.h" |
| #include "mlir/CAPI/Rewrite.h" |
| #include "mlir/CAPI/Support.h" |
| #include "mlir/CAPI/Wrap.h" |
| #include "mlir/IR/Attributes.h" |
| #include "mlir/IR/PDLPatternMatch.h.inc" |
| #include "mlir/IR/PatternMatch.h" |
| #include "mlir/Rewrite/FrozenRewritePatternSet.h" |
| #include "mlir/Transforms/DialectConversion.h" |
| #include "mlir/Transforms/GreedyPatternRewriteDriver.h" |
| #include "mlir/Transforms/WalkPatternRewriteDriver.h" |
| |
| #include <cassert> |
| |
| using namespace mlir; |
| |
| //===----------------------------------------------------------------------===// |
| /// RewriterBase API inherited from OpBuilder |
| //===----------------------------------------------------------------------===// |
| |
| MlirContext mlirRewriterBaseGetContext(MlirRewriterBase rewriter) { |
| return wrap(unwrap(rewriter)->getContext()); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| /// Insertion points methods |
| //===----------------------------------------------------------------------===// |
| |
| void mlirRewriterBaseClearInsertionPoint(MlirRewriterBase rewriter) { |
| unwrap(rewriter)->clearInsertionPoint(); |
| } |
| |
| void mlirRewriterBaseSetInsertionPointBefore(MlirRewriterBase rewriter, |
| MlirOperation op) { |
| unwrap(rewriter)->setInsertionPoint(unwrap(op)); |
| } |
| |
| void mlirRewriterBaseSetInsertionPointAfter(MlirRewriterBase rewriter, |
| MlirOperation op) { |
| unwrap(rewriter)->setInsertionPointAfter(unwrap(op)); |
| } |
| |
| void mlirRewriterBaseSetInsertionPointAfterValue(MlirRewriterBase rewriter, |
| MlirValue value) { |
| unwrap(rewriter)->setInsertionPointAfterValue(unwrap(value)); |
| } |
| |
| void mlirRewriterBaseSetInsertionPointToStart(MlirRewriterBase rewriter, |
| MlirBlock block) { |
| unwrap(rewriter)->setInsertionPointToStart(unwrap(block)); |
| } |
| |
| void mlirRewriterBaseSetInsertionPointToEnd(MlirRewriterBase rewriter, |
| MlirBlock block) { |
| unwrap(rewriter)->setInsertionPointToEnd(unwrap(block)); |
| } |
| |
| MlirBlock mlirRewriterBaseGetInsertionBlock(MlirRewriterBase rewriter) { |
| return wrap(unwrap(rewriter)->getInsertionBlock()); |
| } |
| |
| MlirBlock mlirRewriterBaseGetBlock(MlirRewriterBase rewriter) { |
| return wrap(unwrap(rewriter)->getBlock()); |
| } |
| |
| MlirOperation |
| mlirRewriterBaseGetOperationAfterInsertion(MlirRewriterBase rewriter) { |
| mlir::RewriterBase *base = unwrap(rewriter); |
| mlir::Block *block = base->getInsertionBlock(); |
| mlir::Block::iterator it = base->getInsertionPoint(); |
| if (it == block->end()) |
| return {nullptr}; |
| |
| return wrap(std::addressof(*it)); |
| } |
| |
| MlirRewriterBaseInsertPoint |
| mlirRewriterBaseSaveInsertionPoint(MlirRewriterBase rewriter) { |
| OpBuilder::InsertPoint ip = unwrap(rewriter)->saveInsertionPoint(); |
| if (!ip.isSet()) |
| return {{nullptr}, {nullptr}}; |
| Block *block = ip.getBlock(); |
| MlirOperation operationAfter = ip.getPoint() == block->end() |
| ? MlirOperation{nullptr} |
| : wrap(&*ip.getPoint()); |
| return {wrap(block), operationAfter}; |
| } |
| |
| void mlirRewriterBaseRestoreInsertionPoint( |
| MlirRewriterBase rewriter, MlirRewriterBaseInsertPoint insertPoint) { |
| if (mlirBlockIsNull(insertPoint.block)) { |
| unwrap(rewriter)->clearInsertionPoint(); |
| return; |
| } |
| Block *block = unwrap(insertPoint.block); |
| if (mlirOperationIsNull(insertPoint.operationAfter)) |
| unwrap(rewriter)->setInsertionPointToEnd(block); |
| else |
| unwrap(rewriter)->setInsertionPoint( |
| block, Block::iterator(unwrap(insertPoint.operationAfter))); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| /// Block and operation creation/insertion/cloning |
| //===----------------------------------------------------------------------===// |
| |
| MlirBlock mlirRewriterBaseCreateBlockBefore(MlirRewriterBase rewriter, |
| MlirBlock insertBefore, |
| intptr_t nArgTypes, |
| MlirType const *argTypes, |
| MlirLocation const *locations) { |
| SmallVector<Type, 4> args; |
| ArrayRef<Type> unwrappedArgs = unwrapList(nArgTypes, argTypes, args); |
| SmallVector<Location, 4> locs; |
| ArrayRef<Location> unwrappedLocs = unwrapList(nArgTypes, locations, locs); |
| return wrap(unwrap(rewriter)->createBlock(unwrap(insertBefore), unwrappedArgs, |
| unwrappedLocs)); |
| } |
| |
| MlirOperation mlirRewriterBaseInsert(MlirRewriterBase rewriter, |
| MlirOperation op) { |
| return wrap(unwrap(rewriter)->insert(unwrap(op))); |
| } |
| |
| // Other methods of OpBuilder |
| |
| MlirOperation mlirRewriterBaseClone(MlirRewriterBase rewriter, |
| MlirOperation op) { |
| return wrap(unwrap(rewriter)->clone(*unwrap(op))); |
| } |
| |
| MlirOperation mlirRewriterBaseCloneWithoutRegions(MlirRewriterBase rewriter, |
| MlirOperation op) { |
| return wrap(unwrap(rewriter)->cloneWithoutRegions(*unwrap(op))); |
| } |
| |
| MlirOperation mlirRewriterBaseCloneWithMapping(MlirRewriterBase rewriter, |
| MlirOperation op, |
| MlirIRMapping mapping) { |
| return wrap(unwrap(rewriter)->clone(*unwrap(op), *unwrap(mapping))); |
| } |
| |
| void mlirRewriterBaseCloneRegionBefore(MlirRewriterBase rewriter, |
| MlirRegion region, MlirBlock before) { |
| |
| unwrap(rewriter)->cloneRegionBefore(*unwrap(region), unwrap(before)); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| /// RewriterBase API |
| //===----------------------------------------------------------------------===// |
| |
| void mlirRewriterBaseInlineRegionBefore(MlirRewriterBase rewriter, |
| MlirRegion region, MlirBlock before) { |
| unwrap(rewriter)->inlineRegionBefore(*unwrap(region), unwrap(before)); |
| } |
| |
| void mlirRewriterBaseReplaceOpWithValues(MlirRewriterBase rewriter, |
| MlirOperation op, intptr_t nValues, |
| MlirValue const *values) { |
| SmallVector<Value, 4> vals; |
| ArrayRef<Value> unwrappedVals = unwrapList(nValues, values, vals); |
| unwrap(rewriter)->replaceOp(unwrap(op), unwrappedVals); |
| } |
| |
| void mlirRewriterBaseReplaceOpWithOperation(MlirRewriterBase rewriter, |
| MlirOperation op, |
| MlirOperation newOp) { |
| unwrap(rewriter)->replaceOp(unwrap(op), unwrap(newOp)); |
| } |
| |
| void mlirRewriterBaseEraseOp(MlirRewriterBase rewriter, MlirOperation op) { |
| unwrap(rewriter)->eraseOp(unwrap(op)); |
| } |
| |
| void mlirRewriterBaseEraseBlock(MlirRewriterBase rewriter, MlirBlock block) { |
| unwrap(rewriter)->eraseBlock(unwrap(block)); |
| } |
| |
| void mlirRewriterBaseInlineBlockBefore(MlirRewriterBase rewriter, |
| MlirBlock source, MlirOperation op, |
| intptr_t nArgValues, |
| MlirValue const *argValues) { |
| SmallVector<Value, 4> vals; |
| ArrayRef<Value> unwrappedVals = unwrapList(nArgValues, argValues, vals); |
| |
| unwrap(rewriter)->inlineBlockBefore(unwrap(source), unwrap(op), |
| unwrappedVals); |
| } |
| |
| void mlirRewriterBaseMergeBlocks(MlirRewriterBase rewriter, MlirBlock source, |
| MlirBlock dest, intptr_t nArgValues, |
| MlirValue const *argValues) { |
| SmallVector<Value, 4> args; |
| ArrayRef<Value> unwrappedArgs = unwrapList(nArgValues, argValues, args); |
| unwrap(rewriter)->mergeBlocks(unwrap(source), unwrap(dest), unwrappedArgs); |
| } |
| |
| void mlirRewriterBaseMoveOpBefore(MlirRewriterBase rewriter, MlirOperation op, |
| MlirOperation existingOp) { |
| unwrap(rewriter)->moveOpBefore(unwrap(op), unwrap(existingOp)); |
| } |
| |
| void mlirRewriterBaseMoveOpAfter(MlirRewriterBase rewriter, MlirOperation op, |
| MlirOperation existingOp) { |
| unwrap(rewriter)->moveOpAfter(unwrap(op), unwrap(existingOp)); |
| } |
| |
| void mlirRewriterBaseMoveBlockBefore(MlirRewriterBase rewriter, MlirBlock block, |
| MlirBlock existingBlock) { |
| unwrap(rewriter)->moveBlockBefore(unwrap(block), unwrap(existingBlock)); |
| } |
| |
| void mlirRewriterBaseStartOpModification(MlirRewriterBase rewriter, |
| MlirOperation op) { |
| unwrap(rewriter)->startOpModification(unwrap(op)); |
| } |
| |
| void mlirRewriterBaseFinalizeOpModification(MlirRewriterBase rewriter, |
| MlirOperation op) { |
| unwrap(rewriter)->finalizeOpModification(unwrap(op)); |
| } |
| |
| void mlirRewriterBaseCancelOpModification(MlirRewriterBase rewriter, |
| MlirOperation op) { |
| unwrap(rewriter)->cancelOpModification(unwrap(op)); |
| } |
| |
| void mlirRewriterBaseReplaceAllUsesWith(MlirRewriterBase rewriter, |
| MlirValue from, MlirValue to) { |
| unwrap(rewriter)->replaceAllUsesWith(unwrap(from), unwrap(to)); |
| } |
| |
| void mlirRewriterBaseReplaceAllValueRangeUsesWith(MlirRewriterBase rewriter, |
| intptr_t nValues, |
| MlirValue const *from, |
| MlirValue const *to) { |
| SmallVector<Value, 4> fromVals; |
| ArrayRef<Value> unwrappedFromVals = unwrapList(nValues, from, fromVals); |
| SmallVector<Value, 4> toVals; |
| ArrayRef<Value> unwrappedToVals = unwrapList(nValues, to, toVals); |
| unwrap(rewriter)->replaceAllUsesWith(unwrappedFromVals, unwrappedToVals); |
| } |
| |
| void mlirRewriterBaseReplaceAllOpUsesWithValueRange(MlirRewriterBase rewriter, |
| MlirOperation from, |
| intptr_t nTo, |
| MlirValue const *to) { |
| SmallVector<Value, 4> toVals; |
| ArrayRef<Value> unwrappedToVals = unwrapList(nTo, to, toVals); |
| unwrap(rewriter)->replaceAllOpUsesWith(unwrap(from), unwrappedToVals); |
| } |
| |
| void mlirRewriterBaseReplaceAllOpUsesWithOperation(MlirRewriterBase rewriter, |
| MlirOperation from, |
| MlirOperation to) { |
| unwrap(rewriter)->replaceAllOpUsesWith(unwrap(from), unwrap(to)); |
| } |
| |
| void mlirRewriterBaseReplaceOpUsesWithinBlock(MlirRewriterBase rewriter, |
| MlirOperation op, |
| intptr_t nNewValues, |
| MlirValue const *newValues, |
| MlirBlock block) { |
| SmallVector<Value, 4> vals; |
| ArrayRef<Value> unwrappedVals = unwrapList(nNewValues, newValues, vals); |
| unwrap(rewriter)->replaceOpUsesWithinBlock(unwrap(op), unwrappedVals, |
| unwrap(block)); |
| } |
| |
| void mlirRewriterBaseReplaceAllUsesExcept(MlirRewriterBase rewriter, |
| MlirValue from, MlirValue to, |
| MlirOperation exceptedUser) { |
| unwrap(rewriter)->replaceAllUsesExcept(unwrap(from), unwrap(to), |
| unwrap(exceptedUser)); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| /// IRRewriter API |
| //===----------------------------------------------------------------------===// |
| |
| MlirRewriterBase mlirIRRewriterCreate(MlirContext context) { |
| return wrap(new IRRewriter(unwrap(context))); |
| } |
| |
| MlirRewriterBase mlirIRRewriterCreateFromOp(MlirOperation op) { |
| return wrap(new IRRewriter(unwrap(op))); |
| } |
| |
| void mlirIRRewriterDestroy(MlirRewriterBase rewriter) { |
| delete static_cast<IRRewriter *>(unwrap(rewriter)); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| /// RewritePatternSet and FrozenRewritePatternSet API |
| //===----------------------------------------------------------------------===// |
| |
| MlirFrozenRewritePatternSet |
| mlirFreezeRewritePattern(MlirRewritePatternSet set) { |
| auto *m = new mlir::FrozenRewritePatternSet(std::move(*unwrap(set))); |
| set.ptr = nullptr; |
| return wrap(m); |
| } |
| |
| void mlirFrozenRewritePatternSetDestroy(MlirFrozenRewritePatternSet set) { |
| delete unwrap(set); |
| set.ptr = nullptr; |
| } |
| |
| //===----------------------------------------------------------------------===// |
| /// GreedyRewriteDriverConfig API |
| //===----------------------------------------------------------------------===// |
| |
| inline mlir::GreedyRewriteConfig *unwrap(MlirGreedyRewriteDriverConfig config) { |
| assert(config.ptr && "unexpected null config"); |
| return static_cast<mlir::GreedyRewriteConfig *>(config.ptr); |
| } |
| |
| inline MlirGreedyRewriteDriverConfig wrap(mlir::GreedyRewriteConfig *config) { |
| return {config}; |
| } |
| |
| MlirGreedyRewriteDriverConfig mlirGreedyRewriteDriverConfigCreate() { |
| return wrap(new mlir::GreedyRewriteConfig()); |
| } |
| |
| void mlirGreedyRewriteDriverConfigDestroy( |
| MlirGreedyRewriteDriverConfig config) { |
| delete unwrap(config); |
| } |
| |
| void mlirGreedyRewriteDriverConfigSetMaxIterations( |
| MlirGreedyRewriteDriverConfig config, int64_t maxIterations) { |
| unwrap(config)->setMaxIterations(maxIterations); |
| } |
| |
| void mlirGreedyRewriteDriverConfigSetMaxNumRewrites( |
| MlirGreedyRewriteDriverConfig config, int64_t maxNumRewrites) { |
| unwrap(config)->setMaxNumRewrites(maxNumRewrites); |
| } |
| |
| void mlirGreedyRewriteDriverConfigSetUseTopDownTraversal( |
| MlirGreedyRewriteDriverConfig config, bool useTopDownTraversal) { |
| unwrap(config)->setUseTopDownTraversal(useTopDownTraversal); |
| } |
| |
| void mlirGreedyRewriteDriverConfigEnableFolding( |
| MlirGreedyRewriteDriverConfig config, bool enable) { |
| unwrap(config)->enableFolding(enable); |
| } |
| |
| void mlirGreedyRewriteDriverConfigSetStrictness( |
| MlirGreedyRewriteDriverConfig config, |
| MlirGreedyRewriteStrictness strictness) { |
| mlir::GreedyRewriteStrictness cppStrictness; |
| switch (strictness) { |
| case MLIR_GREEDY_REWRITE_STRICTNESS_ANY_OP: |
| cppStrictness = mlir::GreedyRewriteStrictness::AnyOp; |
| break; |
| case MLIR_GREEDY_REWRITE_STRICTNESS_EXISTING_AND_NEW_OPS: |
| cppStrictness = mlir::GreedyRewriteStrictness::ExistingAndNewOps; |
| break; |
| case MLIR_GREEDY_REWRITE_STRICTNESS_EXISTING_OPS: |
| cppStrictness = mlir::GreedyRewriteStrictness::ExistingOps; |
| break; |
| } |
| unwrap(config)->setStrictness(cppStrictness); |
| } |
| |
| void mlirGreedyRewriteDriverConfigSetRegionSimplificationLevel( |
| MlirGreedyRewriteDriverConfig config, MlirGreedySimplifyRegionLevel level) { |
| mlir::GreedySimplifyRegionLevel cppLevel; |
| switch (level) { |
| case MLIR_GREEDY_SIMPLIFY_REGION_LEVEL_DISABLED: |
| cppLevel = mlir::GreedySimplifyRegionLevel::Disabled; |
| break; |
| case MLIR_GREEDY_SIMPLIFY_REGION_LEVEL_NORMAL: |
| cppLevel = mlir::GreedySimplifyRegionLevel::Normal; |
| break; |
| case MLIR_GREEDY_SIMPLIFY_REGION_LEVEL_AGGRESSIVE: |
| cppLevel = mlir::GreedySimplifyRegionLevel::Aggressive; |
| break; |
| } |
| unwrap(config)->setRegionSimplificationLevel(cppLevel); |
| } |
| |
| void mlirGreedyRewriteDriverConfigEnableConstantCSE( |
| MlirGreedyRewriteDriverConfig config, bool enable) { |
| unwrap(config)->enableConstantCSE(enable); |
| } |
| |
| int64_t mlirGreedyRewriteDriverConfigGetMaxIterations( |
| MlirGreedyRewriteDriverConfig config) { |
| return unwrap(config)->getMaxIterations(); |
| } |
| |
| int64_t mlirGreedyRewriteDriverConfigGetMaxNumRewrites( |
| MlirGreedyRewriteDriverConfig config) { |
| return unwrap(config)->getMaxNumRewrites(); |
| } |
| |
| bool mlirGreedyRewriteDriverConfigGetUseTopDownTraversal( |
| MlirGreedyRewriteDriverConfig config) { |
| return unwrap(config)->getUseTopDownTraversal(); |
| } |
| |
| bool mlirGreedyRewriteDriverConfigIsFoldingEnabled( |
| MlirGreedyRewriteDriverConfig config) { |
| return unwrap(config)->isFoldingEnabled(); |
| } |
| |
| MlirGreedyRewriteStrictness mlirGreedyRewriteDriverConfigGetStrictness( |
| MlirGreedyRewriteDriverConfig config) { |
| mlir::GreedyRewriteStrictness cppStrictness = unwrap(config)->getStrictness(); |
| switch (cppStrictness) { |
| case mlir::GreedyRewriteStrictness::AnyOp: |
| return MLIR_GREEDY_REWRITE_STRICTNESS_ANY_OP; |
| case mlir::GreedyRewriteStrictness::ExistingAndNewOps: |
| return MLIR_GREEDY_REWRITE_STRICTNESS_EXISTING_AND_NEW_OPS; |
| case mlir::GreedyRewriteStrictness::ExistingOps: |
| return MLIR_GREEDY_REWRITE_STRICTNESS_EXISTING_OPS; |
| } |
| llvm_unreachable("Unknown GreedyRewriteStrictness"); |
| } |
| |
| MlirGreedySimplifyRegionLevel |
| mlirGreedyRewriteDriverConfigGetRegionSimplificationLevel( |
| MlirGreedyRewriteDriverConfig config) { |
| mlir::GreedySimplifyRegionLevel cppLevel = |
| unwrap(config)->getRegionSimplificationLevel(); |
| switch (cppLevel) { |
| case mlir::GreedySimplifyRegionLevel::Disabled: |
| return MLIR_GREEDY_SIMPLIFY_REGION_LEVEL_DISABLED; |
| case mlir::GreedySimplifyRegionLevel::Normal: |
| return MLIR_GREEDY_SIMPLIFY_REGION_LEVEL_NORMAL; |
| case mlir::GreedySimplifyRegionLevel::Aggressive: |
| return MLIR_GREEDY_SIMPLIFY_REGION_LEVEL_AGGRESSIVE; |
| } |
| llvm_unreachable("Unknown GreedySimplifyRegionLevel"); |
| } |
| |
| bool mlirGreedyRewriteDriverConfigIsConstantCSEEnabled( |
| MlirGreedyRewriteDriverConfig config) { |
| return unwrap(config)->isConstantCSEEnabled(); |
| } |
| |
| MlirLogicalResult |
| mlirApplyPatternsAndFoldGreedily(MlirModule op, |
| MlirFrozenRewritePatternSet patterns, |
| MlirGreedyRewriteDriverConfig config) { |
| return wrap(mlir::applyPatternsGreedily(unwrap(op), *unwrap(patterns), |
| *unwrap(config))); |
| } |
| |
| MlirLogicalResult |
| mlirApplyPatternsAndFoldGreedilyWithOp(MlirOperation op, |
| MlirFrozenRewritePatternSet patterns, |
| MlirGreedyRewriteDriverConfig config) { |
| return wrap(mlir::applyPatternsGreedily(unwrap(op), *unwrap(patterns), |
| *unwrap(config))); |
| } |
| |
| void mlirWalkAndApplyPatterns(MlirOperation op, |
| MlirFrozenRewritePatternSet patterns) { |
| mlir::walkAndApplyPatterns(unwrap(op), *unwrap(patterns)); |
| } |
| |
| MlirLogicalResult |
| mlirApplyPartialConversion(MlirOperation op, MlirConversionTarget target, |
| MlirFrozenRewritePatternSet patterns, |
| MlirConversionConfig config) { |
| return wrap(mlir::applyPartialConversion(unwrap(op), *unwrap(target), |
| *unwrap(patterns), *unwrap(config))); |
| } |
| |
| MlirLogicalResult mlirApplyFullConversion(MlirOperation op, |
| MlirConversionTarget target, |
| MlirFrozenRewritePatternSet patterns, |
| MlirConversionConfig config) { |
| return wrap(mlir::applyFullConversion(unwrap(op), *unwrap(target), |
| *unwrap(patterns), *unwrap(config))); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| /// ConversionConfig API |
| //===----------------------------------------------------------------------===// |
| |
| MlirConversionConfig mlirConversionConfigCreate(void) { |
| return wrap(new mlir::ConversionConfig()); |
| } |
| |
| void mlirConversionConfigDestroy(MlirConversionConfig config) { |
| delete unwrap(config); |
| } |
| |
| void mlirConversionConfigSetFoldingMode(MlirConversionConfig config, |
| MlirDialectConversionFoldingMode mode) { |
| mlir::DialectConversionFoldingMode cppMode; |
| switch (mode) { |
| case MLIR_DIALECT_CONVERSION_FOLDING_MODE_NEVER: |
| cppMode = mlir::DialectConversionFoldingMode::Never; |
| break; |
| case MLIR_DIALECT_CONVERSION_FOLDING_MODE_BEFORE_PATTERNS: |
| cppMode = mlir::DialectConversionFoldingMode::BeforePatterns; |
| break; |
| case MLIR_DIALECT_CONVERSION_FOLDING_MODE_AFTER_PATTERNS: |
| cppMode = mlir::DialectConversionFoldingMode::AfterPatterns; |
| break; |
| } |
| unwrap(config)->foldingMode = cppMode; |
| } |
| |
| MlirDialectConversionFoldingMode |
| mlirConversionConfigGetFoldingMode(MlirConversionConfig config) { |
| switch (unwrap(config)->foldingMode) { |
| case mlir::DialectConversionFoldingMode::Never: |
| return MLIR_DIALECT_CONVERSION_FOLDING_MODE_NEVER; |
| case mlir::DialectConversionFoldingMode::BeforePatterns: |
| return MLIR_DIALECT_CONVERSION_FOLDING_MODE_BEFORE_PATTERNS; |
| case mlir::DialectConversionFoldingMode::AfterPatterns: |
| return MLIR_DIALECT_CONVERSION_FOLDING_MODE_AFTER_PATTERNS; |
| } |
| } |
| |
| void mlirConversionConfigEnableBuildMaterializations( |
| MlirConversionConfig config, bool enable) { |
| unwrap(config)->buildMaterializations = enable; |
| } |
| |
| bool mlirConversionConfigIsBuildMaterializationsEnabled( |
| MlirConversionConfig config) { |
| return unwrap(config)->buildMaterializations; |
| } |
| |
| //===----------------------------------------------------------------------===// |
| /// PatternRewriter API |
| //===----------------------------------------------------------------------===// |
| |
| MlirRewriterBase mlirPatternRewriterAsBase(MlirPatternRewriter rewriter) { |
| return wrap(static_cast<mlir::RewriterBase *>(unwrap(rewriter))); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| /// ConversionPatternRewriter API |
| //===----------------------------------------------------------------------===// |
| |
| MlirPatternRewriter mlirConversionPatternRewriterAsPatternRewriter( |
| MlirConversionPatternRewriter rewriter) { |
| return wrap(static_cast<mlir::PatternRewriter *>(unwrap(rewriter))); |
| } |
| |
| MlirLogicalResult mlirConversionPatternRewriterConvertRegionTypes( |
| MlirConversionPatternRewriter rewriter, MlirRegion region, |
| MlirTypeConverter typeConverter) { |
| return wrap(unwrap(rewriter)->convertRegionTypes(unwrap(region), |
| *unwrap(typeConverter))); |
| } |
| |
| void mlirConversionPatternRewriterReplaceOpWithMultiple( |
| MlirConversionPatternRewriter rewriter, MlirOperation op, intptr_t nRanges, |
| intptr_t *rangeSizes, MlirValue *values) { |
| SmallVector<SmallVector<Value>> ranges; |
| ranges.reserve(nRanges); |
| MlirValue *cur = values; |
| for (intptr_t i = 0; i < nRanges; ++i) { |
| intptr_t rangeSize = rangeSizes[i]; |
| SmallVector<Value> range; |
| range.reserve(rangeSize); |
| for (intptr_t j = 0; j < rangeSize; ++j, ++cur) |
| range.push_back(unwrap(*cur)); |
| ranges.push_back(std::move(range)); |
| } |
| unwrap(rewriter)->replaceOpWithMultiple(unwrap(op), std::move(ranges)); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| /// ConversionTarget API |
| //===----------------------------------------------------------------------===// |
| |
| MlirConversionTarget mlirConversionTargetCreate(MlirContext context) { |
| return wrap(new mlir::ConversionTarget(*unwrap(context))); |
| } |
| |
| void mlirConversionTargetDestroy(MlirConversionTarget target) { |
| delete unwrap(target); |
| } |
| |
| void mlirConversionTargetAddLegalOp(MlirConversionTarget target, |
| MlirStringRef opName) { |
| unwrap(target)->addLegalOp( |
| mlir::OperationName(unwrap(opName), &unwrap(target)->getContext())); |
| } |
| |
| void mlirConversionTargetAddIllegalOp(MlirConversionTarget target, |
| MlirStringRef opName) { |
| unwrap(target)->addIllegalOp( |
| mlir::OperationName(unwrap(opName), &unwrap(target)->getContext())); |
| } |
| |
| void mlirConversionTargetAddLegalDialect(MlirConversionTarget target, |
| MlirStringRef dialectName) { |
| unwrap(target)->addLegalDialect(unwrap(dialectName)); |
| } |
| |
| void mlirConversionTargetAddIllegalDialect(MlirConversionTarget target, |
| MlirStringRef dialectName) { |
| unwrap(target)->addIllegalDialect(unwrap(dialectName)); |
| } |
| |
| namespace { |
| /// Wraps a C dynamic-legality callback as a C++ DynamicLegalityCallbackFn, |
| /// translating the tri-state MlirConversionTargetLegality result into the |
| /// std::optional<bool> expected by ConversionTarget (NO_OPINION -> nullopt). |
| ConversionTarget::DynamicLegalityCallbackFn |
| wrapLegalityCallback(MlirConversionTargetDynamicLegalityCallback callback, |
| void *userData) { |
| return [callback, userData](Operation *op) -> std::optional<bool> { |
| switch (callback(wrap(op), userData)) { |
| case MLIR_CONVERSION_TARGET_LEGALITY_LEGAL: |
| return true; |
| case MLIR_CONVERSION_TARGET_LEGALITY_ILLEGAL: |
| return false; |
| case MLIR_CONVERSION_TARGET_LEGALITY_NO_OPINION: |
| return std::nullopt; |
| } |
| llvm_unreachable("unknown MlirConversionTargetLegality"); |
| }; |
| } |
| } // namespace |
| |
| void mlirConversionTargetAddDynamicallyLegalOp( |
| MlirConversionTarget target, MlirStringRef opName, |
| MlirConversionTargetDynamicLegalityCallback callback, void *userData) { |
| assert(callback && "expected non-null legality callback"); |
| MLIRContext *ctx = &unwrap(target)->getContext(); |
| OperationName name(unwrap(opName), ctx); |
| unwrap(target)->addDynamicallyLegalOp( |
| name, wrapLegalityCallback(callback, userData)); |
| } |
| |
| void mlirConversionTargetAddDynamicallyLegalDialect( |
| MlirConversionTarget target, MlirStringRef dialectName, |
| MlirConversionTargetDynamicLegalityCallback callback, void *userData) { |
| assert(callback && "expected non-null legality callback"); |
| unwrap(target)->addDynamicallyLegalDialect( |
| wrapLegalityCallback(callback, userData), unwrap(dialectName)); |
| } |
| |
| void mlirConversionTargetMarkOpRecursivelyLegal( |
| MlirConversionTarget target, MlirStringRef opName, |
| MlirConversionTargetDynamicLegalityCallback callback, void *userData) { |
| MLIRContext *ctx = &unwrap(target)->getContext(); |
| OperationName name(unwrap(opName), ctx); |
| ConversionTarget::DynamicLegalityCallbackFn fn; |
| if (callback) |
| fn = wrapLegalityCallback(callback, userData); |
| unwrap(target)->markOpRecursivelyLegal(name, fn); |
| } |
| |
| void mlirConversionTargetMarkUnknownOpDynamicallyLegal( |
| MlirConversionTarget target, |
| MlirConversionTargetDynamicLegalityCallback callback, void *userData) { |
| assert(callback && "expected non-null legality callback"); |
| unwrap(target)->markUnknownOpDynamicallyLegal( |
| wrapLegalityCallback(callback, userData)); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| /// TypeConverter API |
| //===----------------------------------------------------------------------===// |
| |
| MlirTypeConverter mlirTypeConverterCreate() { |
| return wrap(new mlir::TypeConverter()); |
| } |
| |
| void mlirTypeConverterDestroy(MlirTypeConverter typeConverter) { |
| delete unwrap(typeConverter); |
| } |
| |
| void mlirTypeConverterAddConversion( |
| MlirTypeConverter typeConverter, |
| MlirTypeConverterConversionCallback convertType, void *userData) { |
| unwrap(typeConverter) |
| ->addConversion( |
| [convertType, userData](Type type, SmallVectorImpl<Type> &results) |
| -> std::optional<LogicalResult> { |
| MlirType converted{nullptr}; |
| MlirTypeConverterConversionStatus status = |
| convertType(wrap(type), &converted, userData); |
| switch (status) { |
| case MlirTypeConverterConversionStatusSuccess: |
| results.push_back(unwrap(converted)); |
| return success(); |
| case MlirTypeConverterConversionStatusFailure: |
| // Failure: fail the conversion without trying another |
| // registered conversion function. |
| return failure(); |
| case MlirTypeConverterConversionStatusDeclined: |
| // Declined: allow the driver to try another conversion function. |
| return std::nullopt; |
| } |
| llvm_unreachable("unknown MlirTypeConverterConversionStatus"); |
| }); |
| } |
| |
| void mlirTypeConverterConversionResultsAppend( |
| MlirTypeConverterConversionResults results, MlirType type) { |
| static_cast<SmallVectorImpl<Type> *>(results.ptr)->push_back(unwrap(type)); |
| } |
| |
| void mlirTypeConverterAdd1ToNConversion( |
| MlirTypeConverter typeConverter, |
| MlirTypeConverter1ToNConversionCallback convertType, void *userData) { |
| unwrap(typeConverter) |
| ->addConversion( |
| [convertType, userData](Type type, SmallVectorImpl<Type> &results) |
| -> std::optional<LogicalResult> { |
| size_t numPriorResults = results.size(); |
| MlirTypeConverterConversionResults wrappedResults{&results}; |
| MlirTypeConverterConversionStatus status = |
| convertType(wrap(type), wrappedResults, userData); |
| switch (status) { |
| case MlirTypeConverterConversionStatusSuccess: |
| return success(); |
| case MlirTypeConverterConversionStatusFailure: |
| // Failure. Restore any types the callback appended (a |
| // non-succeeding conversion function must not mutate `results`) |
| // and fail the conversion without trying another function. |
| results.truncate(numPriorResults); |
| return failure(); |
| case MlirTypeConverterConversionStatusDeclined: |
| // The callback declined. Restore any types it appended so the |
| // driver's "try the next conversion" invariant holds (a declining |
| // conversion function must not mutate `results`). |
| results.truncate(numPriorResults); |
| return std::nullopt; |
| } |
| llvm_unreachable("unknown MlirTypeConverterConversionStatus"); |
| }); |
| } |
| |
| MlirType mlirTypeConverterConvertType(MlirTypeConverter typeConverter, |
| MlirType type) { |
| return wrap(unwrap(typeConverter)->convertType(unwrap(type))); |
| } |
| |
| namespace { |
| SmallVector<MlirValue> wrapInputs(ValueRange inputs) { |
| SmallVector<MlirValue> wrappedInputs; |
| wrappedInputs.reserve(inputs.size()); |
| for (Value v : inputs) |
| wrappedInputs.push_back(wrap(v)); |
| return wrappedInputs; |
| } |
| |
| std::function<Value(OpBuilder &, Type, ValueRange, Location)> |
| wrapSourceMaterializationCallback( |
| MlirTypeConverterSourceMaterializationCallback callback, void *userData) { |
| return [callback, userData](OpBuilder &builder, Type type, ValueRange inputs, |
| Location loc) -> Value { |
| SmallVector<MlirValue> wrappedInputs = wrapInputs(inputs); |
| MlirValue result = |
| callback(wrap(static_cast<RewriterBase *>(&builder)), wrap(type), |
| static_cast<intptr_t>(wrappedInputs.size()), |
| wrappedInputs.data(), wrap(loc), userData); |
| return mlirValueIsNull(result) ? Value() : unwrap(result); |
| }; |
| } |
| |
| std::function<Value(OpBuilder &, Type, ValueRange, Location, Type)> |
| wrapTargetMaterializationCallback( |
| MlirTypeConverterTargetMaterializationCallback callback, void *userData) { |
| return [callback, userData](OpBuilder &builder, Type type, ValueRange inputs, |
| Location loc, Type originalType) -> Value { |
| SmallVector<MlirValue> wrappedInputs = wrapInputs(inputs); |
| MlirValue result = |
| callback(wrap(static_cast<RewriterBase *>(&builder)), wrap(type), |
| static_cast<intptr_t>(wrappedInputs.size()), |
| wrappedInputs.data(), wrap(loc), wrap(originalType), userData); |
| return mlirValueIsNull(result) ? Value() : unwrap(result); |
| }; |
| } |
| |
| std::function<SmallVector<Value>(OpBuilder &, TypeRange, ValueRange, Location, |
| Type)> |
| wrap1ToNTargetMaterializationCallback( |
| MlirTypeConverter1ToNTargetMaterializationCallback callback, |
| void *userData) { |
| return [callback, userData](OpBuilder &builder, TypeRange outputTypes, |
| ValueRange inputs, Location loc, |
| Type originalType) -> SmallVector<Value> { |
| SmallVector<MlirType> wrappedOutputTypes; |
| wrappedOutputTypes.reserve(outputTypes.size()); |
| for (Type t : outputTypes) |
| wrappedOutputTypes.push_back(wrap(t)); |
| SmallVector<MlirValue> wrappedInputs = wrapInputs(inputs); |
| SmallVector<MlirValue> wrappedOutputs(outputTypes.size(), |
| MlirValue{nullptr}); |
| MlirLogicalResult result = callback( |
| wrap(static_cast<RewriterBase *>(&builder)), |
| static_cast<intptr_t>(wrappedOutputTypes.size()), |
| wrappedOutputTypes.data(), static_cast<intptr_t>(wrappedInputs.size()), |
| wrappedInputs.data(), wrap(loc), wrap(originalType), |
| wrappedOutputs.data(), userData); |
| if (mlirLogicalResultIsFailure(result)) |
| return {}; // declined; another materialization may be attempted |
| SmallVector<Value> outputs; |
| outputs.reserve(wrappedOutputs.size()); |
| for (MlirValue v : wrappedOutputs) { |
| // On success the callback must fill every output; a null entry is a |
| // contract violation (to decline, the callback returns failure instead). |
| assert(!mlirValueIsNull(v) && |
| "1:N target materialization succeeded but left one of the outputs " |
| "null"); |
| outputs.push_back(unwrap(v)); |
| } |
| return outputs; |
| }; |
| } |
| } // namespace |
| |
| void mlirTypeConverterAddSourceMaterialization( |
| MlirTypeConverter typeConverter, |
| MlirTypeConverterSourceMaterializationCallback callback, void *userData) { |
| assert(callback && "expected non-null materialization callback"); |
| unwrap(typeConverter) |
| ->addSourceMaterialization( |
| wrapSourceMaterializationCallback(callback, userData)); |
| } |
| |
| void mlirTypeConverterAddTargetMaterialization( |
| MlirTypeConverter typeConverter, |
| MlirTypeConverterTargetMaterializationCallback callback, void *userData) { |
| assert(callback && "expected non-null materialization callback"); |
| unwrap(typeConverter) |
| ->addTargetMaterialization( |
| wrapTargetMaterializationCallback(callback, userData)); |
| } |
| |
| void mlirTypeConverterAdd1ToNTargetMaterialization( |
| MlirTypeConverter typeConverter, |
| MlirTypeConverter1ToNTargetMaterializationCallback callback, |
| void *userData) { |
| assert(callback && "expected non-null materialization callback"); |
| unwrap(typeConverter) |
| ->addTargetMaterialization( |
| wrap1ToNTargetMaterializationCallback(callback, userData)); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| /// ConversionPattern API |
| //===----------------------------------------------------------------------===// |
| |
| namespace mlir { |
| |
| class ExternalConversionPattern : public mlir::ConversionPattern { |
| public: |
| ExternalConversionPattern(MlirConversionPatternCallbacks callbacks, |
| void *userData, StringRef rootName, |
| PatternBenefit benefit, MLIRContext *context, |
| TypeConverter *typeConverter, |
| ArrayRef<StringRef> generatedNames) |
| : ConversionPattern(*typeConverter, rootName, benefit, context, |
| generatedNames), |
| callbacks(callbacks), userData(userData) { |
| if (callbacks.construct) |
| callbacks.construct(userData); |
| } |
| |
| ~ExternalConversionPattern() { |
| if (callbacks.destruct) |
| callbacks.destruct(userData); |
| } |
| |
| LogicalResult |
| matchAndRewrite(Operation *op, ArrayRef<Value> operands, |
| ConversionPatternRewriter &rewriter) const override { |
| std::vector<MlirValue> wrappedOperands; |
| for (Value val : operands) |
| wrappedOperands.push_back(wrap(val)); |
| return unwrap(callbacks.matchAndRewrite( |
| wrap(static_cast<const mlir::ConversionPattern *>(this)), wrap(op), |
| wrappedOperands.size(), wrappedOperands.data(), wrap(&rewriter), |
| userData)); |
| } |
| |
| LogicalResult |
| matchAndRewrite(Operation *op, ArrayRef<ValueRange> operands, |
| ConversionPatternRewriter &rewriter) const override { |
| // Without a 1:N callback, defer to the default behavior, which dispatches |
| // to the 1:1 matchAndRewrite above or fails to match on a 1:N mapping. |
| if (!callbacks.matchAndRewrite1ToN) |
| return dispatchTo1To1(*this, op, operands, rewriter); |
| SmallVector<intptr_t> rangeSizes; |
| rangeSizes.reserve(operands.size()); |
| std::vector<MlirValue> wrappedOperands; |
| for (ValueRange range : operands) { |
| rangeSizes.push_back(static_cast<intptr_t>(range.size())); |
| for (Value val : range) |
| wrappedOperands.push_back(wrap(val)); |
| } |
| return unwrap(callbacks.matchAndRewrite1ToN( |
| wrap(static_cast<const mlir::ConversionPattern *>(this)), wrap(op), |
| static_cast<intptr_t>(rangeSizes.size()), rangeSizes.data(), |
| static_cast<intptr_t>(wrappedOperands.size()), wrappedOperands.data(), |
| wrap(&rewriter), userData)); |
| } |
| |
| private: |
| MlirConversionPatternCallbacks callbacks; |
| void *userData; |
| }; |
| |
| } // namespace mlir |
| |
| MlirConversionPattern mlirOpConversionPatternCreate( |
| MlirStringRef rootName, unsigned benefit, MlirContext context, |
| MlirTypeConverter typeConverter, MlirConversionPatternCallbacks callbacks, |
| void *userData, size_t nGeneratedNames, MlirStringRef *generatedNames) { |
| std::vector<mlir::StringRef> generatedNamesVec; |
| generatedNamesVec.reserve(nGeneratedNames); |
| for (size_t i = 0; i < nGeneratedNames; ++i) |
| generatedNamesVec.push_back(unwrap(generatedNames[i])); |
| return wrap(new mlir::ExternalConversionPattern( |
| callbacks, userData, unwrap(rootName), PatternBenefit(benefit), |
| unwrap(context), unwrap(typeConverter), generatedNamesVec)); |
| } |
| |
| MlirTypeConverter |
| mlirConversionPatternGetTypeConverter(MlirConversionPattern pattern) { |
| return wrap(const_cast<TypeConverter *>(unwrap(pattern)->getTypeConverter())); |
| } |
| |
| MlirRewritePattern |
| mlirConversionPatternAsRewritePattern(MlirConversionPattern pattern) { |
| return wrap(static_cast<const RewritePattern *>(unwrap(pattern))); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| /// RewritePattern API |
| //===----------------------------------------------------------------------===// |
| |
| namespace mlir { |
| |
| class ExternalRewritePattern : public mlir::RewritePattern { |
| public: |
| ExternalRewritePattern(MlirRewritePatternCallbacks callbacks, void *userData, |
| StringRef rootName, PatternBenefit benefit, |
| MLIRContext *context, |
| ArrayRef<StringRef> generatedNames) |
| : RewritePattern(rootName, benefit, context, generatedNames), |
| callbacks(callbacks), userData(userData) { |
| if (callbacks.construct) |
| callbacks.construct(userData); |
| } |
| |
| ~ExternalRewritePattern() { |
| if (callbacks.destruct) |
| callbacks.destruct(userData); |
| } |
| |
| LogicalResult matchAndRewrite(Operation *op, |
| PatternRewriter &rewriter) const override { |
| return unwrap(callbacks.matchAndRewrite( |
| wrap(static_cast<const mlir::RewritePattern *>(this)), wrap(op), |
| wrap(&rewriter), userData)); |
| } |
| |
| private: |
| MlirRewritePatternCallbacks callbacks; |
| void *userData; |
| }; |
| |
| } // namespace mlir |
| |
| MlirRewritePattern mlirOpRewritePatternCreate( |
| MlirStringRef rootName, unsigned benefit, MlirContext context, |
| MlirRewritePatternCallbacks callbacks, void *userData, |
| size_t nGeneratedNames, MlirStringRef *generatedNames) { |
| std::vector<mlir::StringRef> generatedNamesVec; |
| generatedNamesVec.reserve(nGeneratedNames); |
| for (size_t i = 0; i < nGeneratedNames; ++i) { |
| generatedNamesVec.push_back(unwrap(generatedNames[i])); |
| } |
| return wrap(new mlir::ExternalRewritePattern( |
| callbacks, userData, unwrap(rootName), PatternBenefit(benefit), |
| unwrap(context), generatedNamesVec)); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| /// RewritePatternSet API |
| //===----------------------------------------------------------------------===// |
| |
| MlirRewritePatternSet mlirRewritePatternSetCreate(MlirContext context) { |
| return wrap(new mlir::RewritePatternSet(unwrap(context))); |
| } |
| |
| MlirContext mlirRewritePatternSetGetContext(MlirRewritePatternSet set) { |
| return wrap(unwrap(set)->getContext()); |
| } |
| |
| void mlirRewritePatternSetDestroy(MlirRewritePatternSet set) { |
| delete unwrap(set); |
| } |
| |
| void mlirRewritePatternSetAdd(MlirRewritePatternSet set, |
| MlirRewritePattern pattern) { |
| std::unique_ptr<mlir::RewritePattern> patternPtr( |
| const_cast<mlir::RewritePattern *>(unwrap(pattern))); |
| pattern.ptr = nullptr; |
| unwrap(set)->add(std::move(patternPtr)); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| /// PDLPatternModule API |
| //===----------------------------------------------------------------------===// |
| |
| #if MLIR_ENABLE_PDL_IN_PATTERNMATCH |
| MlirPDLPatternModule mlirPDLPatternModuleFromModule(MlirModule op) { |
| return wrap(new mlir::PDLPatternModule( |
| mlir::OwningOpRef<mlir::ModuleOp>(unwrap(op)))); |
| } |
| |
| void mlirPDLPatternModuleDestroy(MlirPDLPatternModule op) { |
| delete unwrap(op); |
| op.ptr = nullptr; |
| } |
| |
| MlirRewritePatternSet |
| mlirRewritePatternSetFromPDLPatternModule(MlirPDLPatternModule op) { |
| auto *m = new mlir::RewritePatternSet(std::move(*unwrap(op))); |
| op.ptr = nullptr; |
| return wrap(m); |
| } |
| |
| MlirValue mlirPDLValueAsValue(MlirPDLValue value) { |
| return wrap(unwrap(value)->dyn_cast<mlir::Value>()); |
| } |
| |
| MlirType mlirPDLValueAsType(MlirPDLValue value) { |
| return wrap(unwrap(value)->dyn_cast<mlir::Type>()); |
| } |
| |
| MlirOperation mlirPDLValueAsOperation(MlirPDLValue value) { |
| return wrap(unwrap(value)->dyn_cast<mlir::Operation *>()); |
| } |
| |
| MlirAttribute mlirPDLValueAsAttribute(MlirPDLValue value) { |
| return wrap(unwrap(value)->dyn_cast<mlir::Attribute>()); |
| } |
| |
| void mlirPDLResultListPushBackValue(MlirPDLResultList results, |
| MlirValue value) { |
| unwrap(results)->push_back(unwrap(value)); |
| } |
| |
| void mlirPDLResultListPushBackType(MlirPDLResultList results, MlirType value) { |
| unwrap(results)->push_back(unwrap(value)); |
| } |
| |
| void mlirPDLResultListPushBackOperation(MlirPDLResultList results, |
| MlirOperation value) { |
| unwrap(results)->push_back(unwrap(value)); |
| } |
| |
| void mlirPDLResultListPushBackAttribute(MlirPDLResultList results, |
| MlirAttribute value) { |
| unwrap(results)->push_back(unwrap(value)); |
| } |
| |
| inline std::vector<MlirPDLValue> wrap(ArrayRef<PDLValue> values) { |
| std::vector<MlirPDLValue> mlirValues; |
| mlirValues.reserve(values.size()); |
| for (auto &value : values) { |
| mlirValues.push_back(wrap(&value)); |
| } |
| return mlirValues; |
| } |
| |
| void mlirPDLPatternModuleRegisterRewriteFunction( |
| MlirPDLPatternModule pdlModule, MlirStringRef name, |
| MlirPDLRewriteFunction rewriteFn, void *userData) { |
| unwrap(pdlModule)->registerRewriteFunction( |
| unwrap(name), |
| [userData, rewriteFn](PatternRewriter &rewriter, PDLResultList &results, |
| ArrayRef<PDLValue> values) -> LogicalResult { |
| std::vector<MlirPDLValue> mlirValues = wrap(values); |
| return unwrap(rewriteFn(wrap(&rewriter), wrap(&results), |
| mlirValues.size(), mlirValues.data(), |
| userData)); |
| }); |
| } |
| |
| void mlirPDLPatternModuleRegisterConstraintFunction( |
| MlirPDLPatternModule pdlModule, MlirStringRef name, |
| MlirPDLConstraintFunction constraintFn, void *userData) { |
| unwrap(pdlModule)->registerConstraintFunction( |
| unwrap(name), |
| [userData, constraintFn](PatternRewriter &rewriter, |
| PDLResultList &results, |
| ArrayRef<PDLValue> values) -> LogicalResult { |
| std::vector<MlirPDLValue> mlirValues = wrap(values); |
| return unwrap(constraintFn(wrap(&rewriter), wrap(&results), |
| mlirValues.size(), mlirValues.data(), |
| userData)); |
| }); |
| } |
| #endif // MLIR_ENABLE_PDL_IN_PATTERNMATCH |