1 #include "CIRGenBuilder.h" 2 #include "CIRGenFunction.h" 3 4 #include "clang/AST/StmtVisitor.h" 5 6 using namespace clang; 7 using namespace clang::CIRGen; 8 9 namespace { 10 class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> { 11 CIRGenFunction &cgf; 12 CIRGenBuilderTy &builder; 13 14 public: 15 explicit ComplexExprEmitter(CIRGenFunction &cgf) 16 : cgf(cgf), builder(cgf.getBuilder()) {} 17 18 //===--------------------------------------------------------------------===// 19 // Utilities 20 //===--------------------------------------------------------------------===// 21 22 LValue emitBinAssignLValue(const BinaryOperator *e, mlir::Value &val); 23 24 mlir::Value emitCast(CastKind ck, Expr *op, QualType destTy); 25 26 mlir::Value emitConstant(const CIRGenFunction::ConstantEmission &constant, 27 Expr *e); 28 29 /// Given an expression with complex type that represents a value l-value, 30 /// this method emits the address of the l-value, then loads and returns the 31 /// result. 32 mlir::Value emitLoadOfLValue(const Expr *e) { 33 return emitLoadOfLValue(cgf.emitLValue(e), e->getExprLoc()); 34 } 35 36 mlir::Value emitLoadOfLValue(LValue lv, SourceLocation loc); 37 /// Store the specified real/imag parts into the 38 /// specified value pointer. 39 void emitStoreOfComplex(mlir::Location loc, mlir::Value val, LValue lv, 40 bool isInit); 41 42 mlir::Value 43 VisitAbstractConditionalOperator(const AbstractConditionalOperator *e); 44 mlir::Value VisitArraySubscriptExpr(Expr *e); 45 mlir::Value VisitBinAssign(const BinaryOperator *e); 46 mlir::Value VisitBinComma(const BinaryOperator *e); 47 mlir::Value VisitCallExpr(const CallExpr *e); 48 mlir::Value VisitCastExpr(CastExpr *e); 49 mlir::Value VisitChooseExpr(ChooseExpr *e); 50 mlir::Value VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e); 51 mlir::Value VisitDeclRefExpr(DeclRefExpr *e); 52 mlir::Value VisitGenericSelectionExpr(GenericSelectionExpr *e); 53 mlir::Value VisitImplicitCastExpr(ImplicitCastExpr *e); 54 mlir::Value VisitInitListExpr(const InitListExpr *e); 55 mlir::Value VisitImaginaryLiteral(const ImaginaryLiteral *il); 56 mlir::Value VisitParenExpr(ParenExpr *e); 57 mlir::Value 58 VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e); 59 mlir::Value VisitUnaryDeref(const Expr *e); 60 61 struct BinOpInfo { 62 mlir::Location loc; 63 mlir::Value lhs{}; 64 mlir::Value rhs{}; 65 QualType ty{}; // Computation Type. 66 FPOptions fpFeatures{}; 67 }; 68 69 BinOpInfo emitBinOps(const BinaryOperator *e, 70 QualType promotionTy = QualType()); 71 72 mlir::Value emitPromoted(const Expr *e, QualType promotionTy); 73 74 mlir::Value emitPromotedComplexOperand(const Expr *e, QualType promotionTy); 75 76 mlir::Value emitBinAdd(const BinOpInfo &op); 77 mlir::Value emitBinSub(const BinOpInfo &op); 78 79 QualType getPromotionType(QualType ty, bool isDivOpCode = false) { 80 if (auto *complexTy = ty->getAs<ComplexType>()) { 81 QualType elementTy = complexTy->getElementType(); 82 if (isDivOpCode && elementTy->isFloatingType() && 83 cgf.getLangOpts().getComplexRange() == 84 LangOptions::ComplexRangeKind::CX_Promoted) { 85 cgf.cgm.errorNYI("HigherPrecisionTypeForComplexArithmetic"); 86 return QualType(); 87 } 88 89 if (elementTy.UseExcessPrecision(cgf.getContext())) 90 return cgf.getContext().getComplexType(cgf.getContext().FloatTy); 91 } 92 93 if (ty.UseExcessPrecision(cgf.getContext())) 94 return cgf.getContext().FloatTy; 95 return QualType(); 96 } 97 98 #define HANDLEBINOP(OP) \ 99 mlir::Value VisitBin##OP(const BinaryOperator *e) { \ 100 QualType promotionTy = getPromotionType( \ 101 e->getType(), e->getOpcode() == BinaryOperatorKind::BO_Div); \ 102 mlir::Value result = emitBin##OP(emitBinOps(e, promotionTy)); \ 103 if (!promotionTy.isNull()) \ 104 cgf.cgm.errorNYI("Binop emitUnPromotedValue"); \ 105 return result; \ 106 } 107 108 HANDLEBINOP(Add) 109 HANDLEBINOP(Sub) 110 #undef HANDLEBINOP 111 }; 112 } // namespace 113 114 static const ComplexType *getComplexType(QualType type) { 115 type = type.getCanonicalType(); 116 if (const ComplexType *comp = dyn_cast<ComplexType>(type)) 117 return comp; 118 return cast<ComplexType>(cast<AtomicType>(type)->getValueType()); 119 } 120 121 LValue ComplexExprEmitter::emitBinAssignLValue(const BinaryOperator *e, 122 mlir::Value &value) { 123 assert(cgf.getContext().hasSameUnqualifiedType(e->getLHS()->getType(), 124 e->getRHS()->getType()) && 125 "Invalid assignment"); 126 127 // Emit the RHS. __block variables need the RHS evaluated first. 128 value = Visit(e->getRHS()); 129 130 // Compute the address to store into. 131 LValue lhs = cgf.emitLValue(e->getLHS()); 132 133 // Store the result value into the LHS lvalue. 134 emitStoreOfComplex(cgf.getLoc(e->getExprLoc()), value, lhs, /*isInit*/ false); 135 return lhs; 136 } 137 138 mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op, 139 QualType destTy) { 140 switch (ck) { 141 case CK_NoOp: 142 case CK_LValueToRValue: 143 return Visit(op); 144 default: 145 break; 146 } 147 cgf.cgm.errorNYI("ComplexType Cast"); 148 return {}; 149 } 150 151 mlir::Value ComplexExprEmitter::emitConstant( 152 const CIRGenFunction::ConstantEmission &constant, Expr *e) { 153 assert(constant && "not a constant"); 154 if (constant.isReference()) 155 return emitLoadOfLValue(constant.getReferenceLValue(cgf, e), 156 e->getExprLoc()); 157 158 mlir::TypedAttr valueAttr = constant.getValue(); 159 return builder.getConstant(cgf.getLoc(e->getSourceRange()), valueAttr); 160 } 161 162 mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv, 163 SourceLocation loc) { 164 assert(lv.isSimple() && "non-simple complex l-value?"); 165 if (lv.getType()->isAtomicType()) 166 cgf.cgm.errorNYI(loc, "emitLoadOfLValue with Atomic LV"); 167 168 const Address srcAddr = lv.getAddress(); 169 return builder.createLoad(cgf.getLoc(loc), srcAddr); 170 } 171 172 void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val, 173 LValue lv, bool isInit) { 174 if (lv.getType()->isAtomicType() || 175 (!isInit && cgf.isLValueSuitableForInlineAtomic(lv))) { 176 cgf.cgm.errorNYI(loc, "StoreOfComplex with Atomic LV"); 177 return; 178 } 179 180 const Address destAddr = lv.getAddress(); 181 builder.createStore(loc, val, destAddr); 182 } 183 184 mlir::Value ComplexExprEmitter::VisitAbstractConditionalOperator( 185 const AbstractConditionalOperator *e) { 186 mlir::Value condValue = Visit(e->getCond()); 187 mlir::Location loc = cgf.getLoc(e->getSourceRange()); 188 189 return builder 190 .create<cir::TernaryOp>( 191 loc, condValue, 192 /*thenBuilder=*/ 193 [&](mlir::OpBuilder &b, mlir::Location loc) { 194 mlir::Value trueValue = Visit(e->getTrueExpr()); 195 b.create<cir::YieldOp>(loc, trueValue); 196 }, 197 /*elseBuilder=*/ 198 [&](mlir::OpBuilder &b, mlir::Location loc) { 199 mlir::Value falseValue = Visit(e->getFalseExpr()); 200 b.create<cir::YieldOp>(loc, falseValue); 201 }) 202 .getResult(); 203 } 204 205 mlir::Value ComplexExprEmitter::VisitArraySubscriptExpr(Expr *e) { 206 return emitLoadOfLValue(e); 207 } 208 209 mlir::Value ComplexExprEmitter::VisitBinAssign(const BinaryOperator *e) { 210 mlir::Value value; 211 LValue lv = emitBinAssignLValue(e, value); 212 213 // The result of an assignment in C is the assigned r-value. 214 if (!cgf.getLangOpts().CPlusPlus) 215 return value; 216 217 // If the lvalue is non-volatile, return the computed value of the 218 // assignment. 219 if (!lv.isVolatile()) 220 return value; 221 222 return emitLoadOfLValue(lv, e->getExprLoc()); 223 } 224 225 mlir::Value ComplexExprEmitter::VisitBinComma(const BinaryOperator *e) { 226 cgf.emitIgnoredExpr(e->getLHS()); 227 return Visit(e->getRHS()); 228 } 229 230 mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr *e) { 231 if (e->getCallReturnType(cgf.getContext())->isReferenceType()) 232 return emitLoadOfLValue(e); 233 234 return cgf.emitCallExpr(e).getValue(); 235 } 236 237 mlir::Value ComplexExprEmitter::VisitCastExpr(CastExpr *e) { 238 if (const auto *ece = dyn_cast<ExplicitCastExpr>(e)) { 239 // Bind VLAs in the cast type. 240 if (ece->getType()->isVariablyModifiedType()) { 241 cgf.cgm.errorNYI("VisitCastExpr Bind VLAs in the cast type"); 242 return {}; 243 } 244 } 245 246 if (e->changesVolatileQualification()) 247 return emitLoadOfLValue(e); 248 249 return emitCast(e->getCastKind(), e->getSubExpr(), e->getType()); 250 } 251 252 mlir::Value ComplexExprEmitter::VisitChooseExpr(ChooseExpr *e) { 253 return Visit(e->getChosenSubExpr()); 254 } 255 256 mlir::Value 257 ComplexExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e) { 258 mlir::Location loc = cgf.getLoc(e->getExprLoc()); 259 mlir::Type complexTy = cgf.convertType(e->getType()); 260 return builder.getNullValue(complexTy, loc); 261 } 262 263 mlir::Value ComplexExprEmitter::VisitDeclRefExpr(DeclRefExpr *e) { 264 if (CIRGenFunction::ConstantEmission constant = cgf.tryEmitAsConstant(e)) 265 return emitConstant(constant, e); 266 return emitLoadOfLValue(e); 267 } 268 269 mlir::Value 270 ComplexExprEmitter::VisitGenericSelectionExpr(GenericSelectionExpr *e) { 271 return Visit(e->getResultExpr()); 272 } 273 274 mlir::Value ComplexExprEmitter::VisitImplicitCastExpr(ImplicitCastExpr *e) { 275 // Unlike for scalars, we don't have to worry about function->ptr demotion 276 // here. 277 if (e->changesVolatileQualification()) 278 return emitLoadOfLValue(e); 279 return emitCast(e->getCastKind(), e->getSubExpr(), e->getType()); 280 } 281 282 mlir::Value ComplexExprEmitter::VisitInitListExpr(const InitListExpr *e) { 283 mlir::Location loc = cgf.getLoc(e->getExprLoc()); 284 if (e->getNumInits() == 2) { 285 mlir::Value real = cgf.emitScalarExpr(e->getInit(0)); 286 mlir::Value imag = cgf.emitScalarExpr(e->getInit(1)); 287 return builder.createComplexCreate(loc, real, imag); 288 } 289 290 if (e->getNumInits() == 1) { 291 cgf.cgm.errorNYI("Create Complex with InitList with size 1"); 292 return {}; 293 } 294 295 assert(e->getNumInits() == 0 && "Unexpected number of inits"); 296 mlir::Type complexTy = cgf.convertType(e->getType()); 297 return builder.getNullValue(complexTy, loc); 298 } 299 300 mlir::Value 301 ComplexExprEmitter::VisitImaginaryLiteral(const ImaginaryLiteral *il) { 302 auto ty = mlir::cast<cir::ComplexType>(cgf.convertType(il->getType())); 303 mlir::Type elementTy = ty.getElementType(); 304 mlir::Location loc = cgf.getLoc(il->getExprLoc()); 305 306 mlir::TypedAttr realValueAttr; 307 mlir::TypedAttr imagValueAttr; 308 309 if (mlir::isa<cir::IntType>(elementTy)) { 310 llvm::APInt imagValue = cast<IntegerLiteral>(il->getSubExpr())->getValue(); 311 realValueAttr = cir::IntAttr::get(elementTy, 0); 312 imagValueAttr = cir::IntAttr::get(elementTy, imagValue); 313 } else { 314 assert(mlir::isa<cir::FPTypeInterface>(elementTy) && 315 "Expected complex element type to be floating-point"); 316 317 llvm::APFloat imagValue = 318 cast<FloatingLiteral>(il->getSubExpr())->getValue(); 319 realValueAttr = cir::FPAttr::get( 320 elementTy, llvm::APFloat::getZero(imagValue.getSemantics())); 321 imagValueAttr = cir::FPAttr::get(elementTy, imagValue); 322 } 323 324 auto complexAttr = cir::ConstComplexAttr::get(realValueAttr, imagValueAttr); 325 return builder.create<cir::ConstantOp>(loc, complexAttr); 326 } 327 328 mlir::Value ComplexExprEmitter::VisitParenExpr(ParenExpr *e) { 329 return Visit(e->getSubExpr()); 330 } 331 332 mlir::Value ComplexExprEmitter::VisitSubstNonTypeTemplateParmExpr( 333 SubstNonTypeTemplateParmExpr *e) { 334 return Visit(e->getReplacement()); 335 } 336 337 mlir::Value ComplexExprEmitter::VisitUnaryDeref(const Expr *e) { 338 return emitLoadOfLValue(e); 339 } 340 341 mlir::Value ComplexExprEmitter::emitPromoted(const Expr *e, 342 QualType promotionTy) { 343 e = e->IgnoreParens(); 344 if (const auto *bo = dyn_cast<BinaryOperator>(e)) { 345 switch (bo->getOpcode()) { 346 #define HANDLE_BINOP(OP) \ 347 case BO_##OP: \ 348 return emitBin##OP(emitBinOps(bo, promotionTy)); 349 HANDLE_BINOP(Add) 350 HANDLE_BINOP(Sub) 351 #undef HANDLE_BINOP 352 default: 353 break; 354 } 355 } else if (isa<UnaryOperator>(e)) { 356 cgf.cgm.errorNYI("emitPromoted UnaryOperator"); 357 return {}; 358 } 359 360 mlir::Value result = Visit(const_cast<Expr *>(e)); 361 if (!promotionTy.isNull()) 362 cgf.cgm.errorNYI("emitPromoted emitPromotedValue"); 363 364 return result; 365 } 366 367 mlir::Value 368 ComplexExprEmitter::emitPromotedComplexOperand(const Expr *e, 369 QualType promotionTy) { 370 if (e->getType()->isAnyComplexType()) { 371 if (!promotionTy.isNull()) 372 return cgf.emitPromotedComplexExpr(e, promotionTy); 373 return Visit(const_cast<Expr *>(e)); 374 } 375 376 cgf.cgm.errorNYI("emitPromotedComplexOperand non-complex type"); 377 return {}; 378 } 379 380 ComplexExprEmitter::BinOpInfo 381 ComplexExprEmitter::emitBinOps(const BinaryOperator *e, QualType promotionTy) { 382 BinOpInfo binOpInfo{cgf.getLoc(e->getExprLoc())}; 383 binOpInfo.lhs = emitPromotedComplexOperand(e->getLHS(), promotionTy); 384 binOpInfo.rhs = emitPromotedComplexOperand(e->getRHS(), promotionTy); 385 binOpInfo.ty = promotionTy.isNull() ? e->getType() : promotionTy; 386 binOpInfo.fpFeatures = e->getFPFeaturesInEffect(cgf.getLangOpts()); 387 return binOpInfo; 388 } 389 390 mlir::Value ComplexExprEmitter::emitBinAdd(const BinOpInfo &op) { 391 assert(!cir::MissingFeatures::fastMathFlags()); 392 assert(!cir::MissingFeatures::cgFPOptionsRAII()); 393 return builder.create<cir::ComplexAddOp>(op.loc, op.lhs, op.rhs); 394 } 395 396 mlir::Value ComplexExprEmitter::emitBinSub(const BinOpInfo &op) { 397 assert(!cir::MissingFeatures::fastMathFlags()); 398 assert(!cir::MissingFeatures::cgFPOptionsRAII()); 399 return builder.create<cir::ComplexSubOp>(op.loc, op.lhs, op.rhs); 400 } 401 402 LValue CIRGenFunction::emitComplexAssignmentLValue(const BinaryOperator *e) { 403 assert(e->getOpcode() == BO_Assign && "Expected assign op"); 404 405 mlir::Value value; // ignored 406 LValue lvalue = ComplexExprEmitter(*this).emitBinAssignLValue(e, value); 407 if (getLangOpts().OpenMP) 408 cgm.errorNYI("emitComplexAssignmentLValue OpenMP"); 409 410 return lvalue; 411 } 412 413 mlir::Value CIRGenFunction::emitComplexExpr(const Expr *e) { 414 assert(e && getComplexType(e->getType()) && 415 "Invalid complex expression to emit"); 416 417 return ComplexExprEmitter(*this).Visit(const_cast<Expr *>(e)); 418 } 419 420 void CIRGenFunction::emitStoreOfComplex(mlir::Location loc, mlir::Value v, 421 LValue dest, bool isInit) { 422 ComplexExprEmitter(*this).emitStoreOfComplex(loc, v, dest, isInit); 423 } 424 425 mlir::Value CIRGenFunction::emitPromotedComplexExpr(const Expr *e, 426 QualType promotionType) { 427 return ComplexExprEmitter(*this).emitPromoted(e, promotionType); 428 } 429