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::RunCleanupsScope scope(cgf);
204 mlir::Value complexVal = Visit(e->
getSubExpr());
207 scope.forceCleanup({&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()); \
277 "ComplexExprEmitter VisitCXXRewrittenBinaryOperator");
282 mlir::Value VisitBinAddAssign(
const CompoundAssignOperator *e) {
283 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinAdd);
285 mlir::Value VisitBinSubAssign(
const CompoundAssignOperator *e) {
286 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinSub);
288 mlir::Value VisitBinMulAssign(
const CompoundAssignOperator *e) {
289 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinMul);
291 mlir::Value VisitBinDivAssign(
const CompoundAssignOperator *e) {
292 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinDiv);
300 LValue emitBinAssignLValue(
const BinaryOperator *e, mlir::Value &val);
301 mlir::Value VisitBinAssign(
const BinaryOperator *e);
302 mlir::Value VisitBinComma(
const BinaryOperator *e);
305 VisitAbstractConditionalOperator(
const AbstractConditionalOperator *e);
306 mlir::Value VisitChooseExpr(ChooseExpr *e);
308 mlir::Value VisitInitListExpr(InitListExpr *e);
310 mlir::Value VisitCompoundLiteralExpr(CompoundLiteralExpr *e) {
311 return emitLoadOfLValue(e);
314 mlir::Value VisitVAArgExpr(VAArgExpr *e);
316 mlir::Value VisitAtomicExpr(AtomicExpr *e) {
317 return cgf.emitAtomicExpr(e).getComplexValue();
320 mlir::Value VisitPackIndexingExpr(PackIndexingExpr *e) {
332mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv,
334 assert(lv.isSimple() &&
"non-simple complex l-value?");
335 if (lv.getType()->isAtomicType())
336 cgf.
cgm.
errorNYI(loc,
"emitLoadOfLValue with Atomic LV");
338 const Address srcAddr = lv.getAddress();
339 return builder.
createLoad(cgf.
getLoc(loc), srcAddr, lv.isVolatileQualified());
344void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val,
345 LValue lv,
bool isInit) {
346 if (lv.getType()->isAtomicType() ||
348 cgf.
cgm.
errorNYI(loc,
"StoreOfComplex with Atomic LV");
352 const Address destAddr = lv.getAddress();
353 builder.
createStore(loc, val, destAddr, lv.isVolatileQualified());
360mlir::Value ComplexExprEmitter::VisitExpr(Expr *e) {
366ComplexExprEmitter::VisitImaginaryLiteral(
const ImaginaryLiteral *il) {
368 mlir::Type elementTy = ty.getElementType();
371 mlir::TypedAttr realValueAttr;
372 mlir::TypedAttr imagValueAttr;
374 if (mlir::isa<cir::IntType>(elementTy)) {
376 realValueAttr = cir::IntAttr::get(elementTy, 0);
377 imagValueAttr = cir::IntAttr::get(elementTy, imagValue);
379 assert(mlir::isa<cir::FPTypeInterface>(elementTy) &&
380 "Expected complex element type to be floating-point");
382 llvm::APFloat imagValue =
384 realValueAttr = cir::FPAttr::get(
385 elementTy, llvm::APFloat::getZero(imagValue.getSemantics()));
386 imagValueAttr = cir::FPAttr::get(elementTy, imagValue);
389 auto complexAttr = cir::ConstComplexAttr::get(realValueAttr, imagValueAttr);
390 return cir::ConstantOp::create(builder, loc, complexAttr);
393mlir::Value ComplexExprEmitter::VisitCallExpr(
const CallExpr *e) {
395 return emitLoadOfLValue(e);
399mlir::Value ComplexExprEmitter::VisitStmtExpr(
const StmtExpr *e) {
400 CIRGenFunction::StmtExprEvaluation eval(cgf);
404 assert(retAlloca.
isValid() &&
"Expected complex return value");
409mlir::Value ComplexExprEmitter::emitComplexToComplexCast(mlir::Value val,
412 SourceLocation loc) {
413 if (srcType == destType)
417 QualType srcElemTy = srcType->
castAs<ComplexType>()->getElementType();
418 QualType destElemTy = destType->
castAs<ComplexType>()->getElementType();
420 cir::CastKind castOpKind;
422 castOpKind = cir::CastKind::float_complex;
424 castOpKind = cir::CastKind::float_complex_to_int_complex;
426 castOpKind = cir::CastKind::int_complex_to_float_complex;
428 castOpKind = cir::CastKind::int_complex;
430 llvm_unreachable(
"unexpected src type or dest type");
436mlir::Value ComplexExprEmitter::emitScalarToComplexCast(mlir::Value val,
439 SourceLocation loc) {
440 cir::CastKind castOpKind;
442 castOpKind = cir::CastKind::float_to_complex;
444 castOpKind = cir::CastKind::int_to_complex;
446 llvm_unreachable(
"unexpected src type");
452mlir::Value ComplexExprEmitter::emitCast(
CastKind ck, Expr *op,
456 llvm_unreachable(
"dependent type must be resolved before the CIR codegen");
459 case CK_LValueToRValue:
460 case CK_UserDefinedConversion:
463 case CK_AtomicToNonAtomic:
464 case CK_NonAtomicToAtomic: {
465 cgf.
cgm.
errorNYI(
"ComplexExprEmitter::emitCast Atmoic");
469 case CK_LValueBitCast: {
472 origLV.getAddress().withElementType(builder, cgf.
convertType(destTy));
474 return emitLoadOfLValue(destLV, op->
getExprLoc());
477 case CK_LValueToRValueBitCast: {
479 Address addr = sourceLVal.getAddress().withElementType(
483 return emitLoadOfLValue(destLV, op->
getExprLoc());
487 case CK_BaseToDerived:
488 case CK_DerivedToBase:
489 case CK_UncheckedDerivedToBase:
492 case CK_ArrayToPointerDecay:
493 case CK_FunctionToPointerDecay:
494 case CK_NullToPointer:
495 case CK_NullToMemberPointer:
496 case CK_BaseToDerivedMemberPointer:
497 case CK_DerivedToBaseMemberPointer:
498 case CK_MemberPointerToBoolean:
499 case CK_ReinterpretMemberPointer:
500 case CK_ConstructorConversion:
501 case CK_IntegralToPointer:
502 case CK_PointerToIntegral:
503 case CK_PointerToBoolean:
506 case CK_IntegralCast:
507 case CK_BooleanToSignedIntegral:
508 case CK_IntegralToBoolean:
509 case CK_IntegralToFloating:
510 case CK_FloatingToIntegral:
511 case CK_FloatingToBoolean:
512 case CK_FloatingCast:
513 case CK_CPointerToObjCPointerCast:
514 case CK_BlockPointerToObjCPointerCast:
515 case CK_AnyPointerToBlockPointerCast:
516 case CK_ObjCObjectLValueCast:
517 case CK_FloatingComplexToReal:
518 case CK_FloatingComplexToBoolean:
519 case CK_IntegralComplexToReal:
520 case CK_IntegralComplexToBoolean:
521 case CK_ARCProduceObject:
522 case CK_ARCConsumeObject:
523 case CK_ARCReclaimReturnedObject:
524 case CK_ARCExtendBlockObject:
525 case CK_CopyAndAutoreleaseBlockObject:
526 case CK_BuiltinFnToFnPtr:
527 case CK_ZeroToOCLOpaqueType:
528 case CK_AddressSpaceConversion:
529 case CK_IntToOCLSampler:
530 case CK_FloatingToFixedPoint:
531 case CK_FixedPointToFloating:
532 case CK_FixedPointCast:
533 case CK_FixedPointToBoolean:
534 case CK_FixedPointToIntegral:
535 case CK_IntegralToFixedPoint:
537 case CK_HLSLVectorTruncation:
538 case CK_HLSLMatrixTruncation:
539 case CK_HLSLArrayRValue:
540 case CK_HLSLElementwiseCast:
541 case CK_HLSLAggregateSplatCast:
542 llvm_unreachable(
"invalid cast kind for complex value");
544 case CK_FloatingRealToComplex:
545 case CK_IntegralRealToComplex: {
546 CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, op);
551 case CK_FloatingComplexCast:
552 case CK_FloatingComplexToIntegralComplex:
553 case CK_IntegralComplexCast:
554 case CK_IntegralComplexToFloatingComplex: {
555 CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, op);
556 return emitComplexToComplexCast(Visit(op), op->
getType(), destTy,
561 llvm_unreachable(
"unknown cast resulting in complex value");
564mlir::Value ComplexExprEmitter::VisitUnaryPlus(
const UnaryOperator *e) {
566 mlir::Value result = VisitUnaryPlus(e, promotionTy);
567 if (!promotionTy.
isNull())
572mlir::Value ComplexExprEmitter::VisitUnaryPlus(
const UnaryOperator *e,
573 QualType promotionType) {
574 if (!promotionType.
isNull())
579mlir::Value ComplexExprEmitter::VisitUnaryMinus(
const UnaryOperator *e) {
581 mlir::Value result = VisitUnaryMinus(e, promotionTy);
582 if (!promotionTy.
isNull())
587mlir::Value ComplexExprEmitter::VisitUnaryMinus(
const UnaryOperator *e,
588 QualType promotionType) {
590 if (!promotionType.
isNull())
597mlir::Value ComplexExprEmitter::VisitUnaryNot(
const UnaryOperator *e) {
602mlir::Value ComplexExprEmitter::emitBinAdd(
const BinOpInfo &op) {
604 CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, op.fpFeatures);
606 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
607 mlir::isa<cir::ComplexType>(op.rhs.getType()))
608 return cir::ComplexAddOp::create(builder, op.loc, op.lhs, op.rhs);
610 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
613 mlir::Value newReal = builder.
createAdd(op.loc, real, op.rhs);
617 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
620 mlir::Value newReal = builder.
createAdd(op.loc, op.lhs, real);
624mlir::Value ComplexExprEmitter::emitBinSub(
const BinOpInfo &op) {
626 CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, op.fpFeatures);
628 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
629 mlir::isa<cir::ComplexType>(op.rhs.getType()))
630 return cir::ComplexSubOp::create(builder, op.loc, op.lhs, op.rhs);
632 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
635 mlir::Value newReal = builder.
createSub(op.loc, real, op.rhs);
639 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
642 mlir::Value newReal = builder.
createSub(op.loc, op.lhs, real);
646static cir::ComplexRangeKind
650 return cir::ComplexRangeKind::Full;
652 return cir::ComplexRangeKind::Improved;
654 return cir::ComplexRangeKind::Promoted;
656 return cir::ComplexRangeKind::Basic;
659 return cir::ComplexRangeKind::Full;
663mlir::Value ComplexExprEmitter::emitBinMul(
const BinOpInfo &op) {
665 CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, op.fpFeatures);
667 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
668 mlir::isa<cir::ComplexType>(op.rhs.getType())) {
669 cir::ComplexRangeKind rangeKind =
671 return cir::ComplexMulOp::create(builder, op.loc, op.lhs, op.rhs,
675 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
678 mlir::Value newReal = builder.
createMul(op.loc, real, op.rhs);
679 mlir::Value newImag = builder.
createMul(op.loc, imag, op.rhs);
683 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
686 mlir::Value newReal = builder.
createMul(op.loc, op.lhs, real);
687 mlir::Value newImag = builder.
createMul(op.loc, op.lhs, imag);
691mlir::Value ComplexExprEmitter::emitBinDiv(
const BinOpInfo &op) {
693 CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, op.fpFeatures);
699 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
700 mlir::isa<cir::ComplexType>(op.rhs.getType())) {
701 cir::ComplexRangeKind rangeKind =
703 return cir::ComplexDivOp::create(builder, op.loc, op.lhs, op.rhs,
709 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
710 assert(mlir::cast<cir::ComplexType>(op.lhs.getType()).getElementType() ==
714 mlir::Value newReal = builder.
createFDiv(op.loc, real, op.rhs);
715 mlir::Value newImag = builder.
createFDiv(op.loc, imag, op.rhs);
719 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
720 cir::ConstantOp nullValue = builder.
getNullValue(op.lhs.getType(), op.loc);
722 cir::ComplexRangeKind rangeKind =
724 return cir::ComplexDivOp::create(builder, op.loc, lhs, op.rhs, rangeKind);
729 assert(!mlir::cast<cir::ComplexType>(result.getType()).isIntegerComplex() &&
730 "integral complex will never be promoted");
731 return builder.createCast(cir::CastKind::float_complex, result,
737 assert(!mlir::cast<cir::ComplexType>(result.getType()).isIntegerComplex() &&
738 "integral complex will never be promoted");
739 return builder.createCast(cir::CastKind::float_complex, result,
743mlir::Value ComplexExprEmitter::emitPromoted(
const Expr *e,
746 if (
const auto *bo = dyn_cast<BinaryOperator>(e)) {
747 switch (bo->getOpcode()) {
748#define HANDLE_BINOP(OP) \
750 return emitBin##OP(emitBinOps(bo, promotionTy));
759 }
else if (
const auto *unaryOp = dyn_cast<UnaryOperator>(e)) {
760 switch (unaryOp->getOpcode()) {
762 return VisitUnaryPlus(unaryOp, promotionTy);
764 return VisitUnaryMinus(unaryOp, promotionTy);
770 mlir::Value result = Visit(
const_cast<Expr *
>(e));
771 if (!promotionTy.
isNull())
779 return ComplexExprEmitter(*this).emitPromoted(e, promotionType);
783ComplexExprEmitter::emitPromotedComplexOperand(
const Expr *e,
786 if (!promotionTy.
isNull())
788 return Visit(
const_cast<Expr *
>(e));
791 if (!promotionTy.
isNull()) {
799ComplexExprEmitter::BinOpInfo
800ComplexExprEmitter::emitBinOps(
const BinaryOperator *e, QualType promotionTy) {
802 binOpInfo.lhs = emitPromotedComplexOperand(e->
getLHS(), promotionTy);
803 binOpInfo.rhs = emitPromotedComplexOperand(e->
getRHS(), promotionTy);
804 binOpInfo.ty = promotionTy.
isNull() ? e->
getType() : promotionTy;
809LValue ComplexExprEmitter::emitCompoundAssignLValue(
810 const CompoundAssignOperator *e,
811 mlir::Value (ComplexExprEmitter::*func)(
const BinOpInfo &), RValue &value) {
815 mlir::Location loc = cgf.
getLoc(exprLoc);
817 if (lhsTy->
getAs<AtomicType>()) {
818 cgf.
cgm.
errorNYI(
"emitCompoundAssignLValue AtmoicType");
822 BinOpInfo opInfo{loc};
825 CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, opInfo.fpFeatures);
834 QualType complexElementTy =
835 opInfo.ty->castAs<ComplexType>()->getElementType();
836 QualType promotionTypeRHS = getPromotionType(rhsTy);
840 if (!promotionTypeRHS.
isNull()) {
847 if (!promotionTypeRHS.
isNull()) {
851 opInfo.rhs = Visit(e->
getRHS());
860 mlir::Value lhsValue = emitLoadOfLValue(lhs, exprLoc);
861 QualType destTy = promotionTypeLHS.
isNull() ? opInfo.ty : promotionTypeLHS;
862 opInfo.lhs = emitComplexToComplexCast(lhsValue, lhsTy, destTy, exprLoc);
868 QualType promotedComplexElementTy;
869 if (!promotionTypeLHS.
isNull()) {
870 promotedComplexElementTy =
875 promotedComplexElementTy, exprLoc);
883 opInfo.lhs = emitScalarToComplexCast(lhsVal, lhsTy, opInfo.ty, exprLoc);
888 mlir::Value result = (this->*func)(opInfo);
892 mlir::Value resultValue =
893 emitComplexToComplexCast(result, opInfo.ty, lhsTy, exprLoc);
894 emitStoreOfComplex(loc, resultValue, lhs,
false);
897 mlir::Value resultValue =
906mlir::Value ComplexExprEmitter::emitCompoundAssign(
907 const CompoundAssignOperator *e,
908 mlir::Value (ComplexExprEmitter::*func)(
const BinOpInfo &)) {
910 LValue lv = emitCompoundAssignLValue(e, func, val);
917 if (!lv.isVolatileQualified())
923LValue ComplexExprEmitter::emitBinAssignLValue(
const BinaryOperator *e,
924 mlir::Value &value) {
927 "Invalid assignment");
930 value = Visit(e->
getRHS());
941mlir::Value ComplexExprEmitter::VisitBinAssign(
const BinaryOperator *e) {
943 LValue lv = emitBinAssignLValue(e, value);
951 if (!lv.isVolatile())
957mlir::Value ComplexExprEmitter::VisitBinComma(
const BinaryOperator *e) {
959 return Visit(e->
getRHS());
962mlir::Value ComplexExprEmitter::VisitAbstractConditionalOperator(
963 const AbstractConditionalOperator *e) {
967 CIRGenFunction::OpaqueValueMapping binding(cgf, e);
969 CIRGenFunction::ConditionalEvaluation eval(cgf);
974 return cir::TernaryOp::create(
975 builder, loc, condValue,
977 [&](mlir::OpBuilder &
b, mlir::Location loc) {
978 eval.beginEvaluation();
980 cir::YieldOp::create(
b, loc, trueValue);
981 eval.endEvaluation();
984 [&](mlir::OpBuilder &
b, mlir::Location loc) {
985 eval.beginEvaluation();
987 cir::YieldOp::create(
b, loc, falseValue);
988 eval.endEvaluation();
993mlir::Value ComplexExprEmitter::VisitChooseExpr(ChooseExpr *e) {
997mlir::Value ComplexExprEmitter::VisitInitListExpr(InitListExpr *e) {
1008 assert(e->
getNumInits() == 0 &&
"Unexpected number of inits");
1013mlir::Value ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *e) {
1025 "Invalid complex expression to emit");
1027 return ComplexExprEmitter(*this).Visit(
const_cast<Expr *
>(e));
1033 "Invalid complex expression to emit");
1034 ComplexExprEmitter emitter(*
this);
1035 mlir::Value value = emitter.Visit(
const_cast<Expr *
>(e));
1041 LValue dest,
bool isInit) {
1042 ComplexExprEmitter(*this).emitStoreOfComplex(loc, v, dest, isInit);
1046 return ComplexExprEmitter(*this).emitLoadOfLValue(src, loc);
1050 assert(e->
getOpcode() == BO_Assign &&
"Expected assign op");
1053 LValue lvalue = ComplexExprEmitter(*this).emitBinAssignLValue(e, value);
1055 cgm.errorNYI(
"emitComplexAssignmentLValue OpenMP");
1061 mlir::Value (ComplexExprEmitter::*)(
const ComplexExprEmitter::BinOpInfo &);
1066 return &ComplexExprEmitter::emitBinMul;
1068 return &ComplexExprEmitter::emitBinDiv;
1070 return &ComplexExprEmitter::emitBinSub;
1072 return &ComplexExprEmitter::emitBinAdd;
1074 llvm_unreachable(
"unexpected complex compound assignment");
1082 return ComplexExprEmitter(*this).emitCompoundAssignLValue(e, op, val);
1089 mlir::Value incVal = e->
isIncrementOp() ? builder.createInc(loc, inVal)
1090 : builder.createDec(loc, inVal);
1096 cgm.errorNYI(loc,
"emitComplexPrePostIncDec OpenMP");
1100 return e->
isPrefix() ? incVal : inVal;
1109 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)
__device__ __2f16 float __ockl_bool s
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)
mlir::Value createCast(mlir::Location loc, cir::CastKind kind, mlir::Value src, mlir::Type newTy)
mlir::Value createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::None)
mlir::Value createComplexImag(mlir::Location loc, mlir::Value operand)
mlir::Value createNot(mlir::Location loc, mlir::Value value)
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 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 createFDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false)
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)
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)
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.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
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.
SourceLocation getExprLoc() const LLVM_READONLY
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)
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...
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.
The JSON file list parser is used to communicate input to InstallAPI.
CastKind
CastKind - The kind of operation required for a conversion.
U cast(CodeGen::Address addr)
static bool fastMathFlags()