clang: lib/CodeGen/CGExprComplex.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

19#include "llvm/IR/Constants.h"

20#include "llvm/IR/Instructions.h"

21#include "llvm/IR/MDBuilder.h"

22#include "llvm/IR/Metadata.h"

23using namespace clang;

25

26

27

28

29

30namespace llvm {

32}

33

35

36

38 type = type.getCanonicalType();

39 if (const ComplexType *comp = dyn_cast(type)) {

40 return comp;

41 } else {

43 }

44}

45

46namespace {

47class ComplexExprEmitter

48 : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {

49 CodeGenFunction &CGF;

50 CGBuilderTy &Builder;

51 bool IgnoreReal;

52 bool IgnoreImag;

53 bool FPHasBeenPromoted;

54

55public:

56 ComplexExprEmitter(CodeGenFunction &cgf, bool ir = false, bool ii = false)

57 : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii),

58 FPHasBeenPromoted(false) {}

59

60

61

62

63

64 bool TestAndClearIgnoreReal() {

65 bool I = IgnoreReal;

66 IgnoreReal = false;

67 return I;

68 }

69 bool TestAndClearIgnoreImag() {

70 bool I = IgnoreImag;

71 IgnoreImag = false;

72 return I;

73 }

74

75

76

77

80 }

81

82 ComplexPairTy EmitLoadOfLValue(LValue LV, SourceLocation Loc);

83

84

85

86 void EmitStoreOfComplex(ComplexPairTy Val, LValue LV, bool isInit);

87

88

90 QualType DestType, SourceLocation Loc);

91

92 ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType,

93 QualType DestType, SourceLocation Loc);

94

95

96

97

98

100 ApplyDebugLocation DL(CGF, E);

101 return StmtVisitor<ComplexExprEmitter, ComplexPairTy>::Visit(E);

102 }

103

106 llvm_unreachable("Stmt can't have complex result type!");

107 }

109 ComplexPairTy VisitConstantExpr(ConstantExpr *E) {

110 if (llvm::Constant *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E))

112 Result->getAggregateElement(1U));

114 }

116 ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) {

117 return Visit(GE->getResultExpr());

118 }

119 ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL);

121 VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE) {

123 }

126 }

129 }

130 ComplexPairTy VisitUnaryCoawait(const UnaryOperator *E) {

132 }

133

134 ComplexPairTy emitConstant(const CodeGenFunction::ConstantEmission &Constant,

135 Expr *E) {

136 assert(Constant && "not a constant");

140

141 llvm::Constant *pair = Constant.getValue();

142 return ComplexPairTy(pair->getAggregateElement(0U),

143 pair->getAggregateElement(1U));

144 }

145

146

148 if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E))

149 return emitConstant(Constant, E);

150 return EmitLoadOfLValue(E);

151 }

152 ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {

153 return EmitLoadOfLValue(E);

154 }

155 ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) {

157 }

158 ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }

160 if (CodeGenFunction::ConstantEmission Constant =

163 return emitConstant(Constant, ME);

164 }

165 return EmitLoadOfLValue(ME);

166 }

167 ComplexPairTy VisitOpaqueValueExpr(OpaqueValueExpr *E) {

172 }

173

174 ComplexPairTy VisitPseudoObjectExpr(PseudoObjectExpr *E) {

176 }

177

178

179

181 ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) {

182

183

185 return EmitLoadOfLValue(E);

187 }

189 if (const auto *ECE = dyn_cast(E))

192 return EmitLoadOfLValue(E);

194 }

197

198

199 ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E,

200 bool isInc, bool isPre) {

203 }

204 ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) {

205 return VisitPrePostIncDec(E, false, false);

206 }

207 ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) {

208 return VisitPrePostIncDec(E, true, false);

209 }

210 ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) {

211 return VisitPrePostIncDec(E, false, true);

212 }

213 ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) {

214 return VisitPrePostIncDec(E, true, true);

215 }

216 ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }

217

218 ComplexPairTy VisitUnaryPlus(const UnaryOperator *E,

219 QualType PromotionType = QualType());

220 ComplexPairTy VisitPlus(const UnaryOperator *E, QualType PromotionType);

221 ComplexPairTy VisitUnaryMinus(const UnaryOperator *E,

222 QualType PromotionType = QualType());

223 ComplexPairTy VisitMinus(const UnaryOperator *E, QualType PromotionType);

224 ComplexPairTy VisitUnaryNot (const UnaryOperator *E);

225

226 ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) {

228 }

229 ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {

230 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);

231 return Visit(DAE->getExpr());

232 }

233 ComplexPairTy VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {

234 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);

235 return Visit(DIE->getExpr());

236 }

237 ComplexPairTy VisitExprWithCleanups(ExprWithCleanups *E) {

238 CodeGenFunction::RunCleanupsScope Scope(CGF);

240

241

242 Scope.ForceCleanup({&Vals.first, &Vals.second});

243 return Vals;

244 }

245 ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {

247 QualType Elem = E->getType()->castAs()->getElementType();

248 llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));

250 }

251 ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {

253 QualType Elem = E->getType()->castAs()->getElementType();

254 llvm::Constant *Null =

255 llvm::Constant::getNullValue(CGF.ConvertType(Elem));

257 }

258

259 struct BinOpInfo {

262 QualType Ty;

263 FPOptions FPFeatures;

264 };

265

266 BinOpInfo EmitBinOps(const BinaryOperator *E,

267 QualType PromotionTy = QualType());

268 ComplexPairTy EmitPromoted(const Expr *E, QualType PromotionTy);

269 ComplexPairTy EmitPromotedComplexOperand(const Expr *E, QualType PromotionTy);

270 LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,

272 (const BinOpInfo &),

273 RValue &Val);

274 ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,

276 (const BinOpInfo &));

277

282 ComplexPairTy EmitAlgebraicDiv(llvm::Value *A, llvm::Value *B, llvm::Value *C,

283 llvm::Value *D);

284 ComplexPairTy EmitRangeReductionDiv(llvm::Value *A, llvm::Value *B,

285 llvm::Value *C, llvm::Value *D);

