11#include "mlir/Dialect/Arith/IR/Arith.h"
12#include "mlir/IR/BuiltinAttributes.h"
13#include "mlir/IR/BuiltinOps.h"
14#include "mlir/IR/BuiltinTypes.h"
15#include "mlir/IR/PatternMatch.h"
16#include "mlir/Support/LogicalResult.h"
17#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
20#define GEN_PASS_DEF_CONVERTINDEXTOUINT
21#include "circt/Transforms/Passes.h.inc"
34 using OpRewritePattern::OpRewritePattern;
36 LogicalResult matchAndRewrite(arith::CmpIOp op,
37 PatternRewriter &rewriter)
const override {
38 if (!op.getLhs().getType().isIndex() || !op.getRhs().getType().isIndex())
41 FailureOr<IntegerType> targetType = getTargetIntegerType(op);
42 if (failed(targetType))
49 auto convertOperand = [&](Value operand) -> FailureOr<Value> {
50 if (
auto castOp = operand.getDefiningOp<arith::IndexCastOp>()) {
51 Value source = castOp.getIn();
52 auto srcType = dyn_cast<IntegerType>(source.getType());
53 if (!srcType || srcType != *targetType)
58 if (
auto constOp = operand.getDefiningOp<arith::ConstantOp>()) {
59 if (!constOp.getType().isIndex())
62 auto value = dyn_cast<IntegerAttr>(constOp.getValue());
66 auto attr = rewriter.getIntegerAttr(*targetType, value.getInt());
68 arith::ConstantOp::create(rewriter, constOp.getLoc(), attr);
69 return newConst.getResult();
75 FailureOr<Value> lhs = convertOperand(op.getLhs());
76 FailureOr<Value> rhs = convertOperand(op.getRhs());
77 if (failed(lhs) || failed(rhs))
80 rewriter.replaceOpWithNewOp<arith::CmpIOp>(op, op.getPredicate(), *lhs,
86 static FailureOr<IntegerType> getTargetIntegerType(arith::CmpIOp op) {
87 auto pickType = [](Value operand) -> FailureOr<IntegerType> {
88 if (
auto castOp = operand.getDefiningOp<arith::IndexCastOp>()) {
89 if (
auto srcType = dyn_cast<IntegerType>(castOp.getIn().getType()))
95 auto lhsType = pickType(op.getLhs());
96 if (succeeded(lhsType))
99 auto rhsType = pickType(op.getRhs());
100 if (succeeded(rhsType))
108class DropUnusedIndexCastPattern :
public OpRewritePattern<arith::IndexCastOp> {
110 using OpRewritePattern::OpRewritePattern;
112 LogicalResult matchAndRewrite(arith::IndexCastOp op,
113 PatternRewriter &rewriter)
const override {
114 if (!op->use_empty())
116 rewriter.eraseOp(op);
122class DropUnusedIndexConstantPattern
125 using OpRewritePattern::OpRewritePattern;
127 LogicalResult matchAndRewrite(arith::ConstantOp op,
128 PatternRewriter &rewriter)
const override {
129 if (!op.getType().isIndex() || !op->use_empty())
131 rewriter.eraseOp(op);
136struct ConvertIndexToUIntPass
137 :
public circt::impl::ConvertIndexToUIntBase<ConvertIndexToUIntPass> {
138 void runOnOperation()
override {
139 MLIRContext *ctx = &getContext();
141 patterns.add<IndexCmpToIntegerPattern, DropUnusedIndexCastPattern,
142 DropUnusedIndexConstantPattern>(ctx);
144 if (failed(applyPatternsGreedily(getOperation(), std::move(
patterns))))
152 return std::make_unique<ConvertIndexToUIntPass>();
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
std::unique_ptr< mlir::Pass > createConvertIndexToUIntPass()