20 using namespace clang;
21 using namespace CodeGen;
30 I !=
E; ++
I, ++CurField, ++CurCap) {
31 if (CurField->hasCapturedVLAType()) {
32 auto VAT = CurField->getCapturedVLAType();
33 auto *Val = VLASizeMap[VAT->getSizeExpr()];
34 CapturedVars.push_back(Val);
35 }
else if (CurCap->capturesThis())
36 CapturedVars.push_back(CXXThisValue);
37 else if (CurCap->capturesVariableByCopy())
38 CapturedVars.push_back(
41 assert(CurCap->capturesVariable() &&
"Expected capture by reference.");
49 bool isReferenceType =
false) {
61 if (isReferenceType) {
63 auto *RefVal = TmpAddr.getPointer();
76 "CapturedStmtInfo should be set when generating the captured function");
79 assert(CD->
hasBody() &&
"missing CapturedDecl body");
87 for (
auto *FD : RD->
fields()) {
98 I->capturesVariableArrayType())
99 ArgType = Ctx.getUIntPtrType();
101 if (
I->capturesVariable() ||
I->capturesVariableByCopy()) {
102 CapVar =
I->getCapturedVar();
104 }
else if (
I->capturesThis())
107 assert(
I->capturesVariableArrayType());
113 FD->getLocation(), II, ArgType));
132 F->addFnAttr(llvm::Attribute::NoUnwind);
139 for (
auto *FD : RD->
fields()) {
142 if (
I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) {
151 if (FD->hasCapturedVLAType()) {
154 Args[Cnt]->getName(), ArgLVal),
158 auto VAT = FD->getCapturedVLAType();
159 VLASizeMap[VAT->getSizeExpr()] = ExprArg;
160 }
else if (
I->capturesVariable()) {
161 auto *Var =
I->getCapturedVar();
170 }
else if (
I->capturesVariableByCopy()) {
171 assert(!FD->getType()->isAnyPointerType() &&
172 "Not expecting a captured pointer.");
173 auto *Var =
I->getCapturedVar();
175 setAddrOfLocalVar(
I->getCapturedVar(),
177 Args[Cnt]->getName(), ArgLVal,
181 assert(
I->capturesThis());
212 auto DestEnd =
Builder.CreateGEP(DestBegin, NumElements);
217 Builder.CreateICmpEQ(DestBegin, DestEnd,
"omp.arraycpy.isempty");
218 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
221 auto EntryBB =
Builder.GetInsertBlock();
226 llvm::PHINode *SrcElementPHI =
227 Builder.CreatePHI(SrcBegin->getType(), 2,
"omp.arraycpy.srcElementPast");
228 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
233 llvm::PHINode *DestElementPHI =
234 Builder.CreatePHI(DestBegin->getType(), 2,
"omp.arraycpy.destElementPast");
235 DestElementPHI->addIncoming(DestBegin, EntryBB);
241 CopyGen(DestElementCurrent, SrcElementCurrent);
244 auto DestElementNext =
Builder.CreateConstGEP1_32(
245 DestElementPHI, 1,
"omp.arraycpy.dest.element");
246 auto SrcElementNext =
Builder.CreateConstGEP1_32(
247 SrcElementPHI, 1,
"omp.arraycpy.src.element");
250 Builder.CreateICmpEQ(DestElementNext, DestEnd,
"omp.arraycpy.done");
251 Builder.CreateCondBr(Done, DoneBB, BodyBB);
252 DestElementPHI->addIncoming(DestElementNext,
Builder.GetInsertBlock());
253 SrcElementPHI->addIncoming(SrcElementNext,
Builder.GetInsertBlock());
276 auto DestEnd = CGF.
Builder.CreateGEP(DestBegin, NumElements);
281 CGF.
Builder.CreateICmpEQ(DestBegin, DestEnd,
"omp.arrayinit.isempty");
282 CGF.
Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
285 auto EntryBB = CGF.
Builder.GetInsertBlock();
290 llvm::PHINode *DestElementPHI = CGF.
Builder.CreatePHI(
291 DestBegin->getType(), 2,
"omp.arraycpy.destElementPast");
292 DestElementPHI->addIncoming(DestBegin, EntryBB);
305 auto DestElementNext = CGF.
Builder.CreateConstGEP1_32(
306 DestElementPHI, 1,
"omp.arraycpy.dest.element");
309 CGF.
Builder.CreateICmpEQ(DestElementNext, DestEnd,
"omp.arraycpy.done");
310 CGF.
Builder.CreateCondBr(Done, DoneBB, BodyBB);
311 DestElementPHI->addIncoming(DestElementNext, CGF.
Builder.GetInsertBlock());
322 if (BO && BO->getOpcode() ==
BO_Assign) {
329 DestAddr, SrcAddr, OriginalType,
330 [
this, Copy, SrcVD, DestVD](
Address DestElement,
Address SrcElement) {
339 SrcVD, [SrcElement]() ->
Address {
return SrcElement; });
361 auto IRef =
C->varlist_begin();
362 auto InitsRef =
C->inits().begin();
363 for (
auto IInit :
C->private_copies()) {
364 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
365 if (EmittedAsFirstprivate.count(OrigVD) == 0) {
366 EmittedAsFirstprivate.insert(OrigVD);
367 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
368 auto *VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
371 const_cast<VarDecl *>(OrigVD),
383 auto *Init = VD->getInit();
390 Emission.getAllocatedAddress(), OriginalAddr,
Type,
391 [
this, VDInit, Init](
Address DestElement,
396 setAddrOfLocalVar(VDInit, SrcElement);
398 Init->getType().getQualifiers(),
400 LocalDeclMap.erase(VDInit);
404 return Emission.getAllocatedAddress();
412 setAddrOfLocalVar(VDInit, OriginalAddr);
414 LocalDeclMap.erase(VDInit);
418 assert(IsRegistered &&
419 "firstprivate var already registered as private");
426 return !EmittedAsFirstprivate.empty();
436 auto IRef =
C->varlist_begin();
437 for (
auto IInit :
C->private_copies()) {
438 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
439 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
440 auto VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
447 assert(IsRegistered &&
"private var already registered as private");
464 llvm::BasicBlock *CopyBegin =
nullptr, *CopyEnd =
nullptr;
466 auto IRef =
C->varlist_begin();
467 auto ISrcRef =
C->source_exprs().begin();
468 auto IDestRef =
C->destination_exprs().begin();
469 for (
auto *AssignOp :
C->assignment_ops()) {
470 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
472 if (CopiedVars.insert(VD->getCanonicalDecl()).second) {
479 getContext().getTargetInfo().isTLSSupported()) {
481 "Copyin threadprivates should have been captured!");
482 DeclRefExpr DRE(const_cast<VarDecl *>(VD),
true, (*IRef)->getType(),
485 LocalDeclMap.erase(VD);
494 if (CopiedVars.size() == 1) {
506 auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
507 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
508 EmitOMPCopy(Type, PrivateAddr, MasterAddr, DestVD, SrcVD, AssignOp);
527 bool HasAtLeastOneLastprivate =
false;
530 HasAtLeastOneLastprivate =
true;
531 auto IRef =
C->varlist_begin();
532 auto IDestRef =
C->destination_exprs().begin();
533 for (
auto *IInit :
C->private_copies()) {
536 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
537 if (AlreadyEmittedVars.insert(OrigVD->getCanonicalDecl()).second) {
538 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
541 const_cast<VarDecl *>(OrigVD),
551 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
558 assert(IsRegistered &&
559 "lastprivate var already registered as private");
566 return HasAtLeastOneLastprivate;
579 llvm::BasicBlock *ThenBB =
nullptr;
580 llvm::BasicBlock *DoneBB =
nullptr;
581 if (IsLastIterCond) {
584 Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB);
587 llvm::DenseMap<const Decl *, const Expr *> LoopCountersAndUpdates;
588 if (
auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) {
589 auto IC = LoopDirective->counters().begin();
590 for (
auto F : LoopDirective->finals()) {
591 auto *D = cast<DeclRefExpr>(*IC)->getDecl()->getCanonicalDecl();
592 LoopCountersAndUpdates[D] = F;
598 auto IRef =
C->varlist_begin();
599 auto ISrcRef =
C->source_exprs().begin();
600 auto IDestRef =
C->destination_exprs().begin();
601 for (
auto *AssignOp :
C->assignment_ops()) {
602 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
604 auto *CanonicalVD = PrivateVD->getCanonicalDecl();
605 if (AlreadyEmittedVars.insert(CanonicalVD).second) {
609 if (
auto *UpExpr = LoopCountersAndUpdates.lookup(CanonicalVD))
611 auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
612 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
617 if (
auto RefTy = PrivateVD->getType()->getAs<
ReferenceType>())
621 EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp);
638 auto ILHS =
C->lhs_exprs().begin();
639 auto IRHS =
C->rhs_exprs().begin();
640 auto IPriv =
C->privates().begin();
641 for (
auto IRef :
C->varlists()) {
642 auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
643 auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
644 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl());
645 if (
auto *OASE = dyn_cast<OMPArraySectionExpr>(IRef)) {
646 auto *
Base = OASE->getBase()->IgnoreParenImpCasts();
647 while (
auto *TempOASE = dyn_cast<OMPArraySectionExpr>(
Base))
648 Base = TempOASE->getBase()->IgnoreParenImpCasts();
649 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
650 Base = TempASE->getBase()->IgnoreParenImpCasts();
651 auto *DE = cast<DeclRefExpr>(
Base);
652 auto *OrigVD = cast<VarDecl>(DE->getDecl());
657 auto BaseLValue = OriginalBaseLValue;
658 auto *Zero =
Builder.getInt64(0);
660 Indexes.push_back(Zero);
662 OASELValueLB.getPointer()->getType()->getPointerElementType();
663 auto *Ty = BaseLValue.getPointer()->getType()->getPointerElementType();
664 while (Ty != ItemTy) {
665 Indexes.push_back(Zero);
666 Ty = Ty->getPointerElementType();
669 Address(
Builder.CreateInBoundsGEP(BaseLValue.getPointer(), Indexes),
670 OASELValueLB.getAlignment()),
671 OASELValueLB.
getType(), OASELValueLB.getAlignmentSource());
675 return OASELValueLB.getAddress();
679 OrigVD, [
this, PrivateVD, BaseLValue, OASELValueLB, OASELValueUB,
680 OriginalBaseLValue]() ->
Address {
684 auto *Size =
Builder.CreatePtrDiff(OASELValueUB.getPointer(),
685 OASELValueLB.getPointer());
687 Size, llvm::ConstantInt::get(Size->getType(), 1));
689 *
this, cast<OpaqueValueExpr>(
691 .getAsVariableArrayType(PrivateVD->getType())
696 auto Addr = Emission.getAllocatedAddress();
697 auto *Init = PrivateVD->getInit();
701 auto *
Offset =
Builder.CreatePtrDiff(BaseLValue.getPointer(),
702 OASELValueLB.getPointer());
705 Ptr, OriginalBaseLValue.getPointer()->getType());
706 return Address(Ptr, OriginalBaseLValue.getAlignment());
708 assert(IsRegistered &&
"private var already registered as private");
714 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(IRef)) {
715 auto *
Base = ASE->getBase()->IgnoreParenImpCasts();
716 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
717 Base = TempASE->getBase()->IgnoreParenImpCasts();
718 auto *DE = cast<DeclRefExpr>(
Base);
719 auto *OrigVD = cast<VarDecl>(DE->getDecl());
722 auto BaseLValue = OriginalBaseLValue;
723 auto *Zero =
Builder.getInt64(0);
725 Indexes.push_back(Zero);
727 ASELValue.getPointer()->getType()->getPointerElementType();
728 auto *Ty = BaseLValue.getPointer()->getType()->getPointerElementType();
729 while (Ty != ItemTy) {
730 Indexes.push_back(Zero);
731 Ty = Ty->getPointerElementType();
734 Address(
Builder.CreateInBoundsGEP(BaseLValue.getPointer(), Indexes),
735 ASELValue.getAlignment()),
736 ASELValue.
getType(), ASELValue.getAlignmentSource());
740 return ASELValue.getAddress();
744 OrigVD, [
this, PrivateVD, BaseLValue, ASELValue,
745 OriginalBaseLValue]() ->
Address {
749 auto *
Offset =
Builder.CreatePtrDiff(BaseLValue.getPointer(),
750 ASELValue.getPointer());
753 Ptr, OriginalBaseLValue.getPointer()->getType());
754 return Address(Ptr, OriginalBaseLValue.getAlignment());
756 assert(IsRegistered &&
"private var already registered as private");
763 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl());
779 assert(IsRegistered &&
"private var already registered as private");
786 ++ILHS, ++IRHS, ++IPriv;
799 bool HasAtLeastOneReduction =
false;
801 HasAtLeastOneReduction =
true;
802 Privates.append(
C->privates().begin(),
C->privates().end());
803 LHSExprs.append(
C->lhs_exprs().begin(),
C->lhs_exprs().end());
804 RHSExprs.append(
C->rhs_exprs().begin(),
C->rhs_exprs().end());
805 ReductionOps.append(
C->reduction_ops().begin(),
C->reduction_ops().end());
807 if (HasAtLeastOneReduction) {
827 S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
830 auto NumThreads = CGF.
EmitScalarExpr(NumThreadsClause->getNumThreads(),
833 CGF, NumThreads, NumThreadsClause->getLocStart());
838 CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getLocStart());
840 const Expr *IfCond =
nullptr;
843 C->getNameModifier() == OMPD_parallel) {
844 IfCond =
C->getCondition();
849 CapturedVars, IfCond);
857 bool Copyins = CGF.EmitOMPCopyinClause(S);
858 bool Firstprivates = CGF.EmitOMPFirstprivateClause(S, PrivateScope);
859 if (Copyins || Firstprivates) {
864 CGF.CGM.getOpenMPRuntime().emitBarrierCall(
868 CGF.EmitOMPPrivateClause(S, PrivateScope);
869 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
872 CGF.EmitOMPReductionClauseFinal(S);
879 RunCleanupsScope BodyScope(*
this);
886 for (
auto U :
C->updates()) {
893 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
898 BreakContinueStack.pop_back();
902 const Stmt &
S,
bool RequiresCleanup,
const Expr *LoopCond,
915 auto ExitBlock = LoopExit.getBlock();
923 if (ExitBlock != LoopExit.getBlock()) {
933 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
941 BreakContinueStack.pop_back();
953 for (
auto Init :
C->inits()) {
954 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl());
955 auto *OrigVD = cast<VarDecl>(
956 cast<DeclRefExpr>(VD->getInit()->IgnoreImpCasts())->getDecl());
960 VD->getInit()->getExprLoc());
969 if (
auto CS = cast_or_null<BinaryOperator>(
C->getCalcStep()))
970 if (
auto SaveRef = cast<DeclRefExpr>(CS->getLHS())) {
984 auto IC =
C->varlist_begin();
985 for (
auto F :
C->finals()) {
986 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl());
993 [OrigAddr]() ->
Address {
return OrigAddr; });
1006 unsigned ClauseAlignment = 0;
1007 if (
auto AlignmentExpr = Clause->getAlignment()) {
1010 ClauseAlignment =
static_cast<unsigned>(AlignmentCI->getZExtValue());
1012 for (
auto E : Clause->varlists()) {
1013 unsigned Alignment = ClauseAlignment;
1014 if (Alignment == 0) {
1021 E->getType()->getPointeeType()))
1024 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
1025 "alignment is not power of 2");
1026 if (Alignment != 0) {
1040 auto I = PrivateCounters.begin();
1041 for (
auto *
E : Counters) {
1042 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
1043 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl());
1049 Addr = VarEmission.getAllocatedAddress();
1058 const Expr *Cond, llvm::BasicBlock *TrueBlock,
1059 llvm::BasicBlock *FalseBlock, uint64_t TrueCount) {
1068 for (
auto I : S.
inits()) {
1082 auto CurPrivate =
C->privates().begin();
1083 for (
auto *
E :
C->varlists()) {
1084 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
1086 cast<VarDecl>(cast<DeclRefExpr>(*CurPrivate)->getDecl());
1092 assert(IsRegistered &&
"linear var already registered as private");
1108 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.
getScalarVal());
1118 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.
getScalarVal());
1139 for (
auto F : D.
finals()) {
1140 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl());
1146 OMPPrivateScope VarScope(*
this);
1147 VarScope.addPrivate(OrigVD,
1148 [OrigAddr]() ->
Address {
return OrigAddr; });
1149 (void)VarScope.Privatize();
1169 llvm::BasicBlock *ContBlock =
nullptr;
1170 if (CGF.ConstantFoldsToSimpleInteger(S.
getPreCond(), CondConstant)) {
1174 auto *ThenBlock = CGF.createBasicBlock(
"simd.if.then");
1175 ContBlock = CGF.createBasicBlock(
"simd.if.end");
1177 CGF.getProfileCount(&S));
1178 CGF.EmitBlock(ThenBlock);
1179 CGF.incrementProfileCounter(&S);
1184 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
1185 CGF.EmitVarDecl(*IVDecl);
1186 CGF.EmitIgnoredExpr(S.
getInit());
1192 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
1197 CGF.EmitOMPSimdInit(S);
1200 CGF.EmitOMPLinearClauseInit(S);
1201 bool HasLastprivateClause;
1207 CGF.EmitOMPPrivateClause(S, LoopScope);
1208 CGF.EmitOMPReductionClauseInit(S, LoopScope);
1209 HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
1214 CGF.EmitOMPLoopBody(S,
JumpDest());
1215 CGF.EmitStopPoint(&S);
1219 if (HasLastprivateClause) {
1220 CGF.EmitOMPLastprivateClauseFinal(S);
1222 CGF.EmitOMPReductionClauseFinal(S);
1224 CGF.EmitOMPSimdFinal(S);
1227 CGF.EmitBranch(ContBlock);
1228 CGF.EmitBlock(ContBlock,
true);
1234 void CodeGenFunction::EmitOMPForOuterLoop(
1241 const bool DynamicOrOrdered = Ordered || RT.isDynamic(ScheduleKind);
1244 !RT.isStaticNonchunked(ScheduleKind, Chunk !=
nullptr)) &&
1245 "static non-chunked schedule does not need outer loop");
1301 if (DynamicOrOrdered) {
1303 RT.emitForDispatchInit(*
this, S.
getLocStart(), ScheduleKind,
1304 IVSize, IVSigned, Ordered, UBVal, Chunk);
1306 RT.emitForStaticInit(*
this, S.
getLocStart(), ScheduleKind,
1307 IVSize, IVSigned, Ordered, IL, LB, UB, ST, Chunk);
1318 if (!DynamicOrOrdered) {
1326 BoolCondVal = RT.emitForNext(*
this, S.
getLocStart(), IVSize, IVSigned,
1332 auto ExitBlock = LoopExit.getBlock();
1333 if (LoopScope.requiresCleanups())
1337 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
1338 if (ExitBlock != LoopExit.getBlock()) {
1346 if (DynamicOrOrdered)
1351 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1358 EmitOMPSimdInit(S, IsMonotonic);
1363 CGF.EmitOMPLoopBody(S, LoopExit);
1364 CGF.EmitStopPoint(&S);
1368 CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd(
1369 CGF, Loc, IVSize, IVSigned);
1374 BreakContinueStack.pop_back();
1375 if (!DynamicOrOrdered) {
1387 if (!DynamicOrOrdered)
1388 RT.emitForStaticFinish(*
this, S.
getLocEnd());
1394 auto VDecl = cast<VarDecl>(Helper->
getDecl());
1400 struct ScheduleKindModifiersTy {
1407 : Kind(Kind), M1(M1), M2(M2) {}
1411 static std::pair<
llvm::Value * , ScheduleKindModifiersTy>
1418 llvm::Value *Chunk =
nullptr;
1420 ScheduleKind =
C->getScheduleKind();
1421 M1 =
C->getFirstScheduleModifier();
1422 M2 =
C->getSecondScheduleModifier();
1423 if (
const auto *Ch =
C->getChunkSize()) {
1424 if (
auto *ImpRef = cast_or_null<DeclRefExpr>(
C->getHelperChunkSize())) {
1426 const VarDecl *ImpVar = cast<VarDecl>(ImpRef->getDecl());
1436 if (!
C->getHelperChunkSize() || !OuterRegion) {
1444 return std::make_pair(Chunk, ScheduleKindModifiersTy(ScheduleKind, M1, M2));
1450 auto IVDecl = cast<VarDecl>(IVExpr->getDecl());
1464 bool HasLastprivateClause;
1471 llvm::BasicBlock *ContBlock =
nullptr;
1498 OMPPrivateScope LoopScope(*
this);
1512 (void)LoopScope.Privatize();
1519 Chunk = ScheduleInfo.first;
1520 ScheduleKind = ScheduleInfo.second.Kind;
1530 if (RT.isStaticNonchunked(ScheduleKind,
1531 Chunk !=
nullptr) &&
1534 EmitOMPSimdInit(S,
true);
1540 RT.emitForStaticInit(*
this, S.
getLocStart(), ScheduleKind,
1541 IVSize, IVSigned, Ordered,
1554 CGF.EmitOMPLoopBody(S, LoopExit);
1555 CGF.EmitStopPoint(&S);
1562 const bool IsMonotonic = Ordered ||
1563 ScheduleKind == OMPC_SCHEDULE_static ||
1565 M1 == OMPC_SCHEDULE_MODIFIER_monotonic ||
1566 M2 == OMPC_SCHEDULE_MODIFIER_monotonic;
1569 EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered,
1575 if (HasLastprivateClause)
1580 EmitOMPSimdFinal(S);
1588 return HasLastprivateClause;
1593 bool HasLastprivates =
false;
1595 HasLastprivates = CGF.EmitOMPWorksharingLoop(S);
1608 bool HasLastprivates =
false;
1610 HasLastprivates = CGF.EmitOMPWorksharingLoop(S);
1622 llvm::Value *Init =
nullptr) {
1633 bool HasLastprivates =
false;
1635 auto &
C = CGF.CGM.getContext();
1636 auto KmpInt32Ty =
C.getIntTypeForBitwidth(32, 1);
1639 CGF.Builder.getInt32(0));
1640 auto *GlobalUBVal = CS !=
nullptr ? CGF.Builder.getInt32(CS->size() - 1)
1641 : CGF.Builder.getInt32(0);
1645 CGF.Builder.getInt32(1));
1647 CGF.Builder.getInt32(0));
1673 auto *ExitBB = CGF.createBasicBlock(
".omp.sections.exit");
1675 CGF.EmitLoadOfLValue(IV, S.getLocStart()).getScalarVal(), ExitBB,
1676 CS ==
nullptr ? 1 : CS->size());
1678 unsigned CaseNumber = 0;
1679 for (
auto *SubStmt : CS->children()) {
1680 auto CaseBB = CGF.createBasicBlock(
".omp.sections.case");
1681 CGF.EmitBlock(CaseBB);
1682 SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB);
1683 CGF.EmitStmt(SubStmt);
1684 CGF.EmitBranch(ExitBB);
1688 auto CaseBB = CGF.createBasicBlock(
".omp.sections.case");
1689 CGF.EmitBlock(CaseBB);
1690 SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB);
1692 CGF.EmitBranch(ExitBB);
1694 CGF.EmitBlock(ExitBB,
true);
1698 if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
1701 CGF.CGM.getOpenMPRuntime().emitBarrierCall(
1705 CGF.EmitOMPPrivateClause(S, LoopScope);
1706 HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
1707 CGF.EmitOMPReductionClauseInit(S, LoopScope);
1708 (void)LoopScope.Privatize();
1711 CGF.CGM.getOpenMPRuntime().emitForStaticInit(
1712 CGF, S.getLocStart(), OMPC_SCHEDULE_static, 32,
1713 true,
false, IL.getAddress(), LB.
getAddress(),
1716 auto *UBVal = CGF.EmitLoadOfScalar(UB, S.getLocStart());
1717 auto *MinUBGlobalUB = CGF.Builder.CreateSelect(
1718 CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
1719 CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
1721 CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getLocStart()), IV);
1723 CGF.EmitOMPInnerLoop(S,
false, &Cond, &Inc, BodyGen,
1726 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocStart());
1727 CGF.EmitOMPReductionClauseFinal(S);
1730 if (HasLastprivates)
1731 CGF.EmitOMPLastprivateClauseFinal(
1732 S, CGF.Builder.CreateIsNotNull(
1733 CGF.EmitLoadOfScalar(IL, S.getLocStart())));
1736 bool HasCancel =
false;
1737 if (
auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
1738 HasCancel = OSD->hasCancel();
1739 else if (
auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
1740 HasCancel = OPSD->hasCancel();
1752 return OMPD_sections;
1784 CopyprivateVars.append(
C->varlists().begin(),
C->varlists().end());
1785 DestExprs.append(
C->destination_exprs().begin(),
1786 C->destination_exprs().end());
1787 SrcExprs.append(
C->source_exprs().begin(),
C->source_exprs().end());
1788 AssignmentOps.append(
C->assignment_ops().begin(),
1789 C->assignment_ops().end());
1793 bool HasFirstprivates;
1796 HasFirstprivates = CGF.EmitOMPFirstprivateClause(S, SingleScope);
1797 CGF.EmitOMPPrivateClause(S, SingleScope);
1803 CopyprivateVars, DestExprs, SrcExprs,
1808 CopyprivateVars.empty()) {
1828 Expr *Hint =
nullptr;
1830 Hint = HintClause->getHint();
1843 CGF.EmitOMPWorksharingLoop(S);
1855 CGF.EmitOMPWorksharingLoop(S);
1866 (void)CGF.EmitSections(S);
1876 auto *
I = CS->getCapturedDecl()->param_begin();
1877 auto *PartId = std::next(
I);
1885 auto IRef =
C->varlist_begin();
1886 for (
auto *IInit :
C->private_copies()) {
1887 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
1888 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
1889 PrivateVars.push_back(*IRef);
1890 PrivateCopies.push_back(IInit);
1895 EmittedAsPrivate.clear();
1901 auto IRef =
C->varlist_begin();
1902 auto IElemInitRef =
C->inits().begin();
1903 for (
auto *IInit :
C->private_copies()) {
1904 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
1905 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
1906 FirstprivateVars.push_back(*IRef);
1907 FirstprivateCopies.push_back(IInit);
1908 FirstprivateInits.push_back(*IElemInitRef);
1910 ++IRef, ++IElemInitRef;
1917 for (
auto *IRef :
C->varlists()) {
1918 Dependences.push_back(std::make_pair(
C->getDependencyKind(), IRef));
1921 auto &&CodeGen = [PartId, &
S, &PrivateVars, &FirstprivateVars](
1924 auto *CS = cast<CapturedStmt>(S.getAssociatedStmt());
1926 if (!PrivateVars.empty() || !FirstprivateVars.empty()) {
1927 auto *CopyFn = CGF.Builder.CreateLoad(
1928 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(3)));
1929 auto *PrivatesPtr = CGF.Builder.CreateLoad(
1930 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(2)));
1935 CallArgs.push_back(PrivatesPtr);
1936 for (
auto *
E : PrivateVars) {
1937 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
1939 CGF.CreateMemTemp(CGF.getContext().getPointerType(
E->getType()));
1940 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
1941 CallArgs.push_back(PrivatePtr.getPointer());
1943 for (
auto *
E : FirstprivateVars) {
1944 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
1946 CGF.CreateMemTemp(CGF.getContext().getPointerType(
E->getType()));
1947 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
1948 CallArgs.push_back(PrivatePtr.getPointer());
1950 CGF.EmitRuntimeCall(CopyFn, CallArgs);
1951 for (
auto &&Pair : PrivatePtrs) {
1952 Address Replacement(CGF.Builder.CreateLoad(Pair.second),
1953 CGF.getContext().getDeclAlign(Pair.first));
1954 Scope.addPrivate(Pair.first, [Replacement]() {
return Replacement; });
1957 (void)
Scope.Privatize();
1961 CGF.EmitStmt(CS->getCapturedStmt());
1963 auto OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
1964 S, *
I, OMPD_task, CodeGen);
1968 llvm::PointerIntPair<llvm::Value *, 1, bool> Final;
1972 auto *Cond = Clause->getCondition();
1974 if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
1975 Final.setInt(CondConstant);
1977 Final.setPointer(EvaluateExprAsBool(Cond));
1980 Final.setInt(
false);
1982 auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
1983 const Expr *IfCond =
nullptr;
1984 for (
const auto *
C : S.getClausesOfKind<
OMPIfClause>()) {
1986 C->getNameModifier() == OMPD_task) {
1987 IfCond =
C->getCondition();
1991 CGM.getOpenMPRuntime().emitTaskCall(
1992 *
this, S.getLocStart(),
S, Tied, Final, OutlinedFn, SharedsTy,
1993 CapturedStruct, IfCond, PrivateVars, PrivateCopies, FirstprivateVars,
1994 FirstprivateCopies, FirstprivateInits, Dependences);
2022 return llvm::makeArrayRef(FlushClause->varlist_begin(),
2023 FlushClause->varlist_end());
2026 }(), S.getLocStart());
2031 llvm_unreachable(
"CodeGen for 'omp distribute' is not supported yet.");
2040 Fn->addFnAttr(llvm::Attribute::NoInline);
2053 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
2055 CGF.EmitNounwindRuntimeCall(OutlinedFn, CapturedVars);
2068 "DestType must have scalar evaluation kind.");
2069 assert(!Val.
isAggregate() &&
"Must be a scalar or complex.");
2081 "DestType must have complex evaluation kind.");
2087 DestElementType, Loc);
2089 ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType()));
2091 assert(Val.
isComplex() &&
"Must be a scalar or complex.");
2095 Val.
getComplexVal().first, SrcElementType, DestElementType, Loc);
2097 Val.
getComplexVal().second, SrcElementType, DestElementType, Loc);
2107 CGF.
EmitAtomicStore(RVal, LVal, IsSeqCst ? llvm::SequentiallyConsistent
2118 *
this, RVal, RValTy, LVal.
getType(), Loc)),
2127 llvm_unreachable(
"Must be a scalar or complex.");
2135 assert(V->
isLValue() &&
"V of 'omp atomic read' is not lvalue");
2136 assert(X->
isLValue() &&
"X of 'omp atomic read' is not lvalue");
2139 RValue Res = XLValue.isGlobalReg()
2142 IsSeqCst ? llvm::SequentiallyConsistent
2144 XLValue.isVolatile());
2158 assert(X->
isLValue() &&
"X of 'omp atomic write' is not lvalue");
2171 llvm::AtomicOrdering AO,
2172 bool IsXLHSInRHSPart) {
2185 return std::make_pair(
false,
RValue::get(
nullptr));
2187 llvm::AtomicRMWInst::BinOp RMWOp;
2190 RMWOp = llvm::AtomicRMWInst::Add;
2193 if (!IsXLHSInRHSPart)
2194 return std::make_pair(
false,
RValue::get(
nullptr));
2195 RMWOp = llvm::AtomicRMWInst::Sub;
2201 RMWOp = llvm::AtomicRMWInst::Or;
2204 RMWOp = llvm::AtomicRMWInst::Xor;
2208 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min
2209 : llvm::AtomicRMWInst::Max)
2210 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin
2211 : llvm::AtomicRMWInst::UMax);
2215 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max
2216 : llvm::AtomicRMWInst::Min)
2217 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax
2218 : llvm::AtomicRMWInst::UMin);
2221 RMWOp = llvm::AtomicRMWInst::Xchg;
2230 return std::make_pair(
false,
RValue::get(
nullptr));
2248 llvm_unreachable(
"Unsupported atomic update operation");
2251 if (
auto *IC = dyn_cast<llvm::ConstantInt>(UpdateVal)) {
2252 UpdateVal = CGF.
Builder.CreateIntCast(
2286 const Expr *UE,
bool IsXLHSInRHSPart,
2289 "Update expr in 'atomic update' must be a binary operator.");
2297 assert(X->
isLValue() &&
"X of 'omp atomic update' is not lvalue");
2300 auto AO = IsSeqCst ? llvm::SequentiallyConsistent : llvm::Monotonic;
2301 auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
2302 auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
2303 auto *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
2304 auto *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
2306 [&CGF, UE, ExprRValue, XRValExpr, ERValExpr](
RValue XRValue) ->
RValue {
2312 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
2335 llvm_unreachable(
"Must be a scalar or complex.");
2339 bool IsPostfixUpdate,
const Expr *V,
2341 const Expr *UE,
bool IsXLHSInRHSPart,
2343 assert(X->
isLValue() &&
"X of 'omp atomic capture' is not lvalue");
2344 assert(V->
isLValue() &&
"V of 'omp atomic capture' is not lvalue");
2349 auto AO = IsSeqCst ? llvm::SequentiallyConsistent : llvm::Monotonic;
2354 "Update expr in 'atomic capture' must be a binary operator.");
2362 auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
2363 auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
2364 auto *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
2365 NewVValType = XRValExpr->getType();
2366 auto *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
2367 auto &&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr,
2372 NewVVal = IsPostfixUpdate ? XRValue : Res;
2376 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
2379 if (IsPostfixUpdate) {
2381 NewVVal = Res.second;
2395 auto &&Gen = [&CGF, &NewVVal, ExprRValue](
RValue XRValue) ->
RValue {
2401 XLValue, ExprRValue,
BO_Assign,
false, AO,
2405 NewVVal = IsPostfixUpdate ? Res.second : ExprRValue;
2419 bool IsSeqCst,
bool IsPostfixUpdate,
2421 const Expr *UE,
bool IsXLHSInRHSPart,
2436 IsXLHSInRHSPart, Loc);
2440 case OMPC_num_threads:
2442 case OMPC_firstprivate:
2443 case OMPC_lastprivate:
2444 case OMPC_reduction:
2454 case OMPC_copyprivate:
2456 case OMPC_proc_bind:
2463 case OMPC_mergeable:
2468 case OMPC_num_teams:
2469 case OMPC_thread_limit:
2471 case OMPC_grainsize:
2473 case OMPC_num_tasks:
2475 llvm_unreachable(
"Clause is not allowed in 'omp atomic'.");
2484 if (
C->getClauseKind() != OMPC_seq_cst) {
2485 Kind =
C->getClauseKind();
2492 if (
const auto *EWC = dyn_cast<ExprWithCleanups>(CS)) {
2496 if (
const auto *Compound = dyn_cast<CompoundStmt>(CS)) {
2497 for (
const auto *
C : Compound->body()) {
2498 if (
const auto *EWC = dyn_cast<ExprWithCleanups>(
C)) {
2506 CGF.EmitStopPoint(CS);
2521 llvm::Function *Fn =
nullptr;
2522 llvm::Constant *FnID =
nullptr;
2525 const Expr *IfCond =
nullptr;
2528 IfCond =
C->getCondition();
2532 const Expr *Device =
nullptr;
2534 Device =
C->getDevice();
2540 bool IsOffloadEntry =
true;
2544 IsOffloadEntry =
false;
2547 IsOffloadEntry =
false;
2549 assert(
CurFuncDecl &&
"No parent declaration for target region!");
2550 StringRef ParentName;
2553 if (
auto *D = dyn_cast<CXXConstructorDecl>(
CurFuncDecl))
2555 else if (
auto *D = dyn_cast<CXXDestructorDecl>(
CurFuncDecl))
2569 llvm_unreachable(
"CodeGen for 'omp teams' is not supported yet.");
2579 const Expr *IfCond =
nullptr;
2582 C->getNameModifier() == OMPD_cancel) {
2583 IfCond =
C->getCondition();
2593 if (Kind == OMPD_parallel || Kind == OMPD_task)
2595 assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
2596 Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for);
2597 return BreakContinueStack.back().BreakBlock;
2606 *
this, OMPD_target_data,
2614 *
this, OMPD_taskloop,
2623 *
this, OMPD_taskloop_simd,
This represents '#pragma omp master' directive.
virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S)
Emit the captured statement body.
Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy, AlignmentSource *Source=nullptr)
static Address castValueFromUintptr(CodeGenFunction &CGF, QualType DstType, StringRef Name, LValue AddrLV, bool isReferenceType=false)
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)
This represents clause 'copyin' in the '#pragma omp ...' directives.
A (possibly-)qualified type.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument.
llvm::Value * getPointer() const
CodeGenTypes & getTypes()
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)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
static std::pair< llvm::Value *, ScheduleKindModifiersTy > emitScheduleClause(CodeGenFunction &CGF, const OMPLoopDirective &S, bool OuterRegion)
llvm::Module & getModule() const
void EmitOMPDistributeDirective(const OMPDistributeDirective &S)
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
void EmitOMPAggregateAssign(Address DestAddr, Address SrcAddr, QualType OriginalType, const llvm::function_ref< void(Address, Address)> &CopyGen)
Perform element by element copying of arrays with type OriginalType from SrcAddr to DestAddr using co...
void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst)
Store of global named registers are always calls to intrinsics.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
This represents '#pragma omp for simd' directive.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Address getAddress() const
This represents 'if' clause in the '#pragma omp ...' directive.
static void emitLinearClauseFinal(CodeGenFunction &CGF, const OMPLoopDirective &D)
void EmitOMPOrderedDirective(const OMPOrderedDirective &S)
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
The base class of the type hierarchy.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
Address GenerateCapturedStmtArgument(const CapturedStmt &S)
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
This represents '#pragma omp parallel for' directive.
const LangOptions & getLangOpts() const
const CGFunctionInfo & arrangeFreeFunctionDeclaration(QualType ResTy, const FunctionArgList &Args, const FunctionType::ExtInfo &Info, bool isVariadic)
void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit)
void EmitOMPCopy(QualType OriginalType, Address DestAddr, Address SrcAddr, const VarDecl *DestVD, const VarDecl *SrcVD, const Expr *Copy)
Emit proper copying of data from one variable to another.
void EmitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &S)
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)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
llvm::Function * GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S)
QualType getVariableArrayDecayedType(QualType Ty) const
Returns a vla type where known sizes are replaced with [*].
VarDecl - An instance of this class is created to represent a variable declaration or definition...
This represents clause 'private' in the '#pragma omp ...' directives.
void EmitOMPCriticalDirective(const OMPCriticalDirective &S)
llvm::Type * getElementType() const
Return the type of the values stored in this address.
This represents 'num_threads' clause in the '#pragma omp ...' directive.
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
field_iterator field_begin() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
CharUnits getNaturalTypeAlignment(QualType T, AlignmentSource *Source=nullptr, bool forPointeeType=false)
This represents implicit clause 'flush' for the '#pragma omp flush' directive.
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
This represents 'safelen' clause in the '#pragma omp ...' directive.
OpenMPDirectiveKind getDirectiveKind() const
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
void EmitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &S)
RecordDecl - Represents a struct/union/class.
One of these records is kept for each identifier that is lexed.
void EmitOMPSimdDirective(const OMPSimdDirective &S)
This represents '#pragma omp parallel' directive.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
static void emitCommonOMPParallelDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
This represents 'simd' clause in the '#pragma omp ...' directive.
void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
EmitExprAsInit - Emits the code necessary to initialize a location in memory with the given initializ...
The scope used to remap some variables as private in the OpenMP loop body (or other captured region e...
bool isReferenceType() const
This represents clause 'lastprivate' in the '#pragma omp ...' directives.
bool isAnyPointerType() const
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
LValue EmitOMPArraySectionExpr(const OMPArraySectionExpr *E, bool IsLowerBound=true)
static void emitSimdlenSafelenClause(CodeGenFunction &CGF, const OMPExecutableDirective &D, bool IsMonotonic)
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...
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.
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.
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)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
This represents clause 'copyprivate' in the '#pragma omp ...' directives.
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
static bool hasScalarEvaluationKind(QualType T)
ArrayRef< Expr * > finals()
CharUnits getAlignment() const
const TargetInfo & getTargetInfo() const
void emitOMPSimpleStore(LValue LVal, RValue RVal, QualType RValTy, SourceLocation Loc)
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
CharUnits - This is an opaque type for sizes expressed in character units.
void pop()
End the current loop.
Expr * getX()
Get 'x' part of the associated expression/statement.
void EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S)
field_range fields() const
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.
void setVectorizeWidth(unsigned W)
Set the vectorize width for the next loop pushed.
static llvm::Function * emitOutlinedOrderedFunction(CodeGenModule &CGM, const CapturedStmt *S)
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.
void EmitAggregateAssign(Address DestPtr, Address SrcPtr, QualType EltTy)
EmitAggregateCopy - Emit an aggregate assignment.
static LValue EmitOMPHelperVar(CodeGenFunction &CGF, const DeclRefExpr *Helper)
Emit a helper variable and return corresponding lvalue.
Scope - A scope is a transient data structure that is used while parsing the program.
void incrementProfileCounter(const Stmt *S)
Increment the profiler's counter for the given statement.
This represents 'final' clause in the '#pragma omp ...' directive.
void EmitStmt(const Stmt *S)
EmitStmt - Emit the code for the statement.
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.
void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn)
Assign counters to regions and configure them for PGO of a given function.
llvm::Constant * GetAddrOfGlobal(GlobalDecl GD, bool IsForDefinition=false)
void push(llvm::BasicBlock *Header)
Begin a new structured loop.
This represents clause 'reduction' in the '#pragma omp ...' directives.
bool requiresCleanups() const
Determine whether this scope requires any cleanups.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
bool hasCancel() const
Return true if current directive has inner cancel directive.
const RecordDecl * getCapturedRecordDecl() const
Retrieve the record declaration for captured variables.
An ordinary object is located at an address in memory.
This represents the body of a CapturedStmt, and serves as its DeclContext.
detail::InMemoryDirectory::const_iterator I
static void EmitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst, const Expr *X, const Expr *E, SourceLocation Loc)
static llvm::Value * convertToScalarValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, QualType DestType, SourceLocation Loc)
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type...
static CodeGenFunction::ComplexPairTy convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, QualType DestType, SourceLocation Loc)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource AlignSource=AlignmentSource::Type)
ArrayRef< Expr * > private_counters()
OpenMPDirectiveKind getCancelRegion() const
Get cancellation region for the current cancellation point.
llvm::Constant * getStaticLocalDeclAddress(const VarDecl *D)
CompoundStmt - This represents a group of statements like { stmt stmt }.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.
void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S)
This represents '#pragma omp taskgroup' directive.
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
This represents clause 'aligned' in the '#pragma omp ...' directives.
bool addPrivate(const VarDecl *LocalVD, llvm::function_ref< Address()> PrivateGen)
Registers LocalVD variable as a private and apply PrivateGen function for it to generate correspondin...
bool isPostfixUpdate() const
Return true if 'v' expression must be updated to original value of 'x', false if 'v' must be updated ...
SourceLocation getBodyRBrace() const
getBodyRBrace - Gets the right brace of the body, if a body exists.
This represents '#pragma omp distribute' directive.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
virtual StringRef getHelperName() const
Get the name of the capture helper.
static TypeEvaluationKind getEvaluationKind(QualType T)
hasAggregateLLVMType - Return true if the specified AST type will map into an aggregate LLVM type or ...
llvm::Value * getPointer() const
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
Expr - This represents one expression.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
This represents 'simdlen' clause in the '#pragma omp ...' directive.
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type, where the destination type is an LLVM scalar type.
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
void EmitOMPTeamsDirective(const OMPTeamsDirective &S)
void SetInternalFunctionAttributes(const Decl *D, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
Expr * getIterationVariable() const
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.
unsigned getContextParamPosition() const
This represents 'ordered' clause in the '#pragma omp ...' directive.
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.
void EmitOMPMasterDirective(const OMPMasterDirective &S)
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
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
void EmitOMPBarrierDirective(const OMPBarrierDirective &S)
Expr * getNextUpperBound() const
This represents '#pragma omp cancel' directive.
This represents clause 'firstprivate' in the '#pragma omp ...' directives.
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())
GlobalDecl - represents a global declaration.
This represents '#pragma omp flush' directive.
This represents '#pragma omp parallel for simd' directive.
This represents 'seq_cst' clause in the '#pragma omp atomic' directive.
This represents 'untied' clause in the '#pragma omp ...' directive.
SourceLocation getLocStart() const
Returns starting location of directive kind.
static void emitAlignedClause(CodeGenFunction &CGF, const OMPExecutableDirective &D)
The l-value was considered opaque, so the alignment was determined from a type.
void EmitAlignmentAssumption(llvm::Value *PtrValue, unsigned Alignment, llvm::Value *OffsetValue=nullptr)
void EmitOMPFlushDirective(const OMPFlushDirective &S)
static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr, QualType Type, const Expr *Init)
Emit initialization of arrays of complex types.
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
This captures a statement into a function.
ASTContext & getContext() const
This represents '#pragma omp single' directive.
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
This represents 'hint' clause in the '#pragma omp ...' directive.
void EmitOMPForDirective(const OMPForDirective &S)
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
This is a basic class for representing single OpenMP executable directive.
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource AlignSource=AlignmentSource::Type, llvm::MDNode *TBAAInfo=nullptr, QualType TBAABaseTy=QualType(), uint64_t TBAAOffset=0, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
Expr * getLowerBoundVariable() const
This represents 'schedule' clause in the '#pragma omp ...' directive.
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant, or if it does but contains a label, return false.
OpenMPDirectiveKind
OpenMP directives.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
param_iterator param_begin() const
Retrieve an iterator pointing to the first parameter decl.
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...
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
void EmitOMPSingleDirective(const OMPSingleDirective &S)
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
const LangOptions & getLangOpts() const
llvm::function_ref< void(CodeGenFunction &)> RegionCodeGenTy
This represents '#pragma omp target' directive.
const T * castAs() const
Member-template castAs<specific type>.
void EmitOMPForSimdDirective(const OMPForSimdDirective &S)
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)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
void EmitOMPSectionDirective(const OMPSectionDirective &S)
void EmitOMPSectionsDirective(const OMPSectionsDirective &S)
This represents '#pragma omp ordered' directive.
const SpecificClause * getSingleClause() const
Gets a single clause of the specified kind associated with the current directive iff there is only on...
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
void EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S)
void enterFullExpression(const ExprWithCleanups *E)
void EmitDecl(const Decl &D)
EmitDecl - Emit a declaration.
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
Expr * getPreCond() const
JumpDest getOMPCancelDestination(OpenMPDirectiveKind Kind)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
FunctionArgList - Type for representing both the decl and type of parameters to a function...
void GenerateOpenMPCapturedVars(const CapturedStmt &S, SmallVectorImpl< llvm::Value * > &CapturedVars)
CGFunctionInfo - Class to encapsulate the information about a function definition.
CharUnits getAlignment() const
Return the alignment of this pointer.
This class organizes the cross-function state that is used while generating LLVM code.
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
static const Type * getElementType(const Expr *BaseExpr)
This represents 'device' clause in the '#pragma omp ...' directive.
void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address CreateMemTemp(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignment...
bool hasCancel() const
Return true if current directive has inner cancel directive.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
void EmitOMPParallelForDirective(const OMPParallelForDirective &S)
This represents '#pragma omp section' directive.
std::vector< llvm::Triple > OMPTargetTriples
Triples of the OpenMP targets that the host code codegen should take into account in order to generat...
void EmitOMPPrivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
const Stmt * getBody() const
This represents '#pragma omp simd' directive.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::IntegerType * IntPtrTy
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
static RValue convertToType(CodeGenFunction &CGF, RValue Value, QualType SourceType, QualType ResType, SourceLocation Loc)
This represents clause 'linear' in the '#pragma omp ...' directives.
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
Expr * getEnsureUpperBound() const
detail::InMemoryDirectory::const_iterator E
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...
static void emitPrivateLoopCounters(CodeGenFunction &CGF, CodeGenFunction::OMPPrivateScope &LoopScope, ArrayRef< Expr * > Counters, ArrayRef< Expr * > PrivateCounters)
This represents '#pragma omp atomic' directive.
Expr * getCalcLastIteration() const
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
ArrayRef< Expr * > counters()
JumpDest ReturnBlock
ReturnBlock - Unified return block.
SwitchStmt - This represents a 'switch' stmt.
void EmitAutoVarCleanups(const AutoVarEmission &emission)
API for captured statement code generation.
llvm::PointerType * getType() const
Return the type of the pointer value.
Complex values, per C99 6.2.5p11.
static void emitSimpleAtomicStore(CodeGenFunction &CGF, bool IsSeqCst, LValue LVal, RValue RVal)
This file defines OpenMP AST classes for executable directives and clauses.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
ArrayRef< Expr * > inits()
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
Base for LValueReferenceType and RValueReferenceType.
StringRef getMangledName(GlobalDecl GD)
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
param_iterator param_end() const
Retrieve an iterator one past the last parameter decl.
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Expr * getNextLowerBound() const
void EmitOMPReductionClauseInit(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
Emit initial code for reduction variables.
static llvm::iterator_range< specific_clause_iterator< SpecificClause > > getClausesOfKind(ArrayRef< OMPClause * > Clauses)
This represents 'nowait' clause in the '#pragma omp ...' directive.
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block, taking care to avoid creation of branches from dummy blocks.
Privates[]
Gets the list of initial values for linear variables.
LValue EmitLValue(const Expr *E)
EmitLValue - Emit code to compute a designator that specifies the location of the expression...
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
This represents '#pragma omp taskloop simd' directive.
bool EmitOMPCopyinClause(const OMPExecutableDirective &D)
Emit code for copyin clause in D directive.
CGCapturedStmtInfo * CapturedStmtInfo
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...
This represents '#pragma omp sections' directive.
This represents '#pragma omp target data' 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.
static RValue get(llvm::Value *V)
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
Expr * getLastIteration() const
void setVectorizeEnable(bool Enable=true)
Set the next pushed loop 'vectorize.enable'.
void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S)
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
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.
SourceLocation getLocation() const
LValue - This represents an lvalue references.
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.
Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)
emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...
Expr *const * const_capture_init_iterator
Const iterator that walks over the capture initialization arguments.
Stmt * getAssociatedStmt() const
Returns statement associated with the directive.
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument.
virtual bool hasBody() const
Returns true if this Decl represents a declaration for a body of code, such as a function or method d...
void EmitOMPTaskDirective(const OMPTaskDirective &S)
A class which abstracts out some details necessary for making a call.
Expr * getStrideVariable() const
bool Privatize()
Privatizes local variables previously registered as private.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
This represents '#pragma omp taskloop' directive.