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

1

2

3

4

5

6

7

8

9

10

11

12

28#include "llvm/ADT/ArrayRef.h"

29#include "llvm/ADT/DenseMap.h"

30#include "llvm/ADT/SmallSet.h"

31#include "llvm/ADT/StringExtras.h"

32#include "llvm/IR/Assumptions.h"

33#include "llvm/IR/DataLayout.h"

34#include "llvm/IR/InlineAsm.h"

35#include "llvm/IR/Intrinsics.h"

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

37#include "llvm/Support/SaveAndRestore.h"

38#include

39

40using namespace clang;

42

43

44

45

46

47namespace llvm {

49}

50

55 DI->EmitLocation(Builder, Loc);

56

57 LastStopPoint = Loc;

58 }

59}

60

62 assert(S && "Null statement?");

63 PGO->setCurrentStmt(S);

64

65

67 return;

68

69

71

72

73

74

75

77

78

79 assert(isa<DeclStmt>(*S) && "Unexpected DeclStmt!");

80 PGO->markStmtMaybeUsed(S);

81 return;

82 }

83

84

86 }

87

88

90

91

92

94 if (const auto *D = dyn_cast(S)) {

96 return;

97 }

98 }

99

102 case Stmt::CXXCatchStmtClass:

103 case Stmt::SEHExceptStmtClass:

104 case Stmt::SEHFinallyStmtClass:

105 case Stmt::MSDependentExistsStmtClass:

106 llvm_unreachable("invalid statement class to emit generically");

107 case Stmt::NullStmtClass:

108 case Stmt::CompoundStmtClass:

109 case Stmt::DeclStmtClass:

110 case Stmt::LabelStmtClass:

111 case Stmt::AttributedStmtClass:

112 case Stmt::GotoStmtClass:

113 case Stmt::BreakStmtClass:

114 case Stmt::ContinueStmtClass:

115 case Stmt::DefaultStmtClass:

116 case Stmt::CaseStmtClass:

117 case Stmt::DeferStmtClass:

118 case Stmt::SEHLeaveStmtClass:

119 case Stmt::SYCLKernelCallStmtClass:

120 llvm_unreachable("should have emitted these statements as simple");

121

122#define STMT(Type, Base)

123#define ABSTRACT_STMT(Op)

124#define EXPR(Type, Base) \

125 case Stmt::Type##Class:

126#include "clang/AST/StmtNodes.inc"

127 {

128

129 llvm::BasicBlock *incoming = Builder.GetInsertBlock();

130 assert(incoming && "expression emission must have an insertion point");

131

133

134 llvm::BasicBlock *outgoing = Builder.GetInsertBlock();

135 assert(outgoing && "expression emission cleared block!");

136

137

138

139

140

141

142

143

144

145

146

147

148

149 if (incoming != outgoing && outgoing->use_empty()) {

150 outgoing->eraseFromParent();

151 Builder.ClearInsertionPoint();

152 }

153 break;

154 }

155

156 case Stmt::IndirectGotoStmtClass:

158

163

165

167 case Stmt::GCCAsmStmtClass:

169 case Stmt::CoroutineBodyStmtClass:

171 break;

172 case Stmt::CoreturnStmtClass:

174 break;

175 case Stmt::CapturedStmtClass: {

178 }

179 break;

180 case Stmt::ObjCAtTryStmtClass:

182 break;

183 case Stmt::ObjCAtCatchStmtClass:

184 llvm_unreachable(

185 "@catch statements should be handled by EmitObjCAtTryStmt");

186 case Stmt::ObjCAtFinallyStmtClass:

187 llvm_unreachable(

188 "@finally statements should be handled by EmitObjCAtTryStmt");

189 case Stmt::ObjCAtThrowStmtClass:

191 break;

192 case Stmt::ObjCAtSynchronizedStmtClass:

194 break;

195 case Stmt::ObjCForCollectionStmtClass:

197 break;

198 case Stmt::ObjCAutoreleasePoolStmtClass:

200 break;

201

202 case Stmt::CXXTryStmtClass:

204 break;

205 case Stmt::CXXForRangeStmtClass:

207 break;

208 case Stmt::SEHTryStmtClass:

210 break;

211 case Stmt::OMPMetaDirectiveClass:

213 break;

214 case Stmt::OMPCanonicalLoopClass:

216 break;

217 case Stmt::OMPParallelDirectiveClass:

219 break;

220 case Stmt::OMPSimdDirectiveClass:

222 break;

223 case Stmt::OMPTileDirectiveClass:

225 break;

226 case Stmt::OMPStripeDirectiveClass:

228 break;

229 case Stmt::OMPUnrollDirectiveClass:

231 break;

232 case Stmt::OMPReverseDirectiveClass:

234 break;

235 case Stmt::OMPInterchangeDirectiveClass:

237 break;

238 case Stmt::OMPFuseDirectiveClass:

240 break;

241 case Stmt::OMPForDirectiveClass:

243 break;

244 case Stmt::OMPForSimdDirectiveClass:

246 break;

247 case Stmt::OMPSectionsDirectiveClass:

249 break;

250 case Stmt::OMPSectionDirectiveClass:

252 break;

253 case Stmt::OMPSingleDirectiveClass:

255 break;

256 case Stmt::OMPMasterDirectiveClass:

258 break;

259 case Stmt::OMPCriticalDirectiveClass:

261 break;

262 case Stmt::OMPParallelForDirectiveClass:

264 break;

265 case Stmt::OMPParallelForSimdDirectiveClass:

267 break;

268 case Stmt::OMPParallelMasterDirectiveClass:

270 break;

271 case Stmt::OMPParallelSectionsDirectiveClass:

273 break;

274 case Stmt::OMPTaskDirectiveClass:

276 break;

277 case Stmt::OMPTaskyieldDirectiveClass:

279 break;

280 case Stmt::OMPErrorDirectiveClass:

282 break;

283 case Stmt::OMPBarrierDirectiveClass:

285 break;

286 case Stmt::OMPTaskwaitDirectiveClass:

288 break;

289 case Stmt::OMPTaskgroupDirectiveClass:

291 break;

292 case Stmt::OMPFlushDirectiveClass:

294 break;

295 case Stmt::OMPDepobjDirectiveClass:

297 break;

298 case Stmt::OMPScanDirectiveClass:

300 break;

301 case Stmt::OMPOrderedDirectiveClass:

303 break;

304 case Stmt::OMPAtomicDirectiveClass:

306 break;

307 case Stmt::OMPTargetDirectiveClass:

309 break;

310 case Stmt::OMPTeamsDirectiveClass:

312 break;

313 case Stmt::OMPCancellationPointDirectiveClass:

315 break;

316 case Stmt::OMPCancelDirectiveClass:

318 break;

319 case Stmt::OMPTargetDataDirectiveClass:

321 break;

322 case Stmt::OMPTargetEnterDataDirectiveClass:

324 break;

325 case Stmt::OMPTargetExitDataDirectiveClass:

327 break;

328 case Stmt::OMPTargetParallelDirectiveClass:

330 break;

331 case Stmt::OMPTargetParallelForDirectiveClass:

333 break;

334 case Stmt::OMPTaskLoopDirectiveClass:

336 break;

337 case Stmt::OMPTaskLoopSimdDirectiveClass:

339 break;

340 case Stmt::OMPMasterTaskLoopDirectiveClass:

342 break;

343 case Stmt::OMPMaskedTaskLoopDirectiveClass:

345 break;

346 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:

349 break;

350 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:

353 break;

354 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:

357 break;

358 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:

361 break;

362 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:

365 break;

366 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:

369 break;

370 case Stmt::OMPDistributeDirectiveClass:

372 break;

373 case Stmt::OMPTargetUpdateDirectiveClass:

375 break;

376 case Stmt::OMPDistributeParallelForDirectiveClass:

379 break;

380 case Stmt::OMPDistributeParallelForSimdDirectiveClass:

383 break;

384 case Stmt::OMPDistributeSimdDirectiveClass:

386 break;

387 case Stmt::OMPTargetParallelForSimdDirectiveClass:

390 break;

391 case Stmt::OMPTargetSimdDirectiveClass:

393 break;

394 case Stmt::OMPTeamsDistributeDirectiveClass:

396 break;

397 case Stmt::OMPTeamsDistributeSimdDirectiveClass:

400 break;

401 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:

404 break;

405 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:

408 break;

409 case Stmt::OMPTargetTeamsDirectiveClass:

411 break;

412 case Stmt::OMPTargetTeamsDistributeDirectiveClass:

415 break;

416 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:

419 break;

420 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:

423 break;

424 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:

427 break;

428 case Stmt::OMPInteropDirectiveClass:

430 break;

431 case Stmt::OMPDispatchDirectiveClass:

432 CGM.ErrorUnsupported(S, "OpenMP dispatch directive");

433 break;

434 case Stmt::OMPScopeDirectiveClass:

436 break;

437 case Stmt::OMPMaskedDirectiveClass:

439 break;

440 case Stmt::OMPGenericLoopDirectiveClass:

442 break;

443 case Stmt::OMPTeamsGenericLoopDirectiveClass:

445 break;

446 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:

449 break;

450 case Stmt::OMPParallelGenericLoopDirectiveClass:

453 break;

454 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:

457 break;

458 case Stmt::OMPParallelMaskedDirectiveClass:

460 break;

461 case Stmt::OMPAssumeDirectiveClass:

463 break;

464 case Stmt::OpenACCComputeConstructClass:

466 break;

467 case Stmt::OpenACCLoopConstructClass:

469 break;

470 case Stmt::OpenACCCombinedConstructClass:

472 break;

473 case Stmt::OpenACCDataConstructClass:

475 break;

476 case Stmt::OpenACCEnterDataConstructClass:

478 break;

479 case Stmt::OpenACCExitDataConstructClass:

481 break;

482 case Stmt::OpenACCHostDataConstructClass:

484 break;

485 case Stmt::OpenACCWaitConstructClass:

487 break;

488 case Stmt::OpenACCInitConstructClass:

490 break;

491 case Stmt::OpenACCShutdownConstructClass:

493 break;

494 case Stmt::OpenACCSetConstructClass:

496 break;

497 case Stmt::OpenACCUpdateConstructClass:

499 break;

500 case Stmt::OpenACCAtomicConstructClass:

502 break;

503 case Stmt::OpenACCCacheConstructClass:

505 break;

506 }

507}

508

512 default:

513 return false;

514 case Stmt::NullStmtClass:

515 break;

516 case Stmt::CompoundStmtClass:

518 break;

519 case Stmt::DeclStmtClass:

521 break;

522 case Stmt::LabelStmtClass:

524 break;

525 case Stmt::AttributedStmtClass:

527 break;

528 case Stmt::GotoStmtClass:

530 break;

531 case Stmt::BreakStmtClass:

533 break;

534 case Stmt::ContinueStmtClass:

536 break;

537 case Stmt::DefaultStmtClass:

539 break;

540 case Stmt::CaseStmtClass:

542 break;

543 case Stmt::DeferStmtClass:

545 break;

546 case Stmt::SEHLeaveStmtClass:

548 break;

549 case Stmt::SYCLKernelCallStmtClass:

550

551

552

553

554

555

556

557

558

559

560

561

562

563

564

565 break;

566 }

567 return true;

568}

569

570

571

572

576 "LLVM IR generation of compound statement ('{}')");

577

578

580

582}

583

586 bool GetLast,

588

591 I != E; ++I)

593

595 if (GetLast) {

596

597

598

599

600

603 if (const auto *LS = dyn_cast(LastStmt)) {

605 LastStmt = LS->getSubStmt();

606 } else if (const auto *AS = dyn_cast(LastStmt)) {

607

608

609 LastStmt = AS->getSubStmt();

610 } else {

611 llvm_unreachable("unknown value statement");

612 }

613 }

614

616

621 } else {

622

623

624

627 false);

628 }

629 }

630

631 return RetAlloca;

632}

633

635 llvm::BranchInst *BI = dyn_castllvm::BranchInst(BB->getTerminator());

636

637

638

639

641 return;

642

643

644 if (!BI || !BI->isUnconditional())

645 return;

646

647

648 if (BI->getIterator() != BB->begin())

649 return;

650

651 BB->replaceAllUsesWith(BI->getSuccessor(0));

652 BI->eraseFromParent();

653 BB->eraseFromParent();

654}

655

657 llvm::BasicBlock *CurBB = Builder.GetInsertBlock();

658

659

661

662 if (IsFinished && BB->use_empty()) {

663 delete BB;

664 return;

665 }

