27 class ArithConstantOpConversionPattern
33 matchAndRewrite(arith::ConstantOp arithConst,
34 arith::ConstantOp::Adaptor adaptor,
37 arithConst, arithConst.getType(), adaptor.getValue());
46 bool needsUnsignedCmp(arith::CmpIPredicate pred)
const {
48 case arith::CmpIPredicate::eq:
49 case arith::CmpIPredicate::ne:
50 case arith::CmpIPredicate::slt:
51 case arith::CmpIPredicate::sle:
52 case arith::CmpIPredicate::sgt:
53 case arith::CmpIPredicate::sge:
55 case arith::CmpIPredicate::ult:
56 case arith::CmpIPredicate::ule:
57 case arith::CmpIPredicate::ugt:
58 case arith::CmpIPredicate::uge:
61 llvm_unreachable(
"unknown cmpi predicate kind");
66 case arith::CmpIPredicate::eq:
67 return emitc::CmpPredicate::eq;
68 case arith::CmpIPredicate::ne:
69 return emitc::CmpPredicate::ne;
70 case arith::CmpIPredicate::slt:
71 case arith::CmpIPredicate::ult:
72 return emitc::CmpPredicate::lt;
73 case arith::CmpIPredicate::sle:
74 case arith::CmpIPredicate::ule:
75 return emitc::CmpPredicate::le;
76 case arith::CmpIPredicate::sgt:
77 case arith::CmpIPredicate::ugt:
78 return emitc::CmpPredicate::gt;
79 case arith::CmpIPredicate::sge:
80 case arith::CmpIPredicate::uge:
81 return emitc::CmpPredicate::ge;
83 llvm_unreachable(
"unknown cmpi predicate kind");
87 matchAndRewrite(arith::CmpIOp op, OpAdaptor adaptor,
90 Type type = adaptor.getLhs().getType();
91 if (!isa_and_nonnull<IntegerType, IndexType>(type)) {
95 bool needsUnsigned = needsUnsignedCmp(op.getPredicate());
97 Type arithmeticType = type;
102 Value lhs = adaptor.getLhs();
103 Value rhs = adaptor.getRhs();
104 if (arithmeticType != type) {
105 lhs = rewriter.template create<emitc::CastOp>(op.
getLoc(), arithmeticType,
107 rhs = rewriter.template create<emitc::CastOp>(op.
getLoc(), arithmeticType,
115 template <
typename ArithOp,
typename EmitCOp>
121 matchAndRewrite(ArithOp arithOp,
typename ArithOp::Adaptor adaptor,
124 rewriter.template replaceOpWithNewOp<EmitCOp>(arithOp, arithOp.getType(),
125 adaptor.getOperands());
131 template <
typename ArithOp,
typename EmitCOp>
137 matchAndRewrite(ArithOp op,
typename ArithOp::Adaptor adaptor,
140 Type type = this->getTypeConverter()->convertType(op.getType());
141 if (!isa_and_nonnull<IntegerType, IndexType>(type)) {
150 Value lhs = adaptor.getLhs();
151 Value rhs = adaptor.getRhs();
152 Type arithmeticType = type;
154 !bitEnumContainsAll(op.getOverflowFlags(),
155 arith::IntegerOverflowFlags::nsw)) {
161 if (arithmeticType != type) {
162 lhs = rewriter.template create<emitc::CastOp>(op.
getLoc(), arithmeticType,
164 rhs = rewriter.template create<emitc::CastOp>(op.
getLoc(), arithmeticType,
168 Value result = rewriter.template create<EmitCOp>(op.
getLoc(),
169 arithmeticType, lhs, rhs);
171 if (arithmeticType != type) {
173 rewriter.template create<emitc::CastOp>(op.
getLoc(), type, result);
185 matchAndRewrite(arith::SelectOp selectOp, OpAdaptor adaptor,
188 Type dstType = getTypeConverter()->convertType(selectOp.getType());
192 if (!adaptor.getCondition().getType().isInteger(1))
195 "can only be converted if condition is a scalar of type i1");
198 adaptor.getOperands());
205 template <
typename CastOp>
212 matchAndRewrite(CastOp castOp,
typename CastOp::Adaptor adaptor,
215 Type operandType = adaptor.getIn().getType();
218 "unsupported cast source type");
220 Type dstType = this->getTypeConverter()->convertType(castOp.getType());
228 "unsupported cast destination type");
232 Type actualResultType = dstType;
233 if (isa<arith::FPToUIOp>(castOp)) {
240 castOp.getLoc(), actualResultType, adaptor.getOperands());
242 if (isa<arith::FPToUIOp>(castOp)) {
243 result = rewriter.
create<emitc::CastOp>(castOp.getLoc(), dstType, result);
252 template <
typename CastOp>
259 matchAndRewrite(CastOp castOp,
typename CastOp::Adaptor adaptor,
262 Type operandType = adaptor.getIn().getType();
265 "unsupported cast source type");
267 Type dstType = this->getTypeConverter()->convertType(castOp.getType());
273 "unsupported cast destination type");
277 Type actualOperandType = operandType;
278 if (isa<arith::UIToFPOp>(castOp)) {
283 Value fpCastOperand = adaptor.getIn();
284 if (actualOperandType != operandType) {
285 fpCastOperand = rewriter.template create<emitc::CastOp>(
286 castOp.getLoc(), actualOperandType, fpCastOperand);
306 ArithConstantOpConversionPattern,
307 ArithOpConversion<arith::AddFOp, emitc::AddOp>,
308 ArithOpConversion<arith::DivFOp, emitc::DivOp>,
309 ArithOpConversion<arith::MulFOp, emitc::MulOp>,
310 ArithOpConversion<arith::SubFOp, emitc::SubOp>,
311 IntegerOpConversion<arith::AddIOp, emitc::AddOp>,
312 IntegerOpConversion<arith::MulIOp, emitc::MulOp>,
313 IntegerOpConversion<arith::SubIOp, emitc::SubOp>,
316 ItoFCastOpConversion<arith::SIToFPOp>,
317 ItoFCastOpConversion<arith::UIToFPOp>,
318 FtoICastOpConversion<arith::FPToSIOp>,
319 FtoICastOpConversion<arith::FPToUIOp>
320 >(typeConverter, ctx);
IntegerType getIntegerType(unsigned width)
This class implements a pattern rewriter for use with ConversionPatterns.
void replaceOp(Operation *op, ValueRange newValues) override
PatternRewriter hook for replacing an operation.
MLIRContext is the top-level object for a collection of MLIR operations.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
OpConversionPattern is a wrapper around ConversionPattern that allows for matching and rewriting agai...
OpConversionPattern(MLIRContext *context, PatternBenefit benefit=1)
Location getLoc()
The source location the operation was defined or derived from.
MLIRContext * getContext() const
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
std::enable_if_t<!std::is_convertible< CallbackT, Twine >::value, LogicalResult > notifyMatchFailure(Location loc, CallbackT &&reasonCallback)
Used to notify the listener that the IR failed to be rewritten because of a match failure,...
OpTy replaceOpWithNewOp(Operation *op, Args &&...args)
Replace the results of the given (original) op with a new op that is created without verification (re...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
bool isSignedInteger() const
Return true if this is a signed integer type (with the specified width).
bool isSignlessInteger() const
Return true if this is a signless integer type (with the specified width).
bool isUnsignedInteger() const
Return true if this is an unsigned integer type (with the specified width).
bool isInteger() const
Return true if this is an integer type (with the specified width).
unsigned getIntOrFloatBitWidth() const
Return the bit width of an integer or a float type, assert failure on other types.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
bool isSupportedFloatType(mlir::Type type)
Determines whether type is a valid floating-point type in EmitC.
bool isSupportedIntegerType(mlir::Type type)
Determines whether type is a valid integer type in EmitC.
CmpPredicate
Copy of the enum from arith and index to allow the common integer range infrastructure to not depend ...
Include the generated interface declarations.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
void populateArithToEmitCPatterns(TypeConverter &typeConverter, RewritePatternSet &patterns)
This class represents an efficient way to signal success or failure.