blob: 5f831c11d4d912c3cb100d6b4a9764c1c970c8ae [file]
// Copyright 2020 The IREE Authors
//
// Licensed 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
#ifndef IREE_COMPILER_UTILS_PATTERNUTILS_H_
#define IREE_COMPILER_UTILS_PATTERNUTILS_H_
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/Support/LogicalResult.h"
#include "mlir/Transforms/DialectConversion.h"
namespace mlir::iree_compiler {
//===----------------------------------------------------------------------===//
// Generic patterns that can either be greedy rewrite patterns or conversion
// patterns. This allows patterns that operate within supported behavior for
// the conversion framework to use the subset of facilities of the
// PatternRewriter while being compatible with type conversion.
//
// TODO(laurenzo): Start a discussion upstream about the best way to be doing
// this.
//===----------------------------------------------------------------------===//
template <typename OpTy>
using GenericOpRewritePattern = LogicalResult (*)(
OpTy op, typename OpTy::Adaptor operands, PatternRewriter &rewriter);
template <typename OpTy>
static void insertGreedyPattern(RewritePatternSet &patterns,
MLIRContext *context,
GenericOpRewritePattern<OpTy> f,
PatternBenefit benefit = 1) {
struct Pattern : public OpRewritePattern<OpTy> {
Pattern(MLIRContext *context, GenericOpRewritePattern<OpTy> f,
PatternBenefit benefit)
: OpRewritePattern<OpTy>(context, benefit), f(f) {}
LogicalResult matchAndRewrite(OpTy op,
PatternRewriter &rewriter) const override {
// TODO(laurenzo): It would be nice if the operand adaptors did not
// have a dependency on ArrayRef as it requires doing this copy. In
// practice for this level of IR, this is sub-optimal but not the end
// of the world.
SmallVector<Value> operands;
for (unsigned i = 0, e = op.getOperation()->getNumOperands(); i < e;
++i) {
operands.push_back(op.getOperation()->getOperand(i));
}
return f(op, typename OpTy::Adaptor(operands), rewriter);
}
GenericOpRewritePattern<OpTy> f;
};
patterns.insert<Pattern>(context, f, benefit);
}
template <typename OpTy>
static void insertConversionPattern(RewritePatternSet &patterns,
MLIRContext *context,
GenericOpRewritePattern<OpTy> f,
PatternBenefit benefit = 1) {
struct Pattern : public OpConversionPattern<OpTy> {
Pattern(MLIRContext *context, GenericOpRewritePattern<OpTy> f,
PatternBenefit benefit)
: OpConversionPattern<OpTy>(context, benefit), f(f) {}
LogicalResult
matchAndRewrite(OpTy op, typename OpTy::Adaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
return f(op, adaptor, rewriter);
}
GenericOpRewritePattern<OpTy> f;
};
patterns.insert<Pattern>(context, f, benefit);
}
} // namespace mlir::iree_compiler
#endif // IREE_COMPILER_UTILS_PATTERNUTILS_H_