666

667

668

669 if (CurBB && CurBB->getParent())

670 CurFn->insert(std::next(CurBB->getIterator()), BB);

671 else

673 Builder.SetInsertPoint(BB);

674}

675

677

678

679

680 llvm::BasicBlock *CurBB = Builder.GetInsertBlock();

681

682 if (!CurBB || CurBB->getTerminator()) {

683

684

685 } else {

686

688 }

689

690 Builder.ClearInsertionPoint();

691}

692

694 bool inserted = false;

695 for (llvm::User *u : block->users()) {

696 if (llvm::Instruction *insn = dyn_castllvm::Instruction(u)) {

697 CurFn->insert(std::next(insn->getParent()->getIterator()), block);

698 inserted = true;

699 break;

700 }

701 }

702

703 if (!inserted)

705

706 Builder.SetInsertPoint(block);

707}

708

711 JumpDest &Dest = LabelMap[D];

712 if (Dest.isValid()) return Dest;

713

714

718 return Dest;

719}

720

722

723

724

725 if (EHStack.hasNormalCleanups() && CurLexicalScope)

726 CurLexicalScope->addLabel(D);

727

728 JumpDest &Dest = LabelMap[D];

729

730

731

734

735

736

737 } else {

741 }

742

744

745

747 if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {

749 DI->EmitLabel(D, Builder);

750 }

751 }

752

754}

755

756

757

759 assert(!Labels.empty());

761 = CGF.EHStack.getInnermostNormalCleanup();

762

763

764 for (const LabelDecl *Label : Labels) {

765 assert(CGF.LabelMap.count(Label));

766 JumpDest &dest = CGF.LabelMap.find(Label)->second;

770 }

771

772

774 ParentScope->Labels.append(Labels.begin(), Labels.end());

775 }

776}

777

778

788

790 bool nomerge = false;

791 bool noinline = false;

792 bool alwaysinline = false;

793 bool noconvergent = false;

794 HLSLControlFlowHintAttr::Spelling flattenOrBranch =

795 HLSLControlFlowHintAttr::SpellingNotCalculated;

796 const CallExpr *musttail = nullptr;

797 const AtomicAttr *AA = nullptr;

798

799 for (const auto *A : S.getAttrs()) {

800 switch (A->getKind()) {

801 default:

802 break;

803 case attr::NoMerge:

804 nomerge = true;

805 break;

806 case attr::NoInline:

807 noinline = true;

808 break;

809 case attr::AlwaysInline:

810 alwaysinline = true;

811 break;

812 case attr::NoConvergent:

813 noconvergent = true;

814 break;

815 case attr::MustTail: {

819 } break;

820 case attr::CXXAssume: {

825 Builder.CreateAssumption(AssumptionVal);

826 }

827 } break;

828 case attr::Atomic:

830 break;

831 case attr::HLSLControlFlowHint: {

833 } break;

834 }

835 }

844}

845

856

857

862 return;

863 }

864

865

868 llvm::BasicBlock *CurBB = Builder.GetInsertBlock();

869

870

872

873

874

876

878 if (CurBB && CurBB->getTerminator())

880}

881

884

885

886

889 if (Executed) {

892 }

893 return;

894 }

895

896

897

900

903

906

907

908

909 bool CondConstant;

912

914 const Stmt *Skipped = Else;

915 if (!CondConstant)

916 std::swap(Executed, Skipped);

917

918

919

921 if (CondConstant)

923 if (Executed) {

927 }

928 PGO->markStmtMaybeUsed(Skipped);

929 return;

930 }

931 }

932

933

934

937 llvm::BasicBlock *ElseBlock = ContBlock;

938 if (Else)

940

941

942

943

944

945

946

947

948

949

950

951

955 CGM.getCodeGenOpts().OptimizationLevel)

957

958

959

960

961

962

963

964 if (CGM.getCodeGenOpts().MCDCCoverage) {

966 nullptr,

968 } else {

971 Builder.CreateCondBr(BoolCondVal, ThenBlock, ElseBlock);

972 }

973

974

978 else

980 {

983 }

985

986

987 if (Else) {

988 {

989

992 }

993

996 {

999 }

1000 {

1001

1004 }

1005 }

1006

1007

1009

1010

1011

1014}

1015

1017 bool HasEmptyBody) {

1018 if (CGM.getCodeGenOpts().getFiniteLoops() ==

1020 return false;

1021

1022

1023

1024

1025

1026

1028 bool CondIsConstInt =

1029 !ControllingExpression ||

1031 Result.Val.isInt());

1032

1033 bool CondIsTrue = CondIsConstInt && (!ControllingExpression ||

1034 Result.Val.getInt().getBoolValue());

1035

1036

1038 return true;

1039

1040

1041

1042

1043

1044

1045 if (CGM.getCodeGenOpts().getFiniteLoops() ==

1048 if (HasEmptyBody && CondIsTrue) {

1049 CurFn->removeFnAttr(llvm::Attribute::MustProgress);

1050 return false;

1051 }

1052 return true;

1053 }

1054 return false;

1055}

1056

1057

1058

1059

1060

1061

1062

1063

1064

1065

1066template static bool hasEmptyLoopBody(const LoopStmt &S) {

1067 if constexpr (std::is_same_v<LoopStmt, ForStmt>) {

1068 if (S.getInc())

1069 return false;

1070 }

1071 const Stmt *Body = S.getBody();

1073 return true;

1074 if (const CompoundStmt *Compound = dyn_cast(Body))

1075 return Compound->body_empty();

1076 return false;

1077}

1078

1081

1082

1085

1086 if (CGM.shouldEmitConvergenceTokens())

1088 emitConvergenceLoopToken(LoopHeader.getBlock()));

1089

1090

1091

1093

1094

1095 BreakContinueStack.push_back(BreakContinue(S, LoopExit, LoopHeader));

1096

1097

1098

1099

1100

1101

1102

1103

1105

1108

1109

1110

1111

1113

1115

1116

1117

1118 llvm::ConstantInt *C = dyn_castllvm::ConstantInt(BoolCondVal);

1119 bool EmitBoolCondBranch = C || C->isOne();

1125

1126

1129

1130

1131 llvm::BasicBlock *LoopBody = createBasicBlock("while.body");

1132 if (EmitBoolCondBranch) {

1133 llvm::BasicBlock *ExitBlock = LoopExit.getBlock();

1136 llvm::MDNode *Weights =

1138 if (!Weights && CGM.getCodeGenOpts().OptimizationLevel)

1139 BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(

1141 auto *I = Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock, Weights);

1142

1143

1144

1145

1146

1147 if (auto *CondI = dyn_castllvm::Instruction(BoolCondVal))

1150

1151 if (ExitBlock != LoopExit.getBlock()) {

1154 }

1156 CGM.getDiags().Report(A->getLocation(),

1157 diag::warn_attribute_has_no_effect_on_infinite_loop)

1158 << A << A->getRange();

1159 CGM.getDiags().Report(

1161 diag::note_attribute_has_no_effect_on_infinite_loop_here)

1163 }

1164

1165

1166

1167 {

1170

1173 else

1176 }

1177

1178 BreakContinueStack.pop_back();

1179

1180

1182

1184

1186

1188

1189

1191

1192

1193

1194 if (!EmitBoolCondBranch)

1196

1197

1198

1201

1202 if (CGM.shouldEmitConvergenceTokens())

1204}

1205

1210

1212

1213

1214 BreakContinueStack.push_back(BreakContinue(S, LoopExit, LoopCond));

1215

1216

1218

1221 else

1223

1224 if (CGM.shouldEmitConvergenceTokens())

1226

1227 {

1230 }

1231

1233

1236

1237

1238

1239

1240

1241

1242

1244

1245 BreakContinueStack.pop_back();

1246

1247

1248

1249 llvm::ConstantInt *C = dyn_castllvm::ConstantInt(BoolCondVal);

1250 bool EmitBoolCondBranch = C || C->isZero();

1251

1253 LoopStack.push(LoopBody, CGM.getContext(), CGM.getCodeGenOpts(), DoAttrs,

1257

1258

1259 if (EmitBoolCondBranch) {

1261 auto *I = Builder.CreateCondBr(

1262 BoolCondVal, LoopBody, LoopExit.getBlock(),

1263 createProfileWeightsForLoop(S.getCond(), BackedgeCount));

1264

1265

1266

1267

1268

1269

1270 if (auto *CondI = dyn_castllvm::Instruction(BoolCondVal))

1273 }

1274

1276

1277

1279

1280

1281

1282 if (!EmitBoolCondBranch)

1284

1285

1286

1289

1290 if (CGM.shouldEmitConvergenceTokens())

1292}

1293

1297

1298 std::optional ForScope;

1301

1302

1305

1306

1307

1308

1310 llvm::BasicBlock *CondBlock = CondDest.getBlock();

1312

1313 if (CGM.shouldEmitConvergenceTokens())

1315

1317 LoopStack.push(CondBlock, CGM.getContext(), CGM.getCodeGenOpts(), ForAttrs,

1321

1322

1324

1325

1326

1327

1328

1329

1330

1331

1334 Continue = CondDest;

1337 BreakContinueStack.push_back(BreakContinue(S, LoopExit, Continue));

1338

1340

1341

1344

1345

1346

1348 BreakContinueStack.back().ContinueBlock = Continue;

1349 }

1350

1351

1352

1355

1356 llvm::BasicBlock *ExitBlock = LoopExit.getBlock();

1357

1358

1359 if (ForScope && ForScope->requiresCleanups())

1361

1362

1364

1365

1366

1368

1370

1371 llvm::MDNode *Weights =

1373 if (!Weights && CGM.getCodeGenOpts().OptimizationLevel)

1374 BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(

1376

1377 auto *I = Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights);

1378

1379

1380

1381

1382 if (auto *CondI = dyn_castllvm::Instruction(BoolCondVal))

1385

1386 if (ExitBlock != LoopExit.getBlock()) {

1389 }

1390

1392 } else {

1393

1394

1395 }

1396

1397

1400 else

1402 {

1403

1404

1407 }

1408

1409

1410

1411 auto *FinalBodyBB = Builder.GetInsertBlock();

1412

1413

1419 }

1420

1421 BreakContinueStack.pop_back();

1422

1424

1427

1428 if (ForScope)

1429 ForScope->ForceCleanup();

1430

1432

1433

1435

1436

1437

1440

1441 if (CGM.shouldEmitConvergenceTokens())

1443

1444 if (FinalBodyBB) {

1445

1446

1448 }

1449}

1450

1451void

1455

1457

1458

1464

1465

1466

1467

1470

1471 if (CGM.shouldEmitConvergenceTokens())

1473

1475 LoopStack.push(CondBlock, CGM.getContext(), CGM.getCodeGenOpts(), ForAttrs,

1478

1479

1480

1481 llvm::BasicBlock *ExitBlock = LoopExit.getBlock();

1484

1485

1487

1488

1489

1491 llvm::MDNode *Weights =

1493 if (!Weights && CGM.getCodeGenOpts().OptimizationLevel)

1494 BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(

1496 auto *I = Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights);

1497

1498

1499

1500

1501 if (auto *CondI = dyn_castllvm::Instruction(BoolCondVal))

1504

1505 if (ExitBlock != LoopExit.getBlock()) {

1508 }

1509

1513 else

1515

1516

1518

1519

1520 BreakContinueStack.push_back(BreakContinue(S, LoopExit, Continue));

1521

1522 {

1523

1527 }

1528

1529

1530 auto *FinalBodyBB = Builder.GetInsertBlock();

1531

1533

1536

1537 BreakContinueStack.pop_back();

1538

1540

1542

1544

1545

1547

1548

1549

1552

1553 if (CGM.shouldEmitConvergenceTokens())

1555

1556 if (FinalBodyBB) {

1557

1558

1560 }

1561}

1562

1563void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) {

1570 } else {

1572 true);

1573 }

1575}

1576

1577namespace {

1578

1579struct SaveRetExprRAII {

1580 SaveRetExprRAII(const Expr *RetExpr, CodeGenFunction &CGF)

1581 : OldRetExpr(CGF.RetExpr), CGF(CGF) {

1583 }

1584 ~SaveRetExprRAII() { CGF.RetExpr = OldRetExpr; }

1585 const Expr *OldRetExpr;

1586 CodeGenFunction &CGF;

1587};

1588}

1589

1590

