brintos

brintos / llvm-project-archived public Read only

0
0
Text · 41.4 KiB · 9ed9200 Raw
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