28struct ArithToEmitCDialectInterface :
public ConvertToEmitCPatternInterface {
29 ArithToEmitCDialectInterface(Dialect *dialect)
30 : ConvertToEmitCPatternInterface(dialect) {}
34 void populateConvertToEmitCConversionPatterns(
35 ConversionTarget &
target, TypeConverter &typeConverter,
36 RewritePatternSet &patterns, std::optional<bool> lowerToCpp)
const final {
44 dialect->addInterfaces<ArithToEmitCDialectInterface>();
53class ArithConstantOpConversionPattern
54 :
public OpConversionPattern<arith::ConstantOp> {
59 matchAndRewrite(arith::ConstantOp arithConst,
60 arith::ConstantOp::Adaptor adaptor,
61 ConversionPatternRewriter &rewriter)
const override {
62 if (isa<MemRefType>(arithConst.getType()))
63 return rewriter.notifyMatchFailure(arithConst,
64 "memref constants are not supported");
65 Type newTy = this->getTypeConverter()->convertType(arithConst.getType());
67 return rewriter.notifyMatchFailure(arithConst,
"type conversion failed");
68 rewriter.replaceOpWithNewOp<emitc::ConstantOp>(arithConst, newTy,
75Type adaptIntegralTypeSignedness(
Type ty,
bool needsUnsigned) {
76 if (isa<IntegerType>(ty)) {
78 auto signedness = needsUnsigned
79 ? IntegerType::SignednessSemantics::Unsigned
80 : IntegerType::SignednessSemantics::Signed;
85 if (isa<emitc::SizeTType>(ty) != needsUnsigned) {
88 return emitc::PtrDiffTType::get(ty.
getContext());
95Value adaptValueType(
Value val, ConversionPatternRewriter &rewriter,
Type ty) {
96 return rewriter.createOrFold<emitc::CastOp>(val.
getLoc(), ty, val);
99class CmpFOpConversion :
public OpConversionPattern<arith::CmpFOp> {
104 matchAndRewrite(arith::CmpFOp op, OpAdaptor adaptor,
105 ConversionPatternRewriter &rewriter)
const override {
107 if (!isa<FloatType>(adaptor.getRhs().getType())) {
108 return rewriter.notifyMatchFailure(op.getLoc(),
109 "cmpf currently only supported on "
110 "floats, not tensors/vectors thereof");
113 bool unordered =
false;
114 emitc::CmpPredicate predicate;
115 switch (op.getPredicate()) {
116 case arith::CmpFPredicate::AlwaysFalse: {
118 emitc::ConstantOp::create(rewriter, op.getLoc(), rewriter.getI1Type(),
119 rewriter.getBoolAttr(
false));
120 rewriter.replaceOp(op, constant);
123 case arith::CmpFPredicate::OEQ:
125 predicate = emitc::CmpPredicate::eq;
127 case arith::CmpFPredicate::OGT:
129 predicate = emitc::CmpPredicate::gt;
131 case arith::CmpFPredicate::OGE:
133 predicate = emitc::CmpPredicate::ge;
135 case arith::CmpFPredicate::OLT:
137 predicate = emitc::CmpPredicate::lt;
139 case arith::CmpFPredicate::OLE:
141 predicate = emitc::CmpPredicate::le;
143 case arith::CmpFPredicate::ONE:
145 predicate = emitc::CmpPredicate::ne;
147 case arith::CmpFPredicate::ORD: {
149 auto cmp = createCheckIsOrdered(rewriter, op.getLoc(), adaptor.getLhs(),
151 rewriter.replaceOp(op, cmp);
154 case arith::CmpFPredicate::UEQ:
156 predicate = emitc::CmpPredicate::eq;
158 case arith::CmpFPredicate::UGT:
160 predicate = emitc::CmpPredicate::gt;
162 case arith::CmpFPredicate::UGE:
164 predicate = emitc::CmpPredicate::ge;
166 case arith::CmpFPredicate::ULT:
168 predicate = emitc::CmpPredicate::lt;
170 case arith::CmpFPredicate::ULE:
172 predicate = emitc::CmpPredicate::le;
174 case arith::CmpFPredicate::UNE:
176 predicate = emitc::CmpPredicate::ne;
178 case arith::CmpFPredicate::UNO: {
180 auto cmp = createCheckIsUnordered(rewriter, op.getLoc(), adaptor.getLhs(),
182 rewriter.replaceOp(op, cmp);
185 case arith::CmpFPredicate::AlwaysTrue: {
187 emitc::ConstantOp::create(rewriter, op.getLoc(), rewriter.getI1Type(),
188 rewriter.getBoolAttr(
true));
189 rewriter.replaceOp(op, constant);
196 emitc::CmpOp::create(rewriter, op.getLoc(), op.getType(), predicate,
197 adaptor.getLhs(), adaptor.getRhs());
201 auto isUnordered = createCheckIsUnordered(
202 rewriter, op.getLoc(), adaptor.getLhs(), adaptor.getRhs());
203 rewriter.replaceOpWithNewOp<emitc::LogicalOrOp>(op, op.getType(),
204 isUnordered, cmpResult);
208 auto isOrdered = createCheckIsOrdered(rewriter, op.getLoc(),
209 adaptor.getLhs(), adaptor.getRhs());
210 rewriter.replaceOpWithNewOp<emitc::LogicalAndOp>(op, op.getType(),
211 isOrdered, cmpResult);
217 Value isNaN(ConversionPatternRewriter &rewriter, Location loc,
218 Value operand)
const {
220 return emitc::CmpOp::create(rewriter, loc, rewriter.getI1Type(),
221 emitc::CmpPredicate::ne, operand, operand);
225 Value isNotNaN(ConversionPatternRewriter &rewriter, Location loc,
226 Value operand)
const {
228 return emitc::CmpOp::create(rewriter, loc, rewriter.getI1Type(),
229 emitc::CmpPredicate::eq, operand, operand);
234 Value createCheckIsUnordered(ConversionPatternRewriter &rewriter,
235 Location loc, Value first, Value second)
const {
236 auto firstIsNaN = isNaN(rewriter, loc, first);
237 auto secondIsNaN = isNaN(rewriter, loc, second);
238 return emitc::LogicalOrOp::create(rewriter, loc, rewriter.getI1Type(),
239 firstIsNaN, secondIsNaN);
244 Value createCheckIsOrdered(ConversionPatternRewriter &rewriter, Location loc,
245 Value first, Value second)
const {
246 auto firstIsNotNaN = isNotNaN(rewriter, loc, first);
247 auto secondIsNotNaN = isNotNaN(rewriter, loc, second);
248 return emitc::LogicalAndOp::create(rewriter, loc, rewriter.getI1Type(),
249 firstIsNotNaN, secondIsNotNaN);
253class CmpIOpConversion :
public OpConversionPattern<arith::CmpIOp> {
257 bool needsUnsignedCmp(arith::CmpIPredicate pred)
const {
259 case arith::CmpIPredicate::eq:
260 case arith::CmpIPredicate::ne:
261 case arith::CmpIPredicate::slt:
262 case arith::CmpIPredicate::sle:
263 case arith::CmpIPredicate::sgt:
264 case arith::CmpIPredicate::sge:
266 case arith::CmpIPredicate::ult:
267 case arith::CmpIPredicate::ule:
268 case arith::CmpIPredicate::ugt:
269 case arith::CmpIPredicate::uge:
272 llvm_unreachable(
"unknown cmpi predicate kind");
275 emitc::CmpPredicate toEmitCPred(arith::CmpIPredicate pred)
const {
277 case arith::CmpIPredicate::eq:
278 return emitc::CmpPredicate::eq;
279 case arith::CmpIPredicate::ne:
280 return emitc::CmpPredicate::ne;
281 case arith::CmpIPredicate::slt:
282 case arith::CmpIPredicate::ult:
283 return emitc::CmpPredicate::lt;
284 case arith::CmpIPredicate::sle:
285 case arith::CmpIPredicate::ule:
286 return emitc::CmpPredicate::le;
287 case arith::CmpIPredicate::sgt:
288 case arith::CmpIPredicate::ugt:
289 return emitc::CmpPredicate::gt;
290 case arith::CmpIPredicate::sge:
291 case arith::CmpIPredicate::uge:
292 return emitc::CmpPredicate::ge;
294 llvm_unreachable(
"unknown cmpi predicate kind");
298 matchAndRewrite(arith::CmpIOp op, OpAdaptor adaptor,
299 ConversionPatternRewriter &rewriter)
const override {
301 Type type = adaptor.getLhs().getType();
303 return rewriter.notifyMatchFailure(
304 op,
"expected integer or size_t/ssize_t/ptrdiff_t type");
307 bool needsUnsigned = needsUnsignedCmp(op.getPredicate());
308 emitc::CmpPredicate pred = toEmitCPred(op.getPredicate());
310 Type arithmeticType = adaptIntegralTypeSignedness(type, needsUnsigned);
311 Value
lhs = adaptValueType(adaptor.getLhs(), rewriter, arithmeticType);
312 Value
rhs = adaptValueType(adaptor.getRhs(), rewriter, arithmeticType);
314 rewriter.replaceOpWithNewOp<emitc::CmpOp>(op, op.getType(), pred,
lhs,
rhs);
319class NegFOpConversion :
public OpConversionPattern<arith::NegFOp> {
324 matchAndRewrite(arith::NegFOp op, OpAdaptor adaptor,
325 ConversionPatternRewriter &rewriter)
const override {
327 auto adaptedOp = adaptor.getOperand();
328 auto adaptedOpType = adaptedOp.getType();
330 if (isa<TensorType>(adaptedOpType) || isa<VectorType>(adaptedOpType)) {
331 return rewriter.notifyMatchFailure(
333 "negf currently only supports scalar types, not vectors or tensors");
337 return rewriter.notifyMatchFailure(
338 op.getLoc(),
"floating-point type is not supported by EmitC");
341 rewriter.replaceOpWithNewOp<emitc::UnaryMinusOp>(op, adaptedOpType,
347template <
typename ArithOp,
bool castToUn
signed>
348class CastConversion :
public OpConversionPattern<ArithOp> {
350 using OpConversionPattern<ArithOp>::OpConversionPattern;
353 matchAndRewrite(ArithOp op,
typename ArithOp::Adaptor adaptor,
354 ConversionPatternRewriter &rewriter)
const override {
356 Type opReturnType = this->getTypeConverter()->convertType(op.getType());
357 if (!opReturnType || !(isa<IntegerType>(opReturnType) ||
359 return rewriter.notifyMatchFailure(
360 op,
"expected integer or size_t/ssize_t/ptrdiff_t result type");
362 if (adaptor.getOperands().size() != 1) {
363 return rewriter.notifyMatchFailure(
364 op,
"CastConversion only supports unary ops");
367 Type operandType = adaptor.getIn().getType();
368 if (!operandType || !(isa<IntegerType>(operandType) ||
370 return rewriter.notifyMatchFailure(
371 op,
"expected integer or size_t/ssize_t/ptrdiff_t operand type");
374 if (operandType.
isInteger(1) && !castToUnsigned)
375 return rewriter.notifyMatchFailure(op,
376 "operation not supported on i1 type");
383 ? rewriter.getIndexType()
385 auto constOne = emitc::ConstantOp::create(
386 rewriter, op.getLoc(), operandType, rewriter.getOneAttr(attrType));
387 auto oneAndOperand = emitc::BitwiseAndOp::create(
388 rewriter, op.getLoc(), operandType, adaptor.getIn(), constOne);
389 rewriter.replaceOpWithNewOp<emitc::CastOp>(op, opReturnType,
395 (isa<IntegerType>(operandType) && isa<IntegerType>(opReturnType) &&
398 bool doUnsigned = castToUnsigned || isTruncation;
402 Type castDestType = adaptIntegralTypeSignedness(opReturnType, doUnsigned);
405 Type castSrcType = adaptIntegralTypeSignedness(operandType, doUnsigned);
406 Value actualOp = adaptValueType(adaptor.getIn(), rewriter, castSrcType);
410 emitc::CastOp::create(rewriter, op.getLoc(), castDestType, actualOp);
413 auto result = adaptValueType(cast, rewriter, opReturnType);
415 rewriter.replaceOp(op,
result);
420template <
typename ArithOp>
421class UnsignedCastConversion :
public CastConversion<ArithOp, true> {
422 using CastConversion<ArithOp,
true>::CastConversion;
425template <
typename ArithOp>
426class SignedCastConversion :
public CastConversion<ArithOp, false> {
427 using CastConversion<ArithOp,
false>::CastConversion;
430template <
typename ArithOp,
typename EmitCOp>
431class ArithOpConversion final :
public OpConversionPattern<ArithOp> {
433 using OpConversionPattern<ArithOp>::OpConversionPattern;
436 matchAndRewrite(ArithOp arithOp,
typename ArithOp::Adaptor adaptor,
437 ConversionPatternRewriter &rewriter)
const override {
439 Type newTy = this->getTypeConverter()->convertType(arithOp.getType());
441 return rewriter.notifyMatchFailure(arithOp,
442 "converting result type failed");
443 rewriter.template replaceOpWithNewOp<EmitCOp>(arithOp, newTy,
444 adaptor.getOperands());
450template <
class ArithOp,
class EmitCOp>
451class BinaryUIOpConversion final :
public OpConversionPattern<ArithOp> {
453 using OpConversionPattern<ArithOp>::OpConversionPattern;
456 matchAndRewrite(ArithOp uiBinOp,
typename ArithOp::Adaptor adaptor,
457 ConversionPatternRewriter &rewriter)
const override {
458 Type newRetTy = this->getTypeConverter()->convertType(uiBinOp.getType());
460 return rewriter.notifyMatchFailure(uiBinOp,
461 "converting result type failed");
462 if (!isa<IntegerType>(newRetTy)) {
463 return rewriter.notifyMatchFailure(uiBinOp,
"expected integer type");
466 adaptIntegralTypeSignedness(newRetTy,
true);
468 return rewriter.notifyMatchFailure(uiBinOp,
469 "converting result type failed");
470 Value lhsAdapted = adaptValueType(uiBinOp.getLhs(), rewriter, unsignedType);
471 Value rhsAdapted = adaptValueType(uiBinOp.getRhs(), rewriter, unsignedType);
473 auto newDivOp = EmitCOp::create(rewriter, uiBinOp.getLoc(), unsignedType,
474 ArrayRef<Value>{lhsAdapted, rhsAdapted});
475 Value resultAdapted = adaptValueType(newDivOp, rewriter, newRetTy);
476 rewriter.replaceOp(uiBinOp, resultAdapted);
481template <
typename ArithOp,
typename EmitCOp>
482class IntegerOpConversion final :
public OpConversionPattern<ArithOp> {
484 using OpConversionPattern<ArithOp>::OpConversionPattern;
487 matchAndRewrite(ArithOp op,
typename ArithOp::Adaptor adaptor,
488 ConversionPatternRewriter &rewriter)
const override {
490 Type type = this->getTypeConverter()->convertType(op.getType());
492 return rewriter.notifyMatchFailure(
493 op,
"expected integer or size_t/ssize_t/ptrdiff_t type");
498 return rewriter.notifyMatchFailure(op,
"i1 type is not implemented");
501 Type arithmeticType = type;
503 !bitEnumContainsAll(op.getOverflowFlags(),
504 arith::IntegerOverflowFlags::nsw)) {
511 Value
lhs = adaptValueType(adaptor.getLhs(), rewriter, arithmeticType);
512 Value
rhs = adaptValueType(adaptor.getRhs(), rewriter, arithmeticType);
514 Value arithmeticResult =
515 EmitCOp::create(rewriter, op.getLoc(), arithmeticType,
lhs,
rhs);
517 Value
result = adaptValueType(arithmeticResult, rewriter, type);
519 rewriter.replaceOp(op,
result);
524template <
typename ArithOp,
typename EmitCOp>
525class BitwiseOpConversion :
public OpConversionPattern<ArithOp> {
527 using OpConversionPattern<ArithOp>::OpConversionPattern;
530 matchAndRewrite(ArithOp op,
typename ArithOp::Adaptor adaptor,
531 ConversionPatternRewriter &rewriter)
const override {
533 Type type = this->getTypeConverter()->convertType(op.getType());
534 if (!isa_and_nonnull<IntegerType>(type)) {
535 return rewriter.notifyMatchFailure(
537 "expected integer type, vector/tensor support not yet implemented");
542 rewriter.replaceOpWithNewOp<EmitCOp>(op, type, adaptor.getLhs(),
548 Type arithmeticType =
549 adaptIntegralTypeSignedness(type,
true);
551 Value
lhs = adaptValueType(adaptor.getLhs(), rewriter, arithmeticType);
552 Value
rhs = adaptValueType(adaptor.getRhs(), rewriter, arithmeticType);
554 Value arithmeticResult =
555 EmitCOp::create(rewriter, op.getLoc(), arithmeticType,
lhs,
rhs);
557 Value
result = adaptValueType(arithmeticResult, rewriter, type);
559 rewriter.replaceOp(op,
result);
564template <
typename ArithOp,
typename EmitCOp,
bool isUn
signedOp>
565class ShiftOpConversion :
public OpConversionPattern<ArithOp> {
567 using OpConversionPattern<ArithOp>::OpConversionPattern;
570 matchAndRewrite(ArithOp op,
typename ArithOp::Adaptor adaptor,
571 ConversionPatternRewriter &rewriter)
const override {
573 Type type = this->getTypeConverter()->convertType(op.getType());
575 return rewriter.notifyMatchFailure(
576 op,
"expected integer or size_t/ssize_t/ptrdiff_t type");
580 return rewriter.notifyMatchFailure(op,
"i1 type is not implemented");
583 Type arithmeticType = adaptIntegralTypeSignedness(type, isUnsignedOp);
585 Value
lhs = adaptValueType(adaptor.getLhs(), rewriter, arithmeticType);
587 Type rhsType = adaptIntegralTypeSignedness(adaptor.getRhs().getType(),
589 Value
rhs = adaptValueType(adaptor.getRhs(), rewriter, rhsType);
594 Value eight = emitc::ConstantOp::create(rewriter, op.getLoc(), rhsType,
595 rewriter.getIndexAttr(8));
596 emitc::CallOpaqueOp sizeOfCall = emitc::CallOpaqueOp::create(
597 rewriter, op.getLoc(), rhsType,
"sizeof", ArrayRef<Value>{eight});
598 width = emitc::MulOp::create(rewriter, op.getLoc(), rhsType, eight,
599 sizeOfCall.getResult(0));
601 width = emitc::ConstantOp::create(
602 rewriter, op.getLoc(), rhsType,
607 emitc::CmpOp::create(rewriter, op.getLoc(), rewriter.getI1Type(),
608 emitc::CmpPredicate::lt,
rhs, width);
611 Value poison = emitc::ConstantOp::create(
612 rewriter, op.getLoc(), arithmeticType,
613 (isa<IntegerType>(arithmeticType)
614 ? rewriter.getIntegerAttr(arithmeticType, 0)
615 : rewriter.getIndexAttr(0)));
617 emitc::ExpressionOp ternary =
618 emitc::ExpressionOp::create(rewriter, op.getLoc(), arithmeticType,
621 Block &bodyBlock = ternary.createBody();
622 auto currentPoint = rewriter.getInsertionPoint();
623 rewriter.setInsertionPointToStart(&bodyBlock);
624 Value arithmeticResult =
625 EmitCOp::create(rewriter, op.getLoc(), arithmeticType,
626 bodyBlock.getArgument(0), bodyBlock.getArgument(1));
627 Value resultOrPoison = emitc::ConditionalOp::create(
628 rewriter, op.getLoc(), arithmeticType, bodyBlock.getArgument(2),
629 arithmeticResult, bodyBlock.getArgument(3));
630 emitc::YieldOp::create(rewriter, op.getLoc(), resultOrPoison);
631 rewriter.setInsertionPoint(op->getBlock(), currentPoint);
633 Value
result = adaptValueType(ternary, rewriter, type);
635 rewriter.replaceOp(op,
result);
640template <
typename ArithOp,
typename EmitCOp>
641class SignedShiftOpConversion final
642 :
public ShiftOpConversion<ArithOp, EmitCOp, false> {
643 using ShiftOpConversion<ArithOp, EmitCOp,
false>::ShiftOpConversion;
646template <
typename ArithOp,
typename EmitCOp>
647class UnsignedShiftOpConversion final
648 :
public ShiftOpConversion<ArithOp, EmitCOp, true> {
649 using ShiftOpConversion<ArithOp, EmitCOp,
true>::ShiftOpConversion;
652class SelectOpConversion :
public OpConversionPattern<arith::SelectOp> {
657 matchAndRewrite(arith::SelectOp selectOp, OpAdaptor adaptor,
658 ConversionPatternRewriter &rewriter)
const override {
660 Type dstType = getTypeConverter()->convertType(selectOp.getType());
662 return rewriter.notifyMatchFailure(selectOp,
"type conversion failed");
664 if (!adaptor.getCondition().getType().isInteger(1))
665 return rewriter.notifyMatchFailure(
667 "can only be converted if condition is a scalar of type i1");
669 rewriter.replaceOpWithNewOp<emitc::ConditionalOp>(selectOp, dstType,
670 adaptor.getOperands());
677template <
typename CastOp>
678class FtoICastOpConversion :
public OpConversionPattern<CastOp> {
680 FtoICastOpConversion(
const TypeConverter &typeConverter, MLIRContext *context)
681 : OpConversionPattern<CastOp>(typeConverter, context) {}
684 matchAndRewrite(CastOp castOp,
typename CastOp::Adaptor adaptor,
685 ConversionPatternRewriter &rewriter)
const override {
687 Type operandType = adaptor.getIn().getType();
689 return rewriter.notifyMatchFailure(castOp,
690 "unsupported cast source type");
692 Type dstType = this->getTypeConverter()->convertType(castOp.getType());
694 return rewriter.notifyMatchFailure(castOp,
"type conversion failed");
699 return rewriter.notifyMatchFailure(castOp,
700 "unsupported cast destination type");
704 Type actualResultType = dstType;
705 if (isa<arith::FPToUIOp>(castOp)) {
711 Value
result = emitc::CastOp::create(
712 rewriter, castOp.getLoc(), actualResultType, adaptor.getOperands());
714 if (isa<arith::FPToUIOp>(castOp)) {
716 emitc::CastOp::create(rewriter, castOp.getLoc(), dstType,
result);
718 rewriter.replaceOp(castOp,
result);
725template <
typename CastOp>
726class ItoFCastOpConversion :
public OpConversionPattern<CastOp> {
728 ItoFCastOpConversion(
const TypeConverter &typeConverter, MLIRContext *context)
729 : OpConversionPattern<CastOp>(typeConverter, context) {}
732 matchAndRewrite(CastOp castOp,
typename CastOp::Adaptor adaptor,
733 ConversionPatternRewriter &rewriter)
const override {
735 Type operandType = adaptor.getIn().getType();
737 return rewriter.notifyMatchFailure(castOp,
738 "unsupported cast source type");
740 Type dstType = this->getTypeConverter()->convertType(castOp.getType());
742 return rewriter.notifyMatchFailure(castOp,
"type conversion failed");
745 return rewriter.notifyMatchFailure(castOp,
746 "unsupported cast destination type");
750 Type actualOperandType = operandType;
751 if (isa<arith::UIToFPOp>(castOp)) {
756 Value fpCastOperand = adaptor.getIn();
757 if (actualOperandType != operandType) {
758 fpCastOperand = emitc::CastOp::create(rewriter, castOp.getLoc(),
759 actualOperandType, fpCastOperand);
761 rewriter.replaceOpWithNewOp<emitc::CastOp>(castOp, dstType, fpCastOperand);
768template <
typename CastOp>
769class FpCastOpConversion :
public OpConversionPattern<CastOp> {
771 FpCastOpConversion(
const TypeConverter &typeConverter, MLIRContext *context)
772 : OpConversionPattern<CastOp>(typeConverter, context) {}
775 matchAndRewrite(CastOp castOp,
typename CastOp::Adaptor adaptor,
776 ConversionPatternRewriter &rewriter)
const override {
778 Type operandType = adaptor.getIn().getType();
780 return rewriter.notifyMatchFailure(castOp,
781 "unsupported cast source type");
782 if (
auto roundingModeOp =
783 dyn_cast<arith::ArithRoundingModeInterface>(*castOp)) {
785 if (roundingModeOp.getRoundingModeAttr())
786 return rewriter.notifyMatchFailure(castOp,
"unsupported rounding mode");
789 Type dstType = this->getTypeConverter()->convertType(castOp.getType());
791 return rewriter.notifyMatchFailure(castOp,
"type conversion failed");
794 return rewriter.notifyMatchFailure(castOp,
795 "unsupported cast destination type");
797 Value fpCastOperand = adaptor.getIn();
798 rewriter.replaceOpWithNewOp<emitc::CastOp>(castOp, dstType, fpCastOperand);
818 ArithConstantOpConversionPattern,
819 ArithOpConversion<arith::AddFOp, emitc::AddOp>,
820 ArithOpConversion<arith::DivFOp, emitc::DivOp>,
821 ArithOpConversion<arith::DivSIOp, emitc::DivOp>,
822 ArithOpConversion<arith::MulFOp, emitc::MulOp>,
823 ArithOpConversion<arith::RemSIOp, emitc::RemOp>,
824 ArithOpConversion<arith::SubFOp, emitc::SubOp>,
825 BinaryUIOpConversion<arith::DivUIOp, emitc::DivOp>,
826 BinaryUIOpConversion<arith::RemUIOp, emitc::RemOp>,
827 IntegerOpConversion<arith::AddIOp, emitc::AddOp>,
828 IntegerOpConversion<arith::MulIOp, emitc::MulOp>,
829 IntegerOpConversion<arith::SubIOp, emitc::SubOp>,
830 BitwiseOpConversion<arith::AndIOp, emitc::BitwiseAndOp>,
831 BitwiseOpConversion<arith::OrIOp, emitc::BitwiseOrOp>,
832 BitwiseOpConversion<arith::XOrIOp, emitc::BitwiseXorOp>,
833 UnsignedShiftOpConversion<arith::ShLIOp, emitc::BitwiseLeftShiftOp>,
834 SignedShiftOpConversion<arith::ShRSIOp, emitc::BitwiseRightShiftOp>,
835 UnsignedShiftOpConversion<arith::ShRUIOp, emitc::BitwiseRightShiftOp>,
841 UnsignedCastConversion<arith::TruncIOp>,
842 SignedCastConversion<arith::ExtSIOp>,
843 UnsignedCastConversion<arith::ExtUIOp>,
844 SignedCastConversion<arith::IndexCastOp>,
845 UnsignedCastConversion<arith::IndexCastUIOp>,
846 ItoFCastOpConversion<arith::SIToFPOp>,
847 ItoFCastOpConversion<arith::UIToFPOp>,
848 FtoICastOpConversion<arith::FPToSIOp>,
849 FtoICastOpConversion<arith::FPToUIOp>,
850 FpCastOpConversion<arith::ExtFOp>,
851 FpCastOpConversion<arith::TruncFOp>
852 >(typeConverter, ctx);
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
MLIRContext is the top-level object for a collection of MLIR operations.
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.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
MLIRContext * getContext() const
Return the MLIRContext in which this type was uniqued.
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...
Location getLoc() const
Return the location of this value.
bool isSupportedFloatType(mlir::Type type)
Determines whether type is a valid floating-point type in EmitC.
bool isPointerWideType(mlir::Type type)
Determines whether type is a emitc.size_t/ssize_t type.
bool isSupportedIntegerType(mlir::Type type)
Determines whether type is a valid integer type in EmitC.
Include the generated interface declarations.
void registerConvertArithToEmitCInterface(DialectRegistry ®istry)
void populateEmitCSizeTTypeConversions(TypeConverter &converter)
void populateArithToEmitCPatterns(TypeConverter &typeConverter, RewritePatternSet &patterns)