1594 if (calleeQualType->isFunctionPointerType() ||

1595 calleeQualType->isFunctionReferenceType() ||

1596 calleeQualType->isBlockPointerType() ||

1597 calleeQualType->isMemberFunctionPointerType()) {

1599 } else if (auto *ty = dyn_cast(calleeQualType)) {

1600 calleeType = ty;

1601 } else if (auto CMCE = dyn_cast(CE)) {

1602 if (auto methodDecl = CMCE->getMethodDecl()) {

1603

1605 } else {

1606 return false;

1607 }

1608 } else {

1609 return false;

1610 }

1612}

1613

1614

1615

1616

1619 if (requiresReturnValueCheck()) {

1621 auto *SLocPtr =

1622 new llvm::GlobalVariable(CGM.getModule(), SLoc->getType(), false,

1623 llvm::GlobalVariable::PrivateLinkage, SLoc);

1624 SLocPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);

1625 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(SLocPtr);

1626 assert(ReturnLocation.isValid() && "No valid return location");

1627 Builder.CreateStore(SLocPtr, ReturnLocation);

1628 }

1629

1630

1632 Builder.CreateUnreachable();

1633 Builder.ClearInsertionPoint();

1634 }

1635

1636

1638

1639

1640

1641

1642

1643

1644

1645

1646

1647 SaveRetExprRAII SaveRetExpr(RV, *this);

1648

1650 if (const auto *EWC = dyn_cast_or_null(RV))

1651 RV = EWC->getSubExpr();

1652

1653

1654

1655 std::optional<llvm::SaveAndRestore<const CallExpr *>> SaveMustTail;

1658 if (auto CE = dyn_cast(RV)) {

1661 }

1662 }

1663 }

1664

1665

1666

1667

1671 CGM.getOpenMPRuntime()

1673 .isValid())) {

1674

1675

1676

1677

1678

1679

1681 Builder.CreateFlagStore(Builder.getTrue(), NRVOFlag);

1683

1684

1685 if (RV) {

1687 }

1688 } else if (!RV) {

1689

1690 } else if (FnRetTy->isReferenceType()) {

1691

1692

1696 } else {

1702 true);

1703 } else {

1706 }

1707 break;

1708 }

1711 true);

1712 break;

1720 break;

1721 }

1722 }

1723

1724 ++NumReturnExprs;

1726 ++NumSimpleReturnExprs;

1727

1730}

1731

1733

1734

1737

1738 for (const auto *I : S.decls())

1739 EmitDecl(*I, true);

1740}

1741

1743 -> const BreakContinue * {

1744 if (!S.hasLabelTarget())

1745 return &BreakContinueStack.back();

1746

1747 const Stmt *LoopOrSwitch = S.getNamedLoopOrSwitch();

1748 assert(LoopOrSwitch && "break/continue target not set?");

1749 for (const BreakContinue &BC : llvm::reverse(BreakContinueStack))

1750 if (BC.LoopOrSwitch == LoopOrSwitch)

1751 return &BC;

1752

1753 llvm_unreachable("break/continue target not found");

1754}

1755

1757 assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!");

1758

1759

1760

1761

1764

1767}

1768

1770 assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");

1771

1772

1773

1774

1777

1780}

1781

1782

1783

1784

1787 assert(S.getRHS() && "Expected RHS value in CaseStmt");

1788

1791

1792

1793

1794

1798

1799

1800 if (LHS.isSigned() ? RHS.slt(LHS) : RHS.ult(LHS))

1801 return;

1802

1804 llvm::APInt Range = RHS - LHS;

1805

1806 if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) {

1807

1809 unsigned NCases = Range.getZExtValue() + 1;

1810

1811

1812

1813

1814 uint64_t Weight = Total / NCases, Rem = Total % NCases;

1815 for (unsigned I = 0; I != NCases; ++I) {

1816 if (SwitchWeights)

1817 SwitchWeights->push_back(Weight + (Rem ? 1 : 0));

1818 else if (SwitchLikelihood)

1819 SwitchLikelihood->push_back(LH);

1820

1821 if (Rem)

1822 Rem--;

1823 SwitchInsn->addCase(Builder.getInt(LHS), CaseDest);

1824 ++LHS;

1825 }

1826 return;

1827 }

1828

1829

1830

1831 llvm::BasicBlock *RestoreBB = Builder.GetInsertBlock();

1832

1833

1834

1835

1836 llvm::BasicBlock *FalseDest = CaseRangeBlock;

1838

1839 CurFn->insert(CurFn->end(), CaseRangeBlock);

1840 Builder.SetInsertPoint(CaseRangeBlock);

1841

1842

1843 llvm::Value *Diff =

1844 Builder.CreateSub(SwitchInsn->getCondition(), Builder.getInt(LHS));

1845 llvm::Value *Cond =

1846 Builder.CreateICmpULE(Diff, Builder.getInt(Range), "inbounds");

1847

1848 llvm::MDNode *Weights = nullptr;

1849 if (SwitchWeights) {

1851 uint64_t DefaultCount = (*SwitchWeights)[0];

1852 Weights = createProfileWeights(ThisCount, DefaultCount);

1853

1854

1855

1856

1857 (*SwitchWeights)[0] += ThisCount;

1858 } else if (SwitchLikelihood)

1859 Cond = emitCondLikelihoodViaExpectIntrinsic(Cond, LH);

1860

1861 Builder.CreateCondBr(Cond, CaseDest, FalseDest, Weights);

1862

1863

1864 if (RestoreBB)

1865 Builder.SetInsertPoint(RestoreBB);

1866 else

1867 Builder.ClearInsertionPoint();

1868}

1869

1872

1873

1874

1875

1876

1877 if (!SwitchInsn) {

1879 return;

1880 }

1881

1882

1885 return;

1886 }

1887

1888 llvm::ConstantInt *CaseVal =

1890

1891

1893 if (auto ICE = dyn_cast(S.getLHS()))

1894 CE = dyn_cast(ICE->getSubExpr());

1895 else

1896 CE = dyn_cast(S.getLHS());

1897 if (CE) {

1898 if (auto DE = dyn_cast(CE->getSubExpr()))

1900 if (CGM.getCodeGenOpts().hasReducedDebugInfo())

1901 Dbg->EmitGlobalVariable(DE->getDecl(),

1902 APValue(llvm::APSInt(CaseVal->getValue())));

1903 }

1904

1905 if (SwitchLikelihood)

1907

1908

1909

1910

1911 if (CGM.getCodeGenOpts().hasProfileClangInstr() &&

1912 CGM.getCodeGenOpts().OptimizationLevel > 0 &&

1914 JumpDest Block = BreakContinueStack.back().BreakBlock;

1915

1916

1918 if (SwitchWeights)

1920 SwitchInsn->addCase(CaseVal, Block.getBlock());

1921

1922

1923

1924 if (Builder.GetInsertBlock()) {

1926 Builder.ClearInsertionPoint();

1927 }

1928 return;

1929 }

1930 }

1931

1934 if (SwitchWeights)

1936 SwitchInsn->addCase(CaseVal, CaseDest);

1937

1938

1939

1940

1941

1942

1943

1944

1945

1946

1947

1948

1949

1950

1951 const CaseStmt *CurCase = &S;

1953

1954

1955 while (NextCase && NextCase->getRHS() == nullptr) {

1956 CurCase = NextCase;

1957 llvm::ConstantInt *CaseVal =

1959

1960 if (SwitchWeights)

1962 if (CGM.getCodeGenOpts().hasProfileClangInstr()) {

1965 }

1966

1967

1968 if (SwitchLikelihood)

1970

1971 SwitchInsn->addCase(CaseVal, CaseDest);

1972 NextCase = dyn_cast(CurCase->getSubStmt());

1973 }

1974

1975

1976

1977

1980

1981

1983}

1984

1987

1988

1989

1990 if (!SwitchInsn) {

1992 return;

1993 }

1994

1995 llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest();

1996 assert(DefaultBlock->empty() &&

1997 "EmitDefaultStmt: Default block already defined?");

1998

1999 if (SwitchLikelihood)

2001

2003

2005}

2006

2007namespace {

2008struct EmitDeferredStatement final : EHScopeStack::Cleanup {

2011

2013

2014

2015

2016

2017

2018

2019

2020

2021

2022

2023

2024

2025

2026

2027

2028

2029

2030

2031

2032

2033

2034

2035

2036

2037

2038

2039

2040

2041

2042

2043

2044

2045

2046

2047

2048

2049

2050

2051

2052

2053

2054

2055

2056

2057

2058

2059

2060

2061

2062

2063

2064

2065

2066

2067

2068 llvm::Value *SavedCleanupDest = nullptr;

2070 SavedCleanupDest =

2072

2074

2077

2078

2080 }

2081};

2082}

2083

2087

2088

2089

2090

2091

2092

2093

2094

2095

2096

2097

2098

2099

2100

2101

2102

2103

2104

2105

2106

2107

2108

2109

2110

2114 bool &FoundCase,

2116

2117 if (!S)

2119

2120

2121

2122 if (const SwitchCase *SC = dyn_cast(S)) {

2123 if (S == Case) {

2124 FoundCase = true;

2126 ResultStmts);

2127 }

2128

2129

2131 ResultStmts);

2132 }

2133

2134

2135

2138

2139

2140

2141 if (const CompoundStmt *CS = dyn_cast(S)) {

2142

2143

2145 bool StartedInLiveCode = FoundCase;

2146 unsigned StartSize = ResultStmts.size();

2147

2148

2149 if (Case) {

2150

2151

2152

2153 bool HadSkippedDecl = false;

2154

2155

2156

2157 for (; Case && I != E; ++I) {

2159

2163

2164

2165

2166

2167 if (FoundCase) {

2168

2169

2170 if (HadSkippedDecl)

2172

2173 for (++I; I != E; ++I)

2177 }

2178 break;

2180

2181

2182

2183 assert(FoundCase && "Didn't find case but returned fallthrough?");

2184

2185 Case = nullptr;

2186

2187

2188

2189 if (HadSkippedDecl)

2191 break;

2192 }

2193 }

2194

2195 if (!FoundCase)

2197

2198 assert(!HadSkippedDecl && "fallthrough after skipping decl");

2199 }

2200

2201

2202

2203 bool AnyDecls = false;

2204 for (; I != E; ++I) {

2206

2210

2211

2212 break;

2214

2215

2216

2217 for (++I; I != E; ++I)

2221 }

2222 }

2223

2224

2225

2226

2227 if (AnyDecls) {

2228

2229

2230

2231

2232

2234 ResultStmts.resize(StartSize);

2235 ResultStmts.push_back(S);

2236 } else {

2238 }

2239 }

2240

2242 }

2243

2244

2245

2246

2247 if (Case) {

2251 }

2252

2253

2254

2256

2257

2258

2259 ResultStmts.push_back(S);

2261}

2262

2263

2264

2265

2266

2268 const llvm::APSInt &ConstantCondValue,

2272

2273

2275 const DefaultStmt *DefaultCase = nullptr;

2276

2278

2279

2280 if (const DefaultStmt *DS = dyn_cast(Case)) {

2281 DefaultCase = DS;

2282 continue;

2283 }

2284

2285

2287

2288 if (CS->getRHS()) return false;

2289

2290

2292 break;

2293 }

2294

2295

2296

2297 if (!Case) {

2298

2299

2300 if (!DefaultCase)

2302 Case = DefaultCase;

2303 }

2304

2305

2306

2307

2308

2309

2310

2311

2312

2313 bool FoundCase = false;

2314 ResultCase = Case;

2317 FoundCase;

2318}

2319

2320static std::optional<SmallVector<uint64_t, 16>>

2322

2323 if (Likelihoods.size() <= 1)

2324 return std::nullopt;

2325

2326 uint64_t NumUnlikely = 0;

2327 uint64_t NumNone = 0;

2328 uint64_t NumLikely = 0;

2329 for (const auto LH : Likelihoods) {

2330 switch (LH) {

2332 ++NumUnlikely;

2333 break;

2335 ++NumNone;

2336 break;

2338 ++NumLikely;

2339 break;

2340 }

2341 }

2342

2343

2344 if (NumUnlikely == 0 && NumLikely == 0)

2345 return std::nullopt;

2346

2347

2348

2349

2350

2351

2352

2353 const uint64_t Likely = INT32_MAX / (NumLikely + 2);

2354 const uint64_t None = Likely / (NumNone + 1);

2355 const uint64_t Unlikely = 0;

2356

2358 Result.reserve(Likelihoods.size());

2359 for (const auto LH : Likelihoods) {

2360 switch (LH) {

2362 Result.push_back(Unlikely);

2363 break;

2365 Result.push_back(None);

2366 break;

2368 Result.push_back(Likely);

2369 break;

2370 }

2371 }