286

287 ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName,

288 const BinOpInfo &Op);

289

290 QualType HigherPrecisionTypeForComplexArithmetic(QualType ElementType) {

292 const QualType HigherElementType =

294 const llvm::fltSemantics &ElementTypeSemantics =

296 const llvm::fltSemantics &HigherElementTypeSemantics =

298

299

300

301

302

303

304

305 if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 <=

306 llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) {

310 return QualType();

311 FPHasBeenPromoted = true;

313 } else {

314

315

316 return QualType();

317 }

318 }

319

320 QualType getPromotionType(FPOptionsOverride Features, QualType Ty,

321 bool IsComplexDivisor) {

322 if (auto *CT = Ty->getAs()) {

323 QualType ElementType = CT->getElementType().getCanonicalType();

325 bool IsComplexRangePromoted = CGF.getLangOpts().getComplexRange() ==

326 LangOptions::ComplexRangeKind::CX_Promoted;

327 bool HasNoComplexRangeOverride = !Features.hasComplexRangeOverride();

328 bool HasMatchingComplexRange = Features.hasComplexRangeOverride() &&

329 Features.getComplexRangeOverride() ==

331

332 if (IsComplexDivisor && IsFloatingType && IsComplexRangePromoted &&

333 (HasNoComplexRangeOverride || HasMatchingComplexRange))

334 return HigherPrecisionTypeForComplexArithmetic(ElementType);

337 }

340 return QualType();

341 }

342

343#define HANDLEBINOP(OP) \

344 ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \

345 QualType promotionTy = \

346 getPromotionType(E->getStoredFPFeaturesOrDefault(), E->getType(), \

347 (E->getOpcode() == BinaryOperatorKind::BO_Div && \

348 E->getRHS()->getType()->isAnyComplexType())); \

349 ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \

350 if (!promotionTy.isNull()) \

351 result = CGF.EmitUnPromotedValue(result, E->getType()); \

352 return result; \

353 }

354

359#undef HANDLEBINOP

360

363 }

364

365

366 ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) {

368 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);

369 }

370 ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) {

372 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);

373 }

374 ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) {

376 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);

377 }

378 ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) {

380 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);

381 }

382

383

384

385

386

387

388 LValue EmitBinAssignLValue(const BinaryOperator *E,

390 ComplexPairTy VisitBinAssign (const BinaryOperator *E);

391 ComplexPairTy VisitBinComma (const BinaryOperator *E);

392

393

395 VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO);

397

398 ComplexPairTy VisitInitListExpr(InitListExpr *E);

399

400 ComplexPairTy VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {

401 return EmitLoadOfLValue(E);

402 }

403

405

408 }

409

410 ComplexPairTy VisitPackIndexingExpr(PackIndexingExpr *E) {

412 }

413};

414}

415

416

417

418

419

422 return Builder.CreateStructGEP(addr, 0, addr.getName() + ".realp");

423}

424

427 return Builder.CreateStructGEP(addr, 1, addr.getName() + ".imagp");

428}

429

430

431

434 assert(lvalue.isSimple() && "non-simple complex l-value?");

437

440

441 llvm::Value *Real = nullptr, *Imag = nullptr;

442

443 if (!IgnoreReal || isVolatile) {

445 Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr.getName() + ".real");

446 }

447

448 if (!IgnoreImag || isVolatile) {

450 Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr.getName() + ".imag");

451 }

452

454}

455

456

457

458void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, LValue lvalue,

459 bool isInit) {

460 if (lvalue.getType()->isAtomicType() ||

463

464 Address Ptr = lvalue.getAddress();

467

468 auto *R =

469 Builder.CreateStore(Val.first, RealPtr, lvalue.isVolatileQualified());

471 auto *I =

472 Builder.CreateStore(Val.second, ImagPtr, lvalue.isVolatileQualified());

474}

475

476

477

478

479

480

481

482ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) {

484 llvm::Type *EltTy =

486 llvm::Value *U = llvm::PoisonValue::get(EltTy);

488}

489

491VisitImaginaryLiteral(const ImaginaryLiteral *IL) {

493 return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);

494}

495

496

497ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) {

499 return EmitLoadOfLValue(E);

500

502}

503

504ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) {

507 assert(RetAlloca.isValid() && "Expected complex return value");

510}

511

512

514 QualType SrcType,

515 QualType DestType,

516 SourceLocation Loc) {

517

518 SrcType = SrcType->castAs()->getElementType();

519 DestType = DestType->castAs()->getElementType();

520

521

522

523

524 if (Val.first)

526 if (Val.second)

528 return Val;

529}

530

531ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val,

532 QualType SrcType,

533 QualType DestType,

534 SourceLocation Loc) {

535

536 DestType = DestType->castAs()->getElementType();

538

539

540 return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType()));

541}

542

