//===- 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