2372

2373 return Result;

2374}

2375

2377

2378 llvm::SwitchInst *SavedSwitchInsn = SwitchInsn;

2381 llvm::BasicBlock *SavedCRBlock = CaseRangeBlock;

2382

2383

2384

2385 llvm::APSInt ConstantCondValue;

2391 if (Case)

2394

2397

2398

2399

2402

2403

2404

2405

2406 SwitchInsn = nullptr;

2407

2408

2409

2413 PGO->markStmtMaybeUsed(S.getBody());

2414

2415

2416

2417 SwitchInsn = SavedSwitchInsn;

2418

2419 return;

2420 }

2421 }

2422

2424

2426

2429

2434

2435

2436

2437

2438

2439 llvm::BasicBlock *DefaultBlock = createBasicBlock("sw.default");

2440 SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock);

2442

2443 if (HLSLControlFlowAttr != HLSLControlFlowHintAttr::SpellingNotCalculated) {

2444 llvm::MDBuilder MDHelper(CGM.getLLVMContext());

2445 llvm::ConstantInt *BranchHintConstant =

2447 HLSLControlFlowHintAttr::Spelling::Microsoft_branch

2448 ? llvm::ConstantInt::get(CGM.Int32Ty, 1)

2449 : llvm::ConstantInt::get(CGM.Int32Ty, 2);

2450 llvm::Metadata *Vals[] = {MDHelper.createString("hlsl.controlflow.hint"),

2451 MDHelper.createConstant(BranchHintConstant)};

2452 SwitchInsn->setMetadata("hlsl.controlflow.hint",

2453 llvm::MDNode::get(CGM.getLLVMContext(), Vals));

2454 }

2455

2456 if (PGO->haveRegionCounts()) {

2457

2458 uint64_t DefaultCount = 0;

2459 unsigned NumCases = 0;

2461 Case;

2465 NumCases += 1;

2466 }

2468 SwitchWeights->reserve(NumCases);

2469

2470

2471 SwitchWeights->push_back(DefaultCount);

2472 } else if (CGM.getCodeGenOpts().OptimizationLevel) {

2474

2476 }

2477

2478 CaseRangeBlock = DefaultBlock;

2479

2480

2481 Builder.ClearInsertionPoint();

2482

2483

2484

2486 if (!BreakContinueStack.empty())

2487 OuterContinue = BreakContinueStack.back().ContinueBlock;

2488

2489 BreakContinueStack.push_back(BreakContinue(S, SwitchExit, OuterContinue));

2490

2491

2493

2494 BreakContinueStack.pop_back();

2495

2496

2497

2498 SwitchInsn->setDefaultDest(CaseRangeBlock);

2499

2500

2501 if (!DefaultBlock->getParent()) {

2502

2503

2506

2507

2508 } else {

2509 DefaultBlock->replaceAllUsesWith(SwitchExit.getBlock());

2510 delete DefaultBlock;

2511 }

2512 }

2513

2515

2516

2519

2520

2521

2522

2523 auto *Call = dyn_cast(S.getCond());

2524 if (Call && CGM.getCodeGenOpts().OptimizationLevel != 0) {

2525 auto *FD = dyn_cast_or_null(Call->getCalleeDecl());

2526 if (FD && FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) {

2528 SwitchInsn->setMetadata(llvm::LLVMContext::MD_unpredictable,

2529 MDHelper.createUnpredictable());

2530 }

2531 }

2532

2533 if (SwitchWeights) {

2534 assert(SwitchWeights->size() == 1 + SwitchInsn->getNumCases() &&

2535 "switch weights do not match switch cases");

2536

2537 if (SwitchWeights->size() > 1)

2538 SwitchInsn->setMetadata(llvm::LLVMContext::MD_prof,

2539 createProfileWeights(*SwitchWeights));

2540 delete SwitchWeights;

2541 } else if (SwitchLikelihood) {

2542 assert(SwitchLikelihood->size() == 1 + SwitchInsn->getNumCases() &&

2543 "switch likelihoods do not match switch cases");

2544 std::optional<SmallVector<uint64_t, 16>> LHW =

2546 if (LHW) {

2547 llvm::MDBuilder MDHelper(CGM.getLLVMContext());

2548 SwitchInsn->setMetadata(llvm::LLVMContext::MD_prof,

2549 createProfileWeights(*LHW));

2550 }

2551 delete SwitchLikelihood;

2552 }

2553 SwitchInsn = SavedSwitchInsn;

2554 SwitchWeights = SavedSwitchWeights;

2555 SwitchLikelihood = SavedSwitchLikelihood;

2556 CaseRangeBlock = SavedCRBlock;

2557}

2558

2559

2560

2561

2562static std::string

2565 const AsmStmt &Stmt, const bool EarlyClobber,

2566 std::string *GCCReg = nullptr) {

2567 const DeclRefExpr *AsmDeclRef = dyn_cast(&AsmExpr);

2568 if (!AsmDeclRef)

2569 return Constraint;

2571 const VarDecl *Variable = dyn_cast(&Value);

2572 if (!Variable)

2573 return Constraint;

2574 if (Variable->getStorageClass() != SC_Register)

2575 return Constraint;

2576 AsmLabelAttr *Attr = Variable->getAttr();

2578 return Constraint;

2579 StringRef Register = Attr->getLabel();

2580 assert(Target.isValidGCCRegisterName(Register));

2581

2582

2584 if (Target.validateOutputConstraint(Info) &&

2587 return Constraint;

2588 }

2589

2590 Register = Target.getNormalizedGCCRegisterName(Register);

2591 if (GCCReg != nullptr)

2592 *GCCReg = Register.str();

2593 return (EarlyClobber ? "&{" : "{") + Register.str() + "}";

2594}

2595

2596std::pair<llvm::Value*, llvm::Type *> CodeGenFunction::EmitAsmInputLValue(

2597 const TargetInfo::ConstraintInfo &Info, LValue InputValue,

2598 QualType InputType, std::string &ConstraintStr, SourceLocation Loc) {

2602

2603 llvm::Type *Ty = ConvertType(InputType);

2604 uint64_t Size = CGM.getDataLayout().getTypeSizeInBits(Ty);

2605 if ((Size <= 64 && llvm::isPowerOf2_64(Size)) ||

2606 getTargetHooks().isScalarizableAsmOperand(*this, Ty)) {

2607 Ty = llvm::IntegerType::get(getLLVMContext(), Size);

2608

2609 return {Builder.CreateLoad(InputValue.getAddress().withElementType(Ty)),

2610 nullptr};

2611 }

2612 }

2613

2614 Address Addr = InputValue.getAddress();

2615 ConstraintStr += '*';

2616 return {InputValue.getPointer(*this), Addr.getElementType()};

2617}

2618

2619std::pair<llvm::Value *, llvm::Type *>

2620CodeGenFunction::EmitAsmInput(const TargetInfo::ConstraintInfo &Info,

2621 const Expr *InputExpr,

2622 std::string &ConstraintStr) {

2623

2624

2627 Expr::EvalResult EVResult;

2629

2630 llvm::APSInt IntResult;

2633 return {llvm::ConstantInt::get(getLLVMContext(), IntResult), nullptr};

2634 }

2635

2636 Expr::EvalResult Result;

2639 nullptr};

2640 }

2641

2645 if (InputExpr->getStmtClass() == Expr::CXXThisExprClass)

2648 LValue Dest = EmitLValue(InputExpr);

2649 return EmitAsmInputLValue(Info, Dest, InputExpr->getType(), ConstraintStr,

2651}

2652

2653

2654

2655

2656

2660

2661 Locs.push_back(llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(

2663 StringRef StrVal = Str->getString();

2664 if (!StrVal.empty()) {

2667 unsigned StartToken = 0;

2668 unsigned ByteOffset = 0;

2669

2670

2671

2672 for (unsigned i = 0, e = StrVal.size() - 1; i != e; ++i) {

2673 if (StrVal[i] != '\n') continue;

2675 i + 1, SM, LangOpts, CGF.getTarget(), &StartToken, &ByteOffset);

2676 Locs.push_back(llvm::ConstantAsMetadata::get(

2678 }

2679 }

2680

2681 return llvm::MDNode::get(CGF.getLLVMContext(), Locs);

2682}

2683

2685 bool HasUnwindClobber, bool ReadOnly,

2686 bool ReadNone, bool NoMerge, bool NoConvergent,

2688 const std::vector<llvm::Type *> &ResultRegTypes,

2689 const std::vector<llvm::Type *> &ArgElemTypes,

2691 std::vector<llvm::Value *> &RegResults) {

2692 if (!HasUnwindClobber)

2693 Result.addFnAttr(llvm::Attribute::NoUnwind);

2694

2695 if (NoMerge)

2696 Result.addFnAttr(llvm::Attribute::NoMerge);

2697

2698 if (!HasSideEffect) {

2699 if (ReadNone)

2700 Result.setDoesNotAccessMemory();

2701 else if (ReadOnly)

2702 Result.setOnlyReadsMemory();

2703 }

2704

2705

2706 for (auto Pair : llvm::enumerate(ArgElemTypes)) {

2707 if (Pair.value()) {

2708 auto Attr = llvm::Attribute::get(

2709 CGF.getLLVMContext(), llvm::Attribute::ElementType, Pair.value());

2710 Result.addParamAttr(Pair.index(), Attr);

2711 }

2712 }

2713

2714

2715

2717 if (const auto *gccAsmStmt = dyn_cast(&S);

2718 gccAsmStmt &&

2719 (SL = dyn_cast(gccAsmStmt->getAsmStringExpr()))) {

2721 } else {

2722

2723

2724 llvm::Constant *Loc =

2726 Result.setMetadata("srcloc",

2728 llvm::ConstantAsMetadata::get(Loc)));

2729 }

2730

2731

2733

2735

2736

2737

2738

2739 Result.addFnAttr(llvm::Attribute::Convergent);

2740

2741 if (ResultRegTypes.size() == 1) {

2742 RegResults.push_back(&Result);

2743 } else {

2744 for (unsigned i = 0, e = ResultRegTypes.size(); i != e; ++i) {

2745 llvm::Value *Tmp = CGF.Builder.CreateExtractValue(&Result, i, "asmresult");

2746 RegResults.push_back(Tmp);

2747 }

2748 }

2749}

2750

2751static void

2758 const llvm::BitVector &ResultTypeRequiresCast,

2759 const std::vector<std::optional<std::pair<unsigned, unsigned>>>

2760 &ResultBounds) {

2764

2765 assert(RegResults.size() == ResultRegTypes.size());

2766 assert(RegResults.size() == ResultTruncRegTypes.size());

2767 assert(RegResults.size() == ResultRegDests.size());

2768

2769

2770 assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());

2771 assert(ResultBounds.size() <= ResultRegDests.size());

2772

2773 for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {

2774 llvm::Value *Tmp = RegResults[i];

2775 llvm::Type *TruncTy = ResultTruncRegTypes[i];

2776

2777 if ((i < ResultBounds.size()) && ResultBounds[i].has_value()) {

2778 const auto [LowerBound, UpperBound] = ResultBounds[i].value();

2779

2780 assert(LowerBound == 0 && "Output operand lower bound is not zero.");

2781 llvm::Constant *UpperBoundConst =

2782 llvm::ConstantInt::get(Tmp->getType(), UpperBound);

2783 llvm::Value *IsBooleanValue =

2784 Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, UpperBoundConst);

2785 llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);

2786 Builder.CreateCall(FnAssume, IsBooleanValue);

2787 }

2788

2789

2790

2791 if (ResultRegTypes[i] != TruncTy) {

2792

2793

2794

2795 if (TruncTy->isFloatingPointTy())

2796 Tmp = Builder.CreateFPTrunc(Tmp, TruncTy);

2797 else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {

2798 uint64_t ResSize = CGM.getDataLayout().getTypeSizeInBits(TruncTy);

2799 Tmp = Builder.CreateTrunc(

2800 Tmp, llvm::IntegerType::get(CTX, (unsigned)ResSize));

2801 Tmp = Builder.CreateIntToPtr(Tmp, TruncTy);

2802 } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {

2803 uint64_t TmpSize =

2805 Tmp = Builder.CreatePtrToInt(

2806 Tmp, llvm::IntegerType::get(CTX, (unsigned)TmpSize));

2807 Tmp = Builder.CreateTrunc(Tmp, TruncTy);

2808 } else if (Tmp->getType()->isIntegerTy() && TruncTy->isIntegerTy()) {

2809 Tmp = Builder.CreateZExtOrTrunc(Tmp, TruncTy);

2810 } else if (Tmp->getType()->isVectorTy() || TruncTy->isVectorTy()) {

2811 Tmp = Builder.CreateBitCast(Tmp, TruncTy);

2812 }

2813 }