544 QualType DestTy) {

545 switch (CK) {

546 case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!");

547

548

549

550 case CK_AtomicToNonAtomic:

551 case CK_NonAtomicToAtomic:

552 case CK_NoOp:

553 case CK_LValueToRValue:

554 case CK_UserDefinedConversion:

555 return Visit(Op);

556

557 case CK_LValueBitCast: {

559 Address V = origLV.getAddress().withElementType(CGF.ConvertType(DestTy));

561 }

562

563 case CK_LValueToRValueBitCast: {

566 SourceLVal.getAddress().withElementType(CGF.ConvertTypeForMem(DestTy));

569 return EmitLoadOfLValue(DestLV, Op->getExprLoc());

570 }

571

572 case CK_BitCast:

573 case CK_BaseToDerived:

574 case CK_DerivedToBase:

575 case CK_UncheckedDerivedToBase:

576 case CK_Dynamic:

577 case CK_ToUnion:

578 case CK_ArrayToPointerDecay:

579 case CK_FunctionToPointerDecay:

580 case CK_NullToPointer:

581 case CK_NullToMemberPointer:

582 case CK_BaseToDerivedMemberPointer:

583 case CK_DerivedToBaseMemberPointer:

584 case CK_MemberPointerToBoolean:

585 case CK_ReinterpretMemberPointer:

586 case CK_ConstructorConversion:

587 case CK_IntegralToPointer:

588 case CK_PointerToIntegral:

589 case CK_PointerToBoolean:

590 case CK_ToVoid:

591 case CK_VectorSplat:

592 case CK_IntegralCast:

593 case CK_BooleanToSignedIntegral:

594 case CK_IntegralToBoolean:

595 case CK_IntegralToFloating:

596 case CK_FloatingToIntegral:

597 case CK_FloatingToBoolean:

598 case CK_FloatingCast:

599 case CK_CPointerToObjCPointerCast:

600 case CK_BlockPointerToObjCPointerCast:

601 case CK_AnyPointerToBlockPointerCast:

602 case CK_ObjCObjectLValueCast:

603 case CK_FloatingComplexToReal:

604 case CK_FloatingComplexToBoolean:

605 case CK_IntegralComplexToReal:

606 case CK_IntegralComplexToBoolean:

607 case CK_ARCProduceObject:

608 case CK_ARCConsumeObject:

609 case CK_ARCReclaimReturnedObject:

610 case CK_ARCExtendBlockObject:

611 case CK_CopyAndAutoreleaseBlockObject:

612 case CK_BuiltinFnToFnPtr:

613 case CK_ZeroToOCLOpaqueType:

614 case CK_AddressSpaceConversion:

615 case CK_IntToOCLSampler:

616 case CK_FloatingToFixedPoint:

617 case CK_FixedPointToFloating:

618 case CK_FixedPointCast:

619 case CK_FixedPointToBoolean:

620 case CK_FixedPointToIntegral:

621 case CK_IntegralToFixedPoint:

622 case CK_MatrixCast:

623 case CK_HLSLVectorTruncation:

624 case CK_HLSLMatrixTruncation:

625 case CK_HLSLArrayRValue:

626 case CK_HLSLElementwiseCast:

627 case CK_HLSLAggregateSplatCast:

628 llvm_unreachable("invalid cast kind for complex value");

629

630 case CK_FloatingRealToComplex:

631 case CK_IntegralRealToComplex: {

635 }

636

637 case CK_FloatingComplexCast:

638 case CK_FloatingComplexToIntegralComplex:

639 case CK_IntegralComplexCast:

640 case CK_IntegralComplexToFloatingComplex: {

642 return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy,

644 }

645 }

646

647 llvm_unreachable("unknown cast resulting in complex value");

648}

649

650ComplexPairTy ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *E,

651 QualType PromotionType) {

652 QualType promotionTy =

653 PromotionType.isNull()

656 false)

657 : PromotionType;

658 ComplexPairTy result = VisitPlus(E, promotionTy);

659 if (!promotionTy.isNull())

661 return result;

662}

663

664ComplexPairTy ComplexExprEmitter::VisitPlus(const UnaryOperator *E,

665 QualType PromotionType) {

666 TestAndClearIgnoreReal();

667 TestAndClearIgnoreImag();

668 if (!PromotionType.isNull())

671}

672

673ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E,

674 QualType PromotionType) {

675 QualType promotionTy =

676 PromotionType.isNull()

679 false)

680 : PromotionType;

681 ComplexPairTy result = VisitMinus(E, promotionTy);

682 if (!promotionTy.isNull())

684 return result;

685}

686ComplexPairTy ComplexExprEmitter::VisitMinus(const UnaryOperator *E,

687 QualType PromotionType) {

688 TestAndClearIgnoreReal();

689 TestAndClearIgnoreImag();

691 if (!PromotionType.isNull())

693 else

695

696 llvm::Value *ResR, *ResI;

697 if (Op.first->getType()->isFloatingPointTy()) {

698 ResR = Builder.CreateFNeg(Op.first, "neg.r");

699 ResI = Builder.CreateFNeg(Op.second, "neg.i");

700 } else {

701 ResR = Builder.CreateNeg(Op.first, "neg.r");

702 ResI = Builder.CreateNeg(Op.second, "neg.i");

703 }

705}

706

707ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) {

708 TestAndClearIgnoreReal();

709 TestAndClearIgnoreImag();

710

712 llvm::Value *ResI;

713 if (Op.second->getType()->isFloatingPointTy())

714 ResI = Builder.CreateFNeg(Op.second, "conj.i");

715 else

716 ResI = Builder.CreateNeg(Op.second, "conj.i");

717

719}

720

721ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) {

722 llvm::Value *ResR, *ResI;

723

724 if (Op.LHS.first->getType()->isFloatingPointTy()) {

726 ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first, "add.r");

727 if (Op.LHS.second && Op.RHS.second)

728 ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i");

729 else

730 ResI = Op.LHS.second ? Op.LHS.second : Op.RHS.second;

731 assert(ResI && "Only one operand may be real!");

732 } else {

733 ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r");

734 assert(Op.LHS.second && Op.RHS.second &&

735 "Both operands of integer complex operators must be complex!");

736 ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i");

737 }

739}

740

741ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) {

742 llvm::Value *ResR, *ResI;

743 if (Op.LHS.first->getType()->isFloatingPointTy()) {

745 ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first, "sub.r");

746 if (Op.LHS.second && Op.RHS.second)

747 ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i");

748 else

749 ResI = Op.LHS.second ? Op.LHS.second

750 : Builder.CreateFNeg(Op.RHS.second, "sub.i");

751 assert(ResI && "Only one operand may be real!");

752 } else {

753 ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first, "sub.r");

754 assert(Op.LHS.second && Op.RHS.second &&

755 "Both operands of integer complex operators must be complex!");

756 ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i");

757 }

759}

760

761

762ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,

763 const BinOpInfo &Op) {

766 Op.Ty->castAs()->getElementType());

768 Op.Ty->castAs()->getElementType());

770 Op.Ty->castAs()->getElementType());

772 Op.Ty->castAs()->getElementType());

773

774

775

776

777

778

779

780 FunctionProtoType::ExtProtoInfo EPI;

783 SmallVector<QualType, 4> ArgsQTys(

784 4, Op.Ty->castAs()->getElementType());

