1115 lines · cpp
1#include "CIRGenBuilder.h"2#include "CIRGenFunction.h"3 4#include "clang/AST/StmtVisitor.h"5 6using namespace clang;7using namespace clang::CIRGen;8 9#ifndef NDEBUG10/// Return the complex type that we are meant to emit.11static const ComplexType *getComplexType(QualType type) {12 type = type.getCanonicalType();13 if (const ComplexType *comp = dyn_cast<ComplexType>(type))14 return comp;15 return cast<ComplexType>(cast<AtomicType>(type)->getValueType());16}17#endif // NDEBUG18 19namespace {20class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {21 CIRGenFunction &cgf;22 CIRGenBuilderTy &builder;23 24public:25 explicit ComplexExprEmitter(CIRGenFunction &cgf)26 : cgf(cgf), builder(cgf.getBuilder()) {}27 28 //===--------------------------------------------------------------------===//29 // Utilities30 //===--------------------------------------------------------------------===//31 32 /// Given an expression with complex type that represents a value l-value,33 /// this method emits the address of the l-value, then loads and returns the34 /// result.35 mlir::Value emitLoadOfLValue(const Expr *e) {36 return emitLoadOfLValue(cgf.emitLValue(e), e->getExprLoc());37 }38 39 mlir::Value emitLoadOfLValue(LValue lv, SourceLocation loc);40 41 /// Store the specified real/imag parts into the42 /// specified value pointer.43 void emitStoreOfComplex(mlir::Location loc, mlir::Value val, LValue lv,44 bool isInit);45 46 /// Emit a cast from complex value Val to DestType.47 mlir::Value emitComplexToComplexCast(mlir::Value value, QualType srcType,48 QualType destType, SourceLocation loc);49 50 /// Emit a cast from scalar value Val to DestType.51 mlir::Value emitScalarToComplexCast(mlir::Value value, QualType srcType,52 QualType destType, SourceLocation loc);53 54 //===--------------------------------------------------------------------===//55 // Visitor Methods56 //===--------------------------------------------------------------------===//57 58 mlir::Value Visit(Expr *e) {59 return StmtVisitor<ComplexExprEmitter, mlir::Value>::Visit(e);60 }61 62 mlir::Value VisitStmt(Stmt *s) {63 cgf.cgm.errorNYI(s->getBeginLoc(), "ComplexExprEmitter VisitStmt");64 return {};65 }66 67 mlir::Value VisitExpr(Expr *e);68 mlir::Value VisitConstantExpr(ConstantExpr *e) {69 cgf.cgm.errorNYI(e->getExprLoc(), "ComplexExprEmitter VisitConstantExpr");70 return {};71 }72 73 mlir::Value VisitParenExpr(ParenExpr *pe) { return Visit(pe->getSubExpr()); }74 mlir::Value VisitGenericSelectionExpr(GenericSelectionExpr *ge) {75 return Visit(ge->getResultExpr());76 }77 mlir::Value VisitImaginaryLiteral(const ImaginaryLiteral *il);78 mlir::Value79 VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *pe) {80 return Visit(pe->getReplacement());81 }82 mlir::Value VisitCoawaitExpr(CoawaitExpr *s) {83 cgf.cgm.errorNYI(s->getExprLoc(), "ComplexExprEmitter VisitCoawaitExpr");84 return {};85 }86 mlir::Value VisitCoyieldExpr(CoyieldExpr *s) {87 cgf.cgm.errorNYI(s->getExprLoc(), "ComplexExprEmitter VisitCoyieldExpr");88 return {};89 }90 mlir::Value VisitUnaryCoawait(const UnaryOperator *e) {91 cgf.cgm.errorNYI(e->getExprLoc(), "ComplexExprEmitter VisitUnaryCoawait");92 return {};93 }94 95 mlir::Value emitConstant(const CIRGenFunction::ConstantEmission &constant,96 Expr *e) {97 assert(constant && "not a constant");98 if (constant.isReference())99 return emitLoadOfLValue(constant.getReferenceLValue(cgf, e),100 e->getExprLoc());101 102 mlir::TypedAttr valueAttr = constant.getValue();103 return builder.getConstant(cgf.getLoc(e->getSourceRange()), valueAttr);104 }105 106 // l-values.107 mlir::Value VisitDeclRefExpr(DeclRefExpr *e) {108 if (CIRGenFunction::ConstantEmission constant = cgf.tryEmitAsConstant(e))109 return emitConstant(constant, e);110 return emitLoadOfLValue(e);111 }112 mlir::Value VisitObjCIvarRefExpr(ObjCIvarRefExpr *e) {113 cgf.cgm.errorNYI(e->getExprLoc(),114 "ComplexExprEmitter VisitObjCIvarRefExpr");115 return {};116 }117 mlir::Value VisitObjCMessageExpr(ObjCMessageExpr *e) {118 cgf.cgm.errorNYI(e->getExprLoc(),119 "ComplexExprEmitter VisitObjCMessageExpr");120 return {};121 }122 mlir::Value VisitArraySubscriptExpr(Expr *e) { return emitLoadOfLValue(e); }123 mlir::Value VisitMemberExpr(MemberExpr *me) {124 if (CIRGenFunction::ConstantEmission constant = cgf.tryEmitAsConstant(me)) {125 cgf.emitIgnoredExpr(me->getBase());126 return emitConstant(constant, me);127 }128 return emitLoadOfLValue(me);129 }130 mlir::Value VisitOpaqueValueExpr(OpaqueValueExpr *e) {131 if (e->isGLValue())132 return emitLoadOfLValue(cgf.getOrCreateOpaqueLValueMapping(e),133 e->getExprLoc());134 return cgf.getOrCreateOpaqueRValueMapping(e).getComplexValue();135 }136 137 mlir::Value VisitPseudoObjectExpr(PseudoObjectExpr *e) {138 cgf.cgm.errorNYI(e->getExprLoc(),139 "ComplexExprEmitter VisitPseudoObjectExpr");140 return {};141 }142 143 mlir::Value emitCast(CastKind ck, Expr *op, QualType destTy);144 mlir::Value VisitImplicitCastExpr(ImplicitCastExpr *e) {145 // Unlike for scalars, we don't have to worry about function->ptr demotion146 // here.147 if (e->changesVolatileQualification())148 return emitLoadOfLValue(e);149 return emitCast(e->getCastKind(), e->getSubExpr(), e->getType());150 }151 mlir::Value VisitCastExpr(CastExpr *e) {152 if (const auto *ece = dyn_cast<ExplicitCastExpr>(e)) {153 // Bind VLAs in the cast type.154 if (ece->getType()->isVariablyModifiedType()) {155 cgf.cgm.errorNYI(e->getExprLoc(),156 "VisitCastExpr Bind VLAs in the cast type");157 return {};158 }159 }160 161 if (e->changesVolatileQualification())162 return emitLoadOfLValue(e);163 164 return emitCast(e->getCastKind(), e->getSubExpr(), e->getType());165 }166 mlir::Value VisitCallExpr(const CallExpr *e);167 mlir::Value VisitStmtExpr(const StmtExpr *e);168 169 // Operators.170 mlir::Value VisitPrePostIncDec(const UnaryOperator *e, cir::UnaryOpKind op,171 bool isPre) {172 LValue lv = cgf.emitLValue(e->getSubExpr());173 return cgf.emitComplexPrePostIncDec(e, lv, op, isPre);174 }175 mlir::Value VisitUnaryPostDec(const UnaryOperator *e) {176 return VisitPrePostIncDec(e, cir::UnaryOpKind::Dec, false);177 }178 mlir::Value VisitUnaryPostInc(const UnaryOperator *e) {179 return VisitPrePostIncDec(e, cir::UnaryOpKind::Inc, false);180 }181 mlir::Value VisitUnaryPreDec(const UnaryOperator *e) {182 return VisitPrePostIncDec(e, cir::UnaryOpKind::Dec, true);183 }184 mlir::Value VisitUnaryPreInc(const UnaryOperator *e) {185 return VisitPrePostIncDec(e, cir::UnaryOpKind::Inc, true);186 }187 mlir::Value VisitUnaryDeref(const Expr *e) { return emitLoadOfLValue(e); }188 189 mlir::Value VisitUnaryPlus(const UnaryOperator *e);190 mlir::Value VisitUnaryMinus(const UnaryOperator *e);191 mlir::Value VisitPlusMinus(const UnaryOperator *e, cir::UnaryOpKind kind,192 QualType promotionType);193 mlir::Value VisitUnaryNot(const UnaryOperator *e);194 // LNot,Real,Imag never return complex.195 mlir::Value VisitUnaryExtension(const UnaryOperator *e) {196 return Visit(e->getSubExpr());197 }198 mlir::Value VisitCXXDefaultArgExpr(CXXDefaultArgExpr *dae) {199 CIRGenFunction::CXXDefaultArgExprScope scope(cgf, dae);200 return Visit(dae->getExpr());201 }202 mlir::Value VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die) {203 CIRGenFunction::CXXDefaultInitExprScope scope(cgf, die);204 return Visit(die->getExpr());205 }206 mlir::Value VisitExprWithCleanups(ExprWithCleanups *e) {207 cgf.cgm.errorNYI(e->getExprLoc(),208 "ComplexExprEmitter VisitExprWithCleanups");209 return {};210 }211 mlir::Value VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e) {212 mlir::Location loc = cgf.getLoc(e->getExprLoc());213 mlir::Type complexTy = cgf.convertType(e->getType());214 return builder.getNullValue(complexTy, loc);215 }216 mlir::Value VisitImplicitValueInitExpr(ImplicitValueInitExpr *e) {217 cgf.cgm.errorNYI(e->getExprLoc(),218 "ComplexExprEmitter VisitImplicitValueInitExpr");219 return {};220 }221 222 struct BinOpInfo {223 mlir::Location loc;224 mlir::Value lhs{};225 mlir::Value rhs{};226 QualType ty{}; // Computation Type.227 FPOptions fpFeatures{};228 };229 230 BinOpInfo emitBinOps(const BinaryOperator *e,231 QualType promotionTy = QualType());232 233 mlir::Value emitPromoted(const Expr *e, QualType promotionTy);234 mlir::Value emitPromotedComplexOperand(const Expr *e, QualType promotionTy);235 LValue emitCompoundAssignLValue(236 const CompoundAssignOperator *e,237 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &),238 RValue &value);239 mlir::Value emitCompoundAssign(240 const CompoundAssignOperator *e,241 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &));242 243 mlir::Value emitBinAdd(const BinOpInfo &op);244 mlir::Value emitBinSub(const BinOpInfo &op);245 mlir::Value emitBinMul(const BinOpInfo &op);246 mlir::Value emitBinDiv(const BinOpInfo &op);247 248 QualType getPromotionType(QualType ty, bool isDivOpCode = false) {249 if (auto *complexTy = ty->getAs<ComplexType>()) {250 QualType elementTy = complexTy->getElementType();251 if (elementTy.UseExcessPrecision(cgf.getContext()))252 return cgf.getContext().getComplexType(cgf.getContext().FloatTy);253 }254 255 if (ty.UseExcessPrecision(cgf.getContext()))256 return cgf.getContext().FloatTy;257 return QualType();258 }259 260#define HANDLEBINOP(OP) \261 mlir::Value VisitBin##OP(const BinaryOperator *e) { \262 QualType promotionTy = getPromotionType( \263 e->getType(), e->getOpcode() == BinaryOperatorKind::BO_Div); \264 mlir::Value result = emitBin##OP(emitBinOps(e, promotionTy)); \265 if (!promotionTy.isNull()) \266 result = cgf.emitUnPromotedValue(result, e->getType()); \267 return result; \268 }269 270 HANDLEBINOP(Add)271 HANDLEBINOP(Sub)272 HANDLEBINOP(Mul)273 HANDLEBINOP(Div)274#undef HANDLEBINOP275 276 mlir::Value VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *e) {277 cgf.cgm.errorNYI(e->getExprLoc(),278 "ComplexExprEmitter VisitCXXRewrittenBinaryOperator");279 return {};280 }281 282 // Compound assignments.283 mlir::Value VisitBinAddAssign(const CompoundAssignOperator *e) {284 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinAdd);285 }286 mlir::Value VisitBinSubAssign(const CompoundAssignOperator *e) {287 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinSub);288 }289 mlir::Value VisitBinMulAssign(const CompoundAssignOperator *e) {290 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinMul);291 }292 mlir::Value VisitBinDivAssign(const CompoundAssignOperator *e) {293 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinDiv);294 }295 296 // GCC rejects rem/and/or/xor for integer complex.297 // Logical and/or always return int, never complex.298 299 // No comparisons produce a complex result.300 301 LValue emitBinAssignLValue(const BinaryOperator *e, mlir::Value &val);302 mlir::Value VisitBinAssign(const BinaryOperator *e);303 mlir::Value VisitBinComma(const BinaryOperator *e);304 305 mlir::Value306 VisitAbstractConditionalOperator(const AbstractConditionalOperator *e);307 mlir::Value VisitChooseExpr(ChooseExpr *e);308 309 mlir::Value VisitInitListExpr(InitListExpr *e);310 311 mlir::Value VisitCompoundLiteralExpr(CompoundLiteralExpr *e) {312 return emitLoadOfLValue(e);313 }314 315 mlir::Value VisitVAArgExpr(VAArgExpr *e);316 317 mlir::Value VisitAtomicExpr(AtomicExpr *e) {318 return cgf.emitAtomicExpr(e).getComplexValue();319 }320 321 mlir::Value VisitPackIndexingExpr(PackIndexingExpr *e) {322 cgf.cgm.errorNYI(e->getExprLoc(),323 "ComplexExprEmitter VisitPackIndexingExpr");324 return {};325 }326};327} // namespace328 329//===----------------------------------------------------------------------===//330// Utilities331//===----------------------------------------------------------------------===//332 333/// EmitLoadOfLValue - Given an RValue reference for a complex, emit code to334/// load the real and imaginary pieces, returning them as Real/Imag.335mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv,336 SourceLocation loc) {337 assert(lv.isSimple() && "non-simple complex l-value?");338 if (lv.getType()->isAtomicType())339 cgf.cgm.errorNYI(loc, "emitLoadOfLValue with Atomic LV");340 341 const Address srcAddr = lv.getAddress();342 return builder.createLoad(cgf.getLoc(loc), srcAddr, lv.isVolatileQualified());343}344 345/// EmitStoreOfComplex - Store the specified real/imag parts into the346/// specified value pointer.347void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val,348 LValue lv, bool isInit) {349 if (lv.getType()->isAtomicType() ||350 (!isInit && cgf.isLValueSuitableForInlineAtomic(lv))) {351 cgf.cgm.errorNYI(loc, "StoreOfComplex with Atomic LV");352 return;353 }354 355 const Address destAddr = lv.getAddress();356 builder.createStore(loc, val, destAddr, lv.isVolatileQualified());357}358 359//===----------------------------------------------------------------------===//360// Visitor Methods361//===----------------------------------------------------------------------===//362 363mlir::Value ComplexExprEmitter::VisitExpr(Expr *e) {364 cgf.cgm.errorNYI(e->getExprLoc(), "ComplexExprEmitter VisitExpr");365 return {};366}367 368mlir::Value369ComplexExprEmitter::VisitImaginaryLiteral(const ImaginaryLiteral *il) {370 auto ty = mlir::cast<cir::ComplexType>(cgf.convertType(il->getType()));371 mlir::Type elementTy = ty.getElementType();372 mlir::Location loc = cgf.getLoc(il->getExprLoc());373 374 mlir::TypedAttr realValueAttr;375 mlir::TypedAttr imagValueAttr;376 377 if (mlir::isa<cir::IntType>(elementTy)) {378 llvm::APInt imagValue = cast<IntegerLiteral>(il->getSubExpr())->getValue();379 realValueAttr = cir::IntAttr::get(elementTy, 0);380 imagValueAttr = cir::IntAttr::get(elementTy, imagValue);381 } else {382 assert(mlir::isa<cir::FPTypeInterface>(elementTy) &&383 "Expected complex element type to be floating-point");384 385 llvm::APFloat imagValue =386 cast<FloatingLiteral>(il->getSubExpr())->getValue();387 realValueAttr = cir::FPAttr::get(388 elementTy, llvm::APFloat::getZero(imagValue.getSemantics()));389 imagValueAttr = cir::FPAttr::get(elementTy, imagValue);390 }391 392 auto complexAttr = cir::ConstComplexAttr::get(realValueAttr, imagValueAttr);393 return cir::ConstantOp::create(builder, loc, complexAttr);394}395 396mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr *e) {397 if (e->getCallReturnType(cgf.getContext())->isReferenceType())398 return emitLoadOfLValue(e);399 return cgf.emitCallExpr(e).getComplexValue();400}401 402mlir::Value ComplexExprEmitter::VisitStmtExpr(const StmtExpr *e) {403 cgf.cgm.errorNYI(e->getExprLoc(), "ComplexExprEmitter VisitExpr");404 return {};405}406 407mlir::Value ComplexExprEmitter::emitComplexToComplexCast(mlir::Value val,408 QualType srcType,409 QualType destType,410 SourceLocation loc) {411 if (srcType == destType)412 return val;413 414 // Get the src/dest element type.415 QualType srcElemTy = srcType->castAs<ComplexType>()->getElementType();416 QualType destElemTy = destType->castAs<ComplexType>()->getElementType();417 418 cir::CastKind castOpKind;419 if (srcElemTy->isFloatingType() && destElemTy->isFloatingType())420 castOpKind = cir::CastKind::float_complex;421 else if (srcElemTy->isFloatingType() && destElemTy->isIntegerType())422 castOpKind = cir::CastKind::float_complex_to_int_complex;423 else if (srcElemTy->isIntegerType() && destElemTy->isFloatingType())424 castOpKind = cir::CastKind::int_complex_to_float_complex;425 else if (srcElemTy->isIntegerType() && destElemTy->isIntegerType())426 castOpKind = cir::CastKind::int_complex;427 else428 llvm_unreachable("unexpected src type or dest type");429 430 return builder.createCast(cgf.getLoc(loc), castOpKind, val,431 cgf.convertType(destType));432}433 434mlir::Value ComplexExprEmitter::emitScalarToComplexCast(mlir::Value val,435 QualType srcType,436 QualType destType,437 SourceLocation loc) {438 cir::CastKind castOpKind;439 if (srcType->isFloatingType())440 castOpKind = cir::CastKind::float_to_complex;441 else if (srcType->isIntegerType())442 castOpKind = cir::CastKind::int_to_complex;443 else444 llvm_unreachable("unexpected src type");445 446 return builder.createCast(cgf.getLoc(loc), castOpKind, val,447 cgf.convertType(destType));448}449 450mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op,451 QualType destTy) {452 switch (ck) {453 case CK_Dependent:454 llvm_unreachable("dependent type must be resolved before the CIR codegen");455 456 case CK_NoOp:457 case CK_LValueToRValue:458 return Visit(op);459 460 case CK_AtomicToNonAtomic:461 case CK_NonAtomicToAtomic:462 case CK_UserDefinedConversion: {463 cgf.cgm.errorNYI(464 "ComplexExprEmitter::emitCast Atmoic & UserDefinedConversion");465 return {};466 }467 468 case CK_LValueBitCast: {469 LValue origLV = cgf.emitLValue(op);470 Address addr =471 origLV.getAddress().withElementType(builder, cgf.convertType(destTy));472 LValue destLV = cgf.makeAddrLValue(addr, destTy);473 return emitLoadOfLValue(destLV, op->getExprLoc());474 }475 476 case CK_LValueToRValueBitCast: {477 LValue sourceLVal = cgf.emitLValue(op);478 Address addr = sourceLVal.getAddress().withElementType(479 builder, cgf.convertTypeForMem(destTy));480 LValue destLV = cgf.makeAddrLValue(addr, destTy);481 assert(!cir::MissingFeatures::opTBAA());482 return emitLoadOfLValue(destLV, op->getExprLoc());483 }484 485 case CK_BitCast:486 case CK_BaseToDerived:487 case CK_DerivedToBase:488 case CK_UncheckedDerivedToBase:489 case CK_Dynamic:490 case CK_ToUnion:491 case CK_ArrayToPointerDecay:492 case CK_FunctionToPointerDecay:493 case CK_NullToPointer:494 case CK_NullToMemberPointer:495 case CK_BaseToDerivedMemberPointer:496 case CK_DerivedToBaseMemberPointer:497 case CK_MemberPointerToBoolean:498 case CK_ReinterpretMemberPointer:499 case CK_ConstructorConversion:500 case CK_IntegralToPointer:501 case CK_PointerToIntegral:502 case CK_PointerToBoolean:503 case CK_ToVoid:504 case CK_VectorSplat:505 case CK_IntegralCast:506 case CK_BooleanToSignedIntegral:507 case CK_IntegralToBoolean:508 case CK_IntegralToFloating:509 case CK_FloatingToIntegral:510 case CK_FloatingToBoolean:511 case CK_FloatingCast:512 case CK_CPointerToObjCPointerCast:513 case CK_BlockPointerToObjCPointerCast:514 case CK_AnyPointerToBlockPointerCast:515 case CK_ObjCObjectLValueCast:516 case CK_FloatingComplexToReal:517 case CK_FloatingComplexToBoolean:518 case CK_IntegralComplexToReal:519 case CK_IntegralComplexToBoolean:520 case CK_ARCProduceObject:521 case CK_ARCConsumeObject:522 case CK_ARCReclaimReturnedObject:523 case CK_ARCExtendBlockObject:524 case CK_CopyAndAutoreleaseBlockObject:525 case CK_BuiltinFnToFnPtr:526 case CK_ZeroToOCLOpaqueType:527 case CK_AddressSpaceConversion:528 case CK_IntToOCLSampler:529 case CK_FloatingToFixedPoint:530 case CK_FixedPointToFloating:531 case CK_FixedPointCast:532 case CK_FixedPointToBoolean:533 case CK_FixedPointToIntegral:534 case CK_IntegralToFixedPoint:535 case CK_MatrixCast:536 case CK_HLSLVectorTruncation:537 case CK_HLSLArrayRValue:538 case CK_HLSLElementwiseCast:539 case CK_HLSLAggregateSplatCast:540 llvm_unreachable("invalid cast kind for complex value");541 542 case CK_FloatingRealToComplex:543 case CK_IntegralRealToComplex: {544 assert(!cir::MissingFeatures::cgFPOptionsRAII());545 return emitScalarToComplexCast(cgf.emitScalarExpr(op), op->getType(),546 destTy, op->getExprLoc());547 }548 549 case CK_FloatingComplexCast:550 case CK_FloatingComplexToIntegralComplex:551 case CK_IntegralComplexCast:552 case CK_IntegralComplexToFloatingComplex: {553 assert(!cir::MissingFeatures::cgFPOptionsRAII());554 return emitComplexToComplexCast(Visit(op), op->getType(), destTy,555 op->getExprLoc());556 }557 }558 559 llvm_unreachable("unknown cast resulting in complex value");560}561 562mlir::Value ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *e) {563 QualType promotionTy = getPromotionType(e->getSubExpr()->getType());564 mlir::Value result = VisitPlusMinus(e, cir::UnaryOpKind::Plus, promotionTy);565 if (!promotionTy.isNull())566 return cgf.emitUnPromotedValue(result, e->getSubExpr()->getType());567 return result;568}569 570mlir::Value ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *e) {571 QualType promotionTy = getPromotionType(e->getSubExpr()->getType());572 mlir::Value result = VisitPlusMinus(e, cir::UnaryOpKind::Minus, promotionTy);573 if (!promotionTy.isNull())574 return cgf.emitUnPromotedValue(result, e->getSubExpr()->getType());575 return result;576}577 578mlir::Value ComplexExprEmitter::VisitPlusMinus(const UnaryOperator *e,579 cir::UnaryOpKind kind,580 QualType promotionType) {581 assert(kind == cir::UnaryOpKind::Plus ||582 kind == cir::UnaryOpKind::Minus &&583 "Invalid UnaryOp kind for ComplexType Plus or Minus");584 585 mlir::Value op;586 if (!promotionType.isNull())587 op = cgf.emitPromotedComplexExpr(e->getSubExpr(), promotionType);588 else589 op = Visit(e->getSubExpr());590 return builder.createUnaryOp(cgf.getLoc(e->getExprLoc()), kind, op);591}592 593mlir::Value ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *e) {594 mlir::Value op = Visit(e->getSubExpr());595 return builder.createNot(op);596}597 598mlir::Value ComplexExprEmitter::emitBinAdd(const BinOpInfo &op) {599 assert(!cir::MissingFeatures::fastMathFlags());600 assert(!cir::MissingFeatures::cgFPOptionsRAII());601 602 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&603 mlir::isa<cir::ComplexType>(op.rhs.getType()))604 return cir::ComplexAddOp::create(builder, op.loc, op.lhs, op.rhs);605 606 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {607 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);608 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);609 mlir::Value newReal = builder.createAdd(op.loc, real, op.rhs);610 return builder.createComplexCreate(op.loc, newReal, imag);611 }612 613 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));614 mlir::Value real = builder.createComplexReal(op.loc, op.rhs);615 mlir::Value imag = builder.createComplexImag(op.loc, op.rhs);616 mlir::Value newReal = builder.createAdd(op.loc, op.lhs, real);617 return builder.createComplexCreate(op.loc, newReal, imag);618}619 620mlir::Value ComplexExprEmitter::emitBinSub(const BinOpInfo &op) {621 assert(!cir::MissingFeatures::fastMathFlags());622 assert(!cir::MissingFeatures::cgFPOptionsRAII());623 624 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&625 mlir::isa<cir::ComplexType>(op.rhs.getType()))626 return cir::ComplexSubOp::create(builder, op.loc, op.lhs, op.rhs);627 628 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {629 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);630 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);631 mlir::Value newReal = builder.createSub(op.loc, real, op.rhs);632 return builder.createComplexCreate(op.loc, newReal, imag);633 }634 635 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));636 mlir::Value real = builder.createComplexReal(op.loc, op.rhs);637 mlir::Value imag = builder.createComplexImag(op.loc, op.rhs);638 mlir::Value newReal = builder.createSub(op.loc, op.lhs, real);639 return builder.createComplexCreate(op.loc, newReal, imag);640}641 642static cir::ComplexRangeKind643getComplexRangeAttr(LangOptions::ComplexRangeKind range) {644 switch (range) {645 case LangOptions::CX_Full:646 return cir::ComplexRangeKind::Full;647 case LangOptions::CX_Improved:648 return cir::ComplexRangeKind::Improved;649 case LangOptions::CX_Promoted:650 return cir::ComplexRangeKind::Promoted;651 case LangOptions::CX_Basic:652 return cir::ComplexRangeKind::Basic;653 case LangOptions::CX_None:654 // The default value for ComplexRangeKind is Full if no option is selected655 return cir::ComplexRangeKind::Full;656 }657}658 659mlir::Value ComplexExprEmitter::emitBinMul(const BinOpInfo &op) {660 assert(!cir::MissingFeatures::fastMathFlags());661 assert(!cir::MissingFeatures::cgFPOptionsRAII());662 663 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&664 mlir::isa<cir::ComplexType>(op.rhs.getType())) {665 cir::ComplexRangeKind rangeKind =666 getComplexRangeAttr(op.fpFeatures.getComplexRange());667 return cir::ComplexMulOp::create(builder, op.loc, op.lhs, op.rhs,668 rangeKind);669 }670 671 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {672 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);673 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);674 mlir::Value newReal = builder.createMul(op.loc, real, op.rhs);675 mlir::Value newImag = builder.createMul(op.loc, imag, op.rhs);676 return builder.createComplexCreate(op.loc, newReal, newImag);677 }678 679 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));680 mlir::Value real = builder.createComplexReal(op.loc, op.rhs);681 mlir::Value imag = builder.createComplexImag(op.loc, op.rhs);682 mlir::Value newReal = builder.createMul(op.loc, op.lhs, real);683 mlir::Value newImag = builder.createMul(op.loc, op.lhs, imag);684 return builder.createComplexCreate(op.loc, newReal, newImag);685}686 687mlir::Value ComplexExprEmitter::emitBinDiv(const BinOpInfo &op) {688 assert(!cir::MissingFeatures::fastMathFlags());689 assert(!cir::MissingFeatures::cgFPOptionsRAII());690 691 // Handle division between two complex values. In the case of complex integer692 // types mixed with scalar integers, the scalar integer type will always be693 // promoted to a complex integer value with a zero imaginary component when694 // the AST is formed.695 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&696 mlir::isa<cir::ComplexType>(op.rhs.getType())) {697 cir::ComplexRangeKind rangeKind =698 getComplexRangeAttr(op.fpFeatures.getComplexRange());699 return cir::ComplexDivOp::create(builder, op.loc, op.lhs, op.rhs,700 rangeKind);701 }702 703 // The C99 standard (G.5.1) defines division of a complex value by a real704 // value in the following simplified form.705 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {706 assert(mlir::cast<cir::ComplexType>(op.lhs.getType()).getElementType() ==707 op.rhs.getType());708 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);709 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);710 mlir::Value newReal = builder.createFDiv(op.loc, real, op.rhs);711 mlir::Value newImag = builder.createFDiv(op.loc, imag, op.rhs);712 return builder.createComplexCreate(op.loc, newReal, newImag);713 }714 715 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));716 cir::ConstantOp nullValue = builder.getNullValue(op.lhs.getType(), op.loc);717 mlir::Value lhs = builder.createComplexCreate(op.loc, op.lhs, nullValue);718 cir::ComplexRangeKind rangeKind =719 getComplexRangeAttr(op.fpFeatures.getComplexRange());720 return cir::ComplexDivOp::create(builder, op.loc, lhs, op.rhs, rangeKind);721}722 723mlir::Value CIRGenFunction::emitUnPromotedValue(mlir::Value result,724 QualType unPromotionType) {725 assert(!mlir::cast<cir::ComplexType>(result.getType()).isIntegerComplex() &&726 "integral complex will never be promoted");727 return builder.createCast(cir::CastKind::float_complex, result,728 convertType(unPromotionType));729}730 731mlir::Value CIRGenFunction::emitPromotedValue(mlir::Value result,732 QualType promotionType) {733 assert(!mlir::cast<cir::ComplexType>(result.getType()).isIntegerComplex() &&734 "integral complex will never be promoted");735 return builder.createCast(cir::CastKind::float_complex, result,736 convertType(promotionType));737}738 739mlir::Value ComplexExprEmitter::emitPromoted(const Expr *e,740 QualType promotionTy) {741 e = e->IgnoreParens();742 if (const auto *bo = dyn_cast<BinaryOperator>(e)) {743 switch (bo->getOpcode()) {744#define HANDLE_BINOP(OP) \745 case BO_##OP: \746 return emitBin##OP(emitBinOps(bo, promotionTy));747 HANDLE_BINOP(Add)748 HANDLE_BINOP(Sub)749 HANDLE_BINOP(Mul)750 HANDLE_BINOP(Div)751#undef HANDLE_BINOP752 default:753 break;754 }755 } else if (const auto *unaryOp = dyn_cast<UnaryOperator>(e)) {756 switch (unaryOp->getOpcode()) {757 case UO_Minus:758 case UO_Plus: {759 auto kind = unaryOp->getOpcode() == UO_Plus ? cir::UnaryOpKind::Plus760 : cir::UnaryOpKind::Minus;761 return VisitPlusMinus(unaryOp, kind, promotionTy);762 }763 default:764 break;765 }766 }767 768 mlir::Value result = Visit(const_cast<Expr *>(e));769 if (!promotionTy.isNull())770 return cgf.emitPromotedValue(result, promotionTy);771 772 return result;773}774 775mlir::Value CIRGenFunction::emitPromotedComplexExpr(const Expr *e,776 QualType promotionType) {777 return ComplexExprEmitter(*this).emitPromoted(e, promotionType);778}779 780mlir::Value781ComplexExprEmitter::emitPromotedComplexOperand(const Expr *e,782 QualType promotionTy) {783 if (e->getType()->isAnyComplexType()) {784 if (!promotionTy.isNull())785 return cgf.emitPromotedComplexExpr(e, promotionTy);786 return Visit(const_cast<Expr *>(e));787 }788 789 if (!promotionTy.isNull()) {790 QualType complexElementTy =791 promotionTy->castAs<ComplexType>()->getElementType();792 return cgf.emitPromotedScalarExpr(e, complexElementTy);793 }794 return cgf.emitScalarExpr(e);795}796 797ComplexExprEmitter::BinOpInfo798ComplexExprEmitter::emitBinOps(const BinaryOperator *e, QualType promotionTy) {799 BinOpInfo binOpInfo{cgf.getLoc(e->getExprLoc())};800 binOpInfo.lhs = emitPromotedComplexOperand(e->getLHS(), promotionTy);801 binOpInfo.rhs = emitPromotedComplexOperand(e->getRHS(), promotionTy);802 binOpInfo.ty = promotionTy.isNull() ? e->getType() : promotionTy;803 binOpInfo.fpFeatures = e->getFPFeaturesInEffect(cgf.getLangOpts());804 return binOpInfo;805}806 807LValue ComplexExprEmitter::emitCompoundAssignLValue(808 const CompoundAssignOperator *e,809 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &), RValue &value) {810 QualType lhsTy = e->getLHS()->getType();811 QualType rhsTy = e->getRHS()->getType();812 SourceLocation exprLoc = e->getExprLoc();813 mlir::Location loc = cgf.getLoc(exprLoc);814 815 if (lhsTy->getAs<AtomicType>()) {816 cgf.cgm.errorNYI("emitCompoundAssignLValue AtmoicType");817 return {};818 }819 820 BinOpInfo opInfo{loc};821 opInfo.fpFeatures = e->getFPFeaturesInEffect(cgf.getLangOpts());822 823 assert(!cir::MissingFeatures::cgFPOptionsRAII());824 825 // Load the RHS and LHS operands.826 // __block variables need to have the rhs evaluated first, plus this should827 // improve codegen a little.828 QualType promotionTypeCR = getPromotionType(e->getComputationResultType());829 opInfo.ty = promotionTypeCR.isNull() ? e->getComputationResultType()830 : promotionTypeCR;831 832 QualType complexElementTy =833 opInfo.ty->castAs<ComplexType>()->getElementType();834 QualType promotionTypeRHS = getPromotionType(rhsTy);835 836 // The RHS should have been converted to the computation type.837 if (e->getRHS()->getType()->isRealFloatingType()) {838 if (!promotionTypeRHS.isNull()) {839 opInfo.rhs = cgf.emitPromotedScalarExpr(e->getRHS(), promotionTypeRHS);840 } else {841 assert(cgf.getContext().hasSameUnqualifiedType(complexElementTy, rhsTy));842 opInfo.rhs = cgf.emitScalarExpr(e->getRHS());843 }844 } else {845 if (!promotionTypeRHS.isNull()) {846 opInfo.rhs = cgf.emitPromotedComplexExpr(e->getRHS(), promotionTypeRHS);847 } else {848 assert(cgf.getContext().hasSameUnqualifiedType(opInfo.ty, rhsTy));849 opInfo.rhs = Visit(e->getRHS());850 }851 }852 853 LValue lhs = cgf.emitLValue(e->getLHS());854 855 // Load from the l-value and convert it.856 QualType promotionTypeLHS = getPromotionType(e->getComputationLHSType());857 if (lhsTy->isAnyComplexType()) {858 mlir::Value lhsValue = emitLoadOfLValue(lhs, exprLoc);859 QualType destTy = promotionTypeLHS.isNull() ? opInfo.ty : promotionTypeLHS;860 opInfo.lhs = emitComplexToComplexCast(lhsValue, lhsTy, destTy, exprLoc);861 } else {862 mlir::Value lhsVal = cgf.emitLoadOfScalar(lhs, exprLoc);863 // For floating point real operands we can directly pass the scalar form864 // to the binary operator emission and potentially get more efficient code.865 if (lhsTy->isRealFloatingType()) {866 QualType promotedComplexElementTy;867 if (!promotionTypeLHS.isNull()) {868 promotedComplexElementTy =869 cast<ComplexType>(promotionTypeLHS)->getElementType();870 if (!cgf.getContext().hasSameUnqualifiedType(promotedComplexElementTy,871 promotionTypeLHS))872 lhsVal = cgf.emitScalarConversion(lhsVal, lhsTy,873 promotedComplexElementTy, exprLoc);874 } else {875 if (!cgf.getContext().hasSameUnqualifiedType(complexElementTy, lhsTy))876 lhsVal = cgf.emitScalarConversion(lhsVal, lhsTy, complexElementTy,877 exprLoc);878 }879 opInfo.lhs = lhsVal;880 } else {881 opInfo.lhs = emitScalarToComplexCast(lhsVal, lhsTy, opInfo.ty, exprLoc);882 }883 }884 885 // Expand the binary operator.886 mlir::Value result = (this->*func)(opInfo);887 888 // Truncate the result and store it into the LHS lvalue.889 if (lhsTy->isAnyComplexType()) {890 mlir::Value resultValue =891 emitComplexToComplexCast(result, opInfo.ty, lhsTy, exprLoc);892 emitStoreOfComplex(loc, resultValue, lhs, /*isInit*/ false);893 value = RValue::getComplex(resultValue);894 } else {895 mlir::Value resultValue =896 cgf.emitComplexToScalarConversion(result, opInfo.ty, lhsTy, exprLoc);897 cgf.emitStoreOfScalar(resultValue, lhs, /*isInit*/ false);898 value = RValue::get(resultValue);899 }900 901 return lhs;902}903 904mlir::Value ComplexExprEmitter::emitCompoundAssign(905 const CompoundAssignOperator *e,906 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &)) {907 RValue val;908 LValue lv = emitCompoundAssignLValue(e, func, val);909 910 // The result of an assignment in C is the assigned r-value.911 if (!cgf.getLangOpts().CPlusPlus)912 return val.getComplexValue();913 914 // If the lvalue is non-volatile, return the computed value of the assignment.915 if (!lv.isVolatileQualified())916 return val.getComplexValue();917 918 return emitLoadOfLValue(lv, e->getExprLoc());919}920 921LValue ComplexExprEmitter::emitBinAssignLValue(const BinaryOperator *e,922 mlir::Value &value) {923 assert(cgf.getContext().hasSameUnqualifiedType(e->getLHS()->getType(),924 e->getRHS()->getType()) &&925 "Invalid assignment");926 927 // Emit the RHS. __block variables need the RHS evaluated first.928 value = Visit(e->getRHS());929 930 // Compute the address to store into.931 LValue lhs = cgf.emitLValue(e->getLHS());932 933 // Store the result value into the LHS lvalue.934 emitStoreOfComplex(cgf.getLoc(e->getExprLoc()), value, lhs,935 /*isInit*/ false);936 return lhs;937}938 939mlir::Value ComplexExprEmitter::VisitBinAssign(const BinaryOperator *e) {940 mlir::Value value;941 LValue lv = emitBinAssignLValue(e, value);942 943 // The result of an assignment in C is the assigned r-value.944 if (!cgf.getLangOpts().CPlusPlus)945 return value;946 947 // If the lvalue is non-volatile, return the computed value of the948 // assignment.949 if (!lv.isVolatile())950 return value;951 952 return emitLoadOfLValue(lv, e->getExprLoc());953}954 955mlir::Value ComplexExprEmitter::VisitBinComma(const BinaryOperator *e) {956 cgf.emitIgnoredExpr(e->getLHS());957 return Visit(e->getRHS());958}959 960mlir::Value ComplexExprEmitter::VisitAbstractConditionalOperator(961 const AbstractConditionalOperator *e) {962 mlir::Location loc = cgf.getLoc(e->getSourceRange());963 964 // Bind the common expression if necessary.965 CIRGenFunction::OpaqueValueMapping binding(cgf, e);966 967 CIRGenFunction::ConditionalEvaluation eval(cgf);968 969 Expr *cond = e->getCond()->IgnoreParens();970 mlir::Value condValue = cgf.evaluateExprAsBool(cond);971 972 return cir::TernaryOp::create(973 builder, loc, condValue,974 /*thenBuilder=*/975 [&](mlir::OpBuilder &b, mlir::Location loc) {976 eval.beginEvaluation();977 mlir::Value trueValue = Visit(e->getTrueExpr());978 cir::YieldOp::create(b, loc, trueValue);979 eval.endEvaluation();980 },981 /*elseBuilder=*/982 [&](mlir::OpBuilder &b, mlir::Location loc) {983 eval.beginEvaluation();984 mlir::Value falseValue = Visit(e->getFalseExpr());985 cir::YieldOp::create(b, loc, falseValue);986 eval.endEvaluation();987 })988 .getResult();989}990 991mlir::Value ComplexExprEmitter::VisitChooseExpr(ChooseExpr *e) {992 return Visit(e->getChosenSubExpr());993}994 995mlir::Value ComplexExprEmitter::VisitInitListExpr(InitListExpr *e) {996 mlir::Location loc = cgf.getLoc(e->getExprLoc());997 if (e->getNumInits() == 2) {998 mlir::Value real = cgf.emitScalarExpr(e->getInit(0));999 mlir::Value imag = cgf.emitScalarExpr(e->getInit(1));1000 return builder.createComplexCreate(loc, real, imag);1001 }1002 1003 if (e->getNumInits() == 1)1004 return Visit(e->getInit(0));1005 1006 assert(e->getNumInits() == 0 && "Unexpected number of inits");1007 mlir::Type complexTy = cgf.convertType(e->getType());1008 return builder.getNullValue(complexTy, loc);1009}1010 1011mlir::Value ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *e) {1012 return cgf.emitVAArg(e);1013}1014 1015//===----------------------------------------------------------------------===//1016// Entry Point into this File1017//===----------------------------------------------------------------------===//1018 1019/// EmitComplexExpr - Emit the computation of the specified expression of1020/// complex type, ignoring the result.1021mlir::Value CIRGenFunction::emitComplexExpr(const Expr *e) {1022 assert(e && getComplexType(e->getType()) &&1023 "Invalid complex expression to emit");1024 1025 return ComplexExprEmitter(*this).Visit(const_cast<Expr *>(e));1026}1027 1028void CIRGenFunction::emitComplexExprIntoLValue(const Expr *e, LValue dest,1029 bool isInit) {1030 assert(e && getComplexType(e->getType()) &&1031 "Invalid complex expression to emit");1032 ComplexExprEmitter emitter(*this);1033 mlir::Value value = emitter.Visit(const_cast<Expr *>(e));1034 emitter.emitStoreOfComplex(getLoc(e->getExprLoc()), value, dest, isInit);1035}1036 1037/// EmitStoreOfComplex - Store a complex number into the specified l-value.1038void CIRGenFunction::emitStoreOfComplex(mlir::Location loc, mlir::Value v,1039 LValue dest, bool isInit) {1040 ComplexExprEmitter(*this).emitStoreOfComplex(loc, v, dest, isInit);1041}1042 1043mlir::Value CIRGenFunction::emitLoadOfComplex(LValue src, SourceLocation loc) {1044 return ComplexExprEmitter(*this).emitLoadOfLValue(src, loc);1045}1046 1047LValue CIRGenFunction::emitComplexAssignmentLValue(const BinaryOperator *e) {1048 assert(e->getOpcode() == BO_Assign && "Expected assign op");1049 1050 mlir::Value value; // ignored1051 LValue lvalue = ComplexExprEmitter(*this).emitBinAssignLValue(e, value);1052 if (getLangOpts().OpenMP)1053 cgm.errorNYI("emitComplexAssignmentLValue OpenMP");1054 1055 return lvalue;1056}1057 1058using CompoundFunc =1059 mlir::Value (ComplexExprEmitter::*)(const ComplexExprEmitter::BinOpInfo &);1060 1061static CompoundFunc getComplexOp(BinaryOperatorKind op) {1062 switch (op) {1063 case BO_MulAssign:1064 return &ComplexExprEmitter::emitBinMul;1065 case BO_DivAssign:1066 return &ComplexExprEmitter::emitBinDiv;1067 case BO_SubAssign:1068 return &ComplexExprEmitter::emitBinSub;1069 case BO_AddAssign:1070 return &ComplexExprEmitter::emitBinAdd;1071 default:1072 llvm_unreachable("unexpected complex compound assignment");1073 }1074}1075 1076LValue CIRGenFunction::emitComplexCompoundAssignmentLValue(1077 const CompoundAssignOperator *e) {1078 CompoundFunc op = getComplexOp(e->getOpcode());1079 RValue val;1080 return ComplexExprEmitter(*this).emitCompoundAssignLValue(e, op, val);1081}1082 1083mlir::Value CIRGenFunction::emitComplexPrePostIncDec(const UnaryOperator *e,1084 LValue lv,1085 cir::UnaryOpKind op,1086 bool isPre) {1087 assert(op == cir::UnaryOpKind::Inc ||1088 op == cir::UnaryOpKind::Dec && "Invalid UnaryOp kind for ComplexType");1089 1090 mlir::Value inVal = emitLoadOfComplex(lv, e->getExprLoc());1091 mlir::Location loc = getLoc(e->getExprLoc());1092 mlir::Value incVal = builder.createUnaryOp(loc, op, inVal);1093 1094 // Store the updated result through the lvalue.1095 emitStoreOfComplex(loc, incVal, lv, /*isInit=*/false);1096 1097 if (getLangOpts().OpenMP)1098 cgm.errorNYI(loc, "emitComplexPrePostIncDec OpenMP");1099 1100 // If this is a postinc, return the value read from memory, otherwise use the1101 // updated value.1102 return isPre ? incVal : inVal;1103}1104 1105LValue CIRGenFunction::emitScalarCompoundAssignWithComplex(1106 const CompoundAssignOperator *e, mlir::Value &result) {1107 // Key Instructions: Don't need to create an atom group here; one will already1108 // be active through scalar handling code.1109 CompoundFunc op = getComplexOp(e->getOpcode());1110 RValue value;1111 LValue ret = ComplexExprEmitter(*this).emitCompoundAssignLValue(e, op, value);1112 result = value.getValue();1113 return ret;1114}1115