2814

2816 LValue Dest = ResultRegDests[i];

2817

2818

2819 if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) {

2821 Address A = Dest.getAddress().withElementType(ResultRegTypes[i]);

2823 llvm::StoreInst *S = Builder.CreateStore(Tmp, A);

2825 continue;

2826 }

2827

2833 diag::err_store_value_to_reg);

2834 return;

2835 }

2837 }

2839 }

2840}

2841

2844 constexpr auto Name = "__ASM__hipstdpar_unsupported";

2845

2846 std::string Asm;

2847 if (auto GCCAsm = dyn_cast(&S))

2848 Asm = GCCAsm->getAsmString();

2849

2851

2852 auto StrTy = llvm::ConstantDataArray::getString(Ctx, Asm);

2853 auto FnTy = llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx),

2854 {StrTy->getType()}, false);

2855 auto UBF = CGF->CGM.getModule().getOrInsertFunction(Name, FnTy);

2856

2857 CGF->Builder.CreateCall(UBF, {StrTy});

2858}

2859

2861

2863

2864

2866

2867

2870

2872 bool IsValidTargetAsm = true;

2873 for (unsigned i = 0, e = S.getNumOutputs(); i != e && IsValidTargetAsm; i++) {

2874 StringRef Name;

2875 if (const GCCAsmStmt *GAS = dyn_cast(&S))

2876 Name = GAS->getOutputName(i);

2879 if (IsHipStdPar && !IsValid)

2880 IsValidTargetAsm = false;

2881 else

2882 assert(IsValid && "Failed to parse output constraint");

2883 OutputConstraintInfos.push_back(Info);

2884 }

2885

2886 for (unsigned i = 0, e = S.getNumInputs(); i != e && IsValidTargetAsm; i++) {

2887 StringRef Name;

2888 if (const GCCAsmStmt *GAS = dyn_cast(&S))

2889 Name = GAS->getInputName(i);

2891 bool IsValid =

2893 if (IsHipStdPar && !IsValid)

2894 IsValidTargetAsm = false;

2895 else

2896 assert(IsValid && "Failed to parse input constraint");

2897 InputConstraintInfos.push_back(Info);

2898 }

2899

2900 if (!IsValidTargetAsm)

2902

2903 std::string Constraints;

2904

2905 std::vector ResultRegDests;

2906 std::vector ResultRegQualTys;

2907 std::vector<llvm::Type *> ResultRegTypes;

2908 std::vector<llvm::Type *> ResultTruncRegTypes;

2909 std::vector<llvm::Type *> ArgTypes;

2910 std::vector<llvm::Type *> ArgElemTypes;

2911 std::vectorllvm::Value\* Args;

2912 llvm::BitVector ResultTypeRequiresCast;

2913 std::vector<std::optional<std::pair<unsigned, unsigned>>> ResultBounds;

2914

2915

2916 std::string InOutConstraints;

2917 std::vectorllvm::Value\* InOutArgs;

2918 std::vectorllvm::Type\* InOutArgTypes;

2919 std::vectorllvm::Type\* InOutArgElemTypes;

2920

2921

2922 std::vectorstd::string OutputConstraints;

2923

2924

2925 llvm::SmallSet<std::string, 8> PhysRegOutputs;

2926

2927

2928

2929

2930

2931

2932

2933 bool ReadOnly = true, ReadNone = true;

2934

2935 for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) {

2937

2938

2941 StringRef(OutputConstraint).substr(1), &OutputConstraintInfos);

2942

2945

2946 std::string GCCReg;

2950 &GCCReg);

2951

2952 if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second)

2953 CGM.Error(S.getAsmLoc(), "multiple outputs to hard register: " + GCCReg);

2954

2955 OutputConstraints.push_back(OutputConstraint);

2957 if (!Constraints.empty())

2958 Constraints += ',';

2959

2960

2961

2965 if (!Info.allowsMemory() && IsScalarOrAggregate) {

2966

2967 Constraints += "=" + OutputConstraint;

2968 ResultRegQualTys.push_back(QTy);

2969 ResultRegDests.push_back(Dest);

2970

2972

2976 Ty->isAggregateType());

2977

2978 ResultTruncRegTypes.push_back(Ty);

2979 ResultTypeRequiresCast.push_back(RequiresCast);

2980

2981 if (RequiresCast) {

2983 if (Size)

2984 Ty = llvm::IntegerType::get(getLLVMContext(), Size);

2985 else

2986 CGM.Error(OutExpr->getExprLoc(), "output size should not be zero");

2987 }

2988 ResultRegTypes.push_back(Ty);

2989

2990

2991

2993 unsigned InputNo;

2994 for (InputNo = 0; InputNo != S.getNumInputs(); ++InputNo) {

2997 break;

2998 }

2999 assert(InputNo != S.getNumInputs() && "Didn't find matching input!");

3000

3003

3006

3007 ResultRegTypes.back() = ConvertType(InputTy);

3008 }

3009 }

3010 if (llvm::Type* AdjTy =

3011 getTargetHooks().adjustInlineAsmType(*this, OutputConstraint,

3012 ResultRegTypes.back()))

3013 ResultRegTypes.back() = AdjTy;

3014 else {

3016 diag::err_asm_invalid_type_in_input)

3017 << OutExpr->getType() << OutputConstraint;

3018 }

3019

3020

3021 if (auto *VT = dyn_castllvm::VectorType(ResultRegTypes.back()))

3022 LargestVectorWidth =

3023 std::max((uint64_t)LargestVectorWidth,

3024 VT->getPrimitiveSizeInBits().getKnownMinValue());

3025 } else {

3027

3028

3029

3030

3031

3034

3035 ArgTypes.push_back(DestAddr.getType());

3038 Constraints += "=*";

3039 Constraints += OutputConstraint;

3040 ReadOnly = ReadNone = false;

3041 }

3042

3044 InOutConstraints += ',';

3045

3047 llvm::Value *Arg;

3048 llvm::Type *ArgElemType;

3049 std::tie(Arg, ArgElemType) = EmitAsmInputLValue(

3050 Info, Dest, InputExpr->getType(), InOutConstraints,

3052

3053 if (llvm::Type* AdjTy =

3054 getTargetHooks().adjustInlineAsmType(*this, OutputConstraint,

3055 Arg->getType()))

3056 Arg = Builder.CreateBitCast(Arg, AdjTy);

3057

3058

3059 if (auto *VT = dyn_castllvm::VectorType(Arg->getType()))

3060 LargestVectorWidth =

3061 std::max((uint64_t)LargestVectorWidth,

3062 VT->getPrimitiveSizeInBits().getKnownMinValue());

3063

3065 InOutConstraints += llvm::utostr(i);

3066 else

3067 InOutConstraints += OutputConstraint;

3068

3069 InOutArgTypes.push_back(Arg->getType());

3070 InOutArgElemTypes.push_back(ArgElemType);

3071 InOutArgs.push_back(Arg);

3072 }

3073 }

3074

3075

3076

3080

3082 CGM.getTargetCodeGenInfo().addReturnRegisterOutputs(

3083 *this, ReturnSlot, Constraints, ResultRegTypes, ResultTruncRegTypes,

3086 }

3087 }

3088

3089 for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) {

3091

3093

3095 ReadNone = false;

3096

3097 if (!Constraints.empty())

3098 Constraints += ',';

3099

3100

3102 InputConstraint =

3104

3107 getTarget(), CGM, S, false );

3108

3109 std::string ReplaceConstraint (InputConstraint);

3110 llvm::Value *Arg;

3111 llvm::Type *ArgElemType;

3112 std::tie(Arg, ArgElemType) = EmitAsmInput(Info, InputExpr, Constraints);

3113

3114

3115

3116

3117

3118

3123

3126

3129 llvm::Type *OutputTy = ConvertType(OutputType);

3131 Arg = Builder.CreateZExt(Arg, OutputTy);

3134 else if (OutputTy->isFloatingPointTy())

3135 Arg = Builder.CreateFPExt(Arg, OutputTy);

3136 }

3137

3138 ReplaceConstraint = OutputConstraints[Output];

3139 }

3140 if (llvm::Type* AdjTy =

3141 getTargetHooks().adjustInlineAsmType(*this, ReplaceConstraint,

3142 Arg->getType()))

3143 Arg = Builder.CreateBitCast(Arg, AdjTy);

3144 else

3145 CGM.getDiags().Report(S.getAsmLoc(), diag::err_asm_invalid_type_in_input)

3146 << InputExpr->getType() << InputConstraint;

3147

3148

3149 if (auto *VT = dyn_castllvm::VectorType(Arg->getType()))

3150 LargestVectorWidth =

3151 std::max((uint64_t)LargestVectorWidth,

3152 VT->getPrimitiveSizeInBits().getKnownMinValue());

3153

3154 ArgTypes.push_back(Arg->getType());

3155 ArgElemTypes.push_back(ArgElemType);

3156 Args.push_back(Arg);

3157 Constraints += InputConstraint;

3158 }

3159

3160

3161 for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) {

3162 ArgTypes.push_back(InOutArgTypes[i]);

3163 ArgElemTypes.push_back(InOutArgElemTypes[i]);

3164 Args.push_back(InOutArgs[i]);

3165 }

3166 Constraints += InOutConstraints;

3167

3168

3170 llvm::BasicBlock *Fallthrough = nullptr;

3171 bool IsGCCAsmGoto = false;

3172 if (const auto *GS = dyn_cast(&S)) {

3173 IsGCCAsmGoto = GS->isAsmGoto();

3174 if (IsGCCAsmGoto) {

3175 for (const auto *E : GS->labels()) {

3177 Transfer.push_back(Dest.getBlock());

3178 if (!Constraints.empty())

3179 Constraints += ',';

3180 Constraints += "!i";

3181 }

3183 }

3184 }

3185

3186 bool HasUnwindClobber = false;

3187

3188

3189 for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) {

3190 std::string Clobber = S.getClobber(i);

3191

3192 if (Clobber == "memory")

3193 ReadOnly = ReadNone = false;

3194 else if (Clobber == "unwind") {

3195 HasUnwindClobber = true;

3196 continue;

3197 } else if (Clobber != "cc") {

3199 if (CGM.getCodeGenOpts().StackClashProtector &&

3200 getTarget().isSPRegName(Clobber)) {

3202 diag::warn_stack_clash_protection_inline_asm);

3203 }

3204 }

3205

3207 if (Clobber == "eax" || Clobber == "edx") {

3208 if (Constraints.find("=&A") != std:🧵:npos)

3209 continue;

3210 std:🧵:size_type position1 =

3211 Constraints.find("={" + Clobber + "}");

3212 if (position1 != std:🧵:npos) {

3213 Constraints.insert(position1 + 1, "&");

3214 continue;

3215 }

3216 std:🧵:size_type position2 = Constraints.find("=A");

3217 if (position2 != std:🧵:npos) {

3218 Constraints.insert(position2 + 1, "&");

3219 continue;

3220 }

3221 }

3222 }

3223 if (!Constraints.empty())

3224 Constraints += ',';

3225

3226 Constraints += "~{";

3227 Constraints += Clobber;

3228 Constraints += '}';

3229 }

3230

3231 assert(!(HasUnwindClobber && IsGCCAsmGoto) &&

3232 "unwind clobber can't be used with asm goto");

3233

3234

3236 if (!MachineClobbers.empty()) {

3237 if (!Constraints.empty())

3238 Constraints += ',';

3239 Constraints += MachineClobbers;

3240 }

3241

3242 llvm::Type *ResultType;

3243 if (ResultRegTypes.empty())

3244 ResultType = VoidTy;

3245 else if (ResultRegTypes.size() == 1)

3246 ResultType = ResultRegTypes[0];

3247 else

3248 ResultType = llvm::StructType::get(getLLVMContext(), ResultRegTypes);

3249

3250 llvm::FunctionType *FTy =

3251 llvm::FunctionType::get(ResultType, ArgTypes, false);

3252

3254

3255 llvm::InlineAsm::AsmDialect GnuAsmDialect =

3257 ? llvm::InlineAsm::AD_ATT

3258 : llvm::InlineAsm::AD_Intel;