788

791 FTy, LibCallName, llvm::AttributeList(), true);

793

794 llvm::CallBase *Call;

798}

799

800

801

803 switch (Ty->getTypeID()) {

804 default:

805 llvm_unreachable("Unsupported floating point type!");

806 case llvm::Type::HalfTyID:

807 return "__mulhc3";

808 case llvm::Type::FloatTyID:

809 return "__mulsc3";

810 case llvm::Type::DoubleTyID:

811 return "__muldc3";

812 case llvm::Type::PPC_FP128TyID:

813 return "__multc3";

814 case llvm::Type::X86_FP80TyID:

815 return "__mulxc3";

816 case llvm::Type::FP128TyID:

817 return "__multc3";

818 }

819}

820

821

822

823ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) {

824 using llvm::Value;

825 Value *ResR, *ResI;

827

828 if (Op.LHS.first->getType()->isFloatingPointTy()) {

829

830

831

832

833

834

836 if (Op.LHS.second && Op.RHS.second) {

837

838

839

840

841

842

843

844

845

846

847 Value *AC = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul_ac");

848 Value *BD = Builder.CreateFMul(Op.LHS.second, Op.RHS.second, "mul_bd");

849 Value *AD = Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul_ad");

850 Value *BC = Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul_bc");

851

852

853

854 ResR = Builder.CreateFSub(AC, BD, "mul_r");

855 ResI = Builder.CreateFAdd(AD, BC, "mul_i");

856

861

862

863

864 Value *IsRNaN = Builder.CreateFCmpUNO(ResR, ResR, "isnan_cmp");

865 llvm::BasicBlock *ContBB = CGF.createBasicBlock("complex_mul_cont");

866 llvm::BasicBlock *INaNBB = CGF.createBasicBlock("complex_mul_imag_nan");

867 llvm::Instruction *Branch = Builder.CreateCondBr(IsRNaN, INaNBB, ContBB);

868 llvm::BasicBlock *OrigBB = Branch->getParent();

869

870

871 llvm::MDNode *BrWeight = MDHelper.createUnlikelyBranchWeights();

872 Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);

873

874

876 Value *IsINaN = Builder.CreateFCmpUNO(ResI, ResI, "isnan_cmp");

877 llvm::BasicBlock *LibCallBB = CGF.createBasicBlock("complex_mul_libcall");

878 Branch = Builder.CreateCondBr(IsINaN, LibCallBB, ContBB);

879 Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);

880

881

883 Value *LibCallR, *LibCallI;

884 std::tie(LibCallR, LibCallI) = EmitComplexBinOpLibCall(

886 Builder.CreateBr(ContBB);

887

888

889

891 llvm::PHINode *RealPHI = Builder.CreatePHI(ResR->getType(), 3, "real_mul_phi");

892 RealPHI->addIncoming(ResR, OrigBB);

893 RealPHI->addIncoming(ResR, INaNBB);

894 RealPHI->addIncoming(LibCallR, LibCallBB);

895 llvm::PHINode *ImagPHI = Builder.CreatePHI(ResI->getType(), 3, "imag_mul_phi");

896 ImagPHI->addIncoming(ResI, OrigBB);

897 ImagPHI->addIncoming(ResI, INaNBB);

898 ImagPHI->addIncoming(LibCallI, LibCallBB);

900 }

901 assert((Op.LHS.second || Op.RHS.second) &&

902 "At least one operand must be complex!");

903

904

905

906

907 ResR = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul.rl");

908

909 ResI = Op.LHS.second

910 ? Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul.il")

911 : Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul.ir");

912 } else {

913 assert(Op.LHS.second && Op.RHS.second &&

914 "Both operands of integer complex operators must be complex!");

915 Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl");

916 Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second, "mul.rr");

917 ResR = Builder.CreateSub(ResRl, ResRr, "mul.r");

918

919 Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il");

920 Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir");

921 ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i");

922 }

924}

925

926ComplexPairTy ComplexExprEmitter::EmitAlgebraicDiv(llvm::Value *LHSr,

927 llvm::Value *LHSi,

928 llvm::Value *RHSr,

929 llvm::Value *RHSi) {

930

931 llvm::Value *DSTr, *DSTi;

932

933 llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr);

934 llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi);

935 llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD);

936

937 llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr);

938 llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi);

939 llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD);

940

941 llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr);

942 llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi);

943 llvm::Value *BCmAD = Builder.CreateFSub(BC, AD);

944

945 DSTr = Builder.CreateFDiv(ACpBD, CCpDD);

946 DSTi = Builder.CreateFDiv(BCmAD, CCpDD);

948}

949

950

952 llvm::Function *Func =

956}

957

958

959

