28struct ArithToEmitCDialectInterface :
public ConvertToEmitCPatternInterface {
29 ArithToEmitCDialectInterface(Dialect *dialect)
30 : ConvertToEmitCPatternInterface(dialect) {}
34 void populateConvertToEmitCConversionPatterns(
35 ConversionTarget &
target, TypeConverter &typeConverter,
36 RewritePatternSet &patterns)
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 Type newTy = this->getTypeConverter()->convertType(arithConst.getType());
64 return rewriter.notifyMatchFailure(arithConst,
"type conversion failed");
65 rewriter.replaceOpWithNewOp<emitc::ConstantOp>(arithConst, newTy,
72Type adaptIntegralTypeSignedness(
Type ty,
bool needsUnsigned) {
73 if (isa<IntegerType>(ty)) {
75 auto signedness = needsUnsigned
76 ? IntegerType::SignednessSemantics::Unsigned
77 : IntegerType::SignednessSemantics::Signed;
82 if (isa<emitc::SizeTType>(ty) != needsUnsigned) {
85 return emitc::PtrDiffTType::get(ty.
getContext());
92Value adaptValueType(
Value val, ConversionPatternRewriter &rewriter,
Type ty) {
93 return rewriter.createOrFold<emitc::CastOp>(val.
getLoc(), ty, val);
96class CmpFOpConversion :
public OpConversionPattern<arith::CmpFOp> {
101 matchAndRewrite(arith::CmpFOp op, OpAdaptor adaptor,
102 ConversionPatternRewriter &rewriter)
const override {
104 if (!isa<FloatType>(adaptor.getRhs().getType())) {
105 return rewriter.notifyMatchFailure(op.getLoc(),
106 "cmpf currently only supported on "
107 "floats, not tensors/vectors thereof");
110 bool unordered =
false;
111 emitc::CmpPredicate predicate;
112 switch (op.getPredicate()) {
113 case arith::CmpFPredicate::AlwaysFalse: {
115 emitc::ConstantOp::create(rewriter, op.getLoc(), rewriter.getI1Type(),
116 rewriter.getBoolAttr(
false));
117 rewriter.replaceOp(op, constant);
120 case arith::CmpFPredicate::OEQ:
122 predicate = emitc::CmpPredicate::eq;
124 case arith::CmpFPredicate::OGT:
126 predicate = emitc::CmpPredicate::gt;
128 case arith::CmpFPredicate::OGE:
130 predicate = emitc::CmpPredicate::ge;
132 case arith::CmpFPredicate::OLT:
134 predicate = emitc::CmpPredicate::lt;
136 case arith::CmpFPredicate::OLE:
138 predicate = emitc::CmpPredicate::le;
140 case arith::CmpFPredicate::ONE:
142 predicate = emitc::CmpPredicate::ne;
144 case arith::CmpFPredicate::ORD: {
146 auto cmp = createCheckIsOrdered(rewriter, op.getLoc(), adaptor.getLhs(),
148 rewriter.replaceOp(op, cmp);
151 case arith::CmpFPredicate::UEQ:
153 predicate = emitc::CmpPredicate::eq;
155 case arith::CmpFPredicate::UGT:
157 predicate = emitc::CmpPredicate::gt;
159 case arith::CmpFPredicate::UGE:
161 predicate = emitc::CmpPredicate::ge;
163 case arith::CmpFPredicate::ULT:
165 predicate = emitc::CmpPredicate::lt;
167 case arith::CmpFPredicate::ULE:
169 predicate = emitc::CmpPredicate::le;
171 case arith::CmpFPredicate::UNE:
173 predicate = emitc::CmpPredicate::ne;
175 case arith::CmpFPredicate::UNO: {
177 auto cmp = createCheckIsUnordered(rewriter, op.getLoc(), adaptor.getLhs(),
179 rewriter.replaceOp(op, cmp);
182 case arith::CmpFPredicate::AlwaysTrue: {
184 emitc::ConstantOp::create(rewriter, op.getLoc(), rewriter.getI1Type(),
185 rewriter.getBoolAttr(
true));
186 rewriter.replaceOp(op, constant);
193 emitc::CmpOp::create(rewriter, op.getLoc(), op.getType(), predicate,
194 adaptor.getLhs(), adaptor.getRhs());
198 auto isUnordered = createCheckIsUnordered(
199 rewriter, op.getLoc(), adaptor.getLhs(), adaptor.getRhs());
200 rewriter.replaceOpWithNewOp<emitc::LogicalOrOp>(op, op.getType(),
201 isUnordered, cmpResult);
205 auto isOrdered = createCheckIsOrdered(rewriter, op.getLoc(),
206 adaptor.getLhs(), adaptor.getRhs());
207 rewriter.replaceOpWithNewOp<emitc::LogicalAndOp>(op, op.getType(),
208 isOrdered, cmpResult);
214 Value isNaN(ConversionPatternRewriter &rewriter, Location loc,
215 Value operand)
const {
217 return emitc::CmpOp::create(rewriter, loc, rewriter.getI1Type(),
218 emitc::CmpPredicate::ne, operand, operand);
222 Value isNotNaN(ConversionPatternRewriter &rewriter, Location loc,
223 Value operand)
const {
225 return emitc::CmpOp::create(rewriter, loc, rewriter.getI1Type(),
226 emitc::CmpPredicate::eq, operand, operand);
231 Value createCheckIsUnordered(ConversionPatternRewriter &rewriter,
232 Location loc, Value first, Value second)
const {
233 auto firstIsNaN = isNaN(rewriter, loc, first);
234 auto secondIsNaN = isNaN(rewriter, loc, second);
235 return emitc::LogicalOrOp::create(rewriter, loc, rewriter.getI1Type(),
236 firstIsNaN, secondIsNaN);
241 Value createCheckIsOrdered(ConversionPatternRewriter &rewriter, Location loc,
242 Value first, Value second)
const {
243 auto firstIsNotNaN = isNotNaN(rewriter, loc, first);
244 auto secondIsNotNaN = isNotNaN(rewriter, loc, second);
245 return emitc::LogicalAndOp::create(rewriter, loc, rewriter.getI1Type(),
246 firstIsNotNaN, secondIsNotNaN);
250class CmpIOpConversion :
public OpConversionPattern<arith::CmpIOp> {
254 bool needsUnsignedCmp(arith::CmpIPredicate pred)
const {
256 case arith::CmpIPredicate::eq:
257 case arith::CmpIPredicate::ne:
258 case arith::CmpIPredicate::slt:
259 case arith::CmpIPredicate::sle:
260 case arith::CmpIPredicate::sgt:
261 case arith::CmpIPredicate::sge:
263 case arith::CmpIPredicate::ult:
264 case arith::CmpIPredicate::ule:
265 case arith::CmpIPredicate::ugt:
266 case arith::CmpIPredicate::uge:
269 llvm_unreachable(
"unknown cmpi predicate kind");
272 emitc::CmpPredicate toEmitCPred(arith::CmpIPredicate pred)
const {
274 case arith::CmpIPredicate::eq:
275 return emitc::CmpPredicate::eq;
276 case arith::CmpIPredicate::ne:
277 return emitc::CmpPredicate::ne;
278 case arith::CmpIPredicate::slt:
279 case arith::CmpIPredicate::ult:
280 return emitc::CmpPredicate::lt;
281 case arith::CmpIPredicate::sle:
282 case arith::CmpIPredicate::ule:
283 return emitc::CmpPredicate::le;
284 case arith::CmpIPredicate::sgt:
285 case arith::CmpIPredicate::ugt:
286 return emitc::CmpPredicate::gt;
287 case arith::CmpIPredicate::sge:
288 case arith::CmpIPredicate::uge:
289 return emitc::CmpPredicate::ge;
291 llvm_unreachable(
"unknown cmpi predicate kind");
295 matchAndRewrite(arith::CmpIOp op, OpAdaptor adaptor,
296 ConversionPatternRewriter &rewriter)
const override {
298 Type type = adaptor.getLhs().getType();
300 return rewriter.notifyMatchFailure(
301 op,
"expected integer or size_t/ssize_t/ptrdiff_t type");
304 bool needsUnsigned = needsUnsignedCmp(op.getPredicate());
305 emitc::CmpPredicate pred = toEmitCPred(op.getPredicate());
307 Type arithmeticType = adaptIntegralTypeSignedness(type, needsUnsigned);
308 Value
lhs = adaptValueType(adaptor.getLhs(), rewriter, arithmeticType);
309 Value
rhs = adaptValueType(adaptor.getRhs(), rewriter, arithmeticType);
311 rewriter.replaceOpWithNewOp<emitc::CmpOp>(op, op.getType(), pred,
lhs,
rhs);
316class NegFOpConversion :
public OpConversionPattern<arith::NegFOp> {
321 matchAndRewrite(arith::NegFOp op, OpAdaptor adaptor,
322 ConversionPatternRewriter &rewriter)
const override {
324 auto adaptedOp = adaptor.getOperand();
325 auto adaptedOpType = adaptedOp.getType();
327 if (isa<TensorType>(adaptedOpType) || isa<VectorType>(adaptedOpType)) {
328 return rewriter.notifyMatchFailure(
330 "negf currently only supports scalar types, not vectors or tensors");
334 return rewriter.notifyMatchFailure(
335 op.getLoc(),
"floating-point type is not supported by EmitC");
338 rewriter.replaceOpWithNewOp<emitc::UnaryMinusOp>(op, adaptedOpType,
344template <
typename ArithOp,
bool castToUn
signed>
345class CastConversion :
public OpConversionPattern<ArithOp> {
347 using OpConversionPattern<ArithOp>::OpConversionPattern;
350 matchAndRewrite(ArithOp op,
typename ArithOp::Adaptor adaptor,
351 ConversionPatternRewriter &rewriter)
const override {
353 Type opReturnType = this->getTypeConverter()->convertType(op.getType());
354 if (!opReturnType || !(isa<IntegerType>(opReturnType) ||
356 return rewriter.notifyMatchFailure(
357 op,
"expected integer or size_t/ssize_t/ptrdiff_t result type");
359 if (adaptor.getOperands().size() != 1) {
360 return rewriter.notifyMatchFailure(
361 op,
"CastConversion only supports unary ops");
364 Type operandType = adaptor.getIn().getType();
365 if (!operandType || !(isa<IntegerType>(operandType) ||
367 return rewriter.notifyMatchFailure(
368 op,
"expected integer or size_t/ssize_t/ptrdiff_t operand type");
371 if (operandType.
isInteger(1) && !castToUnsigned)
372 return rewriter.notifyMatchFailure(op,
373 "operation not supported on i1 type");
380 ? rewriter.getIndexType()
382 auto constOne = emitc::ConstantOp::create(
383 rewriter, op.getLoc(), operandType, rewriter.getOneAttr(attrType));
384 auto oneAndOperand = emitc::BitwiseAndOp::create(
385 rewriter, op.getLoc(), operandType, adaptor.getIn(), constOne);
386 rewriter.replaceOpWithNewOp<emitc::CastOp>(op, opReturnType,
392 (isa<IntegerType>(operandType) && isa<IntegerType>(opReturnType) &&
395 bool doUnsigned = castToUnsigned || isTruncation;
399 Type castDestType = adaptIntegralTypeSignedness(opReturnType, doUnsigned);
402 Type castSrcType = adaptIntegralTypeSignedness(operandType, doUnsigned);
403 Value actualOp = adaptValueType(adaptor.getIn(), rewriter, castSrcType);
407 emitc::CastOp::create(rewriter, op.getLoc(), castDestType, actualOp);
410 auto result = adaptValueType(cast, rewriter, opReturnType);
412 rewriter.replaceOp(op,
result);
417template <
typename ArithOp>
418class UnsignedCastConversion :
public CastConversion<ArithOp, true> {
419 using CastConversion<ArithOp,
true>::CastConversion;
422template <
typename ArithOp>
423class SignedCastConversion :
public CastConversion<ArithOp, false> {
424 using CastConversion<ArithOp,
false>::CastConversion;
427template <
typename ArithOp,
typename EmitCOp>
428class ArithOpConversion final :
public OpConversionPattern<ArithOp> {
430 using OpConversionPattern<ArithOp>::OpConversionPattern;
433 matchAndRewrite(ArithOp arithOp,
typename ArithOp::Adaptor adaptor,
434 ConversionPatternRewriter &rewriter)
const override {
436 Type newTy = this->getTypeConverter()->convertType(arithOp.getType());
438 return rewriter.notifyMatchFailure(arithOp,
439 "converting result type failed");
440 rewriter.template replaceOpWithNewOp<EmitCOp>(arithOp, newTy,
441 adaptor.getOperands());
447template <
class ArithOp,
class EmitCOp>
448class BinaryUIOpConversion final :
public OpConversionPattern<ArithOp> {
450 using OpConversionPattern<ArithOp>::OpConversionPattern;
453 matchAndRewrite(ArithOp uiBinOp,
typename ArithOp::Adaptor adaptor,
454 ConversionPatternRewriter &rewriter)
const override {
455 Type newRetTy = this->getTypeConverter()->convertType(uiBinOp.getType());
457 return rewriter.notifyMatchFailure(uiBinOp,
458 "converting result type failed");
459 if (!isa<IntegerType>(newRetTy)) {
460 return rewriter.notifyMatchFailure(uiBinOp,
"expected integer type");
463 adaptIntegralTypeSignedness(newRetTy,
true);
465 return rewriter.notifyMatchFailure(uiBinOp,
466 "converting result type failed");
467 Value lhsAdapted = adaptValueType(uiBinOp.getLhs(), rewriter, unsignedType);
468 Value rhsAdapted = adaptValueType(uiBinOp.getRhs(), rewriter, unsignedType);
470 auto newDivOp = EmitCOp::create(rewriter, uiBinOp.getLoc(), unsignedType,
471 ArrayRef<Value>{lhsAdapted, rhsAdapted});
472 Value resultAdapted = adaptValueType(newDivOp, rewriter, newRetTy);
473 rewriter.replaceOp(uiBinOp, resultAdapted);
478template <
typename ArithOp,
typename EmitCOp>
479class IntegerOpConversion final :
public OpConversionPattern<ArithOp> {
481 using OpConversionPattern<ArithOp>::OpConversionPattern;
484 matchAndRewrite(ArithOp op,
typename ArithOp::Adaptor adaptor,
485 ConversionPatternRewriter &rewriter)
const override {
487 Type type = this->getTypeConverter()->convertType(op.getType());
489 return rewriter.notifyMatchFailure(
490 op,
"expected integer or size_t/ssize_t/ptrdiff_t type");
495 return rewriter.notifyMatchFailure(op,
"i1 type is not implemented");
498 Type arithmeticType = type;
500 !bitEnumContainsAll(op.getOverflowFlags(),
501 arith::IntegerOverflowFlags::nsw)) {
508 Value
lhs = adaptValueType(adaptor.getLhs(), rewriter, arithmeticType);
509 Value
rhs = adaptValueType(adaptor.getRhs(), rewriter, arithmeticType);
511 Value arithmeticResult =
512 EmitCOp::create(rewriter, op.getLoc(), arithmeticType,
lhs,
rhs);
514 Value
result = adaptValueType(arithmeticResult, rewriter, type);
516 rewriter.replaceOp(op,
result);
521template <
typename ArithOp,
typename EmitCOp>
522class BitwiseOpConversion :
public OpConversionPattern<ArithOp> {
524 using OpConversionPattern<ArithOp>::OpConversionPattern;
527 matchAndRewrite(ArithOp op,
typename ArithOp::Adaptor adaptor,
528 ConversionPatternRewriter &rewriter)
const override {
530 Type type = this->getTypeConverter()->convertType(op.getType());
531 if (!isa_and_nonnull<IntegerType>(type)) {
532 return rewriter.notifyMatchFailure(
534 "expected integer type, vector/tensor support not yet implemented");
539 rewriter.replaceOpWithNewOp<EmitCOp>(op, type, adaptor.getLhs(),
545 Type arithmeticType =
546 adaptIntegralTypeSignedness(type,
true);
548 Value
lhs = adaptValueType(adaptor.getLhs(), rewriter, arithmeticType);
549 Value
rhs = adaptValueType(adaptor.getRhs(), rewriter, arithmeticType);
551 Value arithmeticResult =
552 EmitCOp::create(rewriter, op.getLoc(), arithmeticType,
lhs,
rhs);
554 Value
result = adaptValueType(arithmeticResult, rewriter, type);
556 rewriter.replaceOp(op,
result);
561template <
typename ArithOp,
typename EmitCOp,
bool isUn
signedOp>
562class ShiftOpConversion :
public OpConversionPattern<ArithOp> {
564 using OpConversionPattern<ArithOp>::OpConversionPattern;
567 matchAndRewrite(ArithOp op,
typename ArithOp::Adaptor adaptor,
568 ConversionPatternRewriter &rewriter)
const override {
570 Type type = this->getTypeConverter()->convertType(op.getType());
572 return rewriter.notifyMatchFailure(
573 op,
"expected integer or size_t/ssize_t/ptrdiff_t type");
577 return rewriter.notifyMatchFailure(op,
"i1 type is not implemented");
580 Type arithmeticType = adaptIntegralTypeSignedness(type, isUnsignedOp);
582 Value
lhs = adaptValueType(adaptor.getLhs(), rewriter, arithmeticType);
584 Type rhsType = adaptIntegralTypeSignedness(adaptor.getRhs().getType(),
586 Value
rhs = adaptValueType(adaptor.getRhs(), rewriter, rhsType);
591 Value eight = emitc::ConstantOp::create(rewriter, op.getLoc(), rhsType,
592 rewriter.getIndexAttr(8));
593 emitc::CallOpaqueOp sizeOfCall = emitc::CallOpaqueOp::create(
594 rewriter, op.getLoc(), rhsType,
"sizeof", ArrayRef<Value>{eight});
595 width = emitc::MulOp::create(rewriter, op.getLoc(), rhsType, eight,
596 sizeOfCall.getResult(0));
598 width = emitc::ConstantOp::create(
599 rewriter, op.getLoc(), rhsType,
604 emitc::CmpOp::create(rewriter, op.getLoc(), rewriter.getI1Type(),
605 emitc::CmpPredicate::lt,
rhs, width);
608 Value poison = emitc::ConstantOp::create(
609 rewriter, op.getLoc(), arithmeticType,
610 (isa<IntegerType>(arithmeticType)
611 ? rewriter.getIntegerAttr(arithmeticType, 0)
612 : rewriter.getIndexAttr(0)));
614 emitc::ExpressionOp ternary =
615 emitc::ExpressionOp::create(rewriter, op.getLoc(), arithmeticType,
618 Block &bodyBlock = ternary.createBody();
619 auto currentPoint = rewriter.getInsertionPoint();
620 rewriter.setInsertionPointToStart(&bodyBlock);
621 Value arithmeticResult =
622 EmitCOp::create(rewriter, op.getLoc(), arithmeticType,
623 bodyBlock.getArgument(0), bodyBlock.getArgument(1));
624 Value resultOrPoison = emitc::ConditionalOp::create(
625 rewriter, op.getLoc(), arithmeticType, bodyBlock.getArgument(2),
626 arithmeticResult, bodyBlock.getArgument(3));
627 emitc::YieldOp::create(rewriter, op.getLoc(), resultOrPoison);
628 rewriter.setInsertionPoint(op->getBlock(), currentPoint);
630 Value
result = adaptValueType(ternary, rewriter, type);
632 rewriter.replaceOp(op,
result);
637template <
typename ArithOp,
typename EmitCOp>
638class SignedShiftOpConversion final
639 :
public ShiftOpConversion<ArithOp, EmitCOp, false> {
640 using ShiftOpConversion<ArithOp, EmitCOp,
false>::ShiftOpConversion;
643template <
typename ArithOp,
typename EmitCOp>
644class UnsignedShiftOpConversion final
645 :
public ShiftOpConversion<ArithOp, EmitCOp, true> {
646 using ShiftOpConversion<ArithOp, EmitCOp,
true>::ShiftOpConversion;
649class SelectOpConversion :
public OpConversionPattern<arith::SelectOp> {
654 matchAndRewrite(arith::SelectOp selectOp, OpAdaptor adaptor,
655 ConversionPatternRewriter &rewriter)
const override {
657 Type dstType = getTypeConverter()->convertType(selectOp.getType());
659 return rewriter.notifyMatchFailure(selectOp,
"type conversion failed");
661 if (!adaptor.getCondition().getType().isInteger(1))
662 return rewriter.notifyMatchFailure(
664 "can only be converted if condition is a scalar of type i1");
666 rewriter.replaceOpWithNewOp<emitc::ConditionalOp>(selectOp, dstType,
667 adaptor.getOperands());
674template <
typename CastOp>
675class FtoICastOpConversion :
public OpConversionPattern<CastOp> {
677 FtoICastOpConversion(
const TypeConverter &typeConverter, MLIRContext *context)
678 : OpConversionPattern<CastOp>(typeConverter, context) {}
681 matchAndRewrite(CastOp castOp,
typename CastOp::Adaptor adaptor,
682 ConversionPatternRewriter &rewriter)
const override {
684 Type operandType = adaptor.getIn().getType();
686 return rewriter.notifyMatchFailure(castOp,
687 "unsupported cast source type");
689 Type dstType = this->getTypeConverter()->convertType(castOp.getType());
691 return rewriter.notifyMatchFailure(castOp,
"type conversion failed");
696 return rewriter.notifyMatchFailure(castOp,
697 "unsupported cast destination type");
701 Type actualResultType = dstType;
702 if (isa<arith::FPToUIOp>(castOp)) {
708 Value
result = emitc::CastOp::create(
709 rewriter, castOp.getLoc(), actualResultType, adaptor.getOperands());
711 if (isa<arith::FPToUIOp>(castOp)) {
713 emitc::CastOp::create(rewriter, castOp.getLoc(), dstType,
result);
715 rewriter.replaceOp(castOp,
result);
722template <
typename CastOp>
723class ItoFCastOpConversion :
public OpConversionPattern<CastOp> {
725 ItoFCastOpConversion(
const TypeConverter &typeConverter, MLIRContext *context)
726 : OpConversionPattern<CastOp>(typeConverter, context) {}
729 matchAndRewrite(CastOp castOp,
typename CastOp::Adaptor adaptor,
730 ConversionPatternRewriter &rewriter)
const override {
732 Type operandType = adaptor.getIn().getType();
734 return rewriter.notifyMatchFailure(castOp,
735 "unsupported cast source type");
737 Type dstType = this->getTypeConverter()->convertType(castOp.getType());
739 return rewriter.notifyMatchFailure(castOp,
"type conversion failed");
742 return rewriter.notifyMatchFailure(castOp,
743 "unsupported cast destination type");
747 Type actualOperandType = operandType;
748 if (isa<arith::UIToFPOp>(castOp)) {
753 Value fpCastOperand = adaptor.getIn();
754 if (actualOperandType != operandType) {
755 fpCastOperand = emitc::CastOp::create(rewriter, castOp.getLoc(),
756 actualOperandType, fpCastOperand);
758 rewriter.replaceOpWithNewOp<emitc::CastOp>(castOp, dstType, fpCastOperand);
765template <
typename CastOp>
766class FpCastOpConversion :
public OpConversionPattern<CastOp> {
768 FpCastOpConversion(
const TypeConverter &typeConverter, MLIRContext *context)
769 : OpConversionPattern<CastOp>(typeConverter, context) {}
772 matchAndRewrite(CastOp castOp,
typename CastOp::Adaptor adaptor,
773 ConversionPatternRewriter &rewriter)
const override {
775 Type operandType = adaptor.getIn().getType();
777 return rewriter.notifyMatchFailure(castOp,
778 "unsupported cast source type");
779 if (
auto roundingModeOp =
780 dyn_cast<arith::ArithRoundingModeInterface>(*castOp)) {
782 if (roundingModeOp.getRoundingModeAttr())
783 return rewriter.notifyMatchFailure(castOp,
"unsupported rounding mode");
786 Type dstType = this->getTypeConverter()->convertType(castOp.getType());
788 return rewriter.notifyMatchFailure(castOp,
"type conversion failed");
791 return rewriter.notifyMatchFailure(castOp,
792 "unsupported cast destination type");
794 Value fpCastOperand = adaptor.getIn();
795 rewriter.replaceOpWithNewOp<emitc::CastOp>(castOp, dstType, fpCastOperand);
815 ArithConstantOpConversionPattern,
816 ArithOpConversion<arith::AddFOp, emitc::AddOp>,
817 ArithOpConversion<arith::DivFOp, emitc::DivOp>,
818 ArithOpConversion<arith::DivSIOp, emitc::DivOp>,
819 ArithOpConversion<arith::MulFOp, emitc::MulOp>,
820 ArithOpConversion<arith::RemSIOp, emitc::RemOp>,
821 ArithOpConversion<arith::SubFOp, emitc::SubOp>,
822 BinaryUIOpConversion<arith::DivUIOp, emitc::DivOp>,
823 BinaryUIOpConversion<arith::RemUIOp, emitc::RemOp>,
824 IntegerOpConversion<arith::AddIOp, emitc::AddOp>,
825 IntegerOpConversion<arith::MulIOp, emitc::MulOp>,
826 IntegerOpConversion<arith::SubIOp, emitc::SubOp>,
827 BitwiseOpConversion<arith::AndIOp, emitc::BitwiseAndOp>,
828 BitwiseOpConversion<arith::OrIOp, emitc::BitwiseOrOp>,
829 BitwiseOpConversion<arith::XOrIOp, emitc::BitwiseXorOp>,
830 UnsignedShiftOpConversion<arith::ShLIOp, emitc::BitwiseLeftShiftOp>,
831 SignedShiftOpConversion<arith::ShRSIOp, emitc::BitwiseRightShiftOp>,
832 UnsignedShiftOpConversion<arith::ShRUIOp, emitc::BitwiseRightShiftOp>,
838 UnsignedCastConversion<arith::TruncIOp>,
839 SignedCastConversion<arith::ExtSIOp>,
840 UnsignedCastConversion<arith::ExtUIOp>,
841 SignedCastConversion<arith::IndexCastOp>,
842 UnsignedCastConversion<arith::IndexCastUIOp>,
843 ItoFCastOpConversion<arith::SIToFPOp>,
844 ItoFCastOpConversion<arith::UIToFPOp>,
845 FtoICastOpConversion<arith::FPToSIOp>,
846 FtoICastOpConversion<arith::FPToUIOp>,
847 FpCastOpConversion<arith::ExtFOp>,
848 FpCastOpConversion<arith::TruncFOp>
849 >(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)