3259 llvm::InlineAsm::AsmDialect AsmDialect = isa(&S) ?

3260 llvm::InlineAsm::AD_Intel : GnuAsmDialect;

3261

3262 llvm::InlineAsm *IA = llvm::InlineAsm::get(

3263 FTy, AsmString, Constraints, HasSideEffect,

3264 false, AsmDialect, HasUnwindClobber);

3265 std::vectorllvm::Value\* RegResults;

3266 llvm::CallBrInst *CBR;

3267 llvm::DenseMap<llvm::BasicBlock *, SmallVector<llvm::Value *, 4>>

3268 CBRRegResults;

3269 if (IsGCCAsmGoto) {

3270 CBR = Builder.CreateCallBr(IA, Fallthrough, Transfer, Args);

3272 UpdateAsmCallInst(*CBR, HasSideEffect, false, ReadOnly,

3275 ArgElemTypes, *this, RegResults);

3276

3277

3278

3279 if (!RegResults.empty()) {

3280 unsigned i = 0;

3281 for (llvm::BasicBlock *Dest : CBR->getIndirectDests()) {

3282 llvm::Twine SynthName = Dest->getName() + ".split";

3284 llvm::IRBuilderBase::InsertPointGuard IPG(Builder);

3285 Builder.SetInsertPoint(SynthBB);

3286

3287 if (ResultRegTypes.size() == 1) {

3288 CBRRegResults[SynthBB].push_back(CBR);

3289 } else {

3290 for (unsigned j = 0, e = ResultRegTypes.size(); j != e; ++j) {

3291 llvm::Value *Tmp = Builder.CreateExtractValue(CBR, j, "asmresult");

3292 CBRRegResults[SynthBB].push_back(Tmp);

3293 }

3294 }

3295

3298 CBR->setIndirectDest(i++, SynthBB);

3299 }

3300 }

3301 } else if (HasUnwindClobber) {

3306 ArgElemTypes, *this, RegResults);

3307 } else {

3308 llvm::CallInst *Result =

3313 ArgElemTypes, *this, RegResults);

3314 }

3315

3316 EmitAsmStores(*this, S, RegResults, ResultRegTypes, ResultTruncRegTypes,

3317 ResultRegDests, ResultRegQualTys, ResultTypeRequiresCast,

3318 ResultBounds);

3319

3320

3321

3322

3323 if (IsGCCAsmGoto && !CBRRegResults.empty()) {

3324 for (llvm::BasicBlock *Succ : CBR->getIndirectDests()) {

3325 llvm::IRBuilderBase::InsertPointGuard IPG(Builder);

3326 Builder.SetInsertPoint(Succ, --(Succ->end()));

3327 EmitAsmStores(*this, S, CBRRegResults[Succ], ResultRegTypes,

3328 ResultTruncRegTypes, ResultRegDests, ResultRegQualTys,

3329 ResultTypeRequiresCast, ResultBounds);

3330 }

3331 }

3332}

3333

3337

3338

3341

3345 I != E; ++I, ++CurField) {

3347 if (CurField->hasCapturedVLAType()) {

3349 } else {

3351 }

3352 }

3353

3354 return SlotLV;

3355}

3356

3357

3358

3359llvm::Function *

3362

3363

3364 CodeGenFunction CGF(CGM, true);

3368

3369

3371

3372 return F;

3373}

3374

3379

3380

3381llvm::Function *

3384 "CapturedStmtInfo should be set when generating the captured function");

3388 assert(CD->hasBody() && "missing CapturedDecl body");

3389

3390

3394

3395

3397 CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);

3398 llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo);

3399

3400 llvm::Function *F =

3401 llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage,

3403 CGM.SetInternalFunctionAttributes(CD, F, FuncInfo);

3405 F->addFnAttr(llvm::Attribute::NoUnwind);

3406

3407

3410

3413

3414

3417 for (auto *FD : RD->fields()) {

3418 if (FD->hasCapturedVLAType()) {

3419 auto *ExprArg =

3422 auto VAT = FD->getCapturedVLAType();

3423 VLASizeMap[VAT->getSizeExpr()] = ExprArg;

3424 }

3425 }

3426

3427

3432 }

3433

3434 PGO->assignRegionCounters(GlobalDecl(CD), F);

3437

3438 return F;

3439}

3440

3441

3442

3444 for (auto &I : *BB) {

3445 if (auto *CI = dyn_castllvm::ConvergenceControlInst(&I))

3446 return CI;

3447 }

3448 return nullptr;

3449}

3450

3451llvm::CallBase *

3452CodeGenFunction::addConvergenceControlToken(llvm::CallBase *Input) {

3454 assert(ParentToken);

3455

3456 llvm::Value *bundleArgs[] = {ParentToken};

3457 llvm::OperandBundleDef OB("convergencectrl", bundleArgs);

3458 auto *Output = llvm::CallBase::addOperandBundle(

3459 Input, llvm::LLVMContext::OB_convergencectrl, OB, Input->getIterator());

3460 Input->replaceAllUsesWith(Output);

3461 Input->eraseFromParent();

3462 return Output;

3463}

3464

3465llvm::ConvergenceControlInst *

3466CodeGenFunction::emitConvergenceLoopToken(llvm::BasicBlock *BB) {

3468 assert(ParentToken);

3469 return llvm::ConvergenceControlInst::CreateLoop(*BB, ParentToken);

3470}

3471

3472llvm::ConvergenceControlInst *

3473CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) {

3474 llvm::BasicBlock *BB = &F->getEntryBlock();

3476 if (Token)

3477 return Token;

3478

3479

3480

3481 F->setConvergent();

3482 return llvm::ConvergenceControlInst::CreateEntry(*BB);

3483}

Defines enum values for all the target-independent builtin functions.

static std::string AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr, const TargetInfo &Target, CodeGenModule &CGM, const AsmStmt &Stmt, const bool EarlyClobber, std::string *GCCReg=nullptr)

AddVariableConstraints - Look at AsmExpr and if it is a variable declared as using a particular regis...

Definition CGStmt.cpp:2563

static bool FindCaseStatementsForValue(const SwitchStmt &S, const llvm::APSInt &ConstantCondValue, SmallVectorImpl< const Stmt * > &ResultStmts, ASTContext &C, const SwitchCase *&ResultCase)

FindCaseStatementsForValue - Find the case statement being jumped to and then invoke CollectStatement...

Definition CGStmt.cpp:2267

static llvm::ConvergenceControlInst * getConvergenceToken(llvm::BasicBlock *BB)

Definition CGStmt.cpp:3443

static void EmitHipStdParUnsupportedAsm(CodeGenFunction *CGF, const AsmStmt &S)

Definition CGStmt.cpp:2842

static std::optional< SmallVector< uint64_t, 16 > > getLikelihoodWeights(ArrayRef< Stmt::Likelihood > Likelihoods)

Definition CGStmt.cpp:2321

static llvm::MDNode * getAsmSrcLocInfo(const StringLiteral *Str, CodeGenFunction &CGF)

getAsmSrcLocInfo - Return the !srcloc metadata node to attach to an inline asm call instruction.

Definition CGStmt.cpp:2657

static bool isSwiftAsyncCallee(const CallExpr *CE)

Determine if the given call uses the swiftasync calling convention.

Definition CGStmt.cpp:1591

static CSFC_Result CollectStatementsForCase(const Stmt *S, const SwitchCase *Case, bool &FoundCase, SmallVectorImpl< const Stmt * > &ResultStmts)

Definition CGStmt.cpp:2112

static void EmitAsmStores(CodeGenFunction &CGF, const AsmStmt &S, const llvm::ArrayRef< llvm::Value * > RegResults, const llvm::ArrayRef< llvm::Type * > ResultRegTypes, const llvm::ArrayRef< llvm::Type * > ResultTruncRegTypes, const llvm::ArrayRef< LValue > ResultRegDests, const llvm::ArrayRef< QualType > ResultRegQualTys, const llvm::BitVector &ResultTypeRequiresCast, const std::vector< std::optional< std::pair< unsigned, unsigned > > > &ResultBounds)

Definition CGStmt.cpp:2752

static bool hasEmptyLoopBody(const LoopStmt &S)

Definition CGStmt.cpp:1066

CSFC_Result

CollectStatementsForCase - Given the body of a 'switch' statement and a constant value that is being ...

Definition CGStmt.cpp:2111

@ CSFC_Failure

Definition CGStmt.cpp:2111

@ CSFC_Success

Definition CGStmt.cpp:2111

@ CSFC_FallThrough

Definition CGStmt.cpp:2111

static void UpdateAsmCallInst(llvm::CallBase &Result, bool HasSideEffect, bool HasUnwindClobber, bool ReadOnly, bool ReadNone, bool NoMerge, bool NoConvergent, const AsmStmt &S, const std::vector< llvm::Type * > &ResultRegTypes, const std::vector< llvm::Type * > &ArgElemTypes, CodeGenFunction &CGF, std::vector< llvm::Value * > &RegResults)

Definition CGStmt.cpp:2684

llvm::MachO::Target Target

Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...

Defines the SourceManager interface.

APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...

bool toIntegralConstant(APSInt &Result, QualType SrcTy, const ASTContext &Ctx) const

Try to convert this value to an integral constant.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

SourceManager & getSourceManager()

QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const

getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...

uint64_t getTypeSize(QualType T) const

Return the size of the specified (complete) type T, in bits.

CanQualType getCanonicalTagType(const TagDecl *TD) const

AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.

std::string getInputConstraint(unsigned i) const

getInputConstraint - Return the specified input constraint.

std::string getOutputConstraint(unsigned i) const

getOutputConstraint - Return the constraint string for the specified output operand.

SourceLocation getAsmLoc() const

const Expr * getInputExpr(unsigned i) const

unsigned getNumClobbers() const

const Expr * getOutputExpr(unsigned i) const

unsigned getNumOutputs() const

std::string generateAsmString(const ASTContext &C) const

Assemble final IR asm string.

unsigned getNumInputs() const

std::string getClobber(unsigned i) const

Attr - This represents one attribute.

Represents an attribute applied to a statement.

ArrayRef< const Attr * > getAttrs() const

BreakStmt - This represents a break.

CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...

DeclStmt * getBeginStmt()

DeclStmt * getLoopVarStmt()

DeclStmt * getRangeStmt()

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

Represents the body of a CapturedStmt, and serves as its DeclContext.

ImplicitParamDecl * getContextParam() const

Retrieve the parameter containing captured variables.

param_iterator param_end() const

Retrieve an iterator one past the last parameter decl.

param_iterator param_begin() const

Retrieve an iterator pointing to the first parameter decl.

Stmt * getBody() const override

getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...

This captures a statement into a function.

CapturedDecl * getCapturedDecl()

Retrieve the outlined function declaration.

const RecordDecl * getCapturedRecordDecl() const

Retrieve the record declaration for captured variables.

capture_init_iterator capture_init_begin()

Retrieve the first initialization argument.

SourceLocation getBeginLoc() const LLVM_READONLY

capture_init_iterator capture_init_end()

Retrieve the iterator pointing one past the last initialization argument.

Expr *const * const_capture_init_iterator

Const iterator that walks over the capture initialization arguments.

CapturedRegionKind getCapturedRegionKind() const

Retrieve the captured region kind.

CaseStmt - Represent a case statement.

ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...

@ Indirect

Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...

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

llvm::Value * emitRawPointer(CodeGenFunction &CGF) const

Return the pointer contained in this class after authenticating it and adding offset to it if necessa...

llvm::Type * getElementType() const

Return the type of the values stored in this address.

Address withElementType(llvm::Type *ElemTy) const

Return address with different element type, but same pointer and alignment.

llvm::PointerType * getType() const

Return the type of the pointer value.

static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)

forAddr - Make a slot for an aggregate value.

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

A scoped helper to set the current debug location to the specified location or preferred location of ...

static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)

Set the IRBuilder to not attach debug locations.

llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)

llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")

This class gathers all debug information during compilation and is responsible for emitting to llvm g...

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

API for captured statement code generation.

RAII for correct setting/restoring of CapturedStmtInfo.

void rescopeLabels()

Change the cleanup scope of the labels in this lexical scope to match the scope of the enclosing cont...

Definition CGStmt.cpp:758

void ForceCleanup()

Force the emission of cleanups now, instead of waiting until this object is destroyed.

Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.

void ForceCleanup(std::initializer_list< llvm::Value ** > ValuesToReload={})

Force the emission of cleanups now, instead of waiting until this object is destroyed.

bool requiresCleanups() const