960ComplexPairTy ComplexExprEmitter::EmitRangeReductionDiv(llvm::Value *LHSr,

961 llvm::Value *LHSi,

962 llvm::Value *RHSr,

963 llvm::Value *RHSi) {

964

965

966

967

968 llvm::Value *FAbsRHSr = EmitllvmFAbs(CGF, RHSr);

969 llvm::Value *FAbsRHSi = EmitllvmFAbs(CGF, RHSi);

970

971 llvm::Value *IsR = Builder.CreateFCmpUGT(FAbsRHSr, FAbsRHSi, "abs_cmp");

972

973 llvm::BasicBlock *TrueBB =

975 llvm::BasicBlock *FalseBB =

977 llvm::BasicBlock *ContBB = CGF.createBasicBlock("complex_div");

978 Builder.CreateCondBr(IsR, TrueBB, FalseBB);

979

981

982

983

984

985

986 llvm::Value *DdC = Builder.CreateFDiv(RHSi, RHSr);

987

988 llvm::Value *RD = Builder.CreateFMul(DdC, RHSi);

989 llvm::Value *CpRD = Builder.CreateFAdd(RHSr, RD);

990

991 llvm::Value *T3 = Builder.CreateFMul(LHSi, DdC);

992 llvm::Value *T4 = Builder.CreateFAdd(LHSr, T3);

993 llvm::Value *DSTTr = Builder.CreateFDiv(T4, CpRD);

994

995 llvm::Value *T5 = Builder.CreateFMul(LHSr, DdC);

996 llvm::Value *T6 = Builder.CreateFSub(LHSi, T5);

997 llvm::Value *DSTTi = Builder.CreateFDiv(T6, CpRD);

998 Builder.CreateBr(ContBB);

999

1001

1002

1003

1004

1005

1006 llvm::Value *CdD = Builder.CreateFDiv(RHSr, RHSi);

1007

1008 llvm::Value *RC = Builder.CreateFMul(CdD, RHSr);

1009 llvm::Value *DpRC = Builder.CreateFAdd(RHSi, RC);

1010

1011 llvm::Value *T7 = Builder.CreateFMul(LHSr, CdD);

1012 llvm::Value *T8 = Builder.CreateFAdd(T7, LHSi);

1013 llvm::Value *DSTFr = Builder.CreateFDiv(T8, DpRC);

1014

1015 llvm::Value *T9 = Builder.CreateFMul(LHSi, CdD);

1016 llvm::Value *T10 = Builder.CreateFSub(T9, LHSr);

1017 llvm::Value *DSTFi = Builder.CreateFDiv(T10, DpRC);

1018 Builder.CreateBr(ContBB);

1019

1020

1022 llvm::PHINode *VALr = Builder.CreatePHI(DSTTr->getType(), 2);

1023 VALr->addIncoming(DSTTr, TrueBB);

1024 VALr->addIncoming(DSTFr, FalseBB);

1025 llvm::PHINode *VALi = Builder.CreatePHI(DSTTi->getType(), 2);

1026 VALi->addIncoming(DSTTi, TrueBB);

1027 VALi->addIncoming(DSTFi, FalseBB);

1029}

1030

1031

1032

1033ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {

1034 llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;

1035 llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;

1036 llvm::Value *DSTr, *DSTi;

1037 if (LHSr->getType()->isFloatingPointTy()) {

1039 if (!RHSi) {

1040 assert(LHSi && "Can have at most one non-complex operand!");

1041

1042 DSTr = Builder.CreateFDiv(LHSr, RHSr);

1043 DSTi = Builder.CreateFDiv(LHSi, RHSr);

1045 }

1046 llvm::Value *OrigLHSi = LHSi;

1047 if (!LHSi)

1048 LHSi = llvm::Constant::getNullValue(RHSi->getType());

1051 !FPHasBeenPromoted))

1052 return EmitRangeReductionDiv(LHSr, LHSi, RHSr, RHSi);

1055 return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);

1056

1057

1059 LHSi = OrigLHSi;

1060

1061

1062

1063

1064 BinOpInfo LibCallOp = Op;

1065

1066 if (!LHSi)

1067 LibCallOp.LHS.second = llvm::Constant::getNullValue(LHSr->getType());

1068

1069 switch (LHSr->getType()->getTypeID()) {

1070 default:

1071 llvm_unreachable("Unsupported floating point type!");

1072 case llvm::Type::HalfTyID:

1073 return EmitComplexBinOpLibCall("__divhc3", LibCallOp);

1074 case llvm::Type::FloatTyID:

1075 return EmitComplexBinOpLibCall("__divsc3", LibCallOp);

1076 case llvm::Type::DoubleTyID:

1077 return EmitComplexBinOpLibCall("__divdc3", LibCallOp);

1078 case llvm::Type::PPC_FP128TyID:

1079 return EmitComplexBinOpLibCall("__divtc3", LibCallOp);

1080 case llvm::Type::X86_FP80TyID:

1081 return EmitComplexBinOpLibCall("__divxc3", LibCallOp);

1082 case llvm::Type::FP128TyID:

1083 return EmitComplexBinOpLibCall("__divtc3", LibCallOp);

1084 }

1085 } else {

1086 return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);

1087 }

1088 } else {

1089 assert(Op.LHS.second && Op.RHS.second &&

1090 "Both operands of integer complex operators must be complex!");

1091

1092 llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr);

1093 llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi);

1094 llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2);

1095

1096 llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr);

1097 llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi);

1098 llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5);

1099

1100 llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr);

1101 llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi);

1102 llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8);

1103

1104 if (Op.Ty->castAs()->getElementType()->isUnsignedIntegerType()) {

1105 DSTr = Builder.CreateUDiv(Tmp3, Tmp6);

1106 DSTi = Builder.CreateUDiv(Tmp9, Tmp6);

1107 } else {

1108 DSTr = Builder.CreateSDiv(Tmp3, Tmp6);

1109 DSTi = Builder.CreateSDiv(Tmp9, Tmp6);

1110 }

1111 }

1112

1114}

1115

1118 llvm::Type *ComplexElementTy =

1120 if (result.first)

1121 result.first =

1122 Builder.CreateFPTrunc(result.first, ComplexElementTy, "unpromotion");

1123 if (result.second)

1124 result.second =

1125 Builder.CreateFPTrunc(result.second, ComplexElementTy, "unpromotion");

1126 return result;

1127}

1128

1131 llvm::Type *ComplexElementTy =

1133 if (result.first)

1134 result.first = Builder.CreateFPExt(result.first, ComplexElementTy, "ext");

1135 if (result.second)

1136 result.second = Builder.CreateFPExt(result.second, ComplexElementTy, "ext");

1137

1138 return result;

1139}

1140

1144 if (auto BO = dyn_cast(E)) {

1145 switch (BO->getOpcode()) {

1146#define HANDLE_BINOP(OP) \

1147 case BO_##OP: \

1148 return EmitBin##OP(EmitBinOps(BO, PromotionType));

1153#undef HANDLE_BINOP

1154 default:

1155 break;

1156 }

1157 } else if (auto UO = dyn_cast(E)) {

1158 switch (UO->getOpcode()) {

1159 case UO_Minus:

1160 return VisitMinus(UO, PromotionType);

1161 case UO_Plus:

1162 return VisitPlus(UO, PromotionType);

1163 default:

1164 break;

1165 }

1166 }

