21class ComplexExprEmitter :
public StmtVisitor<ComplexExprEmitter, mlir::Value> {
23 CIRGenBuilderTy &builder;
26 explicit ComplexExprEmitter(CIRGenFunction &cgf)
27 : cgf(cgf), builder(cgf.getBuilder()) {}
36 mlir::Value emitLoadOfLValue(
const Expr *e) {
37 return emitLoadOfLValue(cgf.emitLValue(e), e->
getExprLoc());
40 mlir::Value emitLoadOfLValue(LValue lv, SourceLocation loc);
44 void emitStoreOfComplex(mlir::Location loc, mlir::Value val, LValue lv,
48 mlir::Value emitComplexToComplexCast(mlir::Value value, QualType srcType,
49 QualType destType, SourceLocation loc);
52 mlir::Value emitScalarToComplexCast(mlir::Value value, QualType srcType,
53 QualType destType, SourceLocation loc);
59 mlir::Value Visit(Expr *e) {
60 return StmtVisitor<ComplexExprEmitter, mlir::Value>::Visit(e);
63 mlir::Value VisitStmt(Stmt *s) {
64 s->
dump(llvm::errs(), cgf.getContext());
65 llvm_unreachable(
"Stmt can't have complex result type!");
68 mlir::Value VisitExpr(Expr *e);
69 mlir::Value VisitConstantExpr(ConstantExpr *e) {
70 if (mlir::Attribute result = ConstantEmitter(cgf).tryEmitConstantExpr(e))
72 mlir::cast<mlir::TypedAttr>(result));
75 "ComplexExprEmitter VisitConstantExpr non constantexpr");
79 mlir::Value VisitParenExpr(ParenExpr *pe) {
return Visit(pe->
getSubExpr()); }
80 mlir::Value VisitGenericSelectionExpr(GenericSelectionExpr *ge) {
83 mlir::Value VisitImaginaryLiteral(
const ImaginaryLiteral *il);
85 VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *pe) {
88 mlir::Value VisitCoawaitExpr(CoawaitExpr *s) {
89 return cgf.emitCoawaitExpr(*s).getComplexValue();
91 mlir::Value VisitCoyieldExpr(CoyieldExpr *s) {
92 cgf.cgm.errorNYI(s->
getExprLoc(),
"ComplexExprEmitter VisitCoyieldExpr");
95 mlir::Value VisitUnaryCoawait(
const UnaryOperator *e) {
96 cgf.cgm.errorNYI(e->
getExprLoc(),
"ComplexExprEmitter VisitUnaryCoawait");
100 mlir::Value emitConstant(
const CIRGenFunction::ConstantEmission &constant,
102 assert(constant &&
"not a constant");
107 mlir::TypedAttr valueAttr = constant.
getValue();
108 return builder.getConstant(cgf.getLoc(e->
getSourceRange()), valueAttr);
112 mlir::Value VisitDeclRefExpr(DeclRefExpr *e) {
113 if (CIRGenFunction::ConstantEmission constant = cgf.tryEmitAsConstant(e))
114 return emitConstant(constant, e);
115 return emitLoadOfLValue(e);
117 mlir::Value VisitObjCIvarRefExpr(ObjCIvarRefExpr *e) {
119 "ComplexExprEmitter VisitObjCIvarRefExpr");
122 mlir::Value VisitObjCMessageExpr(ObjCMessageExpr *e) {
124 "ComplexExprEmitter VisitObjCMessageExpr");
127 mlir::Value VisitArraySubscriptExpr(Expr *e) {
return emitLoadOfLValue(e); }
128 mlir::Value VisitMemberExpr(MemberExpr *me) {
129 if (CIRGenFunction::ConstantEmission constant = cgf.tryEmitAsConstant(me)) {
130 cgf.emitIgnoredExpr(me->
getBase());
131 return emitConstant(constant, me);
133 return emitLoadOfLValue(me);
135 mlir::Value VisitOpaqueValueExpr(OpaqueValueExpr *e) {
137 return emitLoadOfLValue(cgf.getOrCreateOpaqueLValueMapping(e),
139 return cgf.getOrCreateOpaqueRValueMapping(e).getComplexValue();
142 mlir::Value VisitPseudoObjectExpr(PseudoObjectExpr *e) {
144 "ComplexExprEmitter VisitPseudoObjectExpr");
148 mlir::Value emitCast(
CastKind ck, Expr *op, QualType destTy);
149 mlir::Value VisitImplicitCastExpr(ImplicitCastExpr *e) {
153 return emitLoadOfLValue(e);
156 mlir::Value VisitCastExpr(
CastExpr *e) {
157 if (
const auto *ece = dyn_cast<ExplicitCastExpr>(e))
158 cgf.cgm.emitExplicitCastExprType(ece);
160 return emitLoadOfLValue(e);
163 mlir::Value VisitCallExpr(
const CallExpr *e);
164 mlir::Value VisitStmtExpr(
const StmtExpr *e);
167 mlir::Value VisitPrePostIncDec(
const UnaryOperator *e) {
169 return cgf.emitComplexPrePostIncDec(e, lv);
171 mlir::Value VisitUnaryPostDec(
const UnaryOperator *e) {
172 return VisitPrePostIncDec(e);
174 mlir::Value VisitUnaryPostInc(
const UnaryOperator *e) {
175 return VisitPrePostIncDec(e);
177 mlir::Value VisitUnaryPreDec(
const UnaryOperator *e) {
178 return VisitPrePostIncDec(e);
180 mlir::Value VisitUnaryPreInc(
const UnaryOperator *e) {
181 return VisitPrePostIncDec(e);
183 mlir::Value VisitUnaryDeref(
const Expr *e) {
return emitLoadOfLValue(e); }
185 mlir::Value VisitUnaryPlus(
const UnaryOperator *e);
186 mlir::Value VisitUnaryPlus(
const UnaryOperator *e, QualType promotionType);
187 mlir::Value VisitUnaryMinus(
const UnaryOperator *e);
188 mlir::Value VisitUnaryMinus(
const UnaryOperator *e, QualType promotionType);
189 mlir::Value VisitUnaryNot(
const UnaryOperator *e);
191 mlir::Value VisitUnaryExtension(
const UnaryOperator *e) {
194 mlir::Value VisitCXXDefaultArgExpr(CXXDefaultArgExpr *dae) {
195 CIRGenFunction::CXXDefaultArgExprScope scope(cgf, dae);
198 mlir::Value VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die) {
199 CIRGenFunction::CXXDefaultInitExprScope scope(cgf, die);
202 mlir::Value VisitExprWithCleanups(ExprWithCleanups *e) {
203 CIRGenFunction::FullExprCleanupScope scope(cgf, e->
getSubExpr());
204 mlir::Value complexVal = Visit(e->
getSubExpr());
207 scope.exit({&complexVal});
210 mlir::Value VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e) {
211 mlir::Location loc = cgf.getLoc(e->
getExprLoc());
212 mlir::Type complexTy = cgf.convertType(e->
getType());
213 return builder.getNullValue(complexTy, loc);
215 mlir::Value VisitImplicitValueInitExpr(ImplicitValueInitExpr *e) {
216 mlir::Location loc = cgf.getLoc(e->
getExprLoc());
217 mlir::Type complexTy = cgf.convertType(e->
getType());
218 return builder.getNullValue(complexTy, loc);
226 FPOptions fpFeatures{};
229 BinOpInfo emitBinOps(
const BinaryOperator *e,
230 QualType promotionTy = QualType());
232 mlir::Value emitPromoted(
const Expr *e, QualType promotionTy);
233 mlir::Value emitPromotedComplexOperand(
const Expr *e, QualType promotionTy);
234 LValue emitCompoundAssignLValue(
235 const CompoundAssignOperator *e,
236 mlir::Value (ComplexExprEmitter::*func)(
const BinOpInfo &),
238 mlir::Value emitCompoundAssign(
239 const CompoundAssignOperator *e,
240 mlir::Value (ComplexExprEmitter::*func)(
const BinOpInfo &));
242 mlir::Value emitBinAdd(
const BinOpInfo &op);
243 mlir::Value emitBinSub(
const BinOpInfo &op);
244 mlir::Value emitBinMul(
const BinOpInfo &op);
245 mlir::Value emitBinDiv(
const BinOpInfo &op);
247 QualType getPromotionType(QualType ty,
bool isDivOpCode =
false) {
248 if (
auto *complexTy = ty->
getAs<ComplexType>()) {
249 QualType elementTy = complexTy->getElementType();
251 return cgf.getContext().getComplexType(cgf.getContext().FloatTy);
255 return cgf.getContext().FloatTy;
259#define HANDLEBINOP(OP) \
260 mlir::Value VisitBin##OP(const BinaryOperator *e) { \
261 QualType promotionTy = getPromotionType( \
262 e->getType(), e->getOpcode() == BinaryOperatorKind::BO_Div); \
263 mlir::Value result = emitBin##OP(emitBinOps(e, promotionTy)); \
264 if (!promotionTy.isNull()) \
265 result = cgf.emitUnPromotedValue(result, e->getType()); \
280 mlir::Value VisitBinAddAssign(
const CompoundAssignOperator *e) {
281 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinAdd);
283 mlir::Value VisitBinSubAssign(
const CompoundAssignOperator *e) {
284 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinSub);
286 mlir::Value VisitBinMulAssign(
const CompoundAssignOperator *e) {
287 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinMul);
289 mlir::Value VisitBinDivAssign(
const CompoundAssignOperator *e) {
290 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinDiv);
298 LValue emitBinAssignLValue(
const BinaryOperator *e, mlir::Value &val);
299 mlir::Value VisitBinAssign(
const BinaryOperator *e);
300 mlir::Value VisitBinComma(
const BinaryOperator *e);
303 VisitAbstractConditionalOperator(
const AbstractConditionalOperator *e);
304 mlir::Value VisitChooseExpr(ChooseExpr *e);
306 mlir::Value VisitInitListExpr(InitListExpr *e);
308 mlir::Value VisitCompoundLiteralExpr(CompoundLiteralExpr *e) {
309 return emitLoadOfLValue(e);
312 mlir::Value VisitVAArgExpr(VAArgExpr *e);
314 mlir::Value VisitAtomicExpr(AtomicExpr *e) {
315 return cgf.emitAtomicExpr(e).getComplexValue();
318 mlir::Value VisitPackIndexingExpr(PackIndexingExpr *e) {
330mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv,
332 assert(lv.isSimple() &&
"non-simple complex l-value?");
333 if (lv.getType()->isAtomicType())
336 const Address srcAddr = lv.getAddress();
337 return builder.
createLoad(cgf.
getLoc(loc), srcAddr, lv.isVolatileQualified());
342void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val,
343 LValue lv,
bool isInit) {
344 if (lv.getType()->isAtomicType() ||
349 const Address destAddr = lv.getAddress();
350 builder.
createStore(loc, val, destAddr, lv.isVolatileQualified());
357mlir::Value ComplexExprEmitter::VisitExpr(Expr *e) {
361 return builder.
getConstant(loc, cir::PoisonAttr::get(complexTy));
365ComplexExprEmitter::VisitImaginaryLiteral(
const ImaginaryLiteral *il) {
367 mlir::Type elementTy = ty.getElementType();
370 mlir::TypedAttr realValueAttr;
371 mlir::TypedAttr imagValueAttr;
373 if (mlir::isa<cir::IntType>(elementTy)) {
375 realValueAttr = cir::IntAttr::get(elementTy, 0);
376 imagValueAttr = cir::IntAttr::get(elementTy, imagValue);
378 assert(mlir::isa<cir::FPTypeInterface>(elementTy) &&
379 "Expected complex element type to be floating-point");
381 llvm::APFloat imagValue =
383 realValueAttr = cir::FPAttr::get(
384 elementTy, llvm::APFloat::getZero(imagValue.getSemantics()));
385 imagValueAttr = cir::FPAttr::get(elementTy, imagValue);
388 auto complexAttr = cir::ConstComplexAttr::get(realValueAttr, imagValueAttr);
389 return cir::ConstantOp::create(builder, loc, complexAttr);
392mlir::Value ComplexExprEmitter::VisitCallExpr(
const CallExpr *e) {
394 return emitLoadOfLValue(e);
398mlir::Value ComplexExprEmitter::VisitStmtExpr(
const StmtExpr *e) {
399 CIRGenFunction::StmtExprEvaluation eval(cgf);
403 assert(retAlloca.
isValid() &&
"Expected complex return value");
408mlir::Value ComplexExprEmitter::emitComplexToComplexCast(mlir::Value val,
411 SourceLocation loc) {
412 if (srcType == destType)
423 cir::CastKind castOpKind;
425 castOpKind = cir::CastKind::float_complex;
427 castOpKind = cir::CastKind::float_complex_to_int_complex;
429 castOpKind = cir::CastKind::int_complex_to_float_complex;
431 castOpKind = cir::CastKind::int_complex;
433 llvm_unreachable(
"unexpected src type or dest type");
439mlir::Value ComplexExprEmitter::emitScalarToComplexCast(mlir::Value val,
442 SourceLocation loc) {
443 cir::CastKind castOpKind;
445 castOpKind = cir::CastKind::float_to_complex;
447 castOpKind = cir::CastKind::int_to_complex;
449 llvm_unreachable(
"unexpected src type");
455mlir::Value ComplexExprEmitter::emitCast(
CastKind ck, Expr *op,
460 llvm_unreachable(
"dependent type must be resolved before the CIR codegen");
464 case CK_NonAtomicToAtomic:
465 case CK_AtomicToNonAtomic:
467 case CK_LValueToRValue:
468 case CK_UserDefinedConversion:
471 case CK_LValueBitCast: {
474 origLV.getAddress().withElementType(builder, cgf.
convertType(destTy));
476 return emitLoadOfLValue(destLV, op->
getExprLoc());
479 case CK_LValueToRValueBitCast: {
481 Address addr = sourceLVal.getAddress().withElementType(
485 return emitLoadOfLValue(destLV, op->
getExprLoc());
489 case CK_BaseToDerived:
490 case CK_DerivedToBase:
491 case CK_UncheckedDerivedToBase:
494 case CK_ArrayToPointerDecay:
495 case CK_FunctionToPointerDecay:
496 case CK_NullToPointer:
497 case CK_NullToMemberPointer:
498 case CK_BaseToDerivedMemberPointer:
499 case CK_DerivedToBaseMemberPointer:
500 case CK_MemberPointerToBoolean:
501 case CK_ReinterpretMemberPointer:
502 case CK_ConstructorConversion:
503 case CK_IntegralToPointer:
504 case CK_PointerToIntegral:
505 case CK_PointerToBoolean:
508 case CK_IntegralCast:
509 case CK_BooleanToSignedIntegral:
510 case CK_IntegralToBoolean:
511 case CK_IntegralToFloating:
512 case CK_FloatingToIntegral:
513 case CK_FloatingToBoolean:
514 case CK_FloatingCast:
515 case CK_CPointerToObjCPointerCast:
516 case CK_BlockPointerToObjCPointerCast:
517 case CK_AnyPointerToBlockPointerCast:
518 case CK_ObjCObjectLValueCast:
519 case CK_FloatingComplexToReal:
520 case CK_FloatingComplexToBoolean:
521 case CK_IntegralComplexToReal:
522 case CK_IntegralComplexToBoolean:
523 case CK_ARCProduceObject:
524 case CK_ARCConsumeObject:
525 case CK_ARCReclaimReturnedObject:
526 case CK_ARCExtendBlockObject:
527 case CK_CopyAndAutoreleaseBlockObject:
528 case CK_BuiltinFnToFnPtr:
529 case CK_ZeroToOCLOpaqueType:
530 case CK_AddressSpaceConversion:
531 case CK_IntToOCLSampler:
532 case CK_FloatingToFixedPoint:
533 case CK_FixedPointToFloating:
534 case CK_FixedPointCast:
535 case CK_FixedPointToBoolean:
536 case CK_FixedPointToIntegral:
537 case CK_IntegralToFixedPoint:
539 case CK_HLSLVectorTruncation:
540 case CK_HLSLMatrixTruncation:
541 case CK_HLSLArrayRValue:
542 case CK_HLSLElementwiseCast:
543 case CK_HLSLAggregateSplatCast:
544 llvm_unreachable(
"invalid cast kind for complex value");
546 case CK_FloatingRealToComplex:
547 case CK_IntegralRealToComplex: {
548 CIRGenFunction::CIRGenFPOptionsRAII fpOptsRAII(cgf, op);
553 case CK_FloatingComplexCast:
554 case CK_FloatingComplexToIntegralComplex:
555 case CK_IntegralComplexCast:
556 case CK_IntegralComplexToFloatingComplex: {
557 CIRGenFunction::CIRGenFPOptionsRAII fpOptsRAII(cgf, op);
558 return emitComplexToComplexCast(Visit(op), op->
getType(), destTy,
563 llvm_unreachable(
"unknown cast resulting in complex value");
566mlir::Value ComplexExprEmitter::VisitUnaryPlus(
const UnaryOperator *e) {
568 mlir::Value result = VisitUnaryPlus(e, promotionTy);
569 if (!promotionTy.
isNull())
574mlir::Value ComplexExprEmitter::VisitUnaryPlus(
const UnaryOperator *e,
575 QualType promotionType) {
576 if (!promotionType.
isNull())
581mlir::Value ComplexExprEmitter::VisitUnaryMinus(
const UnaryOperator *e) {
583 mlir::Value result = VisitUnaryMinus(e, promotionTy);
584 if (!promotionTy.
isNull())
589mlir::Value ComplexExprEmitter::VisitUnaryMinus(
const UnaryOperator *e,
590 QualType promotionType) {
592 if (!promotionType.
isNull())
602 mlir::Value resultReal;
603 mlir::Value resultImag;
604 if (cir::isFPOrVectorOfFPType(real.getType())) {
615mlir::Value ComplexExprEmitter::VisitUnaryNot(
const UnaryOperator *e) {
620mlir::Value ComplexExprEmitter::emitBinAdd(
const BinOpInfo &op) {
622 CIRGenFunction::CIRGenFPOptionsRAII fpOptsRAII(cgf, op.fpFeatures);
624 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
625 mlir::isa<cir::ComplexType>(op.rhs.getType()))
626 return cir::ComplexAddOp::create(builder, op.loc, op.lhs, op.rhs);
628 auto createAdd = [&](mlir::Location loc, mlir::Value a, mlir::Value b) {
629 return cir::isFPOrVectorOfFPType(a.getType())
634 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
637 mlir::Value newReal = createAdd(op.loc, real, op.rhs);
641 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
644 mlir::Value newReal = createAdd(op.loc, op.lhs, real);
648mlir::Value ComplexExprEmitter::emitBinSub(
const BinOpInfo &op) {
650 CIRGenFunction::CIRGenFPOptionsRAII fpOptsRAII(cgf, op.fpFeatures);
652 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
653 mlir::isa<cir::ComplexType>(op.rhs.getType()))
654 return cir::ComplexSubOp::create(builder, op.loc, op.lhs, op.rhs);
656 auto createSub = [&](mlir::Location loc, mlir::Value a, mlir::Value b) {
657 return cir::isFPOrVectorOfFPType(a.getType())
662 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
665 mlir::Value newReal = createSub(op.loc, real, op.rhs);
669 auto createNeg = [&](mlir::Location loc, mlir::Value a) {
670 return cir::isFPOrVectorOfFPType(a.getType()) ? builder.
createFNeg(loc, a)
674 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
677 mlir::Value newReal = createSub(op.loc, op.lhs, real);
678 mlir::Value newImag = createNeg(op.loc, imag);
682static cir::ComplexRangeKind
686 return cir::ComplexRangeKind::Full;
688 return cir::ComplexRangeKind::Improved;
690 return cir::ComplexRangeKind::Promoted;
692 return cir::ComplexRangeKind::Basic;
695 return cir::ComplexRangeKind::Full;
699mlir::Value ComplexExprEmitter::emitBinMul(
const BinOpInfo &op) {
701 CIRGenFunction::CIRGenFPOptionsRAII fpOptsRAII(cgf, op.fpFeatures);
703 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
704 mlir::isa<cir::ComplexType>(op.rhs.getType())) {
705 cir::ComplexRangeKind rangeKind =
707 return cir::ComplexMulOp::create(builder, op.loc, op.lhs, op.rhs,
711 auto createMul = [&](mlir::Location loc, mlir::Value a, mlir::Value b) {
712 return cir::isFPOrVectorOfFPType(a.getType())
717 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
720 mlir::Value newReal = createMul(op.loc, real, op.rhs);
721 mlir::Value newImag = createMul(op.loc, imag, op.rhs);
725 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
728 mlir::Value newReal = createMul(op.loc, op.lhs, real);
729 mlir::Value newImag = createMul(op.loc, op.lhs, imag);
733mlir::Value ComplexExprEmitter::emitBinDiv(
const BinOpInfo &op) {
735 CIRGenFunction::CIRGenFPOptionsRAII fpOptsRAII(cgf, op.fpFeatures);
741 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
742 mlir::isa<cir::ComplexType>(op.rhs.getType())) {
743 cir::ComplexRangeKind rangeKind =
745 return cir::ComplexDivOp::create(builder, op.loc, op.lhs, op.rhs,
751 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
752 assert(mlir::cast<cir::ComplexType>(op.lhs.getType()).getElementType() ==
756 mlir::Value newReal = builder.
createFDiv(op.loc, real, op.rhs);
757 mlir::Value newImag = builder.
createFDiv(op.loc, imag, op.rhs);
761 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
762 cir::ConstantOp nullValue = builder.
getNullValue(op.lhs.getType(), op.loc);
764 cir::ComplexRangeKind rangeKind =
766 return cir::ComplexDivOp::create(builder, op.loc, lhs, op.rhs, rangeKind);
771 assert(!mlir::cast<cir::ComplexType>(result.getType()).isIntegerComplex() &&
772 "integral complex will never be promoted");
773 return builder.createCast(cir::CastKind::float_complex, result,
779 assert(!mlir::cast<cir::ComplexType>(result.getType()).isIntegerComplex() &&
780 "integral complex will never be promoted");
781 return builder.createCast(cir::CastKind::float_complex, result,
785mlir::Value ComplexExprEmitter::emitPromoted(
const Expr *e,
788 if (
const auto *bo = dyn_cast<BinaryOperator>(e)) {
789 switch (bo->getOpcode()) {
790#define HANDLE_BINOP(OP) \
792 return emitBin##OP(emitBinOps(bo, promotionTy));
801 }
else if (
const auto *unaryOp = dyn_cast<UnaryOperator>(e)) {
802 switch (unaryOp->getOpcode()) {
804 return VisitUnaryPlus(unaryOp, promotionTy);
806 return VisitUnaryMinus(unaryOp, promotionTy);
812 mlir::Value result = Visit(
const_cast<Expr *
>(e));
813 if (!promotionTy.
isNull())
821 return ComplexExprEmitter(*this).emitPromoted(e, promotionType);
825ComplexExprEmitter::emitPromotedComplexOperand(
const Expr *e,
828 if (!promotionTy.
isNull())
830 return Visit(
const_cast<Expr *
>(e));
833 if (!promotionTy.
isNull()) {
841ComplexExprEmitter::BinOpInfo
842ComplexExprEmitter::emitBinOps(
const BinaryOperator *e, QualType promotionTy) {
844 binOpInfo.lhs = emitPromotedComplexOperand(e->
getLHS(), promotionTy);
845 binOpInfo.rhs = emitPromotedComplexOperand(e->
getRHS(), promotionTy);
846 binOpInfo.ty = promotionTy.
isNull() ? e->
getType() : promotionTy;
851LValue ComplexExprEmitter::emitCompoundAssignLValue(
852 const CompoundAssignOperator *e,
853 mlir::Value (ComplexExprEmitter::*func)(
const BinOpInfo &), RValue &value) {
857 mlir::Location loc = cgf.
getLoc(exprLoc);
859 BinOpInfo opInfo{loc};
862 CIRGenFunction::CIRGenFPOptionsRAII fpOptsRAII(cgf, opInfo.fpFeatures);
871 QualType complexElementTy =
872 opInfo.ty->castAs<ComplexType>()->getElementType();
873 QualType promotionTypeRHS = getPromotionType(rhsTy);
877 if (!promotionTypeRHS.
isNull()) {
884 if (!promotionTypeRHS.
isNull()) {
888 opInfo.rhs = Visit(e->
getRHS());
897 mlir::Value lhsValue = emitLoadOfLValue(lhs, exprLoc);
898 QualType destTy = promotionTypeLHS.
isNull() ? opInfo.ty : promotionTypeLHS;
899 opInfo.lhs = emitComplexToComplexCast(lhsValue, lhsTy, destTy, exprLoc);
905 QualType promotedComplexElementTy;
906 if (!promotionTypeLHS.
isNull()) {
907 promotedComplexElementTy =
912 promotedComplexElementTy, exprLoc);
920 opInfo.lhs = emitScalarToComplexCast(lhsVal, lhsTy, opInfo.ty, exprLoc);
925 mlir::Value result = (this->*func)(opInfo);
929 mlir::Value resultValue =
930 emitComplexToComplexCast(result, opInfo.ty, lhsTy, exprLoc);
931 emitStoreOfComplex(loc, resultValue, lhs,
false);
934 mlir::Value resultValue =
943mlir::Value ComplexExprEmitter::emitCompoundAssign(
944 const CompoundAssignOperator *e,
945 mlir::Value (ComplexExprEmitter::*func)(
const BinOpInfo &)) {
947 LValue lv = emitCompoundAssignLValue(e, func, val);
954 if (!lv.isVolatileQualified())
960LValue ComplexExprEmitter::emitBinAssignLValue(
const BinaryOperator *e,
961 mlir::Value &value) {
964 "Invalid assignment");
967 value = Visit(e->
getRHS());
978mlir::Value ComplexExprEmitter::VisitBinAssign(
const BinaryOperator *e) {
980 LValue lv = emitBinAssignLValue(e, value);
988 if (!lv.isVolatile())
994mlir::Value ComplexExprEmitter::VisitBinComma(
const BinaryOperator *e) {
996 return Visit(e->
getRHS());
999mlir::Value ComplexExprEmitter::VisitAbstractConditionalOperator(
1000 const AbstractConditionalOperator *e) {
1004 CIRGenFunction::OpaqueValueMapping binding(cgf, e);
1006 CIRGenFunction::ConditionalEvaluation eval(cgf);
1011 return cir::TernaryOp::create(
1012 builder, loc, condValue,
1014 [&](mlir::OpBuilder &b, mlir::Location loc) {
1015 eval.beginEvaluation();
1017 cir::YieldOp::create(b, loc, trueValue);
1018 eval.endEvaluation();
1021 [&](mlir::OpBuilder &b, mlir::Location loc) {
1022 eval.beginEvaluation();
1024 cir::YieldOp::create(b, loc, falseValue);
1025 eval.endEvaluation();
1030mlir::Value ComplexExprEmitter::VisitChooseExpr(ChooseExpr *e) {
1034mlir::Value ComplexExprEmitter::VisitInitListExpr(InitListExpr *e) {
1045 assert(e->
getNumInits() == 0 &&
"Unexpected number of inits");
1050mlir::Value ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *e) {
1062 "Invalid complex expression to emit");
1064 return ComplexExprEmitter(*this).Visit(
const_cast<Expr *
>(e));
1070 "Invalid complex expression to emit");
1071 ComplexExprEmitter emitter(*
this);
1072 mlir::Value value = emitter.Visit(
const_cast<Expr *
>(e));
1078 LValue dest,
bool isInit) {
1079 ComplexExprEmitter(*this).emitStoreOfComplex(loc, v, dest, isInit);
1083 return ComplexExprEmitter(*this).emitLoadOfLValue(src, loc);
1087 assert(e->
getOpcode() == BO_Assign &&
"Expected assign op");
1090 LValue lvalue = ComplexExprEmitter(*this).emitBinAssignLValue(e, value);
1092 cgm.errorNYI(
"emitComplexAssignmentLValue OpenMP");
1098 mlir::Value (ComplexExprEmitter::*)(
const ComplexExprEmitter::BinOpInfo &);
1103 return &ComplexExprEmitter::emitBinMul;
1105 return &ComplexExprEmitter::emitBinDiv;
1107 return &ComplexExprEmitter::emitBinSub;
1109 return &ComplexExprEmitter::emitBinAdd;
1111 llvm_unreachable(
"unexpected complex compound assignment");
1119 return ComplexExprEmitter(*this).emitCompoundAssignLValue(e, op, val);
1128 mlir::Value real = builder.createComplexReal(loc, inVal);
1129 mlir::Value imag = builder.createComplexImag(loc, inVal);
1131 mlir::Value resultReal;
1132 if (cir::isFPOrVectorOfFPType(real.getType())) {
1133 auto fpType = mlir::cast<cir::FPTypeInterface>(real.getType());
1134 mlir::Value amount = builder.getConstFP(
1135 loc, real.getType(), llvm::APFloat(fpType.getFloatSemantics(), 1));
1136 resultReal = e->
isIncrementOp() ? builder.createFAdd(loc, real, amount)
1137 : builder.createFSub(loc, real, amount);
1139 resultReal = e->
isIncrementOp() ? builder.createInc(loc, real)
1140 : builder.createDec(loc, real);
1143 mlir::Value incVal = builder.createComplexCreate(loc, resultReal, imag);
1149 cgm.errorNYI(loc,
"emitComplexPrePostIncDec OpenMP");
1153 return e->
isPrefix() ? incVal : inVal;
1162 LValue ret = ComplexExprEmitter(*this).emitCompoundAssignLValue(e, op, value);
static CompoundFunc getComplexOp(BinaryOperatorKind op)
static const ComplexType * getComplexType(QualType type)
Return the complex type that we are meant to emit.
mlir::Value(ComplexExprEmitter::*)(const ComplexExprEmitter::BinOpInfo &) CompoundFunc
static cir::ComplexRangeKind getComplexRangeAttr(LangOptions::ComplexRangeKind range)
mlir::Value createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::None)
cir::ConstantOp getNullValue(mlir::Type ty, mlir::Location loc)
cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr)
mlir::Value createCast(mlir::Location loc, cir::CastKind kind, mlir::Value src, mlir::Type newTy)
mlir::Value createFDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::None)
mlir::Value createFNeg(mlir::Location loc, mlir::Value operand)
mlir::Value createFAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createComplexImag(mlir::Location loc, mlir::Value operand)
mlir::Value createFMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::None)
mlir::Value createMinus(mlir::Location loc, mlir::Value input, bool nsw=false)
mlir::Value createComplexCreate(mlir::Location loc, mlir::Value real, mlir::Value imag)
mlir::Value createComplexConj(mlir::Location loc, mlir::Value operand)
mlir::Value createFSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createComplexReal(mlir::Location loc, mlir::Value operand)
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
A builtin binary operation expression such as "x + y" or "x <= y".
SourceLocation getExprLoc() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
mlir::Value createNeg(mlir::Location loc, mlir::Value value, bool nsw=false)
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false, bool isNontemporal=false)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, bool isNontemporal=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
LValue getReferenceLValue(CIRGenFunction &cgf, Expr *refExpr) const
mlir::TypedAttr getValue() const
mlir::Value emitComplexToScalarConversion(mlir::Value src, QualType srcTy, QualType dstTy, SourceLocation loc)
Emit a conversion from the specified complex type to the specified destination type,...
mlir::Type convertType(clang::QualType t)
mlir::Value emitPromotedValue(mlir::Value result, QualType promotionType)
const clang::LangOptions & getLangOpts() const
LValue emitScalarCompoundAssignWithComplex(const CompoundAssignOperator *e, mlir::Value &result)
mlir::Value emitComplexExpr(const Expr *e)
Emit the computation of the specified expression of complex type, returning the result.
RValue emitCallExpr(const clang::CallExpr *e, ReturnValueSlot returnValue=ReturnValueSlot())
LValue emitLValue(const clang::Expr *e)
Emit code to compute a designator that specifies the location of the expression.
mlir::Value evaluateExprAsBool(const clang::Expr *e)
Perform the usual unary conversions on the specified expression and compare the result against zero,...
LValue emitComplexCompoundAssignmentLValue(const CompoundAssignOperator *e)
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
mlir::Value emitScalarConversion(mlir::Value src, clang::QualType srcType, clang::QualType dstType, clang::SourceLocation loc)
Emit a conversion from the specified type to the specified destination type, both of which are CIR sc...
mlir::Value emitPromotedComplexExpr(const Expr *e, QualType promotionType)
mlir::Value emitUnPromotedValue(mlir::Value result, QualType unPromotionType)
RValue emitAtomicLoad(LValue lvalue, SourceLocation loc, AggValueSlot slot=AggValueSlot::ignored())
mlir::Type convertTypeForMem(QualType t)
mlir::Value emitComplexPrePostIncDec(const UnaryOperator *e, LValue lv)
mlir::Value emitLoadOfComplex(LValue src, SourceLocation loc)
Load a complex number from the specified l-value.
void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile, clang::QualType ty, LValueBaseInfo baseInfo, bool isInit=false, bool isNontemporal=false)
void emitStoreOfComplex(mlir::Location loc, mlir::Value v, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
LValue emitComplexAssignmentLValue(const BinaryOperator *e)
mlir::Value emitScalarExpr(const clang::Expr *e, bool ignoreResultAssign=false)
Emit the computation of the specified expression of scalar type.
mlir::Value emitPromotedScalarExpr(const Expr *e, QualType promotionType)
mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit)
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
void emitAtomicStore(RValue rvalue, LValue dest, bool isInit)
clang::ASTContext & getContext() const
mlir::LogicalResult emitCompoundStmt(const clang::CompoundStmt &s, Address *lastValue=nullptr, AggValueSlot slot=AggValueSlot::ignored())
bool isLValueSuitableForInlineAtomic(LValue lv)
An LValue is a candidate for having its loads and stores be made atomic if we are operating under /vo...
void emitIgnoredExpr(const clang::Expr *e)
Emit code to compute the specified expression, ignoring the result.
Address createMemTemp(QualType t, mlir::Location loc, const Twine &name="tmp", Address *alloca=nullptr, mlir::OpBuilder::InsertPoint ip={})
Create a temporary memory object of the given type, with appropriate alignmen and cast it to the defa...
mlir::Value emitVAArg(VAArgExpr *ve)
Generate code to get an argument from the passed in pointer and update it accordingly.
void errorUnsupported(const Stmt *s, llvm::StringRef type)
Print out an error that codegen doesn't support the specified stmt yet.
This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(mlir::Value v)
static RValue getComplex(mlir::Value v)
mlir::Value getValue() const
Return the value of this scalar value.
mlir::Value getComplexValue() const
Return the value of this complex value.
Expr * getExpr()
Get the initialization expression that will be used.
A rewritten comparison expression that was originally written using operator syntax.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Complex values, per C99 6.2.5p11.
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
const Expr * getSubExpr() const
Expr * getResultExpr()
Return the result expression of this controlling expression.
const Expr * getSubExpr() const
unsigned getNumInits() const
const Expr * getInit(unsigned Init) const
ComplexRangeKind
Controls the various implementations for complex multiplication and.
@ CX_Full
Implementation of complex division and multiplication using a call to runtime library functions(gener...
@ CX_Basic
Implementation of complex division and multiplication using algebraic formulas at source precision.
@ CX_Promoted
Implementation of complex division using algebraic formulas at higher precision.
@ CX_None
No range rule is enabled.
@ CX_Improved
Implementation of complex division offering an improved handling for overflow in intermediate calcula...
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
SourceLocation getExprLoc() const LLVM_READONLY
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
bool UseExcessPrecision(const ASTContext &Ctx)
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
Encodes a location in the source.
CompoundStmt * getSubStmt()
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
Expr * getReplacement() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isAnyComplexType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
static bool isIncrementOp(Opcode Op)
static bool isPrefix(Opcode Op)
isPrefix - Return true if this is a prefix operation, like –x.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
@ Address
A pointer to a ValueDecl.
Top level wrappers for InstallAPI frontend operations.
CastKind
CastKind - The kind of operation required for a conversion.
U cast(CodeGen::Address addr)
static bool fastMathFlags()