Determine whether this scope requires any cleanups.

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

void EmitOMPParallelMaskedTaskLoopDirective(const OMPParallelMaskedTaskLoopDirective &S)

void EmitOMPParallelMaskedDirective(const OMPParallelMaskedDirective &S)

void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S)

void EmitCXXTryStmt(const CXXTryStmt &S)

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.

void EmitSehCppScopeBegin()

JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)

The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...

llvm::DenseMap< const VarDecl *, llvm::Value * > NRVOFlags

A mapping from NRVO variables to the flags used to indicate when the NRVO has been applied to this va...

bool IsOutlinedSEHHelper

True if the current function is an outlined SEH helper.

void EmitOMPCanonicalLoop(const OMPCanonicalLoop *S)

Emit an OMPCanonicalLoop using the OpenMPIRBuilder.

static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)

ContainsLabel - Return true if the statement contains a label in it.

void EmitCXXForRangeStmt(const CXXForRangeStmt &S, ArrayRef< const Attr * > Attrs={})

Definition CGStmt.cpp:1452

void EmitOMPGenericLoopDirective(const OMPGenericLoopDirective &S)

void EmitOMPScanDirective(const OMPScanDirective &S)

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

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

static bool hasScalarEvaluationKind(QualType T)

llvm::Type * ConvertType(QualType T)

void EmitOpenACCExitDataConstruct(const OpenACCExitDataConstruct &S)

LValue InitCapturedStruct(const CapturedStmt &S)

Definition CGStmt.cpp:3334

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

Add KeyInstruction and an optional Backup instruction to a new atom group (See ApplyAtomGroup for mor...

CGCapturedStmtInfo * CapturedStmtInfo

void EmitOMPDistributeDirective(const OMPDistributeDirective &S)

void EmitOMPParallelForDirective(const OMPParallelForDirective &S)

llvm::CallBase * EmitCallOrInvoke(llvm::FunctionCallee Callee, ArrayRef< llvm::Value * > Args, const Twine &Name="")

Emits a call or invoke instruction to the given function, depending on the current state of the EH st...

void EmitOMPMasterDirective(const OMPMasterDirective &S)

void EmitOMPParallelMasterTaskLoopSimdDirective(const OMPParallelMasterTaskLoopSimdDirective &S)

void EmitOpenACCInitConstruct(const OpenACCInitConstruct &S)

void EmitOMPFlushDirective(const OMPFlushDirective &S)

void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S)

JumpDest getJumpDestForLabel(const LabelDecl *S)

getBasicBlockForLabel - Return the LLVM basicblock that the specified label maps to.

Definition CGStmt.cpp:710

void EmitCoreturnStmt(const CoreturnStmt &S)

void EmitOMPTargetTeamsDistributeParallelForSimdDirective(const OMPTargetTeamsDistributeParallelForSimdDirective &S)

SmallVector< llvm::ConvergenceControlInst *, 4 > ConvergenceTokenStack

Stack to track the controlled convergence tokens.

void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S)

void EmitOMPDistributeSimdDirective(const OMPDistributeSimdDirective &S)

llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)

Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...

bool EmitSimpleStmt(const Stmt *S, ArrayRef< const Attr * > Attrs)

EmitSimpleStmt - Try to emit a "simple" statement which does not necessarily require an insertion poi...

Definition CGStmt.cpp:509

void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S)

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

createBasicBlock - Create an LLVM basic block.

void EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S)

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

See CGDebugInfo::addInstToCurrentSourceAtom.

const LangOptions & getLangOpts() const

RValue EmitReferenceBindingToExpr(const Expr *E)

Emits a reference binding to the passed in expression.

void EmitOpenACCShutdownConstruct(const OpenACCShutdownConstruct &S)

bool InNoConvergentAttributedStmt

True if the current statement has noconvergent attribute.

void EmitOpenACCWaitConstruct(const OpenACCWaitConstruct &S)

void EmitBlockAfterUses(llvm::BasicBlock *BB)

EmitBlockAfterUses - Emit the given block somewhere hopefully near its uses, and leave the insertion ...

Definition CGStmt.cpp:693

void SimplifyForwardingBlocks(llvm::BasicBlock *BB)

SimplifyForwardingBlocks - If the given basic block is only a branch to another basic block,...

Definition CGStmt.cpp:634

void EmitBranchThroughCleanup(JumpDest Dest)

EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...

bool InNoMergeAttributedStmt

True if the current statement has nomerge attribute.

void EmitOMPScopeDirective(const OMPScopeDirective &S)

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

JumpDest ReturnBlock

ReturnBlock - Unified return block.

void EmitOMPTargetTeamsDistributeSimdDirective(const OMPTargetTeamsDistributeSimdDirective &S)

llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location)

Converts Location to a DebugLoc, if debug information is enabled.

void EmitOMPInterchangeDirective(const OMPInterchangeDirective &S)

void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)

EmitAggregateCopy - Emit an aggregate copy.

LValue EmitLValueForField(LValue Base, const FieldDecl *Field, bool IsInBounds=true)

const TargetInfo & getTarget() const

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

Definition CGStmt.cpp:585

void EmitGotoStmt(const GotoStmt &S)

Definition CGStmt.cpp:846

void EmitOMPDepobjDirective(const OMPDepobjDirective &S)

void EmitOMPMetaDirective(const OMPMetaDirective &S)

void EmitOMPCriticalDirective(const OMPCriticalDirective &S)

void EmitIgnoredExpr(const Expr *E)

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

void EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S)

RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)

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

void EmitOMPCancelDirective(const OMPCancelDirective &S)

const Expr * RetExpr

If a return statement is being visited, this holds the return statment's result expression.

void EmitOMPBarrierDirective(const OMPBarrierDirective &S)

void EmitOMPOrderedDirective(const OMPOrderedDirective &S)

void EmitForStmt(const ForStmt &S, ArrayRef< const Attr * > Attrs={})

Definition CGStmt.cpp:1294

void EmitOMPSectionsDirective(const OMPSectionsDirective &S)

void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S)

void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())

Emit code for the start of a function.

void EmitOMPInteropDirective(const OMPInteropDirective &S)

void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S)

void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S)

llvm::Value * EvaluateExprAsBool(const Expr *E)

EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...

void EmitWhileStmt(const WhileStmt &S, ArrayRef< const Attr * > Attrs={})

Definition CGStmt.cpp:1079

void EmitOMPTargetParallelForSimdDirective(const OMPTargetParallelForSimdDirective &S)

void EmitOMPTargetParallelGenericLoopDirective(const OMPTargetParallelGenericLoopDirective &S)

Emit combined directive 'target parallel loop' as if its constituent constructs are 'target',...

void EmitOpenACCCombinedConstruct(const OpenACCCombinedConstruct &S)

void ResolveBranchFixups(llvm::BasicBlock *Target)

void EmitOMPTeamsDistributeParallelForSimdDirective(const OMPTeamsDistributeParallelForSimdDirective &S)

void EmitOMPMaskedDirective(const OMPMaskedDirective &S)

bool checkIfLoopMustProgress(const Expr *, bool HasEmptyBody)

Returns true if a loop must make progress, which means the mustprogress attribute can be added.

Definition CGStmt.cpp:1016

bool HaveInsertPoint() const

HaveInsertPoint - True if an insertion point is defined.

void EmitOMPTeamsDistributeSimdDirective(const OMPTeamsDistributeSimdDirective &S)

CGDebugInfo * getDebugInfo()

void EmitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective &S)

void EmitOMPReverseDirective(const OMPReverseDirective &S)

llvm::Value * getTypeSize(QualType Ty)

Returns calculated size of the specified type.

void EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S)

void EmitOpenACCDataConstruct(const OpenACCDataConstruct &S)

LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)

EmitLValueForFieldInitialization - Like EmitLValueForField, except that if the Field is a reference,...

void EmitOMPTargetTeamsDistributeParallelForDirective(const OMPTargetTeamsDistributeParallelForDirective &S)

void EmitOMPMaskedTaskLoopDirective(const OMPMaskedTaskLoopDirective &S)

void EmitObjCAtTryStmt(const ObjCAtTryStmt &S)

const TargetCodeGenInfo & getTargetHooks() const

void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S)

void EmitSEHLeaveStmt(const SEHLeaveStmt &S)

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

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

void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S)

bool InNoInlineAttributedStmt

True if the current statement has noinline attribute.

SmallVector< llvm::OperandBundleDef, 1 > getBundlesForFunclet(llvm::Value *Callee)

void EmitOMPMaskedTaskLoopSimdDirective(const OMPMaskedTaskLoopSimdDirective &S)

void EmitCoroutineBody(const CoroutineBodyStmt &S)

void EmitOMPParallelDirective(const OMPParallelDirective &S)

void EmitOMPTaskDirective(const OMPTaskDirective &S)

void EmitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective &S)

void EmitOMPDistributeParallelForDirective(const OMPDistributeParallelForDirective &S)

void EmitOMPAssumeDirective(const OMPAssumeDirective &S)

void EmitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective &S)

ASTContext & getContext() const

void EmitStopPoint(const Stmt *S)

EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.

Definition CGStmt.cpp:51

void EmitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &S)

void EmitOMPTargetTeamsGenericLoopDirective(const OMPTargetTeamsGenericLoopDirective &S)

void EmitIfStmt(const IfStmt &S)

Definition CGStmt.cpp:882

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

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

void EmitDeferStmt(const DeferStmt &S)

Definition CGStmt.cpp:2084

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

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

void EmitOpenACCAtomicConstruct(const OpenACCAtomicConstruct &S)

void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S)

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

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

Definition CGStmt.cpp:573

void EmitOpenACCCacheConstruct(const OpenACCCacheConstruct &S)

void EmitOpenACCLoopConstruct(const OpenACCLoopConstruct &S)

void EmitOMPTeamsDistributeParallelForDirective(const OMPTeamsDistributeParallelForDirective &S)

void EmitOMPFuseDirective(const OMPFuseDirective &S)

void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init)

void EmitAsmStmt(const AsmStmt &S)

Definition CGStmt.cpp:2860

void EmitDefaultStmt(const DefaultStmt &S, ArrayRef< const Attr * > Attrs)

Definition CGStmt.cpp:1985

void EmitOMPTargetTeamsDistributeDirective(const OMPTargetTeamsDistributeDirective &S)

void EmitSwitchStmt(const SwitchStmt &S)

Definition CGStmt.cpp:2376

static bool mightAddDeclToScope(const Stmt *S)

Determine if the given statement might introduce a declaration into the current scope,...

void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)

EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...

RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)

EmitAnyExpr - Emit code to compute the specified expression which can have any type.

void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})

EmitStmt - Emit the code for the statement.

Definition CGStmt.cpp:61

void EmitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &S)

uint64_t getCurrentProfileCount()

Get the profiler's current count.

llvm::Type * ConvertTypeForMem(QualType T)

void EmitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &S)

void EmitOMPTargetDirective(const OMPTargetDirective &S)

void EmitOpenACCEnterDataConstruct(const OpenACCEnterDataConstruct &S)

llvm::Function * EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K)

Generate an outlined function for the body of a CapturedStmt, store any captured variables into the c...

Definition CGStmt.cpp:3360

static TypeEvaluationKind getEvaluationKind(QualType T)

getEvaluationKind - Return the TypeEvaluationKind of QualType T.

void EmitOMPTeamsDirective(const OMPTeamsDirective &S)

static bool containsBreak(const Stmt *S)

containsBreak - Return true if the statement contains a break out of it.

void EmitSimpleOMPExecutableDirective(const OMPExecutableDirective &D)

Emit simple code for OpenMP directives in Simd-only mode.

HLSLControlFlowHintAttr::Spelling HLSLControlFlowAttr

HLSL Branch attribute.

bool InAlwaysInlineAttributedStmt

True if the current statement has always_inline attribute.

void EmitCaseStmt(const CaseStmt &S, ArrayRef< const Attr * > Attrs)

Definition CGStmt.cpp:1870

void EmitOMPErrorDirective(const OMPErrorDirective &S)

void EmitBreakStmt(const BreakStmt &S)

Definition CGStmt.cpp:1756

void EmitOMPParallelMaskedTaskLoopSimdDirective(const OMPParallelMaskedTaskLoopSimdDirective &S)

void EmitOMPTargetTeamsDirective(const OMPTargetTeamsDirective &S)

void EmitOpenACCComputeConstruct(const OpenACCComputeConstruct &S)

void EmitDoStmt(const DoStmt &S, ArrayRef< const Attr * > Attrs={})