1167 auto result = Visit(const_cast<Expr *>(E));

1168 if (!PromotionType.isNull())

1170 else

1171 return result;

1172}

1173

1176 return ComplexExprEmitter(*this).EmitPromoted(E, DstTy);

1177}

1178

1180ComplexExprEmitter::EmitPromotedComplexOperand(const Expr *E,

1181 QualType OverallPromotionType) {

1183 if (!OverallPromotionType.isNull())

1185 else

1186 return Visit(const_cast<Expr *>(E));

1187 } else {

1188 if (!OverallPromotionType.isNull()) {

1192 nullptr);

1193 } else {

1195 }

1196 }

1197}

1198

1199ComplexExprEmitter::BinOpInfo

1200ComplexExprEmitter::EmitBinOps(const BinaryOperator *E,

1201 QualType PromotionType) {

1202 TestAndClearIgnoreReal();

1203 TestAndClearIgnoreImag();

1204 BinOpInfo Ops;

1205

1206 Ops.LHS = EmitPromotedComplexOperand(E->getLHS(), PromotionType);

1207 Ops.RHS = EmitPromotedComplexOperand(E->getRHS(), PromotionType);

1208 if (!PromotionType.isNull())

1209 Ops.Ty = PromotionType;

1210 else

1213 return Ops;

1214}

1215

1216

1217LValue ComplexExprEmitter::

1218EmitCompoundAssignLValue(const CompoundAssignOperator *E,

1221 TestAndClearIgnoreReal();

1222 TestAndClearIgnoreImag();

1224 if (const AtomicType *AT = LHSTy->getAs())

1225 LHSTy = AT->getValueType();

1226

1227 BinOpInfo OpInfo;

1230

1231 const bool IsComplexDivisor = E->getOpcode() == BO_DivAssign &&

1233

1234

1235

1236

1237 QualType PromotionTypeCR;

1238 PromotionTypeCR =

1241 if (PromotionTypeCR.isNull())

1243 OpInfo.Ty = PromotionTypeCR;

1244 QualType ComplexElementTy =

1245 OpInfo.Ty->castAs()->getElementType();

1246 QualType PromotionTypeRHS =

1249

1250

1252 if (!PromotionTypeRHS.isNull())

1255 else {

1258

1260 }

1261 } else {

1262 if (!PromotionTypeRHS.isNull()) {

1265 } else {

1268 OpInfo.RHS = Visit(E->getRHS());

1269 }

1270 }

1271

1273

1274

1275 SourceLocation Loc = E->getExprLoc();

1276 QualType PromotionTypeLHS =

1280 ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, Loc);

1281 if (!PromotionTypeLHS.isNull())

1282 OpInfo.LHS =

1283 EmitComplexToComplexCast(LHSVal, LHSTy, PromotionTypeLHS, Loc);

1284 else

1285 OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);

1286 } else {

1288

1289

1291 QualType PromotedComplexElementTy;

1292 if (!PromotionTypeLHS.isNull()) {

1293 PromotedComplexElementTy =

1296 PromotionTypeLHS))

1298 PromotedComplexElementTy, Loc);

1299 } else {

1301 LHSVal =

1303 }

1305 } else {

1306 OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);

1307 }

1308 }

1309

1310

1312

1313

1316 EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy, Loc);

1317 EmitStoreOfComplex(ResVal, LHS, false);

1319 } else {

1320 llvm::Value *ResVal =

1324 }

1325

1326 return LHS;

1327}

1328

1329

1331EmitCompoundAssign(const CompoundAssignOperator *E,

1334 LValue LV = EmitCompoundAssignLValue(E, Func, Val);

1335

1336

1339

1340

1341 if (!LV.isVolatileQualified())

1343

1344 return EmitLoadOfLValue(LV, E->getExprLoc());

1345}

1346

1347LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E,

1351 "Invalid assignment");

1352 TestAndClearIgnoreReal();

1353 TestAndClearIgnoreImag();

1354

1355

1356 Val = Visit(E->getRHS());

1357

1358

1360

1361

1362 EmitStoreOfComplex(Val, LHS, false);

1363

1364 return LHS;

1365}

1366

1367ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {

1370 LValue LV = EmitBinAssignLValue(E, Val);

1371

1372

1374 return Val;

1375

1376

1377 if (!LV.isVolatileQualified())

1378 return Val;

1379

1380 return EmitLoadOfLValue(LV, E->getExprLoc());

1381}

1382

1383ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {

1385 return Visit(E->getRHS());

1386}

1387

1389VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {

1390 TestAndClearIgnoreReal();

1391 TestAndClearIgnoreImag();

1392 llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");

1393 llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");

1394 llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");

1395

1396

1398

1399

1403

1404 eval.begin(CGF);

1408 else

1410

1412 LHSBlock = Builder.GetInsertBlock();

1414 eval.end(CGF);

1415

1416 eval.begin(CGF);

1421 RHSBlock = Builder.GetInsertBlock();

1425 eval.end(CGF);

1426

1427

1428 llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.r");

1429 RealPN->addIncoming(LHS.first, LHSBlock);

1430 RealPN->addIncoming(RHS.first, RHSBlock);

1431

1432

1433 llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.i");

1434 ImagPN->addIncoming(LHS.second, LHSBlock);

1435 ImagPN->addIncoming(RHS.second, RHSBlock);

1436

1438}

1439

1440ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) {

1442}

1443

1444ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) {

1445 bool Ignore = TestAndClearIgnoreReal();

1446 (void)Ignore;

1447 assert (Ignore == false && "init list ignored");

1448 Ignore = TestAndClearIgnoreImag();

1449 (void)Ignore;

1450 assert (Ignore == false && "init list ignored");

1451

1457 return Visit(E->getInit(0));

1458 }

1459

1460

1461 assert(E->getNumInits() == 0 && "Unexpected number of inits");

1462 QualType Ty = E->getType()->castAs()->getElementType();

1464 llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);

1465 return ComplexPairTy(zeroConstant, zeroConstant);

1466}

1467

