;
40using namespaceCodeGen;
50voidCodeGenFunction::EmitStopPoint(
const Stmt*S) {
53 Loc= S->getBeginLoc();
61assert(S &&
"Null statement?");
78assert(!isa<DeclStmt>(*S) &&
"Unexpected DeclStmt!");
93 if(
const auto*
D= dyn_cast<OMPExecutableDirective>(S)) {
99 switch(S->getStmtClass()) {
101 caseStmt::CXXCatchStmtClass:
102 caseStmt::SEHExceptStmtClass:
103 caseStmt::SEHFinallyStmtClass:
104 caseStmt::MSDependentExistsStmtClass:
105llvm_unreachable(
"invalid statement class to emit generically");
106 caseStmt::NullStmtClass:
107 caseStmt::CompoundStmtClass:
108 caseStmt::DeclStmtClass:
109 caseStmt::LabelStmtClass:
110 caseStmt::AttributedStmtClass:
111 caseStmt::GotoStmtClass:
112 caseStmt::BreakStmtClass:
113 caseStmt::ContinueStmtClass:
114 caseStmt::DefaultStmtClass:
115 caseStmt::CaseStmtClass:
116 caseStmt::SEHLeaveStmtClass:
117 caseStmt::SYCLKernelCallStmtClass:
118llvm_unreachable(
"should have emitted these statements as simple");
120#define STMT(Type, Base) 121#define ABSTRACT_STMT(Op) 122#define EXPR(Type, Base) \ 123 case Stmt::Type##Class: 124#include "clang/AST/StmtNodes.inc" 127llvm::BasicBlock *incoming =
Builder.GetInsertBlock();
128assert(incoming &&
"expression emission must have an insertion point");
132llvm::BasicBlock *outgoing =
Builder.GetInsertBlock();
133assert(outgoing &&
"expression emission cleared block!");
147 if(incoming != outgoing && outgoing->use_empty()) {
148outgoing->eraseFromParent();
149 Builder.ClearInsertionPoint();
154 caseStmt::IndirectGotoStmtClass:
157 caseStmt::IfStmtClass:
EmitIfStmt(cast<IfStmt>(*S));
break;
158 caseStmt::WhileStmtClass:
EmitWhileStmt(cast<WhileStmt>(*S), Attrs);
break;
159 caseStmt::DoStmtClass:
EmitDoStmt(cast<DoStmt>(*S), Attrs);
break;
160 caseStmt::ForStmtClass:
EmitForStmt(cast<ForStmt>(*S), Attrs);
break;
162 caseStmt::ReturnStmtClass:
EmitReturnStmt(cast<ReturnStmt>(*S));
break;
164 caseStmt::SwitchStmtClass:
EmitSwitchStmt(cast<SwitchStmt>(*S));
break;
165 caseStmt::GCCAsmStmtClass:
166 caseStmt::MSAsmStmtClass:
EmitAsmStmt(cast<AsmStmt>(*S));
break;
167 caseStmt::CoroutineBodyStmtClass:
170 caseStmt::CoreturnStmtClass:
173 caseStmt::CapturedStmtClass: {
178 caseStmt::ObjCAtTryStmtClass:
181 caseStmt::ObjCAtCatchStmtClass:
183 "@catch statements should be handled by EmitObjCAtTryStmt");
184 caseStmt::ObjCAtFinallyStmtClass:
186 "@finally statements should be handled by EmitObjCAtTryStmt");
187 caseStmt::ObjCAtThrowStmtClass:
190 caseStmt::ObjCAtSynchronizedStmtClass:
193 caseStmt::ObjCForCollectionStmtClass:
196 caseStmt::ObjCAutoreleasePoolStmtClass:
200 caseStmt::CXXTryStmtClass:
203 caseStmt::CXXForRangeStmtClass:
206 caseStmt::SEHTryStmtClass:
209 caseStmt::OMPMetaDirectiveClass:
212 caseStmt::OMPCanonicalLoopClass:
215 caseStmt::OMPParallelDirectiveClass:
218 caseStmt::OMPSimdDirectiveClass:
221 caseStmt::OMPTileDirectiveClass:
224 caseStmt::OMPUnrollDirectiveClass:
227 caseStmt::OMPReverseDirectiveClass:
230 caseStmt::OMPInterchangeDirectiveClass:
233 caseStmt::OMPForDirectiveClass:
236 caseStmt::OMPForSimdDirectiveClass:
239 caseStmt::OMPSectionsDirectiveClass:
242 caseStmt::OMPSectionDirectiveClass:
245 caseStmt::OMPSingleDirectiveClass:
248 caseStmt::OMPMasterDirectiveClass:
251 caseStmt::OMPCriticalDirectiveClass:
254 caseStmt::OMPParallelForDirectiveClass:
257 caseStmt::OMPParallelForSimdDirectiveClass:
260 caseStmt::OMPParallelMasterDirectiveClass:
263 caseStmt::OMPParallelSectionsDirectiveClass:
266 caseStmt::OMPTaskDirectiveClass:
269 caseStmt::OMPTaskyieldDirectiveClass:
272 caseStmt::OMPErrorDirectiveClass:
275 caseStmt::OMPBarrierDirectiveClass:
278 caseStmt::OMPTaskwaitDirectiveClass:
281 caseStmt::OMPTaskgroupDirectiveClass:
284 caseStmt::OMPFlushDirectiveClass:
287 caseStmt::OMPDepobjDirectiveClass:
290 caseStmt::OMPScanDirectiveClass:
293 caseStmt::OMPOrderedDirectiveClass:
296 caseStmt::OMPAtomicDirectiveClass:
299 caseStmt::OMPTargetDirectiveClass:
302 caseStmt::OMPTeamsDirectiveClass:
305 caseStmt::OMPCancellationPointDirectiveClass:
308 caseStmt::OMPCancelDirectiveClass:
311 caseStmt::OMPTargetDataDirectiveClass:
314 caseStmt::OMPTargetEnterDataDirectiveClass:
317 caseStmt::OMPTargetExitDataDirectiveClass:
320 caseStmt::OMPTargetParallelDirectiveClass:
323 caseStmt::OMPTargetParallelForDirectiveClass:
326 caseStmt::OMPTaskLoopDirectiveClass:
329 caseStmt::OMPTaskLoopSimdDirectiveClass:
332 caseStmt::OMPMasterTaskLoopDirectiveClass:
335 caseStmt::OMPMaskedTaskLoopDirectiveClass:
338 caseStmt::OMPMasterTaskLoopSimdDirectiveClass:
340cast<OMPMasterTaskLoopSimdDirective>(*S));
342 caseStmt::OMPMaskedTaskLoopSimdDirectiveClass:
344cast<OMPMaskedTaskLoopSimdDirective>(*S));
346 caseStmt::OMPParallelMasterTaskLoopDirectiveClass:
348cast<OMPParallelMasterTaskLoopDirective>(*S));
350 caseStmt::OMPParallelMaskedTaskLoopDirectiveClass:
352cast<OMPParallelMaskedTaskLoopDirective>(*S));
354 caseStmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
356cast<OMPParallelMasterTaskLoopSimdDirective>(*S));
358 caseStmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
360cast<OMPParallelMaskedTaskLoopSimdDirective>(*S));
362 caseStmt::OMPDistributeDirectiveClass:
365 caseStmt::OMPTargetUpdateDirectiveClass:
368 caseStmt::OMPDistributeParallelForDirectiveClass:
370cast<OMPDistributeParallelForDirective>(*S));
372 caseStmt::OMPDistributeParallelForSimdDirectiveClass:
374cast<OMPDistributeParallelForSimdDirective>(*S));
376 caseStmt::OMPDistributeSimdDirectiveClass:
379 caseStmt::OMPTargetParallelForSimdDirectiveClass:
381cast<OMPTargetParallelForSimdDirective>(*S));
383 caseStmt::OMPTargetSimdDirectiveClass:
386 caseStmt::OMPTeamsDistributeDirectiveClass:
389 caseStmt::OMPTeamsDistributeSimdDirectiveClass:
391cast<OMPTeamsDistributeSimdDirective>(*S));
393 caseStmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
395cast<OMPTeamsDistributeParallelForSimdDirective>(*S));
397 caseStmt::OMPTeamsDistributeParallelForDirectiveClass:
399cast<OMPTeamsDistributeParallelForDirective>(*S));
401 caseStmt::OMPTargetTeamsDirectiveClass:
404 caseStmt::OMPTargetTeamsDistributeDirectiveClass:
406cast<OMPTargetTeamsDistributeDirective>(*S));
408 caseStmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
410cast<OMPTargetTeamsDistributeParallelForDirective>(*S));
412 caseStmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
414cast<OMPTargetTeamsDistributeParallelForSimdDirective>(*S));
416 caseStmt::OMPTargetTeamsDistributeSimdDirectiveClass:
418cast<OMPTargetTeamsDistributeSimdDirective>(*S));
420 caseStmt::OMPInteropDirectiveClass:
423 caseStmt::OMPDispatchDirectiveClass:
426 caseStmt::OMPScopeDirectiveClass:
429 caseStmt::OMPMaskedDirectiveClass:
432 caseStmt::OMPGenericLoopDirectiveClass:
435 caseStmt::OMPTeamsGenericLoopDirectiveClass:
438 caseStmt::OMPTargetTeamsGenericLoopDirectiveClass:
440cast<OMPTargetTeamsGenericLoopDirective>(*S));
442 caseStmt::OMPParallelGenericLoopDirectiveClass:
444cast<OMPParallelGenericLoopDirective>(*S));
446 caseStmt::OMPTargetParallelGenericLoopDirectiveClass:
448cast<OMPTargetParallelGenericLoopDirective>(*S));
450 caseStmt::OMPParallelMaskedDirectiveClass:
453 caseStmt::OMPAssumeDirectiveClass:
456 caseStmt::OpenACCComputeConstructClass:
459 caseStmt::OpenACCLoopConstructClass:
462 caseStmt::OpenACCCombinedConstructClass:
465 caseStmt::OpenACCDataConstructClass:
468 caseStmt::OpenACCEnterDataConstructClass:
471 caseStmt::OpenACCExitDataConstructClass:
474 caseStmt::OpenACCHostDataConstructClass:
477 caseStmt::OpenACCWaitConstructClass:
480 caseStmt::OpenACCInitConstructClass:
483 caseStmt::OpenACCShutdownConstructClass:
486 caseStmt::OpenACCSetConstructClass:
489 caseStmt::OpenACCUpdateConstructClass:
497 switch(S->getStmtClass()) {
500 caseStmt::NullStmtClass:
502 caseStmt::CompoundStmtClass:
505 caseStmt::DeclStmtClass:
508 caseStmt::LabelStmtClass:
511 caseStmt::AttributedStmtClass:
514 caseStmt::GotoStmtClass:
517 caseStmt::BreakStmtClass:
520 caseStmt::ContinueStmtClass:
523 caseStmt::DefaultStmtClass:
526 caseStmt::CaseStmtClass:
529 caseStmt::SEHLeaveStmtClass:
532 caseStmt::SYCLKernelCallStmtClass:
559 "LLVM IR generation of compound statement ('{}')");
562LexicalScope
Scope(*
this, S.getSourceRange());
573assert((!GetLast || (GetLast &&
ExprResult)) &&
574 "If GetLast is true then the CompoundStmt must have a StmtExprResult");
578 for(
auto*CurStmt : S.body()) {
586 if(
const auto*LS = dyn_cast<LabelStmt>(
ExprResult)) {
589}
else if(
const auto*AS = dyn_cast<AttributedStmt>(
ExprResult)) {
594llvm_unreachable(
"unknown value statement");
621llvm::BranchInst *BI = dyn_cast<llvm::BranchInst>(BB->getTerminator());
630 if(!BI || !BI->isUnconditional())
634 if(BI->getIterator() != BB->begin())
637BB->replaceAllUsesWith(BI->getSuccessor(0));
638BI->eraseFromParent();
639BB->eraseFromParent();
643llvm::BasicBlock *CurBB =
Builder.GetInsertBlock();
648 if(IsFinished && BB->use_empty()) {
655 if(CurBB && CurBB->getParent())
656 CurFn->insert(std::next(CurBB->getIterator()), BB);
666llvm::BasicBlock *CurBB =
Builder.GetInsertBlock();
668 if(!CurBB || CurBB->getTerminator()) {
676 Builder.ClearInsertionPoint();
680 boolinserted =
false;
681 for(llvm::User *u : block->users()) {
682 if(llvm::Instruction *insn = dyn_cast<llvm::Instruction>(u)) {
683 CurFn->insert(std::next(insn->getParent()->getIterator()), block);
692 Builder.SetInsertPoint(block);
695CodeGenFunction::JumpDest
697JumpDest &Dest = LabelMap[
D];
698 if(Dest.isValid())
returnDest;
714JumpDest &Dest = LabelMap[
D];
718 if(!Dest.isValid()) {
724assert(!Dest.getScopeDepth().isValid() &&
"already emitted label!");
745assert(!Labels.empty());
751i = Labels.begin(), e = Labels.end(); i != e; ++i) {
752assert(
CGF.LabelMap.count(*i));
761ParentScope->Labels.append(Labels.begin(), Labels.end());
777 boolnomerge =
false;
778 boolnoinline =
false;
779 boolalwaysinline =
false;
780 boolnoconvergent =
false;
781HLSLControlFlowHintAttr::Spelling flattenOrBranch =
782HLSLControlFlowHintAttr::SpellingNotCalculated;
783 const CallExpr*musttail =
nullptr;
785 for(
const auto*A : S.getAttrs()) {
786 switch(A->getKind()) {
795 caseattr::AlwaysInline:
796alwaysinline =
true;
798 caseattr::NoConvergent:
799noconvergent =
true;
801 caseattr::MustTail: {
802 const Stmt*Sub = S.getSubStmt();
806 caseattr::CXXAssume: {
807 const Expr*Assumption = cast<CXXAssumeAttr>(A)->getAssumption();
811 Builder.CreateAssumption(AssumptionVal);
814 caseattr::HLSLControlFlowHint: {
815flattenOrBranch = cast<HLSLControlFlowHintAttr>(A)->getSemanticSpelling();
825 EmitStmt(S.getSubStmt(), S.getAttrs());
848llvm::BasicBlock *CurBB =
Builder.GetInsertBlock();
855cast<llvm::PHINode>(IndGotoBB->begin())->addIncoming(
V, CurBB);
861 const Stmt*Else = S.getElse();
865 if(S.isConsteval()) {
866 const Stmt*Executed = S.isNegatedConsteval() ? S.getThen() : Else;
868RunCleanupsScope ExecutedScope(*
this);
876LexicalScope ConditionScope(*
this, S.getCond()->getSourceRange());
882 if(S.getConditionVariable())
883 EmitDecl(*S.getConditionVariable());
891 const Stmt*Executed = S.getThen();
892 const Stmt*Skipped = Else;
894std::swap(Executed, Skipped);
902RunCleanupsScope ExecutedScope(*
this);
914llvm::BasicBlock *ElseBlock = ContBlock;
945 Builder.CreateCondBr(BoolCondVal, ThenBlock, ElseBlock);
955RunCleanupsScope ThenScope(*
this);
971RunCleanupsScope ElseScope(*
this);
1002 boolCondIsConstInt =
1003!ControllingExpression ||
1007 boolCondIsTrue = CondIsConstInt && (!ControllingExpression ||
1008 Result.Val.getInt().getBoolValue());
1022 if(HasEmptyBody && CondIsTrue) {
1023 CurFn->removeFnAttr(llvm::Attribute::MustProgress);
1041 if constexpr(std::is_same_v<LoopStmt, ForStmt>) {
1045 const Stmt*Body = S.getBody();
1046 if(!Body || isa<NullStmt>(Body))
1048 if(
const CompoundStmt*Compound = dyn_cast<CompoundStmt>(Body))
1049 returnCompound->body_empty();
1062emitConvergenceLoopToken(LoopHeader.getBlock()));
1069BreakContinueStack.push_back(BreakContinue(
LoopExit, LoopHeader));
1078RunCleanupsScope ConditionScope(*
this);
1080 if(S.getConditionVariable())
1081 EmitDecl(*S.getConditionVariable());
1090llvm::ConstantInt *
C= dyn_cast<llvm::ConstantInt>(BoolCondVal);
1091 boolEmitBoolCondBranch = !
C|| !
C->isOne();
1104 if(EmitBoolCondBranch) {
1105llvm::BasicBlock *ExitBlock =
LoopExit.getBlock();
1106 if(ConditionScope.requiresCleanups())
1108llvm::MDNode *Weights =
1109createProfileWeightsForLoop(S.getCond(),
getProfileCount(S.getBody()));
1111BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(
1113 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock, Weights);
1115 if(ExitBlock !=
LoopExit.getBlock()) {
1121diag::warn_attribute_has_no_effect_on_infinite_loop)
1122<< A << A->getRange();
1125diag::note_attribute_has_no_effect_on_infinite_loop_here)
1126<<
SourceRange(S.getWhileLoc(), S.getRParenLoc());
1132RunCleanupsScope BodyScope(*
this);
1142BreakContinueStack.pop_back();
1145ConditionScope.ForceCleanup();
1158 if(!EmitBoolCondBranch)
1178BreakContinueStack.push_back(BreakContinue(
LoopExit, LoopCond));
1192RunCleanupsScope BodyScope(*
this);
1209BreakContinueStack.pop_back();
1213llvm::ConstantInt *
C= dyn_cast<llvm::ConstantInt>(BoolCondVal);
1214 boolEmitBoolCondBranch = !
C|| !
C->isZero();
1223 if(EmitBoolCondBranch) {
1226BoolCondVal, LoopBody,
LoopExit.getBlock(),
1227createProfileWeightsForLoop(S.getCond(), BackedgeCount));
1237 if(!EmitBoolCondBranch)
1253LexicalScope ForScope(*
this, S.getSourceRange());
1263llvm::BasicBlock *CondBlock = CondDest.getBlock();
1276LexicalScope ConditionScope(*
this, S.getSourceRange());
1287Continue = CondDest;
1288 else if(!S.getConditionVariable())
1290BreakContinueStack.push_back(BreakContinue(
LoopExit, Continue));
1295 if(S.getConditionVariable()) {
1296 EmitDecl(*S.getConditionVariable());
1301BreakContinueStack.back().ContinueBlock = Continue;
1309llvm::BasicBlock *ExitBlock =
LoopExit.getBlock();
1312 if(ForScope.requiresCleanups())
1321llvm::MDNode *Weights =
1322createProfileWeightsForLoop(S.getCond(),
getProfileCount(S.getBody()));
1324BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(
1327 Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights);
1329 if(ExitBlock !=
LoopExit.getBlock()) {
1348RunCleanupsScope BodyScope(*
this);
1360BreakContinueStack.pop_back();
1362ConditionScope.ForceCleanup();
1367ForScope.ForceCleanup();
1388LexicalScope ForScope(*
this, S.getSourceRange());
1413llvm::BasicBlock *ExitBlock =
LoopExit.getBlock();
1414 if(ForScope.requiresCleanups())
1423llvm::MDNode *Weights =
1424createProfileWeightsForLoop(S.getCond(),
getProfileCount(S.getBody()));
1426BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(
1428 Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights);
1430 if(ExitBlock !=
LoopExit.getBlock()) {
1445BreakContinueStack.push_back(BreakContinue(
LoopExit, Continue));
1449LexicalScope BodyScope(*
this, S.getSourceRange());
1459BreakContinueStack.pop_back();
1463ForScope.ForceCleanup();
1479voidCodeGenFunction::EmitReturnOfRValue(
RValueRV,
QualTypeTy) {
1495structSaveRetExprRAII {
1497: OldRetExpr(CGF.RetExpr), CGF(CGF) {
1500~SaveRetExprRAII() { CGF.RetExpr = OldRetExpr; }
1501 const Expr*OldRetExpr;
1510 if(calleeQualType->isFunctionPointerType() ||
1511calleeQualType->isFunctionReferenceType() ||
1512calleeQualType->isBlockPointerType() ||
1513calleeQualType->isMemberFunctionPointerType()) {
1515}
else if(
auto*ty = dyn_cast<FunctionType>(calleeQualType)) {
1517}
else if(
autoCMCE = dyn_cast<CXXMemberCallExpr>(CE)) {
1518 if(
automethodDecl = CMCE->getMethodDecl()) {
1534 if(requiresReturnValueCheck()) {
1537 newllvm::GlobalVariable(
CGM.
getModule(), SLoc->getType(),
false,
1538llvm::GlobalVariable::PrivateLinkage, SLoc);
1539SLocPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1541assert(ReturnLocation.
isValid() &&
"No valid return location");
1548 Builder.ClearInsertionPoint();
1552 const Expr*RV = S.getRetValue();
1562SaveRetExprRAII SaveRetExpr(RV, *
this);
1564RunCleanupsScope cleanupScope(*
this);
1565 if(
const auto*EWC = dyn_cast_or_null<ExprWithCleanups>(RV))
1566RV = EWC->getSubExpr();
1570std::optional<llvm::SaveAndRestore<const CallExpr *>> SaveMustTail;
1573 if(
autoCE = dyn_cast<CallExpr>(RV)) {
1583 if(
getLangOpts().ElideConstructors && S.getNRVOCandidate() &&
1584S.getNRVOCandidate()->isNRVOVariable() &&
1595 if(llvm::Value *NRVOFlag =
NRVOFlags[S.getNRVOCandidate()])
1638++NumSimpleReturnExprs;
1640cleanupScope.ForceCleanup();
1650 for(
const auto*I : S.decls())
1655assert(!BreakContinueStack.empty() &&
"break stmt not in a loop or switch!");
1667assert(!BreakContinueStack.empty() &&
"continue stmt not in a loop!");
1683assert(S.getRHS() &&
"Expected RHS value in CaseStmt");
1685llvm::APSInt LHS = S.getLHS()->EvaluateKnownConstInt(
getContext());
1686llvm::APSInt RHS = S.getRHS()->EvaluateKnownConstInt(
getContext());
1696 if(LHS.isSigned() ? RHS.slt(LHS) : RHS.ult(LHS))
1700llvm::APInt
Range= RHS - LHS;
1702 if(
Range.ult(llvm::APInt(
Range.getBitWidth(), 64))) {
1705 unsignedNCases =
Range.getZExtValue() + 1;
1710 uint64_tWeight = Total / NCases,
Rem= Total % NCases;
1711 for(
unsignedI = 0; I != NCases; ++I) {
1713SwitchWeights->push_back(Weight + (Rem ? 1 : 0));
1714 else if(SwitchLikelihood)
1715SwitchLikelihood->push_back(LH);
1719SwitchInsn->addCase(
Builder.getInt(LHS), CaseDest);
1727llvm::BasicBlock *RestoreBB =
Builder.GetInsertBlock();
1732llvm::BasicBlock *FalseDest = CaseRangeBlock;
1735 CurFn->insert(
CurFn->end(), CaseRangeBlock);
1736 Builder.SetInsertPoint(CaseRangeBlock);
1740 Builder.CreateSub(SwitchInsn->getCondition(),
Builder.getInt(LHS));
1744llvm::MDNode *Weights =
nullptr;
1745 if(SwitchWeights) {
1747 uint64_tDefaultCount = (*SwitchWeights)[0];
1748Weights = createProfileWeights(ThisCount, DefaultCount);
1753(*SwitchWeights)[0] += ThisCount;
1754}
else if(SwitchLikelihood)
1755Cond = emitCondLikelihoodViaExpectIntrinsic(Cond, LH);
1757 Builder.CreateCondBr(Cond, CaseDest, FalseDest, Weights);
1761 Builder.SetInsertPoint(RestoreBB);
1763 Builder.ClearInsertionPoint();
1784llvm::ConstantInt *CaseVal =
1789 if(
autoICE = dyn_cast<ImplicitCastExpr>(S.getLHS()))
1790CE = dyn_cast<ConstantExpr>(ICE->getSubExpr());
1792CE = dyn_cast<ConstantExpr>(S.getLHS());
1794 if(
autoDE = dyn_cast<DeclRefExpr>(CE->
getSubExpr()))
1797Dbg->EmitGlobalVariable(DE->getDecl(),
1798 APValue(llvm::APSInt(CaseVal->getValue())));
1801 if(SwitchLikelihood)
1809isa<BreakStmt>(S.getSubStmt())) {
1810JumpDest
Block= BreakContinueStack.back().BreakBlock;
1816SwitchInsn->addCase(CaseVal,
Block.getBlock());
1820 if(
Builder.GetInsertBlock()) {
1822 Builder.ClearInsertionPoint();
1832SwitchInsn->addCase(CaseVal, CaseDest);
1848 const CaseStmt*NextCase = dyn_cast<CaseStmt>(S.getSubStmt());
1851 while(NextCase && NextCase->
getRHS() ==
nullptr) {
1853llvm::ConstantInt *CaseVal =
1864 if(SwitchLikelihood)
1867SwitchInsn->addCase(CaseVal, CaseDest);
1868NextCase = dyn_cast<CaseStmt>(CurCase->
getSubStmt());
1891llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest();
1892assert(DefaultBlock->empty() &&
1893 "EmitDefaultStmt: Default block already defined?");
1895 if(SwitchLikelihood)
1937 if(
const SwitchCase*SC = dyn_cast<SwitchCase>(S)) {
1951 if(!Case && isa<BreakStmt>(S))
1956 if(
const CompoundStmt*CS = dyn_cast<CompoundStmt>(S)) {
1960 boolStartedInLiveCode = FoundCase;
1961 unsignedStartSize = ResultStmts.size();
1968 boolHadSkippedDecl =
false;
1972 for(; Case && I !=
E; ++I) {
1988 for(++I; I !=
E; ++I)
1998assert(FoundCase &&
"Didn't find case but returned fallthrough?");
2013assert(!HadSkippedDecl &&
"fallthrough after skipping decl");
2018 boolAnyDecls =
false;
2019 for(; I !=
E; ++I) {
2032 for(++I; I !=
E; ++I)
2049ResultStmts.resize(StartSize);
2050ResultStmts.push_back(S);
2074ResultStmts.push_back(S);
2083 constllvm::APSInt &ConstantCondValue,
2089 const SwitchCase*Case = S.getSwitchCaseList();
2095 if(
const DefaultStmt*DS = dyn_cast<DefaultStmt>(Case)) {
2101 const CaseStmt*CS = cast<CaseStmt>(Case);
2103 if(CS->
getRHS())
return false;
2128 boolFoundCase =
false;
2135staticstd::optional<SmallVector<uint64_t, 16>>
2138 if(Likelihoods.size() <= 1)
2139 returnstd::nullopt;
2141uint64_t NumUnlikely = 0;
2142uint64_t NumNone = 0;
2143uint64_t NumLikely = 0;
2144 for(
const autoLH : Likelihoods) {
2159 if(NumUnlikely == 0 && NumLikely == 0)
2160 returnstd::nullopt;
2168 constuint64_t Likely = INT32_MAX / (NumLikely + 2);
2169 constuint64_t
None= Likely / (NumNone + 1);
2170 constuint64_t Unlikely = 0;
2173 Result.reserve(Likelihoods.size());
2174 for(
const autoLH : Likelihoods) {
2177 Result.push_back(Unlikely);
2183 Result.push_back(Likely);
2193llvm::SwitchInst *SavedSwitchInsn = SwitchInsn;
2196llvm::BasicBlock *SavedCRBlock = CaseRangeBlock;
2200llvm::APSInt ConstantCondValue;
2208RunCleanupsScope ExecutedScope(*
this);
2215 if(S.getConditionVariable())
2216 EmitDecl(*S.getConditionVariable());
2221SwitchInsn =
nullptr;
2225 for(
unsignedi = 0, e = CaseStmts.size(); i != e; ++i)
2232SwitchInsn = SavedSwitchInsn;
2240RunCleanupsScope ConditionScope(*
this);
2245 if(S.getConditionVariable())
2246 EmitDecl(*S.getConditionVariable());
2254SwitchInsn =
Builder.CreateSwitch(CondV, DefaultBlock);
2258 unsignedNumCases = 0;
2259 for(
const SwitchCase*Case = S.getSwitchCaseList();
2262 if(isa<DefaultStmt>(Case))
2267SwitchWeights->reserve(NumCases);
2270SwitchWeights->push_back(DefaultCount);
2277CaseRangeBlock = DefaultBlock;
2280 Builder.ClearInsertionPoint();
2284JumpDest OuterContinue;
2285 if(!BreakContinueStack.empty())
2286OuterContinue = BreakContinueStack.back().ContinueBlock;
2288BreakContinueStack.push_back(BreakContinue(SwitchExit, OuterContinue));
2293BreakContinueStack.pop_back();
2297SwitchInsn->setDefaultDest(CaseRangeBlock);
2300 if(!DefaultBlock->getParent()) {
2303 if(ConditionScope.requiresCleanups()) {
2308DefaultBlock->replaceAllUsesWith(SwitchExit.getBlock());
2309 deleteDefaultBlock;
2313ConditionScope.ForceCleanup();
2316 EmitBlock(SwitchExit.getBlock(),
true);
2322 auto*
Call= dyn_cast<CallExpr>(S.getCond());
2324 auto*FD = dyn_cast_or_null<FunctionDecl>(
Call->getCalleeDecl());
2325 if(FD && FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) {
2327SwitchInsn->setMetadata(llvm::LLVMContext::MD_unpredictable,
2328MDHelper.createUnpredictable());
2332 if(SwitchWeights) {
2333assert(SwitchWeights->size() == 1 + SwitchInsn->getNumCases() &&
2334 "switch weights do not match switch cases");
2336 if(SwitchWeights->size() > 1)
2337SwitchInsn->setMetadata(llvm::LLVMContext::MD_prof,
2338createProfileWeights(*SwitchWeights));
2339 deleteSwitchWeights;
2340}
else if(SwitchLikelihood) {
2341assert(SwitchLikelihood->size() == 1 + SwitchInsn->getNumCases() &&
2342 "switch likelihoods do not match switch cases");
2343std::optional<SmallVector<uint64_t, 16>> LHW =
2347SwitchInsn->setMetadata(llvm::LLVMContext::MD_prof,
2348createProfileWeights(*LHW));
2350 deleteSwitchLikelihood;
2352SwitchInsn = SavedSwitchInsn;
2353SwitchWeights = SavedSwitchWeights;
2354SwitchLikelihood = SavedSwitchLikelihood;
2355CaseRangeBlock = SavedCRBlock;
2363 while(*Constraint) {
2364 switch(*Constraint) {
2376 while(Constraint[1] && Constraint[1] !=
',')
2382 while(Constraint[1] && Constraint[1] == *Constraint)
2393 "Must pass output names to constraints with a symbolic name");
2395 boolresult =
Target.resolveSymbolicName(Constraint, *OutCons, Index);
2396assert(result &&
"Could not resolve symbolic name"); (void)result;
2397 Result+= llvm::utostr(Index);
2415std::string *GCCReg =
nullptr) {
2416 const DeclRefExpr*AsmDeclRef = dyn_cast<DeclRefExpr>(&AsmExpr);
2428StringRef Register =
Attr->getLabel();
2429assert(
Target.isValidGCCRegisterName(Register));
2433 if(
Target.validateOutputConstraint(Info) &&
2439Register =
Target.getNormalizedGCCRegisterName(Register);
2440 if(GCCReg !=
nullptr)
2441*GCCReg = Register.str();
2442 return(EarlyClobber ?
"&{":
"{") + Register.str() +
"}";
2445std::pair<llvm::Value*, llvm::Type *> CodeGenFunction::EmitAsmInputLValue(
2454 if((Size <= 64 && llvm::isPowerOf2_64(Size)) ||
2464ConstraintStr +=
'*';
2468std::pair<llvm::Value *, llvm::Type *>
2470 const Expr*InputExpr,
2471std::string &ConstraintStr) {
2479llvm::APSInt IntResult;
2482 return{llvm::ConstantInt::get(
getLLVMContext(), IntResult),
nullptr};
2494 if(InputExpr->
getStmtClass() == Expr::CXXThisExprClass)
2498 returnEmitAsmInputLValue(Info, Dest, InputExpr->
getType(), ConstraintStr,
2510Locs.push_back(llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2513 if(!StrVal.empty()) {
2516 unsignedStartToken = 0;
2517 unsignedByteOffset = 0;
2521 for(
unsignedi = 0, e = StrVal.size() - 1; i != e; ++i) {
2522 if(StrVal[i] !=
'\n')
continue;
2524i + 1,
SM, LangOpts, CGF.
getTarget(), &StartToken, &ByteOffset);
2525Locs.push_back(llvm::ConstantAsMetadata::get(
2534 boolHasUnwindClobber,
boolReadOnly,
2535 boolReadNone,
boolNoMerge,
boolNoConvergent,
2537 conststd::vector<llvm::Type *> &ResultRegTypes,
2538 conststd::vector<llvm::Type *> &ArgElemTypes,
2540std::vector<llvm::Value *> &RegResults) {
2541 if(!HasUnwindClobber)
2542 Result.addFnAttr(llvm::Attribute::NoUnwind);
2545 Result.addFnAttr(llvm::Attribute::NoMerge);
2547 if(!HasSideEffect) {
2549 Result.setDoesNotAccessMemory();
2551 Result.setOnlyReadsMemory();
2555 for(
autoPair : llvm::enumerate(ArgElemTypes)) {
2557 auto Attr= llvm::Attribute::get(
2558CGF.
getLLVMContext(), llvm::Attribute::ElementType, Pair.value());
2565 if(
const auto*gccAsmStmt = dyn_cast<GCCAsmStmt>(&S))
2566 Result.setMetadata(
"srcloc",
2570llvm::Constant *
Loc=
2571llvm::ConstantInt::get(CGF.
Int64Ty, S.getAsmLoc().getRawEncoding());
2572 Result.setMetadata(
"srcloc",
2574llvm::ConstantAsMetadata::get(
Loc)));
2582 Result.addFnAttr(llvm::Attribute::Convergent);
2584 if(ResultRegTypes.size() == 1) {
2585RegResults.push_back(&
Result);
2587 for(
unsignedi = 0, e = ResultRegTypes.size(); i != e; ++i) {
2588llvm::Value *Tmp = CGF.
Builder.CreateExtractValue(&
Result, i,
"asmresult");
2589RegResults.push_back(Tmp);
2601 constllvm::BitVector &ResultTypeRequiresCast,
2602 constllvm::BitVector &ResultRegIsFlagReg) {
2607assert(RegResults.size() == ResultRegTypes.size());
2608assert(RegResults.size() == ResultTruncRegTypes.size());
2609assert(RegResults.size() == ResultRegDests.size());
2612assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
2613assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
2615 for(
unsignedi = 0, e = RegResults.size(); i != e; ++i) {
2616llvm::Value *Tmp = RegResults[i];
2617llvm::Type *TruncTy = ResultTruncRegTypes[i];
2619 if((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
2622llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
2623llvm::Value *IsBooleanValue =
2624 Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
2625llvm::Function *FnAssume =
CGM.
getIntrinsic(llvm::Intrinsic::assume);
2626 Builder.CreateCall(FnAssume, IsBooleanValue);
2631 if(ResultRegTypes[i] != TruncTy) {
2635 if(TruncTy->isFloatingPointTy())
2636Tmp =
Builder.CreateFPTrunc(Tmp, TruncTy);
2637 else if(TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
2640Tmp, llvm::IntegerType::get(CTX, (
unsigned)ResSize));
2641Tmp =
Builder.CreateIntToPtr(Tmp, TruncTy);
2642}
else if(Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
2645Tmp =
Builder.CreatePtrToInt(
2646Tmp, llvm::IntegerType::get(CTX, (
unsigned)TmpSize));
2647Tmp =
Builder.CreateTrunc(Tmp, TruncTy);
2648}
else if(Tmp->getType()->isIntegerTy() && TruncTy->isIntegerTy()) {
2649Tmp =
Builder.CreateZExtOrTrunc(Tmp, TruncTy);
2650}
else if(Tmp->getType()->isVectorTy() || TruncTy->isVectorTy()) {
2651Tmp =
Builder.CreateBitCast(Tmp, TruncTy);
2655 LValueDest = ResultRegDests[i];
2658 if((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) {
2669 const Expr*OutExpr = S.getOutputExpr(i);
2671diag::err_store_value_to_reg);
2682 constexpr autoName =
"__ASM__hipstdpar_unsupported";
2685 if(
autoGCCAsm = dyn_cast<GCCAsmStmt>(&S))
2686 Asm= GCCAsm->getAsmString()->getString();
2690 autoStrTy = llvm::ConstantDataArray::getString(Ctx,
Asm);
2691 autoFnTy = llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx),
2692{StrTy->getType()},
false);
2693 autoUBF = CGF->
CGM.
getModule().getOrInsertFunction(Name, FnTy);
2695CGF->
Builder.CreateCall(UBF, {StrTy});
2700CodeGenFunction::RunCleanupsScope Cleanups(*
this);
2703std::string AsmString = S.generateAsmString(
getContext());
2710 boolIsValidTargetAsm =
true;
2711 for(
unsignedi = 0, e = S.getNumOutputs(); i != e && IsValidTargetAsm; i++) {
2713 if(
const GCCAsmStmt*GAS = dyn_cast<GCCAsmStmt>(&S))
2714Name = GAS->getOutputName(i);
2717 if(IsHipStdPar && !IsValid)
2718IsValidTargetAsm =
false;
2720assert(IsValid &&
"Failed to parse output constraint");
2721OutputConstraintInfos.push_back(Info);
2724 for(
unsignedi = 0, e = S.getNumInputs(); i != e && IsValidTargetAsm; i++) {
2726 if(
const GCCAsmStmt*GAS = dyn_cast<GCCAsmStmt>(&S))
2727Name = GAS->getInputName(i);
2731 if(IsHipStdPar && !IsValid)
2732IsValidTargetAsm =
false;
2734assert(IsValid &&
"Failed to parse input constraint");
2735InputConstraintInfos.push_back(Info);
2738 if(!IsValidTargetAsm)
2741std::string Constraints;
2743std::vector<LValue> ResultRegDests;
2744std::vector<QualType> ResultRegQualTys;
2745std::vector<llvm::Type *> ResultRegTypes;
2746std::vector<llvm::Type *> ResultTruncRegTypes;
2747std::vector<llvm::Type *> ArgTypes;
2748std::vector<llvm::Type *> ArgElemTypes;
2749std::vector<llvm::Value*> Args;
2750llvm::BitVector ResultTypeRequiresCast;
2751llvm::BitVector ResultRegIsFlagReg;
2754std::string InOutConstraints;
2755std::vector<llvm::Value*> InOutArgs;
2756std::vector<llvm::Type*> InOutArgTypes;
2757std::vector<llvm::Type*> InOutArgElemTypes;
2760std::vector<std::string> OutputConstraints;
2763llvm::SmallSet<std::string, 8> PhysRegOutputs;
2771 boolReadOnly =
true, ReadNone =
true;
2773 for(
unsignedi = 0, e = S.getNumOutputs(); i != e; i++) {
2777std::string OutputConstraint(S.getOutputConstraint(i));
2781 const Expr*OutExpr = S.getOutputExpr(i);
2790 if(!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second)
2791 CGM.
Error(S.getAsmLoc(),
"multiple outputs to hard register: "+ GCCReg);
2793OutputConstraints.push_back(OutputConstraint);
2795 if(!Constraints.empty())
2796Constraints +=
',';
2805Constraints +=
"="+ OutputConstraint;
2806ResultRegQualTys.push_back(QTy);
2807ResultRegDests.push_back(Dest);
2809 boolIsFlagReg = llvm::StringRef(OutputConstraint).starts_with(
"{@cc");
2810ResultRegIsFlagReg.push_back(IsFlagReg);
2815Ty->isAggregateType());
2817ResultTruncRegTypes.push_back(Ty);
2818ResultTypeRequiresCast.push_back(RequiresCast);
2827ResultRegTypes.push_back(Ty);
2833 for(InputNo = 0; InputNo != S.getNumInputs(); ++InputNo) {
2838assert(InputNo != S.getNumInputs() &&
"Didn't find matching input!");
2840 QualTypeInputTy = S.getInputExpr(InputNo)->getType();
2849 if(llvm::Type* AdjTy =
2851ResultRegTypes.back()))
2852ResultRegTypes.back() = AdjTy;
2855diag::err_asm_invalid_type_in_input)
2856<< OutExpr->
getType() << OutputConstraint;
2860 if(
auto*VT = dyn_cast<llvm::VectorType>(ResultRegTypes.back()))
2861LargestVectorWidth =
2862std::max((uint64_t)LargestVectorWidth,
2863VT->getPrimitiveSizeInBits().getKnownMinValue());
2874ArgTypes.push_back(DestAddr.
getType());
2877Constraints +=
"=*";
2878Constraints += OutputConstraint;
2879ReadOnly = ReadNone =
false;
2883InOutConstraints +=
',';
2885 const Expr*InputExpr = S.getOutputExpr(i);
2887llvm::Type *ArgElemType;
2888std::tie(Arg, ArgElemType) = EmitAsmInputLValue(
2889Info, Dest, InputExpr->
getType(), InOutConstraints,
2892 if(llvm::Type* AdjTy =
2895Arg =
Builder.CreateBitCast(Arg, AdjTy);
2898 if(
auto*VT = dyn_cast<llvm::VectorType>(Arg->getType()))
2899LargestVectorWidth =
2900std::max((uint64_t)LargestVectorWidth,
2901VT->getPrimitiveSizeInBits().getKnownMinValue());
2904InOutConstraints += llvm::utostr(i);
2906InOutConstraints += OutputConstraint;
2908InOutArgTypes.push_back(Arg->getType());
2909InOutArgElemTypes.push_back(ArgElemType);
2910InOutArgs.push_back(Arg);
2916 if(isa<MSAsmStmt>(&S)) {
2922*
this, ReturnSlot, Constraints, ResultRegTypes, ResultTruncRegTypes,
2923ResultRegDests, AsmString, S.getNumOutputs());
2928 for(
unsignedi = 0, e = S.getNumInputs(); i != e; i++) {
2929 const Expr*InputExpr = S.getInputExpr(i);
2936 if(!Constraints.empty())
2937Constraints +=
',';
2940std::string InputConstraint(S.getInputConstraint(i));
2942&OutputConstraintInfos);
2948std::string ReplaceConstraint (InputConstraint);
2950llvm::Type *ArgElemType;
2951std::tie(Arg, ArgElemType) = EmitAsmInput(Info, InputExpr, Constraints);
2960 QualTypeOutputType = S.getOutputExpr(Output)->getType();
2966 if(isa<llvm::PointerType>(Arg->getType()))
2969 if(isa<llvm::IntegerType>(OutputTy))
2970Arg =
Builder.CreateZExt(Arg, OutputTy);
2971 else if(isa<llvm::PointerType>(OutputTy))
2973 else if(OutputTy->isFloatingPointTy())
2974Arg =
Builder.CreateFPExt(Arg, OutputTy);
2977ReplaceConstraint = OutputConstraints[Output];
2979 if(llvm::Type* AdjTy =
2980 getTargetHooks().adjustInlineAsmType(*
this, ReplaceConstraint,
2982Arg =
Builder.CreateBitCast(Arg, AdjTy);
2985<< InputExpr->
getType() << InputConstraint;
2988 if(
auto*VT = dyn_cast<llvm::VectorType>(Arg->getType()))
2989LargestVectorWidth =
2990std::max((uint64_t)LargestVectorWidth,
2991VT->getPrimitiveSizeInBits().getKnownMinValue());
2993ArgTypes.push_back(Arg->getType());
2994ArgElemTypes.push_back(ArgElemType);
2995Args.push_back(Arg);
2996Constraints += InputConstraint;
3000 for(
unsignedi = 0, e = InOutArgs.size(); i != e; i++) {
3001ArgTypes.push_back(InOutArgTypes[i]);
3002ArgElemTypes.push_back(InOutArgElemTypes[i]);
3003Args.push_back(InOutArgs[i]);
3005Constraints += InOutConstraints;
3009llvm::BasicBlock *Fallthrough =
nullptr;
3010 boolIsGCCAsmGoto =
false;
3011 if(
const auto*GS = dyn_cast<GCCAsmStmt>(&S)) {
3012IsGCCAsmGoto = GS->isAsmGoto();
3014 for(
const auto*
E: GS->labels()) {
3016Transfer.push_back(Dest.getBlock());
3017 if(!Constraints.empty())
3018Constraints +=
',';
3019Constraints +=
"!i";
3025 boolHasUnwindClobber =
false;
3028 for(
unsignedi = 0, e = S.getNumClobbers(); i != e; i++) {
3029StringRef Clobber = S.getClobber(i);
3031 if(Clobber ==
"memory")
3032ReadOnly = ReadNone =
false;
3033 else if(Clobber ==
"unwind") {
3034HasUnwindClobber =
true;
3036}
else if(Clobber !=
"cc") {
3041diag::warn_stack_clash_protection_inline_asm);
3045 if(isa<MSAsmStmt>(&S)) {
3046 if(Clobber ==
"eax"|| Clobber ==
"edx") {
3047 if(Constraints.find(
"=&A") != std::string::npos)
3049std::string::size_type position1 =
3050Constraints.find(
"={"+ Clobber.str() +
"}");
3051 if(position1 != std::string::npos) {
3052Constraints.insert(position1 + 1,
"&");
3055std::string::size_type position2 = Constraints.find(
"=A");
3056 if(position2 != std::string::npos) {
3057Constraints.insert(position2 + 1,
"&");
3062 if(!Constraints.empty())
3063Constraints +=
',';
3065Constraints +=
"~{";
3066Constraints += Clobber;
3067Constraints +=
'}';
3070assert(!(HasUnwindClobber && IsGCCAsmGoto) &&
3071 "unwind clobber can't be used with asm goto");
3075 if(!MachineClobbers.empty()) {
3076 if(!Constraints.empty())
3077Constraints +=
',';
3078Constraints += MachineClobbers;
3081llvm::Type *ResultType;
3082 if(ResultRegTypes.empty())
3084 else if(ResultRegTypes.size() == 1)
3085ResultType = ResultRegTypes[0];
3087ResultType = llvm::StructType::get(
getLLVMContext(), ResultRegTypes);
3089llvm::FunctionType *FTy =
3090llvm::FunctionType::get(ResultType, ArgTypes,
false);
3092 boolHasSideEffect = S.isVolatile() || S.getNumOutputs() == 0;
3094llvm::InlineAsm::AsmDialect GnuAsmDialect =
3096? llvm::InlineAsm::AD_ATT
3097: llvm::InlineAsm::AD_Intel;
3098llvm::InlineAsm::AsmDialect AsmDialect = isa<MSAsmStmt>(&S) ?
3099llvm::InlineAsm::AD_Intel : GnuAsmDialect;
3101llvm::InlineAsm *IA = llvm::InlineAsm::get(
3102FTy, AsmString, Constraints, HasSideEffect,
3103 false, AsmDialect, HasUnwindClobber);
3104std::vector<llvm::Value*> RegResults;
3105llvm::CallBrInst *CBR;
3106llvm::DenseMap<llvm::BasicBlock *, SmallVector<llvm::Value *, 4>>
3109CBR =
Builder.CreateCallBr(IA, Fallthrough, Transfer, Args);
3114ArgElemTypes, *
this, RegResults);
3118 if(!RegResults.empty()) {
3120 for(llvm::BasicBlock *Dest : CBR->getIndirectDests()) {
3121llvm::Twine SynthName = Dest->getName() +
".split";
3123llvm::IRBuilderBase::InsertPointGuard IPG(
Builder);
3124 Builder.SetInsertPoint(SynthBB);
3126 if(ResultRegTypes.size() == 1) {
3127CBRRegResults[SynthBB].push_back(CBR);
3129 for(
unsignedj = 0, e = ResultRegTypes.size(); j != e; ++j) {
3130llvm::Value *Tmp =
Builder.CreateExtractValue(CBR, j,
"asmresult");
3131CBRRegResults[SynthBB].push_back(Tmp);
3137CBR->setIndirectDest(i++, SynthBB);
3140}
else if(HasUnwindClobber) {
3145ArgElemTypes, *
this, RegResults);
3147llvm::CallInst *
Result=
3152ArgElemTypes, *
this, RegResults);
3155 EmitAsmStores(*
this, S, RegResults, ResultRegTypes, ResultTruncRegTypes,
3156ResultRegDests, ResultRegQualTys, ResultTypeRequiresCast,
3157ResultRegIsFlagReg);
3162 if(IsGCCAsmGoto && !CBRRegResults.empty()) {
3163 for(llvm::BasicBlock *Succ : CBR->getIndirectDests()) {
3164llvm::IRBuilderBase::InsertPointGuard IPG(
Builder);
3165 Builder.SetInsertPoint(Succ, --(Succ->end()));
3166 EmitAsmStores(*
this, S, CBRRegResults[Succ], ResultRegTypes,
3167ResultTruncRegTypes, ResultRegDests, ResultRegQualTys,
3168ResultTypeRequiresCast, ResultRegIsFlagReg);
3174 const RecordDecl*RD = S.getCapturedRecordDecl();
3183 E= S.capture_init_end();
3184I !=
E; ++I, ++CurField) {
3186 if(CurField->hasCapturedVLAType()) {
3204CGCapturedStmtRAII CapInfoRAII(CGF,
newCGCapturedStmtInfo(S, K));
3205llvm::Function *F = CGF.GenerateCapturedStmtFunction(S);
3206 deleteCGF.CapturedStmtInfo;
3223 "CapturedStmtInfo should be set when generating the captured function");
3225 const RecordDecl*RD = S.getCapturedRecordDecl();
3227assert(CD->
hasBody() &&
"missing CapturedDecl body");
3240llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
3244F->addFnAttr(llvm::Attribute::NoUnwind);
3256 for(
auto*FD : RD->
fields()) {
3257 if(FD->hasCapturedVLAType()) {
3261 autoVAT = FD->getCapturedVLAType();
3262VLASizeMap[VAT->getSizeExpr()] = ExprArg;
3283 for(
auto&I : *BB) {
3284 if(
auto*CI = dyn_cast<llvm::ConvergenceControlInst>(&I))
3291CodeGenFunction::addConvergenceControlToken(llvm::CallBase *Input) {
3293assert(ParentToken);
3295llvm::Value *bundleArgs[] = {ParentToken};
3296llvm::OperandBundleDef OB(
"convergencectrl", bundleArgs);
3297 auto*Output = llvm::CallBase::addOperandBundle(
3298Input, llvm::LLVMContext::OB_convergencectrl, OB, Input->getIterator());
3299Input->replaceAllUsesWith(Output);
3300Input->eraseFromParent();
3304llvm::ConvergenceControlInst *
3305CodeGenFunction::emitConvergenceLoopToken(llvm::BasicBlock *BB) {
3306CGBuilderTy::InsertPoint IP =
Builder.saveIP();
3310 Builder.SetInsertPoint(BB->getFirstInsertionPt());
3312llvm::CallBase *CB =
Builder.CreateIntrinsic(
3313llvm::Intrinsic::experimental_convergence_loop, {}, {});
3316CB = addConvergenceControlToken(CB);
3317 returncast<llvm::ConvergenceControlInst>(CB);
3320llvm::ConvergenceControlInst *
3321CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) {
3322llvm::BasicBlock *BB = &F->getEntryBlock();
3331CGBuilderTy::InsertPoint IP =
Builder.saveIP();
3332 Builder.SetInsertPoint(&BB->front());
3333llvm::CallBase *I =
Builder.CreateIntrinsic(
3334llvm::Intrinsic::experimental_convergence_entry, {}, {});
3335assert(isa<llvm::IntrinsicInst>(I));
3338 returncast<llvm::ConvergenceControlInst>(I);
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 llvm::ConvergenceControlInst * getConvergenceToken(llvm::BasicBlock *BB)
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 bool isSwiftAsyncCallee(const CallExpr *CE)
Determine if the given call uses the swiftasync calling convention.
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)
static bool hasEmptyLoopBody(const LoopStmt &S)
CSFC_Result
CollectStatementsForCase - Given the body of a 'switch' statement and a constant value that is being ...
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)
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 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 ...
@ 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 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 * 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 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)
void EmitOMPMaskedTaskLoopSimdDirective(const OMPMaskedTaskLoopSimdDirective &S)
bool checkIfLoopMustProgress(const Expr *, bool HasEmptyBody)
Returns true if a loop must make progress, which means the mustprogress attribute can be added.
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.
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
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 EmitWhileStmt(const WhileStmt &S, ArrayRef< const Attr * > Attrs={})
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...
void EmitOMPReverseDirective(const OMPReverseDirective &S)
static bool hasScalarEvaluationKind(QualType T)
void EmitOpenACCExitDataConstruct(const OpenACCExitDataConstruct &S)
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 EmitOpenACCInitConstruct(const OpenACCInitConstruct &S)
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)
SmallVector< llvm::ConvergenceControlInst *, 4 > ConvergenceTokenStack
Stack to track the controlled convergence tokens.
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 EmitOpenACCShutdownConstruct(const OpenACCShutdownConstruct &S)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
bool InNoConvergentAttributedStmt
True if the current statement has noconvergent attribute.
void EmitOMPInterchangeDirective(const OMPInterchangeDirective &S)
void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S)
void EmitOMPTeamsGenericLoopDirective(const OMPTeamsGenericLoopDirective &S)
void EmitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective &S)
SmallVector< llvm::OperandBundleDef, 1 > getBundlesForFunclet(llvm::Value *Callee)
void EmitOpenACCWaitConstruct(const OpenACCWaitConstruct &S)
llvm::Value * EmitCheckedArgForAssume(const Expr *E)
Emits an argument for a call to a __builtin_assume.
void EmitOMPParallelMaskedTaskLoopDirective(const OMPParallelMaskedTaskLoopDirective &S)
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.
LValue EmitLValueForField(LValue Base, const FieldDecl *Field)
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 EmitOMPFlushDirective(const OMPFlushDirective &S)
void EmitOMPMaskedTaskLoopDirective(const OMPMaskedTaskLoopDirective &S)
void EmitSEHLeaveStmt(const SEHLeaveStmt &S)
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.
void EmitCXXForRangeStmt(const CXXForRangeStmt &S, ArrayRef< const Attr * > Attrs={})
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 EmitForStmt(const ForStmt &S, ArrayRef< const Attr * > Attrs={})
void EmitOMPDistributeDirective(const OMPDistributeDirective &S)
void EmitOpenACCCombinedConstruct(const OpenACCCombinedConstruct &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,...
void EmitOpenACCDataConstruct(const OpenACCDataConstruct &S)
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
LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T)
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)
void EmitOMPScopeDirective(const OMPScopeDirective &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 EmitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &S)
ASTContext & getContext() const
void EmitOpenACCLoopConstruct(const OpenACCLoopConstruct &S)
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 EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
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)
void EmitOMPParallelMaskedTaskLoopSimdDirective(const OMPParallelMaskedTaskLoopSimdDirective &S)
llvm::Type * ConvertType(QualType T)
void EmitOMPSectionsDirective(const OMPSectionsDirective &S)
void EmitOpenACCEnterDataConstruct(const OpenACCEnterDataConstruct &S)
llvm::CallBase * EmitCallOrInvoke(llvm::FunctionCallee Callee, ArrayRef< llvm::Value * > Args, const Twine &Name="")
HLSLControlFlowHintAttr::Spelling HLSLControlFlowAttr
HLSL Branch attribute.
void EmitDoStmt(const DoStmt &S, ArrayRef< const Attr * > Attrs={})
bool InAlwaysInlineAttributedStmt
True if the current statement has always_inline attribute.
void EmitOMPTargetSimdDirective(const OMPTargetSimdDirective &S)
void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S)
void EmitOpenACCComputeConstruct(const OpenACCComputeConstruct &S)
void EmitOMPSimdDirective(const OMPSimdDirective &S)
void EmitOMPCriticalDirective(const OMPCriticalDirective &S)
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 EmitOpenACCHostDataConstruct(const OpenACCHostDataConstruct &S)
void EmitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective &S)
void EmitOpenACCUpdateConstruct(const OpenACCUpdateConstruct &S)
void EmitOMPTargetParallelGenericLoopDirective(const OMPTargetParallelGenericLoopDirective &S)
void EmitOMPAssumeDirective(const OMPAssumeDirective &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)
void EmitOpenACCSetConstruct(const OpenACCSetConstruct &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 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 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 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.
bool shouldEmitConvergenceTokens() const
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={})
void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn)
Assign counters to regions and configure them for PGO of a given function.
void markStmtMaybeUsed(const Stmt *S)
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.
llvm::Value * getPointer(CodeGenFunction &CGF) const
Address getAddress() 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...
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.
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 - 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.
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
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.
Token - This structure provides full information about a lexed token.
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.
StorageClass getStorageClass() const
Returns the storage class as written in the source.
WhileStmt - This represents a 'while' stmt.
Defines the clang::TargetInfo interface.
bool Rem(InterpState &S, CodePtr OpPC)
1) Pops the RHS from the stack.
bool Ret(InterpState &S, CodePtr &PC)
The JSON file list parser is used to communicate input to InstallAPI.
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.
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)
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
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4