Definition CGStmt.cpp:1206

void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S)

const TargetInfo & Target

Address GenerateCapturedStmtArgument(const CapturedStmt &S)

Definition CGStmt.cpp:3375

void EmitBranch(llvm::BasicBlock *Block)

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

Definition CGStmt.cpp:676

void EmitOMPSimdDirective(const OMPSimdDirective &S)

RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)

CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...

void EmitOMPParallelGenericLoopDirective(const OMPLoopDirective &S)

void EmitOMPTargetSimdDirective(const OMPTargetSimdDirective &S)

RawAddress NormalCleanupDest

i32s containing the indexes of the cleanup destinations.

void EmitOMPTeamsGenericLoopDirective(const OMPTeamsGenericLoopDirective &S)

unsigned NextCleanupDestIndex

AggValueSlot::Overlap_t getOverlapForReturnValue()

Determine whether a return value slot may overlap some other object.

const BreakContinue * GetDestForLoopControlStmt(const LoopControlStmt &S)

Definition CGStmt.cpp:1742

void EmitAggExpr(const Expr *E, AggValueSlot AS)

EmitAggExpr - Emit the computation of the specified expression of aggregate type.

llvm::BasicBlock * GetIndirectGotoBlock()

void EmitOpenACCHostDataConstruct(const OpenACCHostDataConstruct &S)

void EmitOpenACCUpdateConstruct(const OpenACCUpdateConstruct &S)

void EmitOMPUnrollDirective(const OMPUnrollDirective &S)

void EmitOMPStripeDirective(const OMPStripeDirective &S)

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

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

static bool hasAggregateEvaluationKind(QualType T)

void EmitCaseStmtRange(const CaseStmt &S, ArrayRef< const Attr * > Attrs)

EmitCaseStmtRange - If case statement range is not too big then add multiple cases to switch instruct...

Definition CGStmt.cpp:1785

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

void EmitOMPSingleDirective(const OMPSingleDirective &S)

void EmitReturnStmt(const ReturnStmt &S)

EmitReturnStmt - Note that due to GCC extensions, this can have an operand if the function returns vo...

Definition CGStmt.cpp:1617

void EmitLambdaVLACapture(const VariableArrayType *VAT, LValue LV)

void FinishFunction(SourceLocation EndLoc=SourceLocation())

FinishFunction - Complete IR generation of the current function.

llvm::Value * EmitCheckedArgForAssume(const Expr *E)

Emits an argument for a call to a __builtin_assume.

llvm::Function * GenerateCapturedStmtFunction(const CapturedStmt &S)

Creates the outlined function for a CapturedStmt.

Definition CGStmt.cpp:3382

const CallExpr * MustTailCall

const CGFunctionInfo * CurFnInfo

uint64_t getProfileCount(const Stmt *S)

Get the profiler's count for the given statement.

Address GetAddrOfLocalVar(const VarDecl *VD)

GetAddrOfLocalVar - Return the address of a local variable.

void EmitDeclStmt(const DeclStmt &S)

Definition CGStmt.cpp:1732

void EmitLabelStmt(const LabelStmt &S)

Definition CGStmt.cpp:779

bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)

ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...

void EmitOMPTileDirective(const OMPTileDirective &S)

void EmitDecl(const Decl &D, bool EvaluateConditionDecl=false)

EmitDecl - Emit a declaration.

void EmitOMPAtomicDirective(const OMPAtomicDirective &S)

void EmitOpenACCSetConstruct(const OpenACCSetConstruct &S)

Address ReturnValue

ReturnValue - The temporary alloca to hold the return value.

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

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

void EmitAttributedStmt(const AttributedStmt &S)

Definition CGStmt.cpp:789

void EmitOMPParallelMasterTaskLoopDirective(const OMPParallelMasterTaskLoopDirective &S)

void EmitOMPDistributeParallelForSimdDirective(const OMPDistributeParallelForSimdDirective &S)

void EmitOMPSectionDirective(const OMPSectionDirective &S)

void EnsureInsertPoint()

EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.

void EmitOMPForSimdDirective(const OMPForSimdDirective &S)

llvm::LLVMContext & getLLVMContext()

bool SawAsmBlock

Whether we processed a Microsoft-style asm block during CodeGen.

void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)

void EmitIndirectGotoStmt(const IndirectGotoStmt &S)

Definition CGStmt.cpp:858

void MaybeEmitDeferredVarDeclInit(const VarDecl *var)

bool isObviouslyBranchWithoutCleanups(JumpDest Dest) const

isObviouslyBranchWithoutCleanups - Return true if a branch to the specified destination obviously has...

void EmitSEHTryStmt(const SEHTryStmt &S)

void EmitOMPParallelMasterDirective(const OMPParallelMasterDirective &S)

void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S)

When instrumenting to collect profile data, the counts for some blocks such as switch cases need to n...

void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)

EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...

void EmitOMPForDirective(const OMPForDirective &S)

void EmitLabel(const LabelDecl *D)

EmitLabel - Emit the block for the given label.

Definition CGStmt.cpp:721

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

EmitBlock - Emit the given block.

Definition CGStmt.cpp:656

LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T)

void EmitContinueStmt(const ContinueStmt &S)

Definition CGStmt.cpp:1769

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

llvm::Module & getModule() const

DiagnosticsEngine & getDiags() const

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

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

const LangOptions & getLangOpts() const

const llvm::DataLayout & getDataLayout() const

ASTContext & getContext() const

llvm::LLVMContext & getLLVMContext()

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

A saved depth on the scope stack.

bool encloses(stable_iterator I) const

Returns true if this scope encloses I.

static stable_iterator invalid()

static stable_iterator stable_end()

Create a stable reference to the bottom of the EH stack.

FunctionArgList - Type for representing both the decl and type of parameters to a function.

LValue - This represents an lvalue references.

llvm::Value * getPointer(CodeGenFunction &CGF) 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)

Address getAggregateAddress() const

getAggregateAddr() - Return the Value* of the address of the aggregate.

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.

virtual bool isScalarizableAsmOperand(CodeGen::CodeGenFunction &CGF, llvm::Type *Ty) const

Target hook to decide whether an inline asm operand can be passed by value.

CompoundStmt - This represents a group of statements like { stmt stmt }.

Stmt *const * const_body_iterator

SourceLocation getLBracLoc() const

body_iterator body_begin()

ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...

ContinueStmt - This represents a continue.

A reference to a declared variable, function, enum, etc.

DeclStmt - Adaptor class for mixing declarations with statements and expressions.

SourceLocation getBodyRBrace() const

getBodyRBrace - Gets the right brace of the body, if a body exists.

virtual bool hasBody() const

Returns true if this Decl represents a declaration for a body of code, such as a function or method d...

SourceLocation getLocation() const

DeferStmt - This represents a deferred statement.

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

DoStmt - This represents a 'do/while' stmt.

This represents one expression.

bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const

EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...

Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY

Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...

llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const

EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.

Expr * IgnoreParens() LLVM_READONLY

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

bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const

isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...

bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const

EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...

bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const

HasSideEffects - This routine returns true for all those expressions which have any effect other than...

SourceLocation getExprLoc() const LLVM_READONLY

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

Represents a member of a struct/union/class.

ForStmt - This represents a 'for (init;cond;inc)' stmt.

VarDecl * getConditionVariable() const

Retrieve the variable declared in this "for" statement, if any.

const Expr * getSubExpr() const

FunctionType - C99 6.7.5.3 - Function Declarators.

CallingConv getCallConv() const

This represents a GCC inline-assembly statement extension.

GlobalDecl - represents a global declaration.

GotoStmt - This represents a direct goto.

LabelDecl * getLabel() const

IfStmt - This represents an if/then/else.

bool isNegatedConsteval() const

VarDecl * getConditionVariable()

Retrieve the variable declared in this "if" statement, if any.

IndirectGotoStmt - This represents an indirect goto.

LabelDecl * getConstantTarget()

getConstantTarget - Returns the fixed target of this indirect goto, if one exists.

Represents the declaration of a label.

LabelStmt * getStmt() const

LabelStmt - Represents a label, which has a substatement.

LabelDecl * getDecl() const

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

bool assumeFunctionsAreConvergent() const

Base class for BreakStmt and ContinueStmt.

Represents a point when we exit a loop.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

If a crash happens while one of these objects are live, the message is printed out along with the spe...

A (possibly-)qualified type.

bool isNull() const

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

QualType getCanonicalType() const

The collection of all-type qualifiers we support.

Represents a struct/union/class.

field_range fields() const

specific_decl_iterator< FieldDecl > field_iterator

field_iterator field_begin() const

ReturnStmt - This represents a return, optionally of an expression: return; return 4;.

SourceLocation getBeginLoc() const

const VarDecl * getNRVOCandidate() const

Retrieve the variable that might be used for the named return value optimization.

Scope - A scope is a transient data structure that is used while parsing the program.

Encodes a location in the source.

UIntTy getRawEncoding() const

When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.

This class handles loading and caching of source files into memory.

A trivial tuple used to represent a source range.

SourceLocation getEnd() const

SourceLocation getBegin() const

Stmt - This represents one statement.

StmtClass getStmtClass() const

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

Likelihood

The likelihood of a branch being taken.

@ LH_Unlikely

Branch has the [[unlikely]] attribute.

@ LH_None

No attribute set or branches of the IfStmt have the same attribute.

@ LH_Likely

Branch has the [[likely]] attribute.

static const Attr * getLikelihoodAttr(const Stmt *S)

SourceLocation getBeginLoc() const LLVM_READONLY

static Likelihood getLikelihood(ArrayRef< const Attr * > Attrs)

StringLiteral - This represents a string literal expression, e.g.

SourceLocation getBeginLoc() const LLVM_READONLY

SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken=nullptr, unsigned *StartTokenByteOffset=nullptr) const

getLocationOfByte - Return a source location that points to the specified byte of this string literal...

StringRef getString() const

const SwitchCase * getNextSwitchCase() const

SwitchStmt - This represents a 'switch' stmt.

VarDecl * getConditionVariable()

Retrieve the variable declared in this "switch" statement, if any.

SwitchCase * getSwitchCaseList()

Exposes information about the current target.

bool validateInputConstraint(MutableArrayRef< ConstraintInfo > OutputConstraints, ConstraintInfo &info) const

std::string simplifyConstraint(StringRef Constraint, SmallVectorImpl< ConstraintInfo > *OutCons=nullptr) const

StringRef getNormalizedGCCRegisterName(StringRef Name, bool ReturnCanonical=false) const

Returns the "normalized" GCC register name.

bool validateOutputConstraint(ConstraintInfo &Info) const

virtual std::string_view getClobbers() const =0

Returns a string of target-specific clobbers, in LLVM format.

const T * castAs() const

Member-template castAs.

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

Represents a variable declaration or definition.

bool isNRVOVariable() const

Determine whether this local variable can be used with the named return value optimization (NRVO).

WhileStmt - This represents a 'while' stmt.

SourceLocation getWhileLoc() const

SourceLocation getRParenLoc() const

VarDecl * getConditionVariable()

Retrieve the variable declared in this "while" statement, if any.

Defines the clang::TargetInfo interface.

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

CanQual< Type > CanQualType

Represents a canonical, potentially-qualified type.

bool isa(CodeGen::Address addr)

CapturedRegionKind

The different kinds of captured statement.

@ Asm

Assembly: we accept this only so that we can preprocess it.

@ Result

The result type of a method or function.

U cast(CodeGen::Address addr)

@ None

The alignment was not explicit in code.

Diagnostic wrappers for TextAPI types for error reporting.

cl::opt< bool > EnableSingleByteCoverage

A jump destination is an abstract label, branching to which may require a jump out through normal cle...

void setScopeDepth(EHScopeStack::stable_iterator depth)

llvm::BasicBlock * getBlock() const

EHScopeStack::stable_iterator getScopeDepth() const

llvm::IntegerType * Int64Ty

llvm::IntegerType * IntPtrTy

llvm::PointerType * Int8PtrTy

EvalResult is a struct with detailed info about an evaluated expression.

APValue Val

Val - This is the value the expression can be folded to.

bool hasMatchingInput() const

Return true if this output operand has a matching (tied) input operand.

unsigned getTiedOperand() const

bool allowsMemory() const

std::optional< std::pair< unsigned, unsigned > > getOutputOperandBounds() const

bool requiresImmediateConstant() const

bool hasTiedOperand() const

Return true if this input operand is a matching constraint that ties it to an output operand.

bool allowsRegister() const