1468ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) {

1471

1472 if (!ArgValue.isValid()) {

1474 llvm::Type *EltTy =

1476 llvm::Value *U = llvm::PoisonValue::get(EltTy);

1478 }

1479

1481}

1482

1483

1484

1485

1486

1487

1488

1490 bool IgnoreImag) {

1492 "Invalid complex expression to emit");

1493

1494 return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag)

1495 .Visit(const_cast<Expr *>(E));

1496}

1497

1499 bool isInit) {

1501 "Invalid complex expression to emit");

1502 ComplexExprEmitter Emitter(*this);

1504 Emitter.EmitStoreOfComplex(Val, dest, isInit);

1505}

1506

1507

1509 bool isInit) {

1510 ComplexExprEmitter(*this).EmitStoreOfComplex(V, dest, isInit);

1511}

1512

1513

1516 return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc);

1517}

1518

1520 assert(E->getOpcode() == BO_Assign);

1522 LValue LVal = ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val);

1524 CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*this,

1526 return LVal;

1527}

1528

1530 const ComplexExprEmitter::BinOpInfo &);

1531

1533 switch (Op) {

1534 case BO_MulAssign: return &ComplexExprEmitter::EmitBinMul;

1535 case BO_DivAssign: return &ComplexExprEmitter::EmitBinDiv;

1536 case BO_SubAssign: return &ComplexExprEmitter::EmitBinSub;

1537 case BO_AddAssign: return &ComplexExprEmitter::EmitBinAdd;

1538 default:

1539 llvm_unreachable("unexpected complex compound assignment");

1540 }

1541}

1542

1548 return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);

1549}

1550

1553 llvm::Value *&Result) {

1554

1555

1558 LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);

1560 return Ret;

1561}

static const ComplexType * getComplexType(QualType type)

Return the complex type that we are meant to emit.

Definition CGExprComplex.cpp:37

CodeGenFunction::ComplexPairTy ComplexPairTy

Definition CGExprComplex.cpp:34

static llvm::Value * EmitllvmFAbs(CodeGenFunction &CGF, llvm::Value *Value)

Definition CGExprComplex.cpp:951

static StringRef getComplexMultiplyLibCallName(llvm::Type *Ty)

Lookup the libcall name for a given floating point type complex multiply.

Definition CGExprComplex.cpp:802

static CompoundFunc getComplexOp(BinaryOperatorKind op)

static const ComplexType * getComplexType(QualType type)

Return the complex type that we are meant to emit.

mlir::Value(ComplexExprEmitter::*)(const ComplexExprEmitter::BinOpInfo &) CompoundFunc

const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const

Return the APFloat 'semantics' for the specified scalar floating point type.

const QualType GetHigherPrecisionFPType(QualType ElementType) const

QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const

Return a normal function type with a typed argument list.

QualType getComplexType(QualType T) const

Return the uniqued reference to the type for a complex number with the specified element type.

const TargetInfo & getTargetInfo() const

static bool hasSameUnqualifiedType(QualType T1, QualType T2)

Determine whether the given types are equivalent after cvr-qualifiers have been removed.

Expr * getCond() const

getCond - Return the expression representing the condition for the ?

Expr * getTrueExpr() const

getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...

Expr * getFalseExpr() const

getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...

A builtin binary operation expression such as "x + y" or "x <= y".

FPOptionsOverride getStoredFPFeaturesOrDefault() const

Get the store FPOptionsOverride or default if not stored.

SourceLocation getExprLoc() const

FPOptions getFPFeaturesInEffect(const LangOptions &LO) const

Get the FP features status of this operator.

Expr * getExpr()

Get the initialization expression that will be used.

A rewritten comparison expression that was originally written using operator syntax.

Expr * getSemanticForm()

Get an equivalent semantic form for this expression.

QualType getCallReturnType(const ASTContext &Ctx) const

getCallReturnType - Get the return type of the call expr.

CastKind getCastKind() const

bool changesVolatileQualification() const

Return.

Expr * getChosenSubExpr() const

getChosenSubExpr - Return the subexpression chosen according to the condition.

Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...

llvm::StringRef getName() const

Return the IR name of the pointer value.

A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.

All available information about a concrete callee.

static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())

CGFunctionInfo - Class to encapsulate the information about a function definition.

CallArgList - Type for representing both the value and type of arguments in a call.

void add(RValue rvalue, QualType type)

An object to manage conditionally-evaluated expressions.

LValue getReferenceLValue(CodeGenFunction &CGF, const Expr *RefExpr) const

llvm::Constant * getValue() const

An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.

An RAII object to record that we're evaluating a statement expression.

CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...

void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr, const VarDecl *ConditionalDecl=nullptr)

EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.

RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())

ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)

void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)

EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...

Definition CGExprComplex.cpp:1498

llvm::Type * ConvertType(QualType T)

ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)

EmitLoadOfComplex - Load a complex number from the specified l-value.

Definition CGExprComplex.cpp:1514

RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr, AggValueSlot Slot=AggValueSlot::ignored())

Generate code to get an argument from the passed in pointer and update it accordingly.

RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())

llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)

createBasicBlock - Create an LLVM basic block.

void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)

See CGDebugInfo::addInstToCurrentSourceAtom.

llvm::Value * EmitPromotedScalarExpr(const Expr *E, QualType PromotionType)

const LangOptions & getLangOpts() const

LValue EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E)

Definition CGExprComplex.cpp:1544

ComplexPairTy EmitPromotedComplexExpr(const Expr *E, QualType PromotionType)

Definition CGExprComplex.cpp:1174

LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)

Definition CGExprComplex.cpp:1552

void EmitIgnoredExpr(const Expr *E)

EmitIgnoredExpr - Emit an expression in a context which ignores the result.

RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot(), llvm::CallBase **CallOrInvoke=nullptr)

RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)

EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...

llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)

Emit a conversion from the specified complex type to the specified destination type,...

Address emitAddrOfImagComponent(Address complex, QualType complexType)

Definition CGExprComplex.cpp:425

RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)

RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)

Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.

