27#include "llvm/ADT/ArrayRef.h"
28#include "llvm/ADT/DenseMap.h"
29#include "llvm/ADT/SmallSet.h"
30#include "llvm/ADT/StringExtras.h"
31#include "llvm/IR/Assumptions.h"
32#include "llvm/IR/DataLayout.h"
33#include "llvm/IR/InlineAsm.h"
34#include "llvm/IR/Intrinsics.h"
35#include "llvm/IR/MDBuilder.h"
36#include "llvm/Support/SaveAndRestore.h"
40using namespace CodeGen;
46void CodeGenFunction::EmitStopPoint(
const Stmt *S) {
49 Loc = S->getBeginLoc();
57 assert(S &&
"Null statement?");
74 assert(!isa<DeclStmt>(*S) &&
"Unexpected DeclStmt!");
88 if (
const auto *D = dyn_cast<OMPExecutableDirective>(S)) {
94 switch (S->getStmtClass()) {
96 case Stmt::CXXCatchStmtClass:
97 case Stmt::SEHExceptStmtClass:
98 case Stmt::SEHFinallyStmtClass:
99 case Stmt::MSDependentExistsStmtClass:
100 llvm_unreachable(
"invalid statement class to emit generically");
101 case Stmt::NullStmtClass:
102 case Stmt::CompoundStmtClass:
103 case Stmt::DeclStmtClass:
104 case Stmt::LabelStmtClass:
105 case Stmt::AttributedStmtClass:
106 case Stmt::GotoStmtClass:
107 case Stmt::BreakStmtClass:
108 case Stmt::ContinueStmtClass:
109 case Stmt::DefaultStmtClass:
110 case Stmt::CaseStmtClass:
111 case Stmt::SEHLeaveStmtClass:
112 llvm_unreachable(
"should have emitted these statements as simple");
114#define STMT(Type, Base)
115#define ABSTRACT_STMT(Op)
116#define EXPR(Type, Base) \
117 case Stmt::Type##Class:
118#include "clang/AST/StmtNodes.inc"
121 llvm::BasicBlock *incoming =
Builder.GetInsertBlock();
122 assert(incoming &&
"expression emission must have an insertion point");
126 llvm::BasicBlock *outgoing =
Builder.GetInsertBlock();
127 assert(outgoing &&
"expression emission cleared block!");
141 if (incoming != outgoing && outgoing->use_empty()) {
142 outgoing->eraseFromParent();
148 case Stmt::IndirectGotoStmtClass:
151 case Stmt::IfStmtClass:
EmitIfStmt(cast<IfStmt>(*S));
break;
152 case Stmt::WhileStmtClass:
EmitWhileStmt(cast<WhileStmt>(*S), Attrs);
break;
153 case Stmt::DoStmtClass:
EmitDoStmt(cast<DoStmt>(*S), Attrs);
break;
154 case Stmt::ForStmtClass:
EmitForStmt(cast<ForStmt>(*S), Attrs);
break;
156 case Stmt::ReturnStmtClass:
EmitReturnStmt(cast<ReturnStmt>(*S));
break;
158 case Stmt::SwitchStmtClass:
EmitSwitchStmt(cast<SwitchStmt>(*S));
break;
159 case Stmt::GCCAsmStmtClass:
160 case Stmt::MSAsmStmtClass:
EmitAsmStmt(cast<AsmStmt>(*S));
break;
161 case Stmt::CoroutineBodyStmtClass:
164 case Stmt::CoreturnStmtClass:
167 case Stmt::CapturedStmtClass: {
172 case Stmt::ObjCAtTryStmtClass:
175 case Stmt::ObjCAtCatchStmtClass:
177 "@catch statements should be handled by EmitObjCAtTryStmt");
178 case Stmt::ObjCAtFinallyStmtClass:
180 "@finally statements should be handled by EmitObjCAtTryStmt");
181 case Stmt::ObjCAtThrowStmtClass:
184 case Stmt::ObjCAtSynchronizedStmtClass:
187 case Stmt::ObjCForCollectionStmtClass:
190 case Stmt::ObjCAutoreleasePoolStmtClass:
194 case Stmt::CXXTryStmtClass:
197 case Stmt::CXXForRangeStmtClass:
200 case Stmt::SEHTryStmtClass:
203 case Stmt::OMPMetaDirectiveClass:
206 case Stmt::OMPCanonicalLoopClass:
209 case Stmt::OMPParallelDirectiveClass:
212 case Stmt::OMPSimdDirectiveClass:
215 case Stmt::OMPTileDirectiveClass:
218 case Stmt::OMPUnrollDirectiveClass:
221 case Stmt::OMPForDirectiveClass:
224 case Stmt::OMPForSimdDirectiveClass:
227 case Stmt::OMPSectionsDirectiveClass:
230 case Stmt::OMPSectionDirectiveClass:
233 case Stmt::OMPSingleDirectiveClass:
236 case Stmt::OMPMasterDirectiveClass:
239 case Stmt::OMPCriticalDirectiveClass:
242 case Stmt::OMPParallelForDirectiveClass:
245 case Stmt::OMPParallelForSimdDirectiveClass:
248 case Stmt::OMPParallelMasterDirectiveClass:
251 case Stmt::OMPParallelSectionsDirectiveClass:
254 case Stmt::OMPTaskDirectiveClass:
257 case Stmt::OMPTaskyieldDirectiveClass:
260 case Stmt::OMPErrorDirectiveClass:
263 case Stmt::OMPBarrierDirectiveClass:
266 case Stmt::OMPTaskwaitDirectiveClass:
269 case Stmt::OMPTaskgroupDirectiveClass:
272 case Stmt::OMPFlushDirectiveClass:
275 case Stmt::OMPDepobjDirectiveClass:
278 case Stmt::OMPScanDirectiveClass:
281 case Stmt::OMPOrderedDirectiveClass:
284 case Stmt::OMPAtomicDirectiveClass:
287 case Stmt::OMPTargetDirectiveClass:
290 case Stmt::OMPTeamsDirectiveClass:
293 case Stmt::OMPCancellationPointDirectiveClass:
296 case Stmt::OMPCancelDirectiveClass:
299 case Stmt::OMPTargetDataDirectiveClass:
302 case Stmt::OMPTargetEnterDataDirectiveClass:
305 case Stmt::OMPTargetExitDataDirectiveClass:
308 case Stmt::OMPTargetParallelDirectiveClass:
311 case Stmt::OMPTargetParallelForDirectiveClass:
314 case Stmt::OMPTaskLoopDirectiveClass:
317 case Stmt::OMPTaskLoopSimdDirectiveClass:
320 case Stmt::OMPMasterTaskLoopDirectiveClass:
323 case Stmt::OMPMaskedTaskLoopDirectiveClass:
324 llvm_unreachable(
"masked taskloop directive not supported yet.");
326 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
328 cast<OMPMasterTaskLoopSimdDirective>(*S));
330 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
331 llvm_unreachable(
"masked taskloop simd directive not supported yet.");
333 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
335 cast<OMPParallelMasterTaskLoopDirective>(*S));
337 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
338 llvm_unreachable(
"parallel masked taskloop directive not supported yet.");
340 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
342 cast<OMPParallelMasterTaskLoopSimdDirective>(*S));
344 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
346 "parallel masked taskloop simd directive not supported yet.");
348 case Stmt::OMPDistributeDirectiveClass:
351 case Stmt::OMPTargetUpdateDirectiveClass:
354 case Stmt::OMPDistributeParallelForDirectiveClass:
356 cast<OMPDistributeParallelForDirective>(*S));
358 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
360 cast<OMPDistributeParallelForSimdDirective>(*S));
362 case Stmt::OMPDistributeSimdDirectiveClass:
365 case Stmt::OMPTargetParallelForSimdDirectiveClass:
367 cast<OMPTargetParallelForSimdDirective>(*S));
369 case Stmt::OMPTargetSimdDirectiveClass:
372 case Stmt::OMPTeamsDistributeDirectiveClass:
375 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
377 cast<OMPTeamsDistributeSimdDirective>(*S));
379 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
381 cast<OMPTeamsDistributeParallelForSimdDirective>(*S));
383 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
385 cast<OMPTeamsDistributeParallelForDirective>(*S));
387 case Stmt::OMPTargetTeamsDirectiveClass:
390 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
392 cast<OMPTargetTeamsDistributeDirective>(*S));
394 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
396 cast<OMPTargetTeamsDistributeParallelForDirective>(*S));
398 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
400 cast<OMPTargetTeamsDistributeParallelForSimdDirective>(*S));
402 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
404 cast<OMPTargetTeamsDistributeSimdDirective>(*S));
406 case Stmt::OMPInteropDirectiveClass:
409 case Stmt::OMPDispatchDirectiveClass:
412 case Stmt::OMPScopeDirectiveClass:
413 llvm_unreachable(
"scope not supported with FE outlining");
414 case Stmt::OMPMaskedDirectiveClass:
417 case Stmt::OMPGenericLoopDirectiveClass:
420 case Stmt::OMPTeamsGenericLoopDirectiveClass:
423 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
425 cast<OMPTargetTeamsGenericLoopDirective>(*S));
427 case Stmt::OMPParallelGenericLoopDirectiveClass:
429 cast<OMPParallelGenericLoopDirective>(*S));
431 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
433 cast<OMPTargetParallelGenericLoopDirective>(*S));
435 case Stmt::OMPParallelMaskedDirectiveClass:
443 switch (S->getStmtClass()) {
446 case Stmt::NullStmtClass:
448 case Stmt::CompoundStmtClass:
451 case Stmt::DeclStmtClass:
454 case Stmt::LabelStmtClass:
457 case Stmt::AttributedStmtClass:
460 case Stmt::GotoStmtClass:
463 case Stmt::BreakStmtClass:
466 case Stmt::ContinueStmtClass:
469 case Stmt::DefaultStmtClass:
472 case Stmt::CaseStmtClass:
475 case Stmt::SEHLeaveStmtClass:
488 "LLVM IR generation of compound statement ('{}')");
491 LexicalScope
Scope(*
this, S.getSourceRange());
502 assert((!GetLast || (GetLast &&
ExprResult)) &&
503 "If GetLast is true then the CompoundStmt must have a StmtExprResult");
507 for (
auto *CurStmt : S.body()) {
515 if (
const auto *LS = dyn_cast<LabelStmt>(
ExprResult)) {
518 }
else if (
const auto *AS = dyn_cast<AttributedStmt>(
ExprResult)) {
523 llvm_unreachable(
"unknown value statement");
550 llvm::BranchInst *BI = dyn_cast<llvm::BranchInst>(BB->getTerminator());
559 if (!BI || !BI->isUnconditional())
563 if (BI->getIterator() != BB->begin())
566 BB->replaceAllUsesWith(BI->getSuccessor(0));
567 BI->eraseFromParent();
568 BB->eraseFromParent();
572 llvm::BasicBlock *CurBB =
Builder.GetInsertBlock();
577 if (IsFinished && BB->use_empty()) {
584 if (CurBB && CurBB->getParent())
585 CurFn->insert(std::next(CurBB->getIterator()), BB);
595 llvm::BasicBlock *CurBB =
Builder.GetInsertBlock();
597 if (!CurBB || CurBB->getTerminator()) {
609 bool inserted =
false;
610 for (llvm::User *u : block->users()) {
611 if (llvm::Instruction *insn = dyn_cast<llvm::Instruction>(u)) {
612 CurFn->insert(std::next(insn->getParent()->getIterator()), block);
624CodeGenFunction::JumpDest
626 JumpDest &Dest = LabelMap[D];
627 if (Dest.isValid())
return Dest;
643 JumpDest &Dest = LabelMap[D];
647 if (!Dest.isValid()) {
653 assert(!Dest.getScopeDepth().isValid() &&
"already emitted label!");
674 assert(!Labels.empty());
680 i = Labels.begin(), e = Labels.end(); i != e; ++i) {
681 assert(
CGF.LabelMap.count(*i));
690 ParentScope->Labels.append(Labels.begin(), Labels.end());
706 bool nomerge =
false;
707 bool noinline =
false;
708 bool alwaysinline =
false;
711 for (
const auto *A : S.getAttrs()) {
712 switch (A->getKind()) {
721 case attr::AlwaysInline:
725 const Stmt *Sub = S.getSubStmt();
735 EmitStmt(S.getSubStmt(), S.getAttrs());
758 llvm::BasicBlock *CurBB =
Builder.GetInsertBlock();
765 cast<llvm::PHINode>(IndGotoBB->begin())->addIncoming(
V, CurBB);
773 if (S.isConsteval()) {
774 const Stmt *Executed = S.isNegatedConsteval() ? S.getThen() : S.getElse();
776 RunCleanupsScope ExecutedScope(*
this);
784 LexicalScope ConditionScope(*
this, S.getCond()->getSourceRange());
789 if (S.getConditionVariable())
790 EmitDecl(*S.getConditionVariable());
798 const Stmt *Executed = S.getThen();
799 const Stmt *Skipped = S.getElse();
801 std::swap(Executed, Skipped);
809 RunCleanupsScope ExecutedScope(*
this);
820 llvm::BasicBlock *ElseBlock = ContBlock;
846 RunCleanupsScope ThenScope(*
this);
852 if (
const Stmt *Else = S.getElse()) {
859 RunCleanupsScope ElseScope(*
this);
885 BreakContinueStack.push_back(BreakContinue(
LoopExit, LoopHeader));
894 RunCleanupsScope ConditionScope(*
this);
896 if (S.getConditionVariable())
897 EmitDecl(*S.getConditionVariable());
906 llvm::ConstantInt *
C = dyn_cast<llvm::ConstantInt>(BoolCondVal);
907 bool CondIsConstInt =
C !=
nullptr;
908 bool EmitBoolCondBranch = !CondIsConstInt || !
C->isOne();
917 if (EmitBoolCondBranch) {
918 llvm::BasicBlock *ExitBlock =
LoopExit.getBlock();
919 if (ConditionScope.requiresCleanups())
921 llvm::MDNode *Weights =
922 createProfileWeightsForLoop(S.getCond(),
getProfileCount(S.getBody()));
924 BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(
926 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock, Weights);
928 if (ExitBlock !=
LoopExit.getBlock()) {
934 diag::warn_attribute_has_no_effect_on_infinite_loop)
935 << A << A->getRange();
938 diag::note_attribute_has_no_effect_on_infinite_loop_here)
945 RunCleanupsScope BodyScope(*
this);
951 BreakContinueStack.pop_back();
954 ConditionScope.ForceCleanup();
967 if (!EmitBoolCondBranch)
979 BreakContinueStack.push_back(BreakContinue(
LoopExit, LoopCond));
986 RunCleanupsScope BodyScope(*
this);
1000 BreakContinueStack.pop_back();
1004 llvm::ConstantInt *
C = dyn_cast<llvm::ConstantInt>(BoolCondVal);
1005 bool CondIsConstInt =
C;
1006 bool EmitBoolCondBranch = !
C || !
C->isZero();
1015 if (EmitBoolCondBranch) {
1018 BoolCondVal, LoopBody,
LoopExit.getBlock(),
1019 createProfileWeightsForLoop(S.getCond(), BackedgeCount));
1029 if (!EmitBoolCondBranch)
1037 LexicalScope ForScope(*
this, S.getSourceRange());
1047 llvm::BasicBlock *CondBlock = CondDest.getBlock();
1051 bool CondIsConstInt =
1061 LexicalScope ConditionScope(*
this, S.getSourceRange());
1072 Continue = CondDest;
1073 else if (!S.getConditionVariable())
1075 BreakContinueStack.push_back(BreakContinue(
LoopExit, Continue));
1080 if (S.getConditionVariable()) {
1081 EmitDecl(*S.getConditionVariable());
1086 BreakContinueStack.back().ContinueBlock = Continue;
1089 llvm::BasicBlock *ExitBlock =
LoopExit.getBlock();
1092 if (ForScope.requiresCleanups())
1101 llvm::MDNode *Weights =
1102 createProfileWeightsForLoop(S.getCond(),
getProfileCount(S.getBody()));
1104 BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(
1107 Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights);
1109 if (ExitBlock !=
LoopExit.getBlock()) {
1124 RunCleanupsScope BodyScope(*
this);
1134 BreakContinueStack.pop_back();
1136 ConditionScope.ForceCleanup();
1141 ForScope.ForceCleanup();
1154 LexicalScope ForScope(*
this, S.getSourceRange());
1176 llvm::BasicBlock *ExitBlock =
LoopExit.getBlock();
1177 if (ForScope.requiresCleanups())
1186 llvm::MDNode *Weights =
1187 createProfileWeightsForLoop(S.getCond(),
getProfileCount(S.getBody()));
1189 BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(
1191 Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights);
1193 if (ExitBlock !=
LoopExit.getBlock()) {
1205 BreakContinueStack.push_back(BreakContinue(
LoopExit, Continue));
1209 LexicalScope BodyScope(*
this, S.getSourceRange());
1219 BreakContinueStack.pop_back();
1223 ForScope.ForceCleanup();
1231void CodeGenFunction::EmitReturnOfRValue(
RValue RV,
QualType Ty) {
1247struct SaveRetExprRAII {
1249 : OldRetExpr(CGF.RetExpr), CGF(CGF) {
1252 ~SaveRetExprRAII() { CGF.RetExpr = OldRetExpr; }
1253 const Expr *OldRetExpr;
1264 if (calleeQualType->isFunctionPointerType() ||
1265 calleeQualType->isFunctionReferenceType() ||
1266 calleeQualType->isBlockPointerType() ||
1267 calleeQualType->isMemberFunctionPointerType()) {
1269 }
else if (
auto *ty = dyn_cast<FunctionType>(calleeQualType)) {
1271 }
else if (
auto CMCE = dyn_cast<CXXMemberCallExpr>(CE)) {
1272 if (
auto methodDecl = CMCE->getMethodDecl()) {
1283 auto CI = cast<llvm::CallInst>(&
Builder.GetInsertBlock()->back());
1284 CI->setTailCallKind(llvm::CallInst::TCK_MustTail);
1286 Builder.ClearInsertionPoint();
1294 if (requiresReturnValueCheck()) {
1297 new llvm::GlobalVariable(
CGM.
getModule(), SLoc->getType(),
false,
1298 llvm::GlobalVariable::PrivateLinkage, SLoc);
1299 SLocPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1301 assert(ReturnLocation.
isValid() &&
"No valid return location");
1308 Builder.ClearInsertionPoint();
1312 const Expr *RV = S.getRetValue();
1322 SaveRetExprRAII SaveRetExpr(RV, *
this);
1324 RunCleanupsScope cleanupScope(*
this);
1325 if (
const auto *EWC = dyn_cast_or_null<ExprWithCleanups>(RV))
1326 RV = EWC->getSubExpr();
1330 if (
getLangOpts().ElideConstructors && S.getNRVOCandidate() &&
1331 S.getNRVOCandidate()->isNRVOVariable() &&
1342 if (llvm::Value *NRVOFlag =
NRVOFlags[S.getNRVOCandidate()])
1349 if (
auto *CE = dyn_cast<CallExpr>(RV))
1381 ++NumSimpleReturnExprs;
1383 cleanupScope.ForceCleanup();
1393 for (
const auto *I : S.decls())
1398 assert(!BreakContinueStack.empty() &&
"break stmt not in a loop or switch!");
1410 assert(!BreakContinueStack.empty() &&
"continue stmt not in a loop!");
1426 assert(S.getRHS() &&
"Expected RHS value in CaseStmt");
1428 llvm::APSInt LHS = S.getLHS()->EvaluateKnownConstInt(
getContext());
1429 llvm::APSInt RHS = S.getRHS()->EvaluateKnownConstInt(
getContext());
1439 if (LHS.isSigned() ? RHS.slt(LHS) : RHS.ult(LHS))
1443 llvm::APInt
Range = RHS - LHS;
1445 if (
Range.ult(llvm::APInt(
Range.getBitWidth(), 64))) {
1448 unsigned NCases =
Range.getZExtValue() + 1;
1453 uint64_t Weight = Total / NCases,
Rem = Total % NCases;
1454 for (
unsigned I = 0; I != NCases; ++I) {
1456 SwitchWeights->push_back(Weight + (Rem ? 1 : 0));
1457 else if (SwitchLikelihood)
1458 SwitchLikelihood->push_back(LH);
1462 SwitchInsn->addCase(
Builder.getInt(LHS), CaseDest);
1470 llvm::BasicBlock *RestoreBB =
Builder.GetInsertBlock();
1475 llvm::BasicBlock *FalseDest = CaseRangeBlock;
1479 Builder.SetInsertPoint(CaseRangeBlock);
1483 Builder.CreateSub(SwitchInsn->getCondition(),
Builder.getInt(LHS));
1487 llvm::MDNode *Weights =
nullptr;
1488 if (SwitchWeights) {
1490 uint64_t DefaultCount = (*SwitchWeights)[0];
1491 Weights = createProfileWeights(ThisCount, DefaultCount);
1496 (*SwitchWeights)[0] += ThisCount;
1497 }
else if (SwitchLikelihood)
1498 Cond = emitCondLikelihoodViaExpectIntrinsic(Cond, LH);
1500 Builder.CreateCondBr(Cond, CaseDest, FalseDest, Weights);
1504 Builder.SetInsertPoint(RestoreBB);
1506 Builder.ClearInsertionPoint();
1527 llvm::ConstantInt *CaseVal =
1532 if (
auto ICE = dyn_cast<ImplicitCastExpr>(S.getLHS()))
1533 CE = dyn_cast<ConstantExpr>(ICE->getSubExpr());
1535 CE = dyn_cast<ConstantExpr>(S.getLHS());
1537 if (
auto DE = dyn_cast<DeclRefExpr>(CE->
getSubExpr()))
1540 Dbg->EmitGlobalVariable(DE->getDecl(),
1541 APValue(llvm::APSInt(CaseVal->getValue())));
1544 if (SwitchLikelihood)
1552 isa<BreakStmt>(S.getSubStmt())) {
1553 JumpDest
Block = BreakContinueStack.back().BreakBlock;
1559 SwitchInsn->addCase(CaseVal,
Block.getBlock());
1563 if (
Builder.GetInsertBlock()) {
1565 Builder.ClearInsertionPoint();
1575 SwitchInsn->addCase(CaseVal, CaseDest);
1591 const CaseStmt *NextCase = dyn_cast<CaseStmt>(S.getSubStmt());
1594 while (NextCase && NextCase->
getRHS() ==
nullptr) {
1596 llvm::ConstantInt *CaseVal =
1607 if (SwitchLikelihood)
1610 SwitchInsn->addCase(CaseVal, CaseDest);
1611 NextCase = dyn_cast<CaseStmt>(CurCase->
getSubStmt());
1634 llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest();
1635 assert(DefaultBlock->empty() &&
1636 "EmitDefaultStmt: Default block already defined?");
1638 if (SwitchLikelihood)
1680 if (
const SwitchCase *SC = dyn_cast<SwitchCase>(S)) {
1694 if (!Case && isa<BreakStmt>(S))
1699 if (
const CompoundStmt *CS = dyn_cast<CompoundStmt>(S)) {
1703 bool StartedInLiveCode = FoundCase;
1704 unsigned StartSize = ResultStmts.size();
1711 bool HadSkippedDecl =
false;
1715 for (; Case && I != E; ++I) {
1731 for (++I; I != E; ++I)
1741 assert(FoundCase &&
"Didn't find case but returned fallthrough?");
1756 assert(!HadSkippedDecl &&
"fallthrough after skipping decl");
1761 bool AnyDecls =
false;
1762 for (; I != E; ++I) {
1775 for (++I; I != E; ++I)
1792 ResultStmts.resize(StartSize);
1793 ResultStmts.push_back(S);
1817 ResultStmts.push_back(S);
1826 const llvm::APSInt &ConstantCondValue,
1832 const SwitchCase *Case = S.getSwitchCaseList();
1838 if (
const DefaultStmt *DS = dyn_cast<DefaultStmt>(Case)) {
1844 const CaseStmt *CS = cast<CaseStmt>(Case);
1846 if (CS->
getRHS())
return false;
1871 bool FoundCase =
false;
1878static std::optional<SmallVector<uint64_t, 16>>
1881 if (Likelihoods.size() <= 1)
1882 return std::nullopt;
1884 uint64_t NumUnlikely = 0;
1885 uint64_t NumNone = 0;
1886 uint64_t NumLikely = 0;
1887 for (
const auto LH : Likelihoods) {
1902 if (NumUnlikely == 0 && NumLikely == 0)
1903 return std::nullopt;
1911 const uint64_t Likely = INT32_MAX / (NumLikely + 2);
1912 const uint64_t
None = Likely / (NumNone + 1);
1913 const uint64_t Unlikely = 0;
1916 Result.reserve(Likelihoods.size());
1917 for (
const auto LH : Likelihoods) {
1920 Result.push_back(Unlikely);
1926 Result.push_back(Likely);
1936 llvm::SwitchInst *SavedSwitchInsn = SwitchInsn;
1939 llvm::BasicBlock *SavedCRBlock = CaseRangeBlock;
1943 llvm::APSInt ConstantCondValue;
1951 RunCleanupsScope ExecutedScope(*
this);
1958 if (S.getConditionVariable())
1959 EmitDecl(*S.getConditionVariable());
1964 SwitchInsn =
nullptr;
1968 for (
unsigned i = 0, e = CaseStmts.size(); i != e; ++i)
1974 SwitchInsn = SavedSwitchInsn;
1982 RunCleanupsScope ConditionScope(*
this);
1987 if (S.getConditionVariable())
1988 EmitDecl(*S.getConditionVariable());
1996 SwitchInsn =
Builder.CreateSwitch(CondV, DefaultBlock);
2000 unsigned NumCases = 0;
2001 for (
const SwitchCase *Case = S.getSwitchCaseList();
2004 if (isa<DefaultStmt>(Case))
2009 SwitchWeights->reserve(NumCases);
2012 SwitchWeights->push_back(DefaultCount);
2019 CaseRangeBlock = DefaultBlock;
2022 Builder.ClearInsertionPoint();
2026 JumpDest OuterContinue;
2027 if (!BreakContinueStack.empty())
2028 OuterContinue = BreakContinueStack.back().ContinueBlock;
2030 BreakContinueStack.push_back(BreakContinue(SwitchExit, OuterContinue));
2035 BreakContinueStack.pop_back();
2039 SwitchInsn->setDefaultDest(CaseRangeBlock);
2042 if (!DefaultBlock->getParent()) {
2045 if (ConditionScope.requiresCleanups()) {
2050 DefaultBlock->replaceAllUsesWith(SwitchExit.getBlock());
2051 delete DefaultBlock;
2055 ConditionScope.ForceCleanup();
2064 auto *
Call = dyn_cast<CallExpr>(S.getCond());
2066 auto *FD = dyn_cast_or_null<FunctionDecl>(
Call->getCalleeDecl());
2067 if (FD && FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) {
2069 SwitchInsn->setMetadata(llvm::LLVMContext::MD_unpredictable,
2070 MDHelper.createUnpredictable());
2074 if (SwitchWeights) {
2075 assert(SwitchWeights->size() == 1 + SwitchInsn->getNumCases() &&
2076 "switch weights do not match switch cases");
2078 if (SwitchWeights->size() > 1)
2079 SwitchInsn->setMetadata(llvm::LLVMContext::MD_prof,
2080 createProfileWeights(*SwitchWeights));
2081 delete SwitchWeights;
2082 }
else if (SwitchLikelihood) {
2083 assert(SwitchLikelihood->size() == 1 + SwitchInsn->getNumCases() &&
2084 "switch likelihoods do not match switch cases");
2085 std::optional<SmallVector<uint64_t, 16>> LHW =
2089 SwitchInsn->setMetadata(llvm::LLVMContext::MD_prof,
2090 createProfileWeights(*LHW));
2092 delete SwitchLikelihood;
2094 SwitchInsn = SavedSwitchInsn;
2095 SwitchWeights = SavedSwitchWeights;
2096 SwitchLikelihood = SavedSwitchLikelihood;
2097 CaseRangeBlock = SavedCRBlock;
2105 while (*Constraint) {
2106 switch (*Constraint) {
2118 while (Constraint[1] && Constraint[1] !=
',')
2124 while (Constraint[1] && Constraint[1] == *Constraint)
2135 "Must pass output names to constraints with a symbolic name");
2138 assert(result &&
"Could not resolve symbolic name"); (void)result;
2139 Result += llvm::utostr(Index);
2157 std::string *GCCReg =
nullptr) {
2158 const DeclRefExpr *AsmDeclRef = dyn_cast<DeclRefExpr>(&AsmExpr);
2167 AsmLabelAttr *
Attr = Variable->getAttr<AsmLabelAttr>();
2170 StringRef Register =
Attr->getLabel();
2182 if (GCCReg !=
nullptr)
2183 *GCCReg = Register.str();
2184 return (EarlyClobber ?
"&{" :
"{") + Register.str() +
"}";
2187std::pair<llvm::Value*, llvm::Type *> CodeGenFunction::EmitAsmInputLValue(
2196 if ((Size <= 64 && llvm::isPowerOf2_64(Size)) ||
2207 ConstraintStr +=
'*';
2211std::pair<llvm::Value *, llvm::Type *>
2213 const Expr *InputExpr,
2214 std::string &ConstraintStr) {
2222 llvm::APSInt IntResult;
2225 return {llvm::ConstantInt::get(
getLLVMContext(), IntResult),
nullptr};
2237 if (InputExpr->
getStmtClass() == Expr::CXXThisExprClass)
2241 return EmitAsmInputLValue(Info, Dest, InputExpr->
getType(), ConstraintStr,
2253 Locs.push_back(llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2256 if (!StrVal.empty()) {
2259 unsigned StartToken = 0;
2260 unsigned ByteOffset = 0;
2264 for (
unsigned i = 0, e = StrVal.size() - 1; i != e; ++i) {
2265 if (StrVal[i] !=
'\n')
continue;
2267 i + 1,
SM, LangOpts, CGF.
getTarget(), &StartToken, &ByteOffset);
2268 Locs.push_back(llvm::ConstantAsMetadata::get(
2277 bool HasUnwindClobber,
bool ReadOnly,
2278 bool ReadNone,
bool NoMerge,
const AsmStmt &S,
2279 const std::vector<llvm::Type *> &ResultRegTypes,
2280 const std::vector<llvm::Type *> &ArgElemTypes,
2282 std::vector<llvm::Value *> &RegResults) {
2283 if (!HasUnwindClobber)
2284 Result.addFnAttr(llvm::Attribute::NoUnwind);
2287 Result.addFnAttr(llvm::Attribute::NoMerge);
2289 if (!HasSideEffect) {
2291 Result.setDoesNotAccessMemory();
2293 Result.setOnlyReadsMemory();
2297 for (
auto Pair : llvm::enumerate(ArgElemTypes)) {
2299 auto Attr = llvm::Attribute::get(
2300 CGF.
getLLVMContext(), llvm::Attribute::ElementType, Pair.value());
2307 if (
const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(&S))
2308 Result.setMetadata(
"srcloc",
2312 llvm::Constant *Loc =
2313 llvm::ConstantInt::get(CGF.
Int64Ty, S.getAsmLoc().getRawEncoding());
2314 Result.setMetadata(
"srcloc",
2316 llvm::ConstantAsMetadata::get(Loc)));
2324 Result.addFnAttr(llvm::Attribute::Convergent);
2326 if (ResultRegTypes.size() == 1) {
2327 RegResults.push_back(&
Result);
2329 for (
unsigned i = 0, e = ResultRegTypes.size(); i != e; ++i) {
2330 llvm::Value *Tmp = CGF.
Builder.CreateExtractValue(&
Result, i,
"asmresult");
2331 RegResults.push_back(Tmp);
2343 const llvm::BitVector &ResultTypeRequiresCast,
2344 const llvm::BitVector &ResultRegIsFlagReg) {
2349 assert(RegResults.size() == ResultRegTypes.size());
2350 assert(RegResults.size() == ResultTruncRegTypes.size());
2351 assert(RegResults.size() == ResultRegDests.size());
2354 assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
2355 assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
2357 for (
unsigned i = 0, e = RegResults.size(); i != e; ++i) {
2358 llvm::Value *Tmp = RegResults[i];
2359 llvm::Type *TruncTy = ResultTruncRegTypes[i];
2361 if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
2364 llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
2365 llvm::Value *IsBooleanValue =
2366 Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
2368 Builder.CreateCall(FnAssume, IsBooleanValue);
2373 if (ResultRegTypes[i] != TruncTy) {
2377 if (TruncTy->isFloatingPointTy())
2378 Tmp =
Builder.CreateFPTrunc(Tmp, TruncTy);
2379 else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
2382 Tmp, llvm::IntegerType::get(CTX, (
unsigned)ResSize));
2383 Tmp =
Builder.CreateIntToPtr(Tmp, TruncTy);
2384 }
else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
2388 Tmp, llvm::IntegerType::get(CTX, (
unsigned)TmpSize));
2389 Tmp =
Builder.CreateTrunc(Tmp, TruncTy);
2390 }
else if (TruncTy->isIntegerTy()) {
2391 Tmp =
Builder.CreateZExtOrTrunc(Tmp, TruncTy);
2392 }
else if (TruncTy->isVectorTy()) {
2393 Tmp =
Builder.CreateBitCast(Tmp, TruncTy);
2397 LValue Dest = ResultRegDests[i];
2400 if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) {
2411 const Expr *OutExpr = S.getOutputExpr(i);
2413 diag::err_store_value_to_reg);
2424 constexpr auto Name =
"__ASM__hipstdpar_unsupported";
2427 if (
auto GCCAsm = dyn_cast<GCCAsmStmt>(&S))
2428 Asm = GCCAsm->getAsmString()->getString();
2432 auto StrTy = llvm::ConstantDataArray::getString(Ctx,
Asm);
2433 auto FnTy = llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx),
2434 {StrTy->getType()},
false);
2435 auto UBF = CGF->
CGM.
getModule().getOrInsertFunction(Name, FnTy);
2437 CGF->
Builder.CreateCall(UBF, {StrTy});
2442 CodeGenFunction::RunCleanupsScope Cleanups(*
this);
2445 std::string AsmString = S.generateAsmString(
getContext());
2452 bool IsValidTargetAsm =
true;
2453 for (
unsigned i = 0, e = S.getNumOutputs(); i != e && IsValidTargetAsm; i++) {
2455 if (
const GCCAsmStmt *GAS = dyn_cast<GCCAsmStmt>(&S))
2456 Name = GAS->getOutputName(i);
2459 if (IsHipStdPar && !IsValid)
2460 IsValidTargetAsm =
false;
2462 assert(IsValid &&
"Failed to parse output constraint");
2463 OutputConstraintInfos.push_back(Info);
2466 for (
unsigned i = 0, e = S.getNumInputs(); i != e && IsValidTargetAsm; i++) {
2468 if (
const GCCAsmStmt *GAS = dyn_cast<GCCAsmStmt>(&S))
2469 Name = GAS->getInputName(i);
2473 if (IsHipStdPar && !IsValid)
2474 IsValidTargetAsm =
false;
2476 assert(IsValid &&
"Failed to parse input constraint");
2477 InputConstraintInfos.push_back(Info);
2480 if (!IsValidTargetAsm)
2483 std::string Constraints;
2485 std::vector<LValue> ResultRegDests;
2486 std::vector<QualType> ResultRegQualTys;
2487 std::vector<llvm::Type *> ResultRegTypes;
2488 std::vector<llvm::Type *> ResultTruncRegTypes;
2489 std::vector<llvm::Type *> ArgTypes;
2490 std::vector<llvm::Type *> ArgElemTypes;
2491 std::vector<llvm::Value*> Args;
2492 llvm::BitVector ResultTypeRequiresCast;
2493 llvm::BitVector ResultRegIsFlagReg;
2496 std::string InOutConstraints;
2497 std::vector<llvm::Value*> InOutArgs;
2498 std::vector<llvm::Type*> InOutArgTypes;
2499 std::vector<llvm::Type*> InOutArgElemTypes;
2502 std::vector<std::string> OutputConstraints;
2505 llvm::SmallSet<std::string, 8> PhysRegOutputs;
2513 bool ReadOnly =
true, ReadNone =
true;
2515 for (
unsigned i = 0, e = S.getNumOutputs(); i != e; i++) {
2519 std::string OutputConstraint(S.getOutputConstraint(i));
2523 const Expr *OutExpr = S.getOutputExpr(i);
2532 if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second)
2533 CGM.
Error(S.getAsmLoc(),
"multiple outputs to hard register: " + GCCReg);
2535 OutputConstraints.push_back(OutputConstraint);
2537 if (!Constraints.empty())
2547 Constraints +=
"=" + OutputConstraint;
2548 ResultRegQualTys.push_back(QTy);
2549 ResultRegDests.push_back(Dest);
2551 bool IsFlagReg = llvm::StringRef(OutputConstraint).startswith(
"{@cc");
2552 ResultRegIsFlagReg.push_back(IsFlagReg);
2557 Ty->isAggregateType());
2559 ResultTruncRegTypes.push_back(Ty);
2560 ResultTypeRequiresCast.push_back(RequiresCast);
2566 ResultRegTypes.push_back(Ty);
2572 for (InputNo = 0; InputNo != S.getNumInputs(); ++InputNo) {
2577 assert(InputNo != S.getNumInputs() &&
"Didn't find matching input!");
2579 QualType InputTy = S.getInputExpr(InputNo)->getType();
2588 if (llvm::Type* AdjTy =
2590 ResultRegTypes.back()))
2591 ResultRegTypes.back() = AdjTy;
2594 diag::err_asm_invalid_type_in_input)
2595 << OutExpr->
getType() << OutputConstraint;
2599 if (
auto *VT = dyn_cast<llvm::VectorType>(ResultRegTypes.back()))
2600 LargestVectorWidth =
2601 std::max((uint64_t)LargestVectorWidth,
2602 VT->getPrimitiveSizeInBits().getKnownMinValue());
2613 ArgTypes.push_back(DestAddr.
getType());
2616 Constraints +=
"=*";
2617 Constraints += OutputConstraint;
2618 ReadOnly = ReadNone =
false;
2622 InOutConstraints +=
',';
2624 const Expr *InputExpr = S.getOutputExpr(i);
2626 llvm::Type *ArgElemType;
2627 std::tie(Arg, ArgElemType) = EmitAsmInputLValue(
2628 Info, Dest, InputExpr->
getType(), InOutConstraints,
2631 if (llvm::Type* AdjTy =
2634 Arg =
Builder.CreateBitCast(Arg, AdjTy);
2637 if (
auto *VT = dyn_cast<llvm::VectorType>(Arg->getType()))
2638 LargestVectorWidth =
2639 std::max((uint64_t)LargestVectorWidth,
2640 VT->getPrimitiveSizeInBits().getKnownMinValue());
2643 InOutConstraints += llvm::utostr(i);
2645 InOutConstraints += OutputConstraint;
2647 InOutArgTypes.push_back(Arg->getType());
2648 InOutArgElemTypes.push_back(ArgElemType);
2649 InOutArgs.push_back(Arg);
2655 if (isa<MSAsmStmt>(&S)) {
2661 *
this, ReturnSlot, Constraints, ResultRegTypes, ResultTruncRegTypes,
2662 ResultRegDests, AsmString, S.getNumOutputs());
2667 for (
unsigned i = 0, e = S.getNumInputs(); i != e; i++) {
2668 const Expr *InputExpr = S.getInputExpr(i);
2675 if (!Constraints.empty())
2679 std::string InputConstraint(S.getInputConstraint(i));
2681 &OutputConstraintInfos);
2687 std::string ReplaceConstraint (InputConstraint);
2689 llvm::Type *ArgElemType;
2690 std::tie(Arg, ArgElemType) = EmitAsmInput(Info, InputExpr, Constraints);
2699 QualType OutputType = S.getOutputExpr(Output)->getType();
2705 if (isa<llvm::PointerType>(Arg->getType()))
2708 if (isa<llvm::IntegerType>(OutputTy))
2709 Arg =
Builder.CreateZExt(Arg, OutputTy);
2710 else if (isa<llvm::PointerType>(OutputTy))
2712 else if (OutputTy->isFloatingPointTy())
2713 Arg =
Builder.CreateFPExt(Arg, OutputTy);
2716 ReplaceConstraint = OutputConstraints[Output];
2718 if (llvm::Type* AdjTy =
2721 Arg =
Builder.CreateBitCast(Arg, AdjTy);
2724 << InputExpr->
getType() << InputConstraint;
2727 if (
auto *VT = dyn_cast<llvm::VectorType>(Arg->getType()))
2728 LargestVectorWidth =
2729 std::max((uint64_t)LargestVectorWidth,
2730 VT->getPrimitiveSizeInBits().getKnownMinValue());
2732 ArgTypes.push_back(Arg->getType());
2733 ArgElemTypes.push_back(ArgElemType);
2734 Args.push_back(Arg);
2735 Constraints += InputConstraint;
2739 for (
unsigned i = 0, e = InOutArgs.size(); i != e; i++) {
2740 ArgTypes.push_back(InOutArgTypes[i]);
2741 ArgElemTypes.push_back(InOutArgElemTypes[i]);
2742 Args.push_back(InOutArgs[i]);
2744 Constraints += InOutConstraints;
2748 llvm::BasicBlock *Fallthrough =
nullptr;
2749 bool IsGCCAsmGoto =
false;
2750 if (
const auto *GS = dyn_cast<GCCAsmStmt>(&S)) {
2751 IsGCCAsmGoto = GS->isAsmGoto();
2753 for (
const auto *E : GS->labels()) {
2755 Transfer.push_back(Dest.getBlock());
2756 if (!Constraints.empty())
2758 Constraints +=
"!i";
2764 bool HasUnwindClobber =
false;
2767 for (
unsigned i = 0, e = S.getNumClobbers(); i != e; i++) {
2768 StringRef Clobber = S.getClobber(i);
2770 if (Clobber ==
"memory")
2771 ReadOnly = ReadNone =
false;
2772 else if (Clobber ==
"unwind") {
2773 HasUnwindClobber =
true;
2775 }
else if (Clobber !=
"cc") {
2780 diag::warn_stack_clash_protection_inline_asm);
2784 if (isa<MSAsmStmt>(&S)) {
2785 if (Clobber ==
"eax" || Clobber ==
"edx") {
2786 if (Constraints.find(
"=&A") != std::string::npos)
2788 std::string::size_type position1 =
2789 Constraints.find(
"={" + Clobber.str() +
"}");
2790 if (position1 != std::string::npos) {
2791 Constraints.insert(position1 + 1,
"&");
2794 std::string::size_type position2 = Constraints.find(
"=A");
2795 if (position2 != std::string::npos) {
2796 Constraints.insert(position2 + 1,
"&");
2801 if (!Constraints.empty())
2804 Constraints +=
"~{";
2805 Constraints += Clobber;
2809 assert(!(HasUnwindClobber && IsGCCAsmGoto) &&
2810 "unwind clobber can't be used with asm goto");
2814 if (!MachineClobbers.empty()) {
2815 if (!Constraints.empty())
2817 Constraints += MachineClobbers;
2820 llvm::Type *ResultType;
2821 if (ResultRegTypes.empty())
2823 else if (ResultRegTypes.size() == 1)
2824 ResultType = ResultRegTypes[0];
2826 ResultType = llvm::StructType::get(
getLLVMContext(), ResultRegTypes);
2828 llvm::FunctionType *FTy =
2829 llvm::FunctionType::get(ResultType, ArgTypes,
false);
2831 bool HasSideEffect = S.isVolatile() || S.getNumOutputs() == 0;
2833 llvm::InlineAsm::AsmDialect GnuAsmDialect =
2835 ? llvm::InlineAsm::AD_ATT
2836 : llvm::InlineAsm::AD_Intel;
2837 llvm::InlineAsm::AsmDialect AsmDialect = isa<MSAsmStmt>(&S) ?
2838 llvm::InlineAsm::AD_Intel : GnuAsmDialect;
2840 llvm::InlineAsm *IA = llvm::InlineAsm::get(
2841 FTy, AsmString, Constraints, HasSideEffect,
2842 false, AsmDialect, HasUnwindClobber);
2843 std::vector<llvm::Value*> RegResults;
2844 llvm::CallBrInst *CBR;
2845 llvm::DenseMap<llvm::BasicBlock *, SmallVector<llvm::Value *, 4>>
2848 CBR =
Builder.CreateCallBr(IA, Fallthrough, Transfer, Args);
2856 if (!RegResults.empty()) {
2858 for (llvm::BasicBlock *Dest : CBR->getIndirectDests()) {
2859 llvm::Twine SynthName = Dest->getName() +
".split";
2861 llvm::IRBuilderBase::InsertPointGuard IPG(
Builder);
2862 Builder.SetInsertPoint(SynthBB);
2864 if (ResultRegTypes.size() == 1) {
2865 CBRRegResults[SynthBB].push_back(CBR);
2867 for (
unsigned j = 0, e = ResultRegTypes.size(); j != e; ++j) {
2868 llvm::Value *Tmp =
Builder.CreateExtractValue(CBR, j,
"asmresult");
2869 CBRRegResults[SynthBB].push_back(Tmp);
2875 CBR->setIndirectDest(i++, SynthBB);
2878 }
else if (HasUnwindClobber) {
2891 EmitAsmStores(*
this, S, RegResults, ResultRegTypes, ResultTruncRegTypes,
2892 ResultRegDests, ResultRegQualTys, ResultTypeRequiresCast,
2893 ResultRegIsFlagReg);
2898 if (IsGCCAsmGoto && !CBRRegResults.empty()) {
2899 for (llvm::BasicBlock *Succ : CBR->getIndirectDests()) {
2900 llvm::IRBuilderBase::InsertPointGuard IPG(
Builder);
2901 Builder.SetInsertPoint(Succ, --(Succ->end()));
2902 EmitAsmStores(*
this, S, CBRRegResults[Succ], ResultRegTypes,
2903 ResultTruncRegTypes, ResultRegDests, ResultRegQualTys,
2904 ResultTypeRequiresCast, ResultRegIsFlagReg);
2910 const RecordDecl *RD = S.getCapturedRecordDecl();
2919 E = S.capture_init_end();
2920 I != E; ++I, ++CurField) {
2922 if (CurField->hasCapturedVLAType()) {
2940 CGCapturedStmtRAII CapInfoRAII(CGF,
new CGCapturedStmtInfo(S, K));
2941 llvm::Function *F = CGF.GenerateCapturedStmtFunction(S);
2942 delete CGF.CapturedStmtInfo;
2959 "CapturedStmtInfo should be set when generating the captured function");
2961 const RecordDecl *RD = S.getCapturedRecordDecl();
2963 assert(CD->
hasBody() &&
"missing CapturedDecl body");
2976 llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
2980 F->addFnAttr(llvm::Attribute::NoUnwind);
2992 for (
auto *FD : RD->
fields()) {
2993 if (FD->hasCapturedVLAType()) {
2997 auto VAT = FD->getCapturedVLAType();
2998 VLASizeMap[VAT->getSizeExpr()] = ExprArg;
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...
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...
static void EmitHipStdParUnsupportedAsm(CodeGenFunction *CGF, const AsmStmt &S)
static std::optional< SmallVector< uint64_t, 16 > > getLikelihoodWeights(ArrayRef< Stmt::Likelihood > Likelihoods)
static llvm::MDNode * getAsmSrcLocInfo(const StringLiteral *Str, CodeGenFunction &CGF)
getAsmSrcLocInfo - Return the !srcloc metadata node to attach to an inline asm call instruction.
static std::string SimplifyConstraint(const char *Constraint, const TargetInfo &Target, SmallVectorImpl< TargetInfo::ConstraintInfo > *OutCons=nullptr)
static void UpdateAsmCallInst(llvm::CallBase &Result, bool HasSideEffect, bool HasUnwindClobber, bool ReadOnly, bool ReadNone, bool NoMerge, const AsmStmt &S, const std::vector< llvm::Type * > &ResultRegTypes, const std::vector< llvm::Type * > &ArgElemTypes, CodeGenFunction &CGF, std::vector< llvm::Value * > &RegResults)
static void makeTailCallIfSwiftAsync(const CallExpr *CE, CGBuilderTy &Builder, const CGFunctionInfo *CurFnInfo)
If we have 'return f(...);', where both caller and callee are SwiftAsync, codegen it as 'tail call ....
static CSFC_Result CollectStatementsForCase(const Stmt *S, const SwitchCase *Case, bool &FoundCase, SmallVectorImpl< const Stmt * > &ResultStmts)
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 llvm::BitVector &ResultRegIsFlagReg)
CSFC_Result
CollectStatementsForCase - Given the body of a 'switch' statement and a constant value that is being ...
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 getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl.
QualType getRecordType(const RecordDecl *Decl) const
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.
AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
Attr - This represents one attribute.
Represents an attribute applied to a statement.
BreakStmt - This represents a break.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
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.
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.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
bool hasReducedDebugInfo() const
Check if type and variable info should be emitted.
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
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::Value * getPointer() const
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.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::StoreInst * CreateFlagStore(bool Value, llvm::Value *Addr)
Emit a store to an i1 flag variable.
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.
ABIArgInfo & getReturnInfo()
CallingConv getASTCallingConvention() const
getASTCallingConvention() - Return the AST-specified calling convention.
virtual Address getAddressOfLocalVariable(CodeGenFunction &CGF, const VarDecl *VD)
Gets the OpenMP-specific address of the local variable.
virtual llvm::Value * getContextValue() const
virtual void setContextValue(llvm::Value *V)
bool isCXXThisExprCaptured() const
virtual FieldDecl * getThisFieldDecl() const
virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S)
Emit the captured statement body.
virtual StringRef getHelperName() const
Get the name of the capture helper.
void rescopeLabels()
Change the cleanup scope of the labels in this lexical scope to match the scope of the enclosing cont...
void addLabel(const LabelDecl *label)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitForStmt(const ForStmt &S, ArrayRef< const Attr * > Attrs=std::nullopt)
void EmitGotoStmt(const GotoStmt &S)
void EmitOMPTargetTeamsDirective(const OMPTargetTeamsDirective &S)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void EmitOMPParallelGenericLoopDirective(const OMPLoopDirective &S)
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
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...
void EmitSehCppScopeBegin()
void EmitIfStmt(const IfStmt &S)
void EmitOMPOrderedDirective(const OMPOrderedDirective &S)
void EmitOMPTargetDirective(const OMPTargetDirective &S)
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 EmitOMPAtomicDirective(const OMPAtomicDirective &S)
void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S)
void EmitOMPParallelMasterTaskLoopDirective(const OMPParallelMasterTaskLoopDirective &S)
Address EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
static bool hasScalarEvaluationKind(QualType T)
CGCapturedStmtInfo * CapturedStmtInfo
void EmitIndirectGotoStmt(const IndirectGotoStmt &S)
void EmitDecl(const Decl &D)
EmitDecl - Emit a declaration.
void EmitCXXTryStmt(const CXXTryStmt &S)
bool EmitSimpleStmt(const Stmt *S, ArrayRef< const Attr * > Attrs)
EmitSimpleStmt - Try to emit a "simple" statement which does not necessarily require an insertion poi...
void EmitLabel(const LabelDecl *D)
EmitLabel - Emit the block for the given label.
void EmitOMPTeamsDistributeParallelForDirective(const OMPTeamsDistributeParallelForDirective &S)
void EmitOMPTaskDirective(const OMPTaskDirective &S)
void EmitOMPScanDirective(const OMPScanDirective &S)
void EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S)
void EmitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective &S)
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
void EmitCaseStmt(const CaseStmt &S, ArrayRef< const Attr * > Attrs)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitDefaultStmt(const DefaultStmt &S, ArrayRef< const Attr * > Attrs)
const LangOptions & getLangOpts() const
void EmitOMPDistributeSimdDirective(const OMPDistributeSimdDirective &S)
void EmitOMPDistributeParallelForDirective(const OMPDistributeParallelForDirective &S)
LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)
EmitLValueForFieldInitialization - Like EmitLValueForField, except that if the Field is a reference,...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S)
void EmitOMPTeamsGenericLoopDirective(const OMPTeamsGenericLoopDirective &S)
void EmitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective &S)
SmallVector< llvm::OperandBundleDef, 1 > getBundlesForFunclet(llvm::Value *Callee)
void SimplifyForwardingBlocks(llvm::BasicBlock *BB)
SimplifyForwardingBlocks - If the given basic block is only a branch to another basic block,...
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
void EmitOMPParallelDirective(const OMPParallelDirective &S)
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...
void EmitBlockAfterUses(llvm::BasicBlock *BB)
EmitBlockAfterUses - Emit the given block somewhere hopefully near its uses, and leave the insertion ...
void EmitContinueStmt(const ContinueStmt &S)
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
bool InNoMergeAttributedStmt
True if the current statement has nomerge attribute.
llvm::Type * ConvertTypeForMem(QualType T)
void EmitOMPDistributeParallelForSimdDirective(const OMPDistributeParallelForSimdDirective &S)
LValue MakeAddrLValueWithoutTBAA(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitOMPForSimdDirective(const OMPForSimdDirective &S)
JumpDest ReturnBlock
ReturnBlock - Unified return block.
bool checkIfLoopMustProgress(bool HasConstantCond)
Returns true if a loop must make progress, which means the mustprogress attribute can be added.
LValue EmitLValueForField(LValue Base, const FieldDecl *Field)
void EmitOMPFlushDirective(const OMPFlushDirective &S)
void EmitSEHLeaveStmt(const SEHLeaveStmt &S)
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
void EmitAttributedStmt(const AttributedStmt &S)
void EmitOMPCancelDirective(const OMPCancelDirective &S)
void EmitOMPGenericLoopDirective(const OMPGenericLoopDirective &S)
void EmitOMPTargetTeamsDistributeDirective(const OMPTargetTeamsDistributeDirective &S)
void EmitCaseStmtRange(const CaseStmt &S, ArrayRef< const Attr * > Attrs)
const TargetInfo & getTarget() const
void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S)
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location)
Converts Location to a DebugLoc, if debug information is enabled.
llvm::Value * getTypeSize(QualType Ty)
Returns calculated size of the specified type.
void EmitLabelStmt(const LabelStmt &S)
void EmitOMPDepobjDirective(const OMPDepobjDirective &S)
const Expr * RetExpr
If a return statement is being visited, this holds the return statment's result expression.
void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init)
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
void EmitOMPSingleDirective(const OMPSingleDirective &S)
void EmitOMPTargetTeamsGenericLoopDirective(const OMPTargetTeamsGenericLoopDirective &S)
void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S)
void EmitSimpleOMPExecutableDirective(const OMPExecutableDirective &D)
Emit simple code for OpenMP directives in Simd-only mode.
void EmitOMPDistributeDirective(const OMPDistributeDirective &S)
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 EmitOMPParallelForDirective(const OMPParallelForDirective &S)
void EmitOMPTeamsDirective(const OMPTeamsDirective &S)
uint64_t getCurrentProfileCount()
Get the profiler's current count.
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 EmitOMPUnrollDirective(const OMPUnrollDirective &S)
void EmitOMPParallelMasterTaskLoopSimdDirective(const OMPParallelMasterTaskLoopSimdDirective &S)
void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S)
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
void EmitSwitchStmt(const SwitchStmt &S)
CGDebugInfo * getDebugInfo()
void EmitOMPTargetTeamsDistributeParallelForSimdDirective(const OMPTargetTeamsDistributeParallelForSimdDirective &S)
void EmitOMPTeamsDistributeParallelForSimdDirective(const OMPTeamsDistributeParallelForSimdDirective &S)
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
llvm::Function * GenerateCapturedStmtFunction(const CapturedStmt &S)
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
void EmitSEHTryStmt(const SEHTryStmt &S)
void EmitOMPInteropDirective(const OMPInteropDirective &S)
const TargetCodeGenInfo & getTargetHooks() const
RValue EmitReferenceBindingToExpr(const Expr *E)
Emits a reference binding to the passed in expression.
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
void EmitDeclStmt(const DeclStmt &S)
bool InNoInlineAttributedStmt
True if the current statement has noinline attribute.
void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S)
void EmitOMPParallelMaskedDirective(const OMPParallelMaskedDirective &S)
void EmitCoroutineBody(const CoroutineBodyStmt &S)
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
void EmitDoStmt(const DoStmt &S, ArrayRef< const Attr * > Attrs=std::nullopt)
void EmitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &S)
ASTContext & getContext() const
Address CreateMemTemp(QualType T, const Twine &Name="tmp", Address *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
void EmitCXXForRangeStmt(const CXXForRangeStmt &S, ArrayRef< const Attr * > Attrs=std::nullopt)
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
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)
JumpDest getJumpDestForLabel(const LabelDecl *S)
getBasicBlockForLabel - Return the LLVM basicblock that the specified label maps to.
void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S)
llvm::Function * EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K)
llvm::Type * ConvertType(QualType T)
void EmitOMPSectionsDirective(const OMPSectionsDirective &S)
llvm::CallBase * EmitCallOrInvoke(llvm::FunctionCallee Callee, ArrayRef< llvm::Value * > Args, const Twine &Name="")
bool InAlwaysInlineAttributedStmt
True if the current statement has always_inline attribute.
void EmitOMPTargetSimdDirective(const OMPTargetSimdDirective &S)
void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S)
void EmitOMPSimdDirective(const OMPSimdDirective &S)
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
void EmitOMPCriticalDirective(const OMPCriticalDirective &S)
const TargetInfo & Target
void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S)
void EmitOMPForDirective(const OMPForDirective &S)
void EmitOMPMetaDirective(const OMPMetaDirective &S)
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
void EmitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &S)
LValue InitCapturedStruct(const CapturedStmt &S)
void EmitOMPParallelMasterDirective(const OMPParallelMasterDirective &S)
void EmitReturnStmt(const ReturnStmt &S)
unsigned NextCleanupDestIndex
AggValueSlot::Overlap_t getOverlapForReturnValue()
Determine whether a return value slot may overlap some other object.
void EmitOMPTargetTeamsDistributeSimdDirective(const OMPTargetTeamsDistributeSimdDirective &S)
void EmitOMPMasterDirective(const OMPMasterDirective &S)
void EmitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective &S)
void EmitOMPTargetParallelGenericLoopDirective(const OMPTargetParallelGenericLoopDirective &S)
static bool mightAddDeclToScope(const Stmt *S)
Determine if the given statement might introduce a declaration into the current scope,...
void EmitOMPMaskedDirective(const OMPMaskedDirective &S)
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
static bool hasAggregateEvaluationKind(QualType T)
void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S)
void EmitOMPTargetParallelForSimdDirective(const OMPTargetParallelForSimdDirective &S)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
void EmitBreakStmt(const BreakStmt &S)
Address GenerateCapturedStmtArgument(const CapturedStmt &S)
void EmitLambdaVLACapture(const VariableArrayType *VAT, LValue LV)
const CallExpr * MustTailCall
const CGFunctionInfo * CurFnInfo
bool isObviouslyBranchWithoutCleanups(JumpDest Dest) const
isObviouslyBranchWithoutCleanups - Return true if a branch to the specified destination obviously has...
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
void EmitCoreturnStmt(const CoreturnStmt &S)
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S)
void EmitOMPErrorDirective(const OMPErrorDirective &S)
void EmitOMPSectionDirective(const OMPSectionDirective &S)
void EmitOMPBarrierDirective(const OMPBarrierDirective &S)
void EmitStopPoint(const Stmt *S)
EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
void EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S)
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs=std::nullopt)
EmitStmt - Emit the code for the statement.
void EmitWhileStmt(const WhileStmt &S, ArrayRef< const Attr * > Attrs=std::nullopt)
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
llvm::LLVMContext & getLLVMContext()
void EmitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &S)
bool SawAsmBlock
Whether we processed a Microsoft-style asm block during CodeGen.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void ResolveBranchFixups(llvm::BasicBlock *Target)
void EmitOMPTargetTeamsDistributeParallelForDirective(const OMPTargetTeamsDistributeParallelForDirective &S)
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S)
void EmitOMPCanonicalLoop(const OMPCanonicalLoop *S)
Emit an OMPCanonicalLoop using the OpenMPIRBuilder.
void EmitOMPTeamsDistributeSimdDirective(const OMPTeamsDistributeSimdDirective &S)
llvm::BasicBlock * GetIndirectGotoBlock()
void EmitAsmStmt(const AsmStmt &S)
void EmitObjCAtTryStmt(const ObjCAtTryStmt &S)
void EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S)
static bool containsBreak(const Stmt *S)
containsBreak - Return true if the statement contains a break out of it.
This class organizes the cross-function state that is used while generating LLVM code.
void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
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
CodeGenTypes & getTypes()
const llvm::DataLayout & getDataLayout() const
void Error(SourceLocation loc, StringRef error)
Emit a general error that something can't be done.
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
SanitizerMetadata * getSanitizerMetadata()
ASTContext & getContext() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=std::nullopt)
void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn)
Assign counters to regions and configure them for PGO of a given function.
void setCurrentStmt(const Stmt *S)
If the execution count for the current statement is known, record that as the current count.
bool haveRegionCounts() const
Whether or not we have PGO region data for the current function.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
A saved depth on the scope stack.
bool encloses(stable_iterator I) const
Returns true if this scope encloses I.
static stable_iterator invalid()
stable_iterator getInnermostNormalCleanup() const
Returns the innermost normal cleanup on the stack, or stable_end() if there are no normal cleanups.
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
bool empty() const
Determines whether the exception-scopes stack is empty.
bool hasNormalCleanups() const
Determines whether there are any normal cleanups on the stack.
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.
Address getAddress(CodeGenFunction &CGF) const
llvm::Value * getPointer(CodeGenFunction &CGF) const
void pop()
End the current loop.
void push(llvm::BasicBlock *Header, const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
Begin a new structured loop.
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 void addReturnRegisterOutputs(CodeGen::CodeGenFunction &CGF, CodeGen::LValue ReturnValue, std::string &Constraints, std::vector< llvm::Type * > &ResultRegTypes, std::vector< llvm::Type * > &ResultTruncRegTypes, std::vector< CodeGen::LValue > &ResultRegDests, std::string &AsmString, unsigned NumOutputs) const
Adds constraints and types for result registers.
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
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
ContinueStmt - This represents a continue.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
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
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, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) 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...
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.
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.
IfStmt - This represents an if/then/else.
IndirectGotoStmt - This represents an indirect goto.
Represents the declaration of a label.
LabelStmt * getStmt() const
LabelStmt - Represents a label, which has a substatement.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool assumeFunctionsAreConvergent() const
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
field_iterator field_begin() const
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
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
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.
Exposes information about the current target.
bool validateInputConstraint(MutableArrayRef< ConstraintInfo > OutputConstraints, ConstraintInfo &info) const
bool resolveSymbolicName(const char *&Name, ArrayRef< ConstraintInfo > OutputConstraints, unsigned &Index) 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.
virtual std::string convertConstraint(const char *&Constraint) const
virtual bool isValidGCCRegisterName(StringRef Name) const
Returns whether the passed in string is a valid register name according to GCC.
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
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.
WhileStmt - This represents a 'while' stmt.
Defines the clang::TargetInfo interface.
bool Rem(InterpState &S, CodePtr OpPC)
1) Pops the RHS from the stack.
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.
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
void setScopeDepth(EHScopeStack::stable_iterator depth)
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
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