20 using namespace clang;
21 using namespace CodeGen;
31 auto SrcBegin = SrcAddr;
32 auto DestBegin = DestAddr;
36 SrcBegin =
Builder.CreatePointerBitCastOrAddrSpaceCast(SrcBegin,
37 DestBegin->getType());
38 auto DestEnd =
Builder.CreateGEP(DestBegin, NumElements);
43 Builder.CreateICmpEQ(DestBegin, DestEnd,
"omp.arraycpy.isempty");
44 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
47 auto EntryBB =
Builder.GetInsertBlock();
49 auto SrcElementCurrent =
50 Builder.CreatePHI(SrcBegin->getType(), 2,
"omp.arraycpy.srcElementPast");
51 SrcElementCurrent->addIncoming(SrcBegin, EntryBB);
52 auto DestElementCurrent =
Builder.CreatePHI(DestBegin->getType(), 2,
53 "omp.arraycpy.destElementPast");
54 DestElementCurrent->addIncoming(DestBegin, EntryBB);
57 CopyGen(DestElementCurrent, SrcElementCurrent);
60 auto DestElementNext =
Builder.CreateConstGEP1_32(
61 DestElementCurrent, 1,
"omp.arraycpy.dest.element");
62 auto SrcElementNext =
Builder.CreateConstGEP1_32(
63 SrcElementCurrent, 1,
"omp.arraycpy.src.element");
66 Builder.CreateICmpEQ(DestElementNext, DestEnd,
"omp.arraycpy.done");
67 Builder.CreateCondBr(Done, DoneBB, BodyBB);
68 DestElementCurrent->addIncoming(DestElementNext,
Builder.GetInsertBlock());
69 SrcElementCurrent->addIncoming(SrcElementNext,
Builder.GetInsertBlock());
88 DestAddr, SrcAddr, OriginalType,
89 [&CGF, Copy, SrcVD, DestVD](
llvm::Value *DestElement,
99 SrcVD, [SrcElement]() ->
llvm::Value *{
return SrcElement; });
119 auto *
C = cast<OMPFirstprivateClause>(*I);
120 auto IRef =
C->varlist_begin();
121 auto InitsRef =
C->inits().begin();
122 for (
auto IInit :
C->private_copies()) {
123 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
124 if (EmittedAsFirstprivate.count(OrigVD) == 0) {
125 EmittedAsFirstprivate.insert(OrigVD);
126 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
127 auto *VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
130 const_cast<VarDecl *>(OrigVD),
142 auto *Init = VD->getInit();
149 Emission.getAllocatedAddress(), OriginalAddr, Type,
155 LocalDeclMap[VDInit] = SrcElement;
157 Init->getType().getQualifiers(),
159 LocalDeclMap.erase(VDInit);
163 return Emission.getAllocatedAddress();
171 LocalDeclMap[VDInit] = OriginalAddr;
173 LocalDeclMap.erase(VDInit);
177 assert(IsRegistered &&
178 "firstprivate var already registered as private");
185 return !EmittedAsFirstprivate.empty();
193 auto *
C = cast<OMPPrivateClause>(*I);
194 auto IRef =
C->varlist_begin();
195 for (
auto IInit :
C->private_copies()) {
196 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
197 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
198 auto VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
205 assert(IsRegistered &&
"private var already registered as private");
220 llvm::BasicBlock *CopyBegin =
nullptr, *CopyEnd =
nullptr;
222 auto *
C = cast<OMPCopyinClause>(*I);
223 auto IRef =
C->varlist_begin();
224 auto ISrcRef =
C->source_exprs().begin();
225 auto IDestRef =
C->destination_exprs().begin();
226 for (
auto *AssignOp :
C->assignment_ops()) {
227 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
229 if (CopiedVars.insert(VD->getCanonicalDecl()).second) {
238 "Copyin threadprivates should have been captured!");
239 DeclRefExpr DRE(const_cast<VarDecl *>(VD),
true, (*IRef)->getType(),
248 if (CopiedVars.size() == 1) {
260 auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
261 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
262 EmitOMPCopy(*
this, Type, PrivateAddr, MasterAddr, DestVD, SrcVD,
280 bool HasAtLeastOneLastprivate =
false;
283 HasAtLeastOneLastprivate =
true;
284 auto *
C = cast<OMPLastprivateClause>(*I);
285 auto IRef =
C->varlist_begin();
286 auto IDestRef =
C->destination_exprs().begin();
287 for (
auto *IInit :
C->private_copies()) {
290 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
291 if (AlreadyEmittedVars.insert(OrigVD->getCanonicalDecl()).second) {
292 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
295 const_cast<VarDecl *>(OrigVD),
305 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
312 assert(IsRegistered &&
313 "lastprivate var already registered as private");
320 return HasAtLeastOneLastprivate;
331 llvm::BasicBlock *ThenBB =
nullptr;
332 llvm::BasicBlock *DoneBB =
nullptr;
333 if (IsLastIterCond) {
336 Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB);
339 llvm::DenseMap<const Decl *, const Expr *> LoopCountersAndUpdates;
340 const Expr *LastIterVal =
nullptr;
341 const Expr *IVExpr =
nullptr;
342 const Expr *IncExpr =
nullptr;
343 if (
auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) {
345 LastIterVal = cast<VarDecl>(cast<DeclRefExpr>(
346 LoopDirective->getUpperBoundVariable())
348 ->getAnyInitializer();
349 IVExpr = LoopDirective->getIterationVariable();
350 IncExpr = LoopDirective->getInc();
351 auto IUpdate = LoopDirective->updates().begin();
352 for (
auto *E : LoopDirective->counters()) {
353 auto *D = cast<DeclRefExpr>(E)->getDecl()->getCanonicalDecl();
354 LoopCountersAndUpdates[D] = *IUpdate;
361 bool FirstLCV =
true;
363 auto *
C = cast<OMPLastprivateClause>(*I);
364 auto IRef =
C->varlist_begin();
365 auto ISrcRef =
C->source_exprs().begin();
366 auto IDestRef =
C->destination_exprs().begin();
367 for (
auto *AssignOp :
C->assignment_ops()) {
368 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
370 auto *CanonicalVD = PrivateVD->getCanonicalDecl();
371 if (AlreadyEmittedVars.insert(CanonicalVD).second) {
375 if (
auto *UpExpr = LoopCountersAndUpdates.lookup(CanonicalVD)) {
376 if (FirstLCV && LastIterVal) {
385 auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
386 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
391 EmitOMPCopy(*
this, Type, OriginalAddr, PrivateAddr, DestVD, SrcVD,
400 if (IsLastIterCond) {
409 auto *
C = cast<OMPReductionClause>(*I);
410 auto ILHS =
C->lhs_exprs().begin();
411 auto IRHS =
C->rhs_exprs().begin();
412 for (
auto IRef :
C->varlists()) {
413 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl());
414 auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
415 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
431 assert(IsRegistered &&
"private var already registered as private");
444 bool HasAtLeastOneReduction =
false;
446 HasAtLeastOneReduction =
true;
447 auto *
C = cast<OMPReductionClause>(*I);
448 LHSExprs.append(
C->lhs_exprs().begin(),
C->lhs_exprs().end());
449 RHSExprs.append(
C->rhs_exprs().begin(),
C->rhs_exprs().end());
450 ReductionOps.append(
C->reduction_ops().begin(),
C->reduction_ops().end());
452 if (HasAtLeastOneReduction) {
456 *
this, D.
getLocEnd(), LHSExprs, RHSExprs, ReductionOps,
471 S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
474 auto NumThreadsClause = cast<OMPNumThreadsClause>(
C);
475 auto NumThreads = CGF.
EmitScalarExpr(NumThreadsClause->getNumThreads(),
478 CGF, NumThreads, NumThreadsClause->getLocStart());
482 auto *ProcBindClause = cast<OMPProcBindClause>(
C);
484 CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getLocStart());
486 const Expr *IfCond =
nullptr;
488 IfCond = cast<OMPIfClause>(
C)->getCondition();
491 CapturedStruct, IfCond);
499 bool Copyins = CGF.EmitOMPCopyinClause(S);
500 bool Firstprivates = CGF.EmitOMPFirstprivateClause(S, PrivateScope);
501 if (Copyins || Firstprivates) {
506 CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.
getLocStart(),
509 CGF.EmitOMPPrivateClause(S, PrivateScope);
510 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
513 CGF.EmitOMPReductionClauseFinal(S);
515 CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.
getLocStart(),
523 RunCleanupsScope BodyScope(*
this);
530 auto *
C = cast<OMPLinearClause>(*I);
531 for (
auto U :
C->updates()) {
538 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
543 BreakContinueStack.pop_back();
551 const Stmt &
S,
bool RequiresCleanup,
const Expr *LoopCond,
564 auto ExitBlock = LoopExit.getBlock();
572 if (ExitBlock != LoopExit.getBlock()) {
582 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
590 BreakContinueStack.pop_back();
600 auto *
C = cast<OMPLinearClause>(*I);
601 for (
auto Init :
C->inits()) {
602 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl());
603 auto *OrigVD = cast<VarDecl>(
604 cast<DeclRefExpr>(VD->getInit()->IgnoreImpCasts())->getDecl());
608 VD->getInit()->getExprLoc());
612 VD->getType(), Emission.Alignment),
618 if (
auto CS = cast_or_null<BinaryOperator>(
C->getCalcStep()))
619 if (
auto SaveRef = cast<DeclRefExpr>(CS->getLHS())) {
631 auto *
C = cast<OMPLinearClause>(*I);
632 auto IC =
C->varlist_begin();
633 for (
auto F :
C->finals()) {
634 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl());
641 [OrigAddr]() ->
llvm::Value *{
return OrigAddr; });
652 auto *Clause = cast<OMPAlignedClause>(*I);
653 unsigned ClauseAlignment = 0;
654 if (
auto AlignmentExpr = Clause->getAlignment()) {
657 ClauseAlignment =
static_cast<unsigned>(AlignmentCI->getZExtValue());
659 for (
auto E : Clause->varlists()) {
660 unsigned Alignment = ClauseAlignment;
661 if (Alignment == 0) {
668 E->getType()->getPointeeType()))
671 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
672 "alignment is not power of 2");
673 if (Alignment != 0) {
684 for (
auto *E : Counters) {
685 auto VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
690 return VarEmission.getAllocatedAddress();
696 const Expr *Cond, llvm::BasicBlock *TrueBlock,
697 llvm::BasicBlock *FalseBlock, uint64_t TrueCount) {
703 for (
auto I : S.
inits()) {
715 auto *
C = cast<OMPLinearClause>(*I);
716 for (
auto *E :
C->varlists()) {
717 auto VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
722 return VarEmission.getAllocatedAddress();
724 assert(IsRegistered &&
"linear var already registered as private");
737 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.
getScalarVal());
748 LoopStack.setParallel();
749 LoopStack.setVectorizerEnable(
true);
755 for (
auto F : D.
finals()) {
756 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl());
757 if (LocalDeclMap.lookup(OrigVD) || CapturedStmtInfo->lookup(OrigVD)) {
759 CapturedStmtInfo->lookup(OrigVD) !=
nullptr,
760 (*IC)->getType(),
VK_LValue, (*IC)->getExprLoc());
761 auto *OrigAddr = EmitLValue(&DRE).getAddress();
762 OMPPrivateScope VarScope(*
this);
763 VarScope.addPrivate(OrigVD,
764 [OrigAddr]() ->
llvm::Value *{
return OrigAddr; });
765 (void)VarScope.Privatize();
785 llvm::BasicBlock *ContBlock =
nullptr;
786 if (CGF.ConstantFoldsToSimpleInteger(S.
getPreCond(), CondConstant)) {
790 auto *ThenBlock = CGF.createBasicBlock(
"simd.if.then");
791 ContBlock = CGF.createBasicBlock(
"simd.if.end");
793 CGF.getProfileCount(&S));
794 CGF.EmitBlock(ThenBlock);
795 CGF.incrementProfileCounter(&S);
800 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
801 CGF.EmitVarDecl(*IVDecl);
802 CGF.EmitIgnoredExpr(S.
getInit());
808 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
813 CGF.EmitOMPSimdInit(S);
816 CGF.EmitOMPLinearClauseInit(S);
817 bool HasLastprivateClause;
822 CGF.EmitOMPPrivateClause(S, LoopScope);
823 CGF.EmitOMPReductionClauseInit(S, LoopScope);
824 HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
830 CGF.EmitStopPoint(&S);
834 if (HasLastprivateClause) {
835 CGF.EmitOMPLastprivateClauseFinal(S);
837 CGF.EmitOMPReductionClauseFinal(S);
839 CGF.EmitOMPSimdFinal(S);
842 CGF.EmitBranch(ContBlock);
843 CGF.EmitBlock(ContBlock,
true);
846 CGM.getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_simd, CodeGen);
851 OMPPrivateScope &LoopScope,
855 auto &RT = CGM.getOpenMPRuntime();
858 const bool DynamicOrOrdered = Ordered || RT.isDynamic(ScheduleKind);
861 !RT.isStaticNonchunked(ScheduleKind, Chunk !=
nullptr)) &&
862 "static non-chunked schedule does not need outer loop");
915 const unsigned IVSize = getContext().getTypeSize(IVExpr->
getType());
919 *
this, S.
getLocStart(), ScheduleKind, IVSize, IVSigned, Ordered, IL, LB,
924 auto LoopExit = getJumpDestInCurrentScope(
"omp.dispatch.end");
927 auto CondBlock = createBasicBlock(
"omp.dispatch.cond");
928 EmitBlock(CondBlock);
929 LoopStack.push(CondBlock);
932 if (!DynamicOrOrdered) {
938 BoolCondVal = EvaluateExprAsBool(S.
getCond());
940 BoolCondVal = RT.emitForNext(*
this, S.
getLocStart(), IVSize, IVSigned,
946 auto ExitBlock = LoopExit.getBlock();
947 if (LoopScope.requiresCleanups())
948 ExitBlock = createBasicBlock(
"omp.dispatch.cleanup");
950 auto LoopBody = createBasicBlock(
"omp.dispatch.body");
951 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
952 if (ExitBlock != LoopExit.getBlock()) {
953 EmitBlock(ExitBlock);
954 EmitBranchThroughCleanup(LoopExit);
960 if (DynamicOrOrdered)
964 auto Continue = getJumpDestInCurrentScope(
"omp.dispatch.inc");
965 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
970 LoopStack.setParallel((ScheduleKind == OMPC_SCHEDULE_dynamic ||
971 ScheduleKind == OMPC_SCHEDULE_guided) &&
978 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.
getCond(), S.
getInc(),
980 CGF.EmitOMPLoopBody(S, LoopExit);
981 CGF.EmitStopPoint(&S);
985 CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd(
986 CGF, Loc, IVSize, IVSigned);
990 EmitBlock(Continue.getBlock());
991 BreakContinueStack.pop_back();
992 if (!DynamicOrOrdered) {
998 EmitBranch(CondBlock);
1001 EmitBlock(LoopExit.getBlock());
1004 if (!DynamicOrOrdered)
1005 RT.emitForStaticFinish(*
this, S.
getLocEnd());
1011 auto VDecl = cast<VarDecl>(Helper->
getDecl());
1024 ScheduleKind =
C->getScheduleKind();
1025 if (
const auto *Ch =
C->getChunkSize()) {
1026 if (
auto *ImpRef = cast_or_null<DeclRefExpr>(
C->getHelperChunkSize())) {
1028 const VarDecl *ImpVar = cast<VarDecl>(ImpRef->getDecl());
1038 if (!
C->getHelperChunkSize() || !OuterRegion) {
1045 return std::make_pair(Chunk, ScheduleKind);
1051 auto IVDecl = cast<VarDecl>(IVExpr->getDecl());
1052 EmitVarDecl(*IVDecl);
1058 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
1063 auto &RT = CGM.getOpenMPRuntime();
1065 bool HasLastprivateClause;
1072 llvm::BasicBlock *ContBlock =
nullptr;
1073 if (ConstantFoldsToSimpleInteger(S.
getPreCond(), CondConstant)) {
1077 auto *ThenBlock = createBasicBlock(
"omp.precond.then");
1078 ContBlock = createBasicBlock(
"omp.precond.end");
1080 getProfileCount(&S));
1081 EmitBlock(ThenBlock);
1082 incrementProfileCounter(&S);
1086 EmitOMPLinearClauseInit(S);
1099 OMPPrivateScope LoopScope(*
this);
1100 if (EmitOMPFirstprivateClause(S, LoopScope)) {
1103 CGM.getOpenMPRuntime().emitBarrierCall(*
this, S.
getLocStart(),
1106 EmitOMPPrivateClause(S, LoopScope);
1107 HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
1108 EmitOMPReductionClauseInit(S, LoopScope);
1111 (void)LoopScope.Privatize();
1118 Chunk = ScheduleInfo.first;
1119 ScheduleKind = ScheduleInfo.second;
1120 const unsigned IVSize = getContext().getTypeSize(IVExpr->
getType());
1123 if (RT.isStaticNonchunked(ScheduleKind,
1124 Chunk !=
nullptr) &&
1134 RT.emitForInit(*
this, S.
getLocStart(), ScheduleKind, IVSize, IVSigned,
1137 auto LoopExit = getJumpDestInCurrentScope(createBasicBlock(
"omp.loop.exit"));
1143 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.
getCond(),
1146 CGF.EmitOMPLoopBody(S, LoopExit);
1147 CGF.EmitStopPoint(&S);
1150 EmitBlock(LoopExit.getBlock());
1156 EmitOMPForOuterLoop(ScheduleKind, S, LoopScope, Ordered,
1160 EmitOMPReductionClauseFinal(S);
1162 if (HasLastprivateClause)
1163 EmitOMPLastprivateClauseFinal(
1167 EmitOMPSimdFinal(S);
1171 EmitBranch(ContBlock);
1172 EmitBlock(ContBlock,
true);
1175 return HasLastprivateClause;
1180 bool HasLastprivates =
false;
1182 HasLastprivates = CGF.EmitOMPWorksharingLoop(S);
1184 CGM.getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_for, CodeGen);
1188 CGM.getOpenMPRuntime().emitBarrierCall(*
this, S.
getLocStart(), OMPD_for);
1194 bool HasLastprivates =
false;
1196 HasLastprivates = CGF.EmitOMPWorksharingLoop(S);
1198 CGM.getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_simd, CodeGen);
1202 CGM.getOpenMPRuntime().emitBarrierCall(*
this, S.
getLocStart(), OMPD_for);
1219 if (CS && CS->size() > 1) {
1220 bool HasLastprivates =
false;
1222 auto &
C = CGF.CGM.getContext();
1223 auto KmpInt32Ty =
C.getIntTypeForBitwidth(32, 1);
1226 CGF.Builder.getInt32(0));
1227 auto *GlobalUBVal = CGF.Builder.getInt32(CS->size() - 1);
1231 CGF.Builder.getInt32(1));
1233 CGF.Builder.getInt32(0));
1259 auto *ExitBB = CGF.createBasicBlock(
".omp.sections.exit");
1261 CGF.EmitLoadOfLValue(IV, S.getLocStart()).getScalarVal(), ExitBB,
1263 unsigned CaseNumber = 0;
1264 for (
auto *SubStmt : CS->children()) {
1265 auto CaseBB = CGF.createBasicBlock(
".omp.sections.case");
1266 CGF.EmitBlock(CaseBB);
1267 SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB);
1268 CGF.EmitStmt(SubStmt);
1269 CGF.EmitBranch(ExitBB);
1272 CGF.EmitBlock(ExitBB,
true);
1276 if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
1279 CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(),
1282 CGF.EmitOMPPrivateClause(S, LoopScope);
1283 HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
1284 CGF.EmitOMPReductionClauseInit(S, LoopScope);
1285 (void)LoopScope.Privatize();
1288 CGF.CGM.getOpenMPRuntime().emitForInit(
1289 CGF, S.getLocStart(), OMPC_SCHEDULE_static, 32,
1290 true,
false, IL.getAddress(),
1293 auto *UBVal = CGF.EmitLoadOfScalar(UB, S.getLocStart());
1294 auto *MinUBGlobalUB = CGF.Builder.CreateSelect(
1295 CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
1296 CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
1298 CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getLocStart()), IV);
1300 CGF.EmitOMPInnerLoop(S,
false, &Cond, &Inc, BodyGen,
1303 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocStart());
1304 CGF.EmitOMPReductionClauseFinal(S);
1307 if (HasLastprivates)
1308 CGF.EmitOMPLastprivateClauseFinal(
1309 S, CGF.Builder.CreateIsNotNull(
1310 CGF.EmitLoadOfScalar(IL, S.getLocStart())));
1313 CGM.getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_sections, CodeGen);
1317 if (HasLastprivates && S.getSingleClause(OMPC_nowait)) {
1320 CGM.getOpenMPRuntime().emitBarrierCall(*
this, S.getLocStart(),
1323 return OMPD_sections;
1327 bool HasFirstprivates;
1330 bool HasReductions = !S.getClausesOfKind(OMPC_reduction).empty();
1334 bool HasLastprivates = !S.getClausesOfKind(OMPC_lastprivate).empty();
1337 HasFirstprivates = CGF.EmitOMPFirstprivateClause(S, SingleScope);
1338 CGF.EmitOMPPrivateClause(S, SingleScope);
1339 (void)SingleScope.Privatize();
1343 CGM.getOpenMPRuntime().emitSingleRegion(*
this, CodeGen, S.getLocStart(),
1349 if ((HasFirstprivates || HasLastprivates || HasReductions) &&
1350 S.getSingleClause(OMPC_nowait)) {
1353 CGM.getOpenMPRuntime().emitBarrierCall(*
this, S.getLocStart(),
OMPD_unknown);
1363 CGM.getOpenMPRuntime().emitBarrierCall(*
this, S.
getLocStart(), EmittedAs);
1371 CGF.EnsureInsertPoint();
1373 CGM.getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_section, CodeGen);
1387 auto *
C = cast<OMPCopyprivateClause>(*I);
1388 CopyprivateVars.append(
C->varlists().begin(),
C->varlists().end());
1389 DestExprs.append(
C->destination_exprs().begin(),
1390 C->destination_exprs().end());
1391 SrcExprs.append(
C->source_exprs().begin(),
C->source_exprs().end());
1392 AssignmentOps.append(
C->assignment_ops().begin(),
1393 C->assignment_ops().end());
1397 bool HasFirstprivates;
1400 HasFirstprivates = CGF.EmitOMPFirstprivateClause(S, SingleScope);
1401 CGF.EmitOMPPrivateClause(S, SingleScope);
1405 CGF.EnsureInsertPoint();
1407 CGM.getOpenMPRuntime().emitSingleRegion(*
this, CodeGen, S.
getLocStart(),
1408 CopyprivateVars, DestExprs, SrcExprs,
1413 CopyprivateVars.empty()) {
1414 CGM.getOpenMPRuntime().emitBarrierCall(
1424 CGF.EnsureInsertPoint();
1426 CGM.getOpenMPRuntime().emitMasterRegion(*
this, CodeGen, S.
getLocStart());
1433 CGF.EnsureInsertPoint();
1435 CGM.getOpenMPRuntime().emitCriticalRegion(
1439 void CodeGenFunction::EmitOMPParallelForDirective(
1446 CGF.EmitOMPWorksharingLoop(S);
1450 CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.
getLocStart(),
1456 void CodeGenFunction::EmitOMPParallelForSimdDirective(
1463 CGF.EmitOMPWorksharingLoop(S);
1467 CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.
getLocStart(),
1473 void CodeGenFunction::EmitOMPParallelSectionsDirective(
1479 (void)CGF.EmitSections(S);
1481 CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.
getLocStart(),
1491 auto CapturedStruct = GenerateCapturedStmtArgument(*CS);
1492 auto *I = CS->getCapturedDecl()->param_begin();
1493 auto *PartId = std::next(I);
1501 auto *
C = cast<OMPPrivateClause>(*I);
1502 auto IRef =
C->varlist_begin();
1503 for (
auto *IInit :
C->private_copies()) {
1504 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
1505 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
1506 PrivateVars.push_back(*IRef);
1507 PrivateCopies.push_back(IInit);
1512 EmittedAsPrivate.clear();
1518 auto *
C = cast<OMPFirstprivateClause>(*I);
1519 auto IRef =
C->varlist_begin();
1520 auto IElemInitRef =
C->inits().begin();
1521 for (
auto *IInit :
C->private_copies()) {
1522 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
1523 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
1524 FirstprivateVars.push_back(*IRef);
1525 FirstprivateCopies.push_back(IInit);
1526 FirstprivateInits.push_back(*IElemInitRef);
1528 ++IRef, ++IElemInitRef;
1535 auto *
C = cast<OMPDependClause>(*I);
1536 for (
auto *IRef :
C->varlists()) {
1537 Dependences.push_back(std::make_pair(
C->getDependencyKind(), IRef));
1540 auto &&CodeGen = [PartId, &
S, &PrivateVars, &FirstprivateVars](
1543 auto *CS = cast<CapturedStmt>(S.getAssociatedStmt());
1545 if (!PrivateVars.empty() || !FirstprivateVars.empty()) {
1546 auto *CopyFn = CGF.Builder.CreateAlignedLoad(
1547 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(3)),
1548 CGF.PointerAlignInBytes);
1549 auto *PrivatesPtr = CGF.Builder.CreateAlignedLoad(
1550 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(2)),
1551 CGF.PointerAlignInBytes);
1556 CallArgs.push_back(PrivatesPtr);
1557 for (
auto *E : PrivateVars) {
1558 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
1560 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()));
1561 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
1562 CallArgs.push_back(PrivatePtr);
1564 for (
auto *E : FirstprivateVars) {
1565 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
1567 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()));
1568 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
1569 CallArgs.push_back(PrivatePtr);
1571 CGF.EmitRuntimeCall(CopyFn, CallArgs);
1572 for (
auto &&Pair : PrivatePtrs) {
1574 CGF.Builder.CreateAlignedLoad(Pair.second, CGF.PointerAlignInBytes);
1575 Scope.addPrivate(Pair.first, [Replacement]() {
return Replacement; });
1578 (void)
Scope.Privatize();
1582 CGF.EmitStmt(CS->getCapturedStmt());
1584 auto OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
1585 S, *I, OMPD_task, CodeGen);
1587 bool Tied = !S.getSingleClause(OMPC_untied);
1589 llvm::PointerIntPair<llvm::Value *, 1, bool> Final;
1590 if (
auto *Clause = S.getSingleClause(OMPC_final)) {
1593 auto *Cond = cast<OMPFinalClause>(Clause)->getCondition();
1595 if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
1596 Final.setInt(CondConstant);
1598 Final.setPointer(EvaluateExprAsBool(Cond));
1601 Final.setInt(
false);
1603 auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
1604 const Expr *IfCond =
nullptr;
1605 if (
auto C = S.getSingleClause(OMPC_if)) {
1606 IfCond = cast<OMPIfClause>(
C)->getCondition();
1608 CGM.getOpenMPRuntime().emitTaskCall(
1609 *
this, S.getLocStart(),
S, Tied, Final, OutlinedFn, SharedsTy,
1610 CapturedStruct, IfCond, PrivateVars, PrivateCopies, FirstprivateVars,
1611 FirstprivateCopies, FirstprivateInits, Dependences);
1614 void CodeGenFunction::EmitOMPTaskyieldDirective(
1632 CGF.EnsureInsertPoint();
1640 auto FlushClause = cast<OMPFlushClause>(
C);
1641 return llvm::makeArrayRef(FlushClause->varlist_begin(),
1642 FlushClause->varlist_end());
1652 CGF.EnsureInsertPoint();
1660 "DestType must have scalar evaluation kind.");
1661 assert(!Val.
isAggregate() &&
"Must be a scalar or complex.");
1672 "DestType must have complex evaluation kind.");
1680 ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType()));
1682 assert(Val.
isComplex() &&
"Must be a scalar or complex.");
1686 Val.
getComplexVal().first, SrcElementType, DestElementType);
1688 Val.
getComplexVal().second, SrcElementType, DestElementType);
1698 CGF.
EmitAtomicStore(RVal, LVal, IsSeqCst ? llvm::SequentiallyConsistent
1718 llvm_unreachable(
"Must be a scalar or complex.");
1726 assert(V->
isLValue() &&
"V of 'omp atomic read' is not lvalue");
1727 assert(X->
isLValue() &&
"X of 'omp atomic read' is not lvalue");
1730 RValue Res = XLValue.isGlobalReg()
1733 IsSeqCst ? llvm::SequentiallyConsistent
1735 XLValue.isVolatile());
1749 assert(X->
isLValue() &&
"X of 'omp atomic write' is not lvalue");
1762 llvm::AtomicOrdering AO,
1763 bool IsXLHSInRHSPart) {
1772 X.
getAddress()->getType()->getPointerElementType())) ||
1773 !X.
getAddress()->getType()->getPointerElementType()->isIntegerTy() ||
1776 return std::make_pair(
false,
RValue::get(
nullptr));
1778 llvm::AtomicRMWInst::BinOp RMWOp;
1781 RMWOp = llvm::AtomicRMWInst::Add;
1784 if (!IsXLHSInRHSPart)
1785 return std::make_pair(
false,
RValue::get(
nullptr));
1786 RMWOp = llvm::AtomicRMWInst::Sub;
1792 RMWOp = llvm::AtomicRMWInst::Or;
1795 RMWOp = llvm::AtomicRMWInst::Xor;
1799 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min
1800 : llvm::AtomicRMWInst::Max)
1801 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin
1802 : llvm::AtomicRMWInst::UMax);
1806 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max
1807 : llvm::AtomicRMWInst::Min)
1808 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax
1809 : llvm::AtomicRMWInst::UMin);
1812 RMWOp = llvm::AtomicRMWInst::Xchg;
1821 return std::make_pair(
false,
RValue::get(
nullptr));
1839 llvm_unreachable(
"Unsupported atomic update operation");
1842 if (
auto *IC = dyn_cast<llvm::ConstantInt>(UpdateVal)) {
1843 UpdateVal = CGF.
Builder.CreateIntCast(
1844 IC, X.
getAddress()->getType()->getPointerElementType(),
1877 const Expr *UE,
bool IsXLHSInRHSPart,
1880 "Update expr in 'atomic update' must be a binary operator.");
1888 assert(X->
isLValue() &&
"X of 'omp atomic update' is not lvalue");
1891 auto AO = IsSeqCst ? llvm::SequentiallyConsistent : llvm::Monotonic;
1892 auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
1893 auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
1894 auto *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
1895 auto *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
1897 [&CGF, UE, ExprRValue, XRValExpr, ERValExpr](
RValue XRValue) ->
RValue {
1903 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
1924 llvm_unreachable(
"Must be a scalar or complex.");
1928 bool IsPostfixUpdate,
const Expr *V,
1930 const Expr *UE,
bool IsXLHSInRHSPart,
1932 assert(X->
isLValue() &&
"X of 'omp atomic capture' is not lvalue");
1933 assert(V->
isLValue() &&
"V of 'omp atomic capture' is not lvalue");
1938 auto AO = IsSeqCst ? llvm::SequentiallyConsistent : llvm::Monotonic;
1943 "Update expr in 'atomic capture' must be a binary operator.");
1951 auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
1952 auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
1953 auto *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
1954 NewVValType = XRValExpr->getType();
1955 auto *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
1956 auto &&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr,
1961 NewVVal = IsPostfixUpdate ? XRValue : Res;
1965 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
1968 if (IsPostfixUpdate) {
1970 NewVVal = Res.second;
1984 auto &&Gen = [&CGF, &NewVVal, ExprRValue](
RValue XRValue) ->
RValue {
1990 XLValue, ExprRValue,
BO_Assign,
false, AO,
1994 NewVVal = IsPostfixUpdate ? Res.second : ExprRValue;
2008 bool IsSeqCst,
bool IsPostfixUpdate,
2010 const Expr *UE,
bool IsXLHSInRHSPart,
2025 IsXLHSInRHSPart, Loc);
2029 case OMPC_num_threads:
2031 case OMPC_firstprivate:
2032 case OMPC_lastprivate:
2033 case OMPC_reduction:
2042 case OMPC_copyprivate:
2044 case OMPC_proc_bind:
2051 case OMPC_mergeable:
2052 llvm_unreachable(
"Clause is not allowed in 'omp atomic'.");
2061 if (
C->getClauseKind() != OMPC_seq_cst) {
2062 Kind =
C->getClauseKind();
2069 if (
const auto *EWC = dyn_cast<ExprWithCleanups>(CS)) {
2073 if (
const auto *Compound = dyn_cast<CompoundStmt>(CS)) {
2074 for (
const auto *
C : Compound->body()) {
2075 if (
const auto *EWC = dyn_cast<ExprWithCleanups>(
C)) {
2091 llvm_unreachable(
"CodeGen for 'omp target' is not supported yet.");
2095 llvm_unreachable(
"CodeGen for 'omp teams' is not supported yet.");
2111 if (Kind == OMPD_parallel || Kind == OMPD_task)
2113 else if (Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections)
2114 return BreakContinueStack.empty() ?
JumpDest()
2115 : BreakContinueStack.back().BreakBlock;
This represents '#pragma omp master' directive.
This represents '#pragma omp task' directive.
bool isXLHSInRHSPart() const
Return true if helper update expression has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and...
void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S)
void setVectorizerWidth(unsigned W)
Set the vectorizer width for the next loop pushed.
const OMPClause * getSingleClause(OpenMPClauseKind K) const
Gets a single clause of the specified kind K associated with the current directive iff there is only ...
void EmitOMPReductionClauseFinal(const OMPExecutableDirective &D)
Emit final update of reduction values to original variables at the end of the directive.
ArrayRef< OMPClause * > clauses()
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount)
void EmitVarDecl(const VarDecl &D)
void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst)
Store of global named registers are always calls to intrinsics.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
This represents '#pragma omp for simd' directive.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
void EmitOMPCopy(CodeGenFunction &CGF, QualType OriginalType, llvm::Value *DestAddr, llvm::Value *SrcAddr, const VarDecl *DestVD, const VarDecl *SrcVD, const Expr *Copy)
Emit proper copying of data from one variable to another.
static void emitLinearClauseFinal(CodeGenFunction &CGF, const OMPLoopDirective &D)
void EmitOMPOrderedDirective(const OMPOrderedDirective &S)
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
bool addPrivate(const VarDecl *LocalVD, const std::function< llvm::Value *()> &PrivateGen)
Registers LocalVD variable as a private and apply PrivateGen function for it to generate correspondin...
This represents '#pragma omp parallel for' directive.
const LangOptions & getLangOpts() const
void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit)
void EmitOMPAggregateAssign(llvm::Value *DestAddr, llvm::Value *SrcAddr, QualType OriginalType, const llvm::function_ref< void(llvm::Value *, llvm::Value *)> &CopyGen)
Perform element by element copying of arrays with type OriginalType from SrcAddr to DestAddr using co...
llvm::Value * getAddress() const
static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty, const Twine &Name, llvm::Value *Init=nullptr)
static void emitPrivateLinearVars(CodeGenFunction &CGF, const OMPExecutableDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope)
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
OpenMPDirectiveKind getDirectiveKind() const
Expr * IgnoreImpCasts() LLVM_READONLY
static void emitSafelenClause(CodeGenFunction &CGF, const OMPExecutableDirective &D)
This represents '#pragma omp parallel' directive.
static void emitCommonOMPParallelDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)
void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
The scope used to remap some variables as private in the OpenMP loop body (or other captured region e...
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
ArrayRef< Expr * > updates()
void EmitAtomicUpdate(LValue LVal, llvm::AtomicOrdering AO, const llvm::function_ref< RValue(RValue)> &UpdateOp, bool IsVolatile)
virtual const FieldDecl * lookup(const VarDecl *VD) const
Lookup the captured field decl for a variable.
This represents '#pragma omp barrier' directive.
This is a common base class for loop directives ('omp simd', 'omp for', 'omp for simd' etc...
void EmitAggregateAssign(llvm::Value *DestPtr, llvm::Value *SrcPtr, QualType EltTy)
This represents '#pragma omp critical' directive.
static std::pair< bool, RValue > emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X, RValue Update, BinaryOperatorKind BO, llvm::AtomicOrdering AO, bool IsXLHSInRHSPart)
OpenMPDirectiveKind getCancelRegion() const
Get cancellation region for the current cancellation point.
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy)
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
bool EmitOMPLastprivateClauseInit(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
Emit initial code for lastprivate variables. If some variable is not also firstprivate, then the default initialization is used. Otherwise initialization of this variable is performed by EmitOMPFirstprivateClause method.
static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, bool IsSeqCst, bool IsPostfixUpdate, const Expr *X, const Expr *V, const Expr *E, const Expr *UE, bool IsXLHSInRHSPart, SourceLocation Loc)
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment=CharUnits())
static bool hasScalarEvaluationKind(QualType T)
ArrayRef< Expr * > finals()
CharUnits getAlignment() const
const TargetInfo & getTargetInfo() const
static void emitPrivateLoopCounters(CodeGenFunction &CGF, CodeGenFunction::OMPPrivateScope &LoopScope, ArrayRef< Expr * > Counters)
void pop()
End the current loop.
Expr * getX()
Get 'x' part of the associated expression/statement.
void EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S)
void EmitOMPLastprivateClauseFinal(const OMPExecutableDirective &D, llvm::Value *IsLastIterCond=nullptr)
Emit final copying of lastprivate values to original variables at the end of the worksharing or simd ...
void EmitOMPTargetDirective(const OMPTargetDirective &S)
A builtin binary operation expression such as "x + y" or "x <= y".
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
virtual bool hasBuiltinAtomic(uint64_t AtomicSizeInBits, uint64_t AlignmentInBits) const
Returns true if the given target supports lock-free atomic operations at the specified width and alig...
This represents '#pragma omp cancellation point' directive.
static LValue EmitOMPHelperVar(CodeGenFunction &CGF, const DeclRefExpr *Helper)
Emit a helper variable and return corresponding lvalue.
void incrementProfileCounter(const Stmt *S)
Increment the profiler's counter for the given statement.
void EmitStmt(const Stmt *S)
void EmitOMPParallelDirective(const OMPParallelDirective &S)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
This represents '#pragma omp teams' directive.
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
bool requiresCleanups() const
Determine whether this scope requires any cleanups.
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
An ordinary object is located at an address in memory.
static void EmitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst, const Expr *X, const Expr *E, SourceLocation Loc)
const ArrayType * getAsArrayTypeUnsafe() const
OpenMPDirectiveKind getCancelRegion() const
Get cancellation region for the current cancellation point.
llvm::Constant * getStaticLocalDeclAddress(const VarDecl *D)
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
This represents '#pragma omp taskgroup' directive.
bool isPostfixUpdate() const
Return true if 'v' expression must be updated to original value of 'x', false if 'v' must be updated ...
static TypeEvaluationKind getEvaluationKind(QualType T)
llvm::Value * GenerateCapturedStmtArgument(const CapturedStmt &S)
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
llvm::Value * GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
void EmitOMPTeamsDirective(const OMPTeamsDirective &S)
static CodeGenFunction::ComplexPairTy convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, QualType DestType)
Expr * getIterationVariable() const
llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, llvm::Value *&addr)
static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S, const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount)
OpenMPClauseKind
OpenMP clauses.
ASTContext & getContext() const
void EmitOMPLinearClauseInit(const OMPLoopDirective &D)
Emit initial code for linear variables. Creates private copies and initializes them with the values a...
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
std::pair< bool, RValue > EmitOMPAtomicSimpleUpdateExpr(LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart, llvm::AtomicOrdering AO, SourceLocation Loc, const llvm::function_ref< RValue(RValue)> &CommonGen)
Emit atomic update code for constructs: X = X BO E or X = E BO E.
This represents '#pragma omp for' directive.
static void EmitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst, const Expr *X, const Expr *V, SourceLocation Loc)
void setParallel(bool Enable=true)
Set the next pushed loop as parallel.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
Expr * getIsLastIterVariable() const
void EmitOMPBarrierDirective(const OMPBarrierDirective &S)
Expr * getNextUpperBound() const
This represents '#pragma omp cancel' directive.
static void EmitOMPAtomicUpdateExpr(CodeGenFunction &CGF, bool IsSeqCst, const Expr *X, const Expr *E, const Expr *UE, bool IsXLHSInRHSPart, SourceLocation Loc)
RValue EmitAtomicLoad(LValue LV, SourceLocation SL, AggValueSlot Slot=AggValueSlot::ignored())
static llvm::Value * convertToScalarValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, QualType DestType)
This represents '#pragma omp flush' directive.
This represents '#pragma omp parallel for simd' directive.
SourceLocation getLocStart() const
Returns starting location of directive kind.
void EmitAnyExprToMem(const Expr *E, llvm::Value *Location, Qualifiers Quals, bool IsInitializer)
static void emitAlignedClause(CodeGenFunction &CGF, const OMPExecutableDirective &D)
void EmitAlignmentAssumption(llvm::Value *PtrValue, unsigned Alignment, llvm::Value *OffsetValue=nullptr)
void EmitOMPFlushDirective(const OMPFlushDirective &S)
ASTContext & getContext() const
This represents '#pragma omp single' directive.
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
This is a basic class for representing single OpenMP executable directive.
Expr * getLowerBoundVariable() const
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
OpenMPDirectiveKind
OpenMP directives.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
This represents '#pragma omp taskwait' directive.
void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S)
bool isTrivialInitializer(const Expr *Init)
Determine whether the given initializer is trivial in the sense that it requires no code to be genera...
llvm::AllocaInst * CreateMemTemp(QualType T, const Twine &Name="tmp")
llvm::function_ref< void(CodeGenFunction &)> RegionCodeGenTy
This represents '#pragma omp target' directive.
Expr * getUpperBoundVariable() const
static void EmitOMPAtomicCaptureExpr(CodeGenFunction &CGF, bool IsSeqCst, bool IsPostfixUpdate, const Expr *V, const Expr *X, const Expr *E, const Expr *UE, bool IsXLHSInRHSPart, SourceLocation Loc)
Expr * getV()
Get 'v' part of the associated expression/statement.
void EmitOMPAtomicDirective(const OMPAtomicDirective &S)
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
This represents '#pragma omp ordered' directive.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
void enterFullExpression(const ExprWithCleanups *E)
void EmitDecl(const Decl &D)
Expr * getPreCond() const
JumpDest getOMPCancelDestination(OpenMPDirectiveKind Kind)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
static void emitSimpleStore(CodeGenFunction &CGF, LValue LVal, RValue RVal, QualType RValTy)
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
static const Type * getElementType(const Expr *BaseExpr)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
This represents '#pragma omp section' directive.
static RValue convertToType(CodeGenFunction &CGF, RValue Value, QualType SourceType, QualType ResType)
void EmitOMPPrivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
const Stmt * getBody() const
This represents '#pragma omp simd' directive.
llvm::IntegerType * IntPtrTy
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
Expr * getEnsureUpperBound() const
bool EmitOMPFirstprivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
void EmitOMPCancelDirective(const OMPCancelDirective &S)
Expr * getUpdateExpr()
Get helper expression of the form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 'OpaqueValueExp...
This represents '#pragma omp atomic' directive.
Expr * getCalcLastIteration() const
QualType getNonReferenceType() const
ArrayRef< Expr * > counters()
JumpDest ReturnBlock
ReturnBlock - Unified return block.
void EmitAutoVarCleanups(const AutoVarEmission &emission)
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy)
static void emitSimpleAtomicStore(CodeGenFunction &CGF, bool IsSeqCst, LValue LVal, RValue RVal)
This file defines OpenMP AST classes for executable directives and clauses.
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
filtered_clause_iterator< ClauseKindFilter > getClausesOfKind(OpenMPClauseKind Kind) const
ArrayRef< Expr * > inits()
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
bool isTLSSupported() const
Whether the target supports thread-local storage.
static std::pair< llvm::Value *, OpenMPScheduleClauseKind > emitScheduleClause(CodeGenFunction &CGF, const OMPLoopDirective &S, bool OuterRegion)
Expr * getNextLowerBound() const
void EmitOMPReductionClauseInit(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
Emit initial code for reduction variables. Creates reduction copies and initializes them with the val...
BoundNodesTreeBuilder *const Builder
void EmitBranch(llvm::BasicBlock *Block)
LValue EmitLValue(const Expr *E)
llvm::Constant * GetAddrOfGlobal(GlobalDecl GD)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
bool EmitOMPCopyinClause(const OMPExecutableDirective &D)
Emit code for copyin clause in D directive. The next code is generated at the start of outlined funct...
CGCapturedStmtInfo * CapturedStmtInfo
This represents '#pragma omp sections' directive.
void EmitOMPInnerLoop(const Stmt &S, bool RequiresCleanup, const Expr *LoopCond, const Expr *IncExpr, const llvm::function_ref< void(CodeGenFunction &)> &BodyGen, const llvm::function_ref< void(CodeGenFunction &)> &PostIncGen)
Emit inner loop of the worksharing/simd construct.
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
static RValue get(llvm::Value *V)
Expr * getLastIteration() const
void EmitBranchThroughCleanup(JumpDest Dest)
An l-value expression is a reference to an object with independent storage.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
This represents '#pragma omp taskyield' directive.
This represents '#pragma omp parallel sections' directive.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g., it is an signed integer type or a vector.
SourceLocation getLocEnd() const
Returns ending location of directive.
Stmt * getAssociatedStmt() const
Returns statement associated with the directive.
void push(llvm::BasicBlock *Header, llvm::ArrayRef< const Attr * > Attrs=llvm::None)
Begin a new structured loop. The set of staged attributes will be applied to the loop and then cleare...
Expr * getStrideVariable() const
bool Privatize()
Privatizes local variables previously registered as private. Registration is separate from the actual...
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.