RValue EmitAtomicLoad(LValue LV, SourceLocation SL, AggValueSlot Slot=AggValueSlot::ignored())

CGDebugInfo * getDebugInfo()

LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)

Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.

ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)

EmitComplexExpr - Emit the computation of the specified expression of complex type,...

Definition CGExprComplex.cpp:1489

RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)

EmitCall - Generate a call of the given function, expecting the given result type,...

void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)

Increment the profiler's counter for the given statement by StepV.

ASTContext & getContext() const

void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)

EmitStoreOfComplex - Store a complex number into the specified l-value.

Definition CGExprComplex.cpp:1508

void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)

EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...

Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())

EmitCompoundStmt - Emit a compound statement {..} node.

LValue EmitComplexAssignmentLValue(const BinaryOperator *E)

Emit an l-value for an assignment (simple or compound) of complex type.

Definition CGExprComplex.cpp:1519

llvm::Type * ConvertTypeForMem(QualType T)

RValue EmitAtomicExpr(AtomicExpr *E)

RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)

void EmitBranch(llvm::BasicBlock *Block)

EmitBranch - Emit a branch to the specified basic block from the current insert block,...

bool LValueIsSuitableForInlineAtomic(LValue Src)

An LValue is a candidate for having its loads and stores be made atomic if we are operating under /vo...

Address emitAddrOfRealComponent(Address complex, QualType complexType)

Definition CGExprComplex.cpp:420

llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)

EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...

ComplexPairTy EmitUnPromotedValue(ComplexPairTy result, QualType PromotionType)

Definition CGExprComplex.cpp:1116

LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)

void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit)

uint64_t getProfileCount(const Stmt *S)

Get the profiler's count for the given statement.

void ErrorUnsupported(const Stmt *S, const char *Type)

ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.

std::pair< llvm::Value *, llvm::Value * > ComplexPairTy

ConstantEmission tryEmitAsConstant(const DeclRefExpr *RefExpr)

Try to emit a reference to the given value without producing it as an l-value.

LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)

EmitLValue - Emit code to compute a designator that specifies the location of the expression.

llvm::LLVMContext & getLLVMContext()

ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)

Definition CGExprComplex.cpp:1129

llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)

Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...

void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)

EmitBlock - Emit the given block.

void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)

Emit type info if type of an expression is a variably modified type.

llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)

Create or return a runtime function declaration with the specified type and name.

CodeGenTypes & getTypes()

llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})

llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)

GetFunctionType - Get the LLVM function type for.

const CGFunctionInfo & arrangeFreeFunctionCall(const CallArgList &Args, const FunctionType *Ty, bool ChainCall)

Figure out the rules for calling a function with the given formal type using the given arguments.

LValue - This represents an lvalue references.

bool isVolatileQualified() const

Address getAddress() const

RValue - This trivial value class is used to represent the result of an expression that is evaluated.

static RValue get(llvm::Value *V)

static RValue getComplex(llvm::Value *V1, llvm::Value *V2)

llvm::Value * getScalarVal() const

getScalarVal() - Return the Value* of this scalar value.

std::pair< llvm::Value *, llvm::Value * > getComplexVal() const

getComplexVal - Return the real/imag components of this complex value.

ReturnValueSlot - Contains the address where the return value of a function can be stored,...

Complex values, per C99 6.2.5p11.

QualType getElementType() const

CompoundAssignOperator - For compound assignments (e.g.

QualType getComputationLHSType() const

QualType getComputationResultType() const

This represents one expression.

Expr * IgnoreParens() LLVM_READONLY

Skip past any parentheses which might surround this expression until reaching a fixed point.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

const Expr * getSubExpr() const

const Expr * getSubExpr() const

unsigned getNumInits() const

const Expr * getInit(unsigned Init) const

@ CX_Full

Implementation of complex division and multiplication using a call to runtime library functions(gener...

@ CX_Basic

Implementation of complex division and multiplication using algebraic formulas at source precision.

@ CX_Promoted

Implementation of complex division using algebraic formulas at higher precision.

@ CX_Improved

Implementation of complex division offering an improved handling for overflow in intermediate calcula...

SourceLocation getExprLoc() const LLVM_READONLY

Expr * getSelectedExpr() const

const Expr * getSubExpr() const

A (possibly-)qualified type.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

const Type * getTypePtr() const

Retrieves a pointer to the underlying (unqualified) type.

QualType getCanonicalType() const

QualType getUnqualifiedType() const

Retrieve the unqualified variant of the given type, removing as little sugar as possible.

bool UseExcessPrecision(const ASTContext &Ctx)

Encodes a location in the source.

CompoundStmt * getSubStmt()

StmtVisitor - This class implements a simple visitor for Stmt subclasses.

void dump() const

Dumps the specified AST fragment and all subtrees to llvm::errs().

Expr * getReplacement() const

virtual bool hasLongDoubleType() const

Determine whether the long double type is supported on this target.

const T * castAs() const

Member-template castAs.

bool isReferenceType() const

bool isAnyComplexType() const

bool isAtomicType() const

bool isRealFloatingType() const

Floating point categories.

bool isFloatingType() const

const T * getAs() const

Member-template getAs'.

Expr * getSubExpr() const

FPOptionsOverride getStoredFPFeaturesOrDefault() const

Get the store FPOptionsOverride or default if not stored.

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

const AstTypeMatcher< ComplexType > complexType

bool Null(InterpState &S, CodePtr OpPC, uint64_t Value, const Descriptor *Desc)

bool GE(InterpState &S, CodePtr OpPC)

The JSON file list parser is used to communicate input to InstallAPI.

@ Result

The result type of a method or function.

CastKind

CastKind - The kind of operation required for a conversion.

U cast(CodeGen::Address addr)

@ EST_BasicNoexcept

noexcept

Diagnostic wrappers for TextAPI types for error reporting.

cl::opt< bool > EnableSingleByteCoverage

Definition CGExprComplex.cpp:31

llvm::CallingConv::ID getRuntimeCC() const

static TBAAAccessInfo getMayAliasInfo()

ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &ESI)