33 void populateConvertToEmitCConversionPatterns(
34 ConversionTarget &
target, TypeConverter &typeConverter,
35 RewritePatternSet &
patterns)
const final {
43 dialect->addInterfaces<ArithToEmitCDialectInterface>();
52class ArithConstantOpConversionPattern
53 :
public OpConversionPattern<arith::ConstantOp> {
58 matchAndRewrite(arith::ConstantOp arithConst,
59 arith::ConstantOp::Adaptor adaptor,
60 ConversionPatternRewriter &rewriter)
const override {
61 Type newTy = this->getTypeConverter()->convertType(arithConst.getType());
63 return rewriter.notifyMatchFailure(arithConst,
"type conversion failed");
64 rewriter.replaceOpWithNewOp<emitc::ConstantOp>(arithConst, newTy,
71Type adaptIntegralTypeSignedness(
Type ty,
bool needsUnsigned) {
72 if (isa<IntegerType>(ty)) {
74 auto signedness = needsUnsigned
75 ? IntegerType::SignednessSemantics::Unsigned
76 : IntegerType::SignednessSemantics::Signed;
81 if (isa<emitc::SizeTType>(ty) != needsUnsigned) {
84 return emitc::PtrDiffTType::get(ty.
getContext());
91Value adaptValueType(
Value val, ConversionPatternRewriter &rewriter,
Type ty) {
92 return rewriter.createOrFold<emitc::CastOp>(val.
getLoc(), ty, val);
95class CmpFOpConversion :
public OpConversionPattern<arith::CmpFOp> {
100 matchAndRewrite(arith::CmpFOp op, OpAdaptor adaptor,
101 ConversionPatternRewriter &rewriter)
const override {
103 if (!isa<FloatType>(adaptor.getRhs().getType())) {
104 return rewriter.notifyMatchFailure(op.getLoc(),
105 "cmpf currently only supported on "
106 "floats, not tensors/vectors thereof");
109 bool unordered =
false;
110 emitc::CmpPredicate predicate;
111 switch (op.getPredicate()) {
112 case arith::CmpFPredicate::AlwaysFalse: {
114 emitc::ConstantOp::create(rewriter, op.getLoc(), rewriter.getI1Type(),
115 rewriter.getBoolAttr(
false));
116 rewriter.replaceOp(op, constant);
119 case arith::CmpFPredicate::OEQ:
121 predicate = emitc::CmpPredicate::eq;
123 case arith::CmpFPredicate::OGT:
125 predicate = emitc::CmpPredicate::gt;
127 case arith::CmpFPredicate::OGE:
129 predicate = emitc::CmpPredicate::ge;
131 case arith::CmpFPredicate::OLT:
133 predicate = emitc::CmpPredicate::lt;
135 case arith::CmpFPredicate::OLE:
137 predicate = emitc::CmpPredicate::le;
139 case arith::CmpFPredicate::ONE:
141 predicate = emitc::CmpPredicate::ne;
143 case arith::CmpFPredicate::ORD: {
145 auto cmp = createCheckIsOrdered(rewriter, op.getLoc(), adaptor.getLhs(),
147 rewriter.replaceOp(op, cmp);
150 case arith::CmpFPredicate::UEQ:
152 predicate = emitc::CmpPredicate::eq;
154 case arith::CmpFPredicate::UGT:
156 predicate = emitc::CmpPredicate::gt;
158 case arith::CmpFPredicate::UGE:
160 predicate = emitc::CmpPredicate::ge;
162 case arith::CmpFPredicate::ULT:
164 predicate = emitc::CmpPredicate::lt;
166 case arith::CmpFPredicate::ULE:
168 predicate = emitc::CmpPredicate::le;
170 case arith::CmpFPredicate::UNE:
172 predicate = emitc::CmpPredicate::ne;
174 case arith::CmpFPredicate::UNO: {
176 auto cmp = createCheckIsUnordered(rewriter, op.getLoc(), adaptor.getLhs(),
178 rewriter.replaceOp(op, cmp);
181 case arith::CmpFPredicate::AlwaysTrue: {
183 emitc::ConstantOp::create(rewriter, op.getLoc(), rewriter.getI1Type(),
184 rewriter.getBoolAttr(
true));
185 rewriter.replaceOp(op, constant);
192 emitc::CmpOp::create(rewriter, op.getLoc(), op.getType(), predicate,
193 adaptor.getLhs(), adaptor.getRhs());
197 auto isUnordered = createCheckIsUnordered(
198 rewriter, op.getLoc(), adaptor.getLhs(), adaptor.getRhs());
199 rewriter.replaceOpWithNewOp<emitc::LogicalOrOp>(op, op.getType(),
200 isUnordered, cmpResult);
204 auto isOrdered = createCheckIsOrdered(rewriter, op.getLoc(),
205 adaptor.getLhs(), adaptor.getRhs());
206 rewriter.replaceOpWithNewOp<emitc::LogicalAndOp>(op, op.getType(),
207 isOrdered, cmpResult);
213 Value isNaN(ConversionPatternRewriter &rewriter, Location loc,
214 Value operand)
const {
216 return emitc::CmpOp::create(rewriter, loc, rewriter.getI1Type(),
217 emitc::CmpPredicate::ne, operand, operand);
221 Value isNotNaN(ConversionPatternRewriter &rewriter, Location loc,
222 Value operand)
const {
224 return emitc::CmpOp::create(rewriter, loc, rewriter.getI1Type(),
225 emitc::CmpPredicate::eq, operand, operand);
230 Value createCheckIsUnordered(ConversionPatternRewriter &rewriter,
231 Location loc, Value first, Value second)
const {
232 auto firstIsNaN = isNaN(rewriter, loc, first);
233 auto secondIsNaN = isNaN(rewriter, loc, second);
234 return emitc::LogicalOrOp::create(rewriter, loc, rewriter.getI1Type(),
235 firstIsNaN, secondIsNaN);
240 Value createCheckIsOrdered(ConversionPatternRewriter &rewriter, Location loc,
241 Value first, Value second)
const {
242 auto firstIsNotNaN = isNotNaN(rewriter, loc, first);
243 auto secondIsNotNaN = isNotNaN(rewriter, loc, second);
244 return emitc::LogicalAndOp::create(rewriter, loc, rewriter.getI1Type(),
245 firstIsNotNaN, secondIsNotNaN);
249class CmpIOpConversion :
public OpConversionPattern<arith::CmpIOp> {
253 bool needsUnsignedCmp(arith::CmpIPredicate pred)
const {
255 case arith::CmpIPredicate::eq:
256 case arith::CmpIPredicate::ne:
257 case arith::CmpIPredicate::slt:
258 case arith::CmpIPredicate::sle:
259 case arith::CmpIPredicate::sgt:
260 case arith::CmpIPredicate::sge:
262 case arith::CmpIPredicate::ult:
263 case arith::CmpIPredicate::ule:
264 case arith::CmpIPredicate::ugt:
265 case arith::CmpIPredicate::uge:
268 llvm_unreachable(
"unknown cmpi predicate kind");
271 emitc::CmpPredicate toEmitCPred(arith::CmpIPredicate pred)
const {
273 case arith::CmpIPredicate::eq:
274 return emitc::CmpPredicate::eq;
275 case arith::CmpIPredicate::ne:
276 return emitc::CmpPredicate::ne;
277 case arith::CmpIPredicate::slt:
278 case arith::CmpIPredicate::ult:
279 return emitc::CmpPredicate::lt;
280 case arith::CmpIPredicate::sle:
281 case arith::CmpIPredicate::ule:
282 return emitc::CmpPredicate::le;
283 case arith::CmpIPredicate::sgt:
284 case arith::CmpIPredicate::ugt:
285 return emitc::CmpPredicate::gt;
286 case arith::CmpIPredicate::sge:
287 case arith::CmpIPredicate::uge:
288 return emitc::CmpPredicate::ge;
290 llvm_unreachable(
"unknown cmpi predicate kind");
294 matchAndRewrite(arith::CmpIOp op, OpAdaptor adaptor,
295 ConversionPatternRewriter &rewriter)
const override {
297 Type type = adaptor.getLhs().getType();
299 return rewriter.notifyMatchFailure(
300 op,
"expected integer or size_t/ssize_t/ptrdiff_t type");
303 bool needsUnsigned = needsUnsignedCmp(op.getPredicate());
304 emitc::CmpPredicate pred = toEmitCPred(op.getPredicate());
306 Type arithmeticType = adaptIntegralTypeSignedness(type, needsUnsigned);
307 Value
lhs = adaptValueType(adaptor.getLhs(), rewriter, arithmeticType);
308 Value
rhs = adaptValueType(adaptor.getRhs(), rewriter, arithmeticType);
310 rewriter.replaceOpWithNewOp<emitc::CmpOp>(op, op.getType(), pred,
lhs,
rhs);
315class NegFOpConversion :
public OpConversionPattern<arith::NegFOp> {
320 matchAndRewrite(arith::NegFOp op, OpAdaptor adaptor,
321 ConversionPatternRewriter &rewriter)
const override {
323 auto adaptedOp = adaptor.getOperand();
324 auto adaptedOpType = adaptedOp.getType();
326 if (isa<TensorType>(adaptedOpType) || isa<VectorType>(adaptedOpType)) {
327 return rewriter.notifyMatchFailure(
329 "negf currently only supports scalar types, not vectors or tensors");
333 return rewriter.notifyMatchFailure(
334 op.getLoc(),
"floating-point type is not supported by EmitC");
337 rewriter.replaceOpWithNewOp<emitc::UnaryMinusOp>(op, adaptedOpType,
343template <
typename ArithOp,
bool castToUn
signed>
344class CastConversion :
public OpConversionPattern<ArithOp> {
346 using OpConversionPattern<ArithOp>::OpConversionPattern;
349 matchAndRewrite(ArithOp op,
typename ArithOp::Adaptor adaptor,
350 ConversionPatternRewriter &rewriter)
const override {
352 Type opReturnType = this->getTypeConverter()->convertType(op.getType());
353 if (!opReturnType || !(isa<IntegerType>(opReturnType) ||
355 return rewriter.notifyMatchFailure(
356 op,
"expected integer or size_t/ssize_t/ptrdiff_t result type");
358 if (adaptor.getOperands().size() != 1) {
359 return rewriter.notifyMatchFailure(
360 op,
"CastConversion only supports unary ops");
363 Type operandType = adaptor.getIn().getType();
364 if (!operandType || !(isa<IntegerType>(operandType) ||
366 return rewriter.notifyMatchFailure(
367 op,
"expected integer or size_t/ssize_t/ptrdiff_t operand type");
370 if (operandType.
isInteger(1) && !castToUnsigned)
371 return rewriter.notifyMatchFailure(op,
372 "operation not supported on i1 type");
379 ? rewriter.getIndexType()
381 auto constOne = emitc::ConstantOp::create(
382 rewriter, op.getLoc(), operandType, rewriter.getOneAttr(attrType));
383 auto oneAndOperand = emitc::BitwiseAndOp::create(
384 rewriter, op.getLoc(), operandType, adaptor.getIn(), constOne);
385 rewriter.replaceOpWithNewOp<emitc::CastOp>(op, opReturnType,
391 (isa<IntegerType>(operandType) && isa<IntegerType>(opReturnType) &&
394 bool doUnsigned = castToUnsigned || isTruncation;
398 Type castDestType = adaptIntegralTypeSignedness(opReturnType, doUnsigned);
401 Type castSrcType = adaptIntegralTypeSignedness(operandType, doUnsigned);
402 Value actualOp = adaptValueType(adaptor.getIn(), rewriter, castSrcType);
406 emitc::CastOp::create(rewriter, op.getLoc(), castDestType, actualOp);
409 auto result = adaptValueType(cast, rewriter, opReturnType);
411 rewriter.replaceOp(op,
result);
416template <
typename ArithOp>
417class UnsignedCastConversion :
public CastConversion<ArithOp, true> {
418 using CastConversion<ArithOp,
true>::CastConversion;
421template <
typename ArithOp>
422class SignedCastConversion :
public CastConversion<ArithOp, false> {
423 using CastConversion<ArithOp,
false>::CastConversion;
426template <
typename ArithOp,
typename EmitCOp>
427class ArithOpConversion final :
public OpConversionPattern<ArithOp> {
429 using OpConversionPattern<ArithOp>::OpConversionPattern;
432 matchAndRewrite(ArithOp arithOp,
typename ArithOp::Adaptor adaptor,
433 ConversionPatternRewriter &rewriter)
const override {
435 Type newTy = this->getTypeConverter()->convertType(arithOp.getType());
437 return rewriter.notifyMatchFailure(arithOp,
438 "converting result type failed");
439 rewriter.template replaceOpWithNewOp<EmitCOp>(arithOp, newTy,
440 adaptor.getOperands());
446template <
class ArithOp,
class EmitCOp>
447class BinaryUIOpConversion final :
public OpConversionPattern<ArithOp> {
449 using OpConversionPattern<ArithOp>::OpConversionPattern;
452 matchAndRewrite(ArithOp uiBinOp,
typename ArithOp::Adaptor adaptor,
453 ConversionPatternRewriter &rewriter)
const override {
454 Type newRetTy = this->getTypeConverter()->convertType(uiBinOp.getType());
456 return rewriter.notifyMatchFailure(uiBinOp,
457 "converting result type failed");
458 if (!isa<IntegerType>(newRetTy)) {
459 return rewriter.notifyMatchFailure(uiBinOp,
"expected integer type");
462 adaptIntegralTypeSignedness(newRetTy,
true);
464 return rewriter.notifyMatchFailure(uiBinOp,
465 "converting result type failed");
466 Value lhsAdapted = adaptValueType(uiBinOp.getLhs(), rewriter, unsignedType);
467 Value rhsAdapted = adaptValueType(uiBinOp.getRhs(), rewriter, unsignedType);
469 auto newDivOp = EmitCOp::create(rewriter, uiBinOp.getLoc(), unsignedType,
470 ArrayRef<Value>{lhsAdapted, rhsAdapted});
471 Value resultAdapted = adaptValueType(newDivOp, rewriter, newRetTy);
472 rewriter.replaceOp(uiBinOp, resultAdapted);
477template <
typename ArithOp,
typename EmitCOp>
478class IntegerOpConversion final :
public OpConversionPattern<ArithOp> {
480 using OpConversionPattern<ArithOp>::OpConversionPattern;
483 matchAndRewrite(ArithOp op,
typename ArithOp::Adaptor adaptor,
484 ConversionPatternRewriter &rewriter)
const override {
486 Type type = this->getTypeConverter()->convertType(op.getType());
488 return rewriter.notifyMatchFailure(
489 op,
"expected integer or size_t/ssize_t/ptrdiff_t type");
494 return rewriter.notifyMatchFailure(op,
"i1 type is not implemented");
497 Type arithmeticType = type;
499 !bitEnumContainsAll(op.getOverflowFlags(),
500 arith::IntegerOverflowFlags::nsw)) {
507 Value
lhs = adaptValueType(adaptor.getLhs(), rewriter, arithmeticType);
508 Value
rhs = adaptValueType(adaptor.getRhs(), rewriter, arithmeticType);
510 Value arithmeticResult =
511 EmitCOp::create(rewriter, op.getLoc(), arithmeticType,
lhs,
rhs);
513 Value
result = adaptValueType(arithmeticResult, rewriter, type);
515 rewriter.replaceOp(op,
result);
520template <
typename ArithOp,
typename EmitCOp>
521class BitwiseOpConversion :
public OpConversionPattern<ArithOp> {
523 using OpConversionPattern<ArithOp>::OpConversionPattern;
526 matchAndRewrite(ArithOp op,
typename ArithOp::Adaptor adaptor,
527 ConversionPatternRewriter &rewriter)
const override {
529 Type type = this->getTypeConverter()->convertType(op.getType());
530 if (!isa_and_nonnull<IntegerType>(type)) {
531 return rewriter.notifyMatchFailure(
533 "expected integer type, vector/tensor support not yet implemented");
538 rewriter.replaceOpWithNewOp<EmitCOp>(op, type, adaptor.getLhs(),
544 Type arithmeticType =
545 adaptIntegralTypeSignedness(type,
true);
547 Value
lhs = adaptValueType(adaptor.getLhs(), rewriter, arithmeticType);
548 Value
rhs = adaptValueType(adaptor.getRhs(), rewriter, arithmeticType);
550 Value arithmeticResult =
551 EmitCOp::create(rewriter, op.getLoc(), arithmeticType,
lhs,
rhs);
553 Value
result = adaptValueType(arithmeticResult, rewriter, type);
555 rewriter.replaceOp(op,
result);
560template <
typename ArithOp,
typename EmitCOp,
bool isUn
signedOp>
561class ShiftOpConversion :
public OpConversionPattern<ArithOp> {
563 using OpConversionPattern<ArithOp>::OpConversionPattern;
566 matchAndRewrite(ArithOp op,
typename ArithOp::Adaptor adaptor,
567 ConversionPatternRewriter &rewriter)
const override {
569 Type type = this->getTypeConverter()->convertType(op.getType());
571 return rewriter.notifyMatchFailure(
572 op,
"expected integer or size_t/ssize_t/ptrdiff_t type");
576 return rewriter.notifyMatchFailure(op,
"i1 type is not implemented");
579 Type arithmeticType = adaptIntegralTypeSignedness(type, isUnsignedOp);
581 Value
lhs = adaptValueType(adaptor.getLhs(), rewriter, arithmeticType);
583 Type rhsType = adaptIntegralTypeSignedness(adaptor.getRhs().getType(),
585 Value
rhs = adaptValueType(adaptor.getRhs(), rewriter, rhsType);
590 Value eight = emitc::ConstantOp::create(rewriter, op.getLoc(), rhsType,
591 rewriter.getIndexAttr(8));
592 emitc::CallOpaqueOp sizeOfCall = emitc::CallOpaqueOp::create(
593 rewriter, op.getLoc(), rhsType,
"sizeof", ArrayRef<Value>{eight});
594 width = emitc::MulOp::create(rewriter, op.getLoc(), rhsType, eight,
595 sizeOfCall.getResult(0));
597 width = emitc::ConstantOp::create(
598 rewriter, op.getLoc(), rhsType,
603 emitc::CmpOp::create(rewriter, op.getLoc(), rewriter.getI1Type(),
604 emitc::CmpPredicate::lt,
rhs, width);
607 Value poison = emitc::ConstantOp::create(
608 rewriter, op.getLoc(), arithmeticType,
609 (isa<IntegerType>(arithmeticType)
610 ? rewriter.getIntegerAttr(arithmeticType, 0)
611 : rewriter.getIndexAttr(0)));
613 emitc::ExpressionOp ternary =
614 emitc::ExpressionOp::create(rewriter, op.getLoc(), arithmeticType,
617 Block &bodyBlock = ternary.createBody();
618 auto currentPoint = rewriter.getInsertionPoint();
619 rewriter.setInsertionPointToStart(&bodyBlock);
620 Value arithmeticResult =
621 EmitCOp::create(rewriter, op.getLoc(), arithmeticType,
622 bodyBlock.getArgument(0), bodyBlock.getArgument(1));
623 Value resultOrPoison = emitc::ConditionalOp::create(
624 rewriter, op.getLoc(), arithmeticType, bodyBlock.getArgument(2),
625 arithmeticResult, bodyBlock.getArgument(3));
626 emitc::YieldOp::create(rewriter, op.getLoc(), resultOrPoison);
627 rewriter.setInsertionPoint(op->getBlock(), currentPoint);
629 Value
result = adaptValueType(ternary, rewriter, type);
631 rewriter.replaceOp(op,
result);
636template <
typename ArithOp,
typename EmitCOp>
637class SignedShiftOpConversion final
638 :
public ShiftOpConversion<ArithOp, EmitCOp, false> {
639 using ShiftOpConversion<ArithOp, EmitCOp,
false>::ShiftOpConversion;
642template <
typename ArithOp,
typename EmitCOp>
643class UnsignedShiftOpConversion final
644 :
public ShiftOpConversion<ArithOp, EmitCOp, true> {
645 using ShiftOpConversion<ArithOp, EmitCOp,
true>::ShiftOpConversion;
648class SelectOpConversion :
public OpConversionPattern<arith::SelectOp> {
653 matchAndRewrite(arith::SelectOp selectOp, OpAdaptor adaptor,
654 ConversionPatternRewriter &rewriter)
const override {
656 Type dstType = getTypeConverter()->convertType(selectOp.getType());
658 return rewriter.notifyMatchFailure(selectOp,
"type conversion failed");
660 if (!adaptor.getCondition().getType().isInteger(1))
661 return rewriter.notifyMatchFailure(
663 "can only be converted if condition is a scalar of type i1");
665 rewriter.replaceOpWithNewOp<emitc::ConditionalOp>(selectOp, dstType,
666 adaptor.getOperands());
673template <
typename CastOp>
674class FtoICastOpConversion :
public OpConversionPattern<CastOp> {
676 FtoICastOpConversion(
const TypeConverter &typeConverter, MLIRContext *context)
677 : OpConversionPattern<CastOp>(typeConverter, context) {}
680 matchAndRewrite(CastOp castOp,
typename CastOp::Adaptor adaptor,
681 ConversionPatternRewriter &rewriter)
const override {
683 Type operandType = adaptor.getIn().getType();
685 return rewriter.notifyMatchFailure(castOp,
686 "unsupported cast source type");
688 Type dstType = this->getTypeConverter()->convertType(castOp.getType());
690 return rewriter.notifyMatchFailure(castOp,
"type conversion failed");
695 return rewriter.notifyMatchFailure(castOp,
696 "unsupported cast destination type");
700 Type actualResultType = dstType;
701 if (isa<arith::FPToUIOp>(castOp)) {
707 Value
result = emitc::CastOp::create(
708 rewriter, castOp.getLoc(), actualResultType, adaptor.getOperands());
710 if (isa<arith::FPToUIOp>(castOp)) {
712 emitc::CastOp::create(rewriter, castOp.getLoc(), dstType,
result);
714 rewriter.replaceOp(castOp,
result);
721template <
typename CastOp>
722class ItoFCastOpConversion :
public OpConversionPattern<CastOp> {
724 ItoFCastOpConversion(
const TypeConverter &typeConverter, MLIRContext *context)
725 : OpConversionPattern<CastOp>(typeConverter, context) {}
728 matchAndRewrite(CastOp castOp,
typename CastOp::Adaptor adaptor,
729 ConversionPatternRewriter &rewriter)
const override {
731 Type operandType = adaptor.getIn().getType();
733 return rewriter.notifyMatchFailure(castOp,
734 "unsupported cast source type");
736 Type dstType = this->getTypeConverter()->convertType(castOp.getType());
738 return rewriter.notifyMatchFailure(castOp,
"type conversion failed");
741 return rewriter.notifyMatchFailure(castOp,
742 "unsupported cast destination type");
746 Type actualOperandType = operandType;
747 if (isa<arith::UIToFPOp>(castOp)) {
752 Value fpCastOperand = adaptor.getIn();
753 if (actualOperandType != operandType) {
754 fpCastOperand = emitc::CastOp::create(rewriter, castOp.getLoc(),
755 actualOperandType, fpCastOperand);
757 rewriter.replaceOpWithNewOp<emitc::CastOp>(castOp, dstType, fpCastOperand);
764template <
typename CastOp>
765class FpCastOpConversion :
public OpConversionPattern<CastOp> {
767 FpCastOpConversion(
const TypeConverter &typeConverter, MLIRContext *context)
768 : OpConversionPattern<CastOp>(typeConverter, context) {}
771 matchAndRewrite(CastOp castOp,
typename CastOp::Adaptor adaptor,
772 ConversionPatternRewriter &rewriter)
const override {
774 Type operandType = adaptor.getIn().getType();
776 return rewriter.notifyMatchFailure(castOp,
777 "unsupported cast source type");
778 if (
auto roundingModeOp =
779 dyn_cast<arith::ArithRoundingModeInterface>(*castOp)) {
781 if (roundingModeOp.getRoundingModeAttr())
782 return rewriter.notifyMatchFailure(castOp,
"unsupported rounding mode");
785 Type dstType = this->getTypeConverter()->convertType(castOp.getType());
787 return rewriter.notifyMatchFailure(castOp,
"type conversion failed");
790 return rewriter.notifyMatchFailure(castOp,
791 "unsupported cast destination type");
793 Value fpCastOperand = adaptor.getIn();
794 rewriter.replaceOpWithNewOp<emitc::CastOp>(castOp, dstType, fpCastOperand);
814 ArithConstantOpConversionPattern,
815 ArithOpConversion<arith::AddFOp, emitc::AddOp>,
816 ArithOpConversion<arith::DivFOp, emitc::DivOp>,
817 ArithOpConversion<arith::DivSIOp, emitc::DivOp>,
818 ArithOpConversion<arith::MulFOp, emitc::MulOp>,
819 ArithOpConversion<arith::RemSIOp, emitc::RemOp>,
820 ArithOpConversion<arith::SubFOp, emitc::SubOp>,
821 BinaryUIOpConversion<arith::DivUIOp, emitc::DivOp>,
822 BinaryUIOpConversion<arith::RemUIOp, emitc::RemOp>,
823 IntegerOpConversion<arith::AddIOp, emitc::AddOp>,
824 IntegerOpConversion<arith::MulIOp, emitc::MulOp>,
825 IntegerOpConversion<arith::SubIOp, emitc::SubOp>,
826 BitwiseOpConversion<arith::AndIOp, emitc::BitwiseAndOp>,
827 BitwiseOpConversion<arith::OrIOp, emitc::BitwiseOrOp>,
828 BitwiseOpConversion<arith::XOrIOp, emitc::BitwiseXorOp>,
829 UnsignedShiftOpConversion<arith::ShLIOp, emitc::BitwiseLeftShiftOp>,
830 SignedShiftOpConversion<arith::ShRSIOp, emitc::BitwiseRightShiftOp>,
831 UnsignedShiftOpConversion<arith::ShRUIOp, emitc::BitwiseRightShiftOp>,
837 UnsignedCastConversion<arith::TruncIOp>,
838 SignedCastConversion<arith::ExtSIOp>,
839 UnsignedCastConversion<arith::ExtUIOp>,
840 SignedCastConversion<arith::IndexCastOp>,
841 UnsignedCastConversion<arith::IndexCastUIOp>,
842 ItoFCastOpConversion<arith::SIToFPOp>,
843 ItoFCastOpConversion<arith::UIToFPOp>,
844 FtoICastOpConversion<arith::FPToSIOp>,
845 FtoICastOpConversion<arith::FPToUIOp>,
846 FpCastOpConversion<arith::ExtFOp>,
847 FpCastOpConversion<arith::TruncFOp>
848 >(typeConverter, ctx);
ConvertToEmitCPatternInterface(Dialect *dialect)
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.
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)
const FrozenRewritePatternSet & patterns
void populateArithToEmitCPatterns(TypeConverter &typeConverter, RewritePatternSet &patterns)