21 using namespace clang;
22 using namespace CodeGen;
29 for (
const auto *C : S.
clauses()) {
31 if (
const auto *PreInit =
32 cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {
33 for (
const auto *I : PreInit->decls()) {
34 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
58 const bool EmitPreInitStmt =
true)
62 emitPreInitStmt(CGF, S);
63 if (!CapturedRegion.hasValue())
66 "Expected associated statement for inlined directive.");
68 for (
const auto &C : CS->captures()) {
69 if (
C.capturesVariable() ||
C.capturesVariableByCopy()) {
70 auto *VD =
C.getCapturedVar();
72 "Canonical decl must be captured.");
89 class OMPParallelScope final :
public OMPLexicalScope {
99 : OMPLexicalScope(CGF, S,
llvm::
None,
100 EmitPreInitStmt(S)) {}
105 class OMPTeamsScope final :
public OMPLexicalScope {
114 : OMPLexicalScope(CGF, S,
llvm::
None,
115 EmitPreInitStmt(S)) {}
123 for (
const auto *E : S.
counters()) {
124 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
128 (void)PreCondVars.
apply(CGF);
129 if (
const auto *PreInits = cast_or_null<DeclStmt>(S.
getPreInits())) {
130 for (
const auto *I : PreInits->decls())
139 emitPreInitStmt(CGF, S);
150 cast<BlockDecl>(CGF.
CurCodeDecl)->capturesVariable(VD));
156 InlinedShareds(CGF) {
157 for (
const auto *C : S.
clauses()) {
159 if (
const auto *PreInit =
160 cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {
161 for (
const auto *I : PreInit->decls()) {
162 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
171 }
else if (
const auto *UDP = dyn_cast<OMPUseDevicePtrClause>(C)) {
172 for (
const Expr *E : UDP->varlists()) {
173 const Decl *D = cast<DeclRefExpr>(E)->getDecl();
174 if (
const auto *OED = dyn_cast<OMPCapturedExprDecl>(D))
181 if (
const auto *TG = dyn_cast<OMPTaskgroupDirective>(&S)) {
182 if (
const Expr *E = TG->getReductionRef())
183 CGF.
EmitVarDecl(*cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()));
187 for (
auto &C : CS->captures()) {
188 if (
C.capturesVariable() ||
C.capturesVariableByCopy()) {
189 auto *VD =
C.getCapturedVar();
191 "Canonical decl must be captured.");
193 isCapturedVar(CGF, VD) ||
216 if (
const auto *OrigDRE = dyn_cast<DeclRefExpr>(E)) {
217 if (
const auto *OrigVD = dyn_cast<VarDecl>(OrigDRE->getDecl())) {
218 OrigVD = OrigVD->getCanonicalDecl();
220 LambdaCaptureFields.lookup(OrigVD) ||
221 (CapturedStmtInfo && CapturedStmtInfo->lookup(OrigVD)) ||
222 (CurCodeDecl && isa<BlockDecl>(CurCodeDecl));
223 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD), IsCaptured,
224 OrigDRE->getType(),
VK_LValue, OrigDRE->getExprLoc());
225 return EmitLValue(&DRE);
228 return EmitLValue(E);
235 if (SizeInChars.isZero()) {
240 Size = Size ? Builder.CreateNUWMul(Size, VlaSize.
NumElts)
244 if (SizeInChars.isZero())
245 return llvm::ConstantInt::get(SizeTy, 0);
246 return Builder.CreateNUWMul(Size, CGM.getSize(SizeInChars));
248 return CGM.getSize(SizeInChars);
258 I != E; ++I, ++CurField, ++CurCap) {
259 if (CurField->hasCapturedVLAType()) {
262 CapturedVars.push_back(Val);
263 }
else if (CurCap->capturesThis()) {
264 CapturedVars.push_back(CXXThisValue);
265 }
else if (CurCap->capturesVariableByCopy()) {
266 llvm::Value *CV = EmitLoadOfScalar(EmitLValue(*I), CurCap->getLocation());
270 if (!CurField->getType()->isAnyPointerType()) {
272 Address DstAddr = CreateMemTemp(
274 Twine(CurCap->getCapturedVar()->getName(),
".casted"));
281 MakeNaturalAlignAddrLValue(SrcAddrVal, CurField->getType());
287 CV = EmitLoadOfScalar(DstLV, CurCap->getLocation());
289 CapturedVars.push_back(CV);
291 assert(CurCap->capturesVariable() &&
"Expected capture by reference.");
292 CapturedVars.push_back(EmitLValue(*I).getAddress().getPointer());
319 if (
const auto *VLA = dyn_cast<VariableArrayType>(A))
321 if (!A->isVariablyModifiedType())
329 struct FunctionOptions {
334 const bool UIntPtrCastRequired =
true;
337 const bool RegisterCastedArgsOnly =
false;
339 const StringRef FunctionName;
340 explicit FunctionOptions(
const CapturedStmt *S,
bool UIntPtrCastRequired,
341 bool RegisterCastedArgsOnly,
342 StringRef FunctionName)
343 : S(S), UIntPtrCastRequired(UIntPtrCastRequired),
344 RegisterCastedArgsOnly(UIntPtrCastRequired && RegisterCastedArgsOnly),
345 FunctionName(FunctionName) {}
351 llvm::MapVector<
const Decl *, std::pair<const VarDecl *, Address>>
353 llvm::DenseMap<
const Decl *, std::pair<const Expr *, llvm::Value *>>
355 llvm::Value *&CXXThisValue,
const FunctionOptions &FO) {
357 const RecordDecl *RD = FO.S->getCapturedRecordDecl();
358 assert(CD->
hasBody() &&
"missing CapturedDecl body");
360 CXXThisValue =
nullptr;
370 auto I = FO.S->captures().begin();
372 if (!FO.UIntPtrCastRequired) {
391 if (FO.UIntPtrCastRequired &&
393 I->capturesVariableArrayType()))
396 if (I->capturesVariable() || I->capturesVariableByCopy()) {
397 CapVar = I->getCapturedVar();
399 }
else if (I->capturesThis()) {
402 assert(I->capturesVariableArrayType());
408 if (DebugFunctionDecl && (CapVar || I->capturesThis())) {
410 Ctx, DebugFunctionDecl,
411 CapVar ? CapVar->
getBeginLoc() : FD->getBeginLoc(),
412 CapVar ? CapVar->
getLocation() : FD->getLocation(), II, ArgType,
418 Args.emplace_back(Arg);
420 TargetArgs.emplace_back(
421 FO.UIntPtrCastRequired
443 F->setDoesNotThrow();
444 F->setDoesNotRecurse();
450 I = FO.S->captures().begin();
454 if (!FO.UIntPtrCastRequired && Args[Cnt] != TargetArgs[Cnt]) {
462 if (I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) {
463 const VarDecl *CurVD = I->getCapturedVar();
464 if (!FO.RegisterCastedArgsOnly)
465 LocalAddrs.insert({Args[Cnt], {CurVD, LocalAddr}});
473 if (FD->hasCapturedVLAType()) {
474 if (FO.UIntPtrCastRequired) {
477 Args[Cnt]->getName(), ArgLVal),
482 VLASizes.try_emplace(Args[Cnt], VAT->
getSizeExpr(), ExprArg);
483 }
else if (I->capturesVariable()) {
484 const VarDecl *Var = I->getCapturedVar();
494 if (!FO.RegisterCastedArgsOnly) {
499 }
else if (I->capturesVariableByCopy()) {
500 assert(!FD->getType()->isAnyPointerType() &&
501 "Not expecting a captured pointer.");
502 const VarDecl *Var = I->getCapturedVar();
503 LocalAddrs.insert({Args[Cnt],
504 {Var, FO.UIntPtrCastRequired
506 CGF, I->getLocation(), FD->getType(),
507 Args[Cnt]->getName(), ArgLVal)
511 assert(I->capturesThis());
513 LocalAddrs.insert({Args[Cnt], {
nullptr, ArgLVal.
getAddress()}});
526 "CapturedStmtInfo should be set when generating the captured function");
529 bool NeedWrapperFunction =
533 llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>> LocalAddrs;
534 llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> VLASizes;
536 llvm::raw_svector_ostream Out(Buffer);
537 Out << CapturedStmtInfo->getHelperName();
538 if (NeedWrapperFunction)
540 FunctionOptions FO(&S, !NeedWrapperFunction,
false,
543 VLASizes, CXXThisValue, FO);
545 for (
const auto &LocalAddrPair : LocalAddrs) {
546 if (LocalAddrPair.second.first) {
547 LocalScope.
addPrivate(LocalAddrPair.second.first, [&LocalAddrPair]() {
548 return LocalAddrPair.second.second;
553 for (
const auto &VLASizePair : VLASizes)
554 VLASizeMap[VLASizePair.second.first] = VLASizePair.second.second;
556 CapturedStmtInfo->EmitBody(*
this, CD->
getBody());
559 if (!NeedWrapperFunction)
562 FunctionOptions WrapperFO(&S,
true,
564 CapturedStmtInfo->getHelperName());
566 WrapperCGF.CapturedStmtInfo = CapturedStmtInfo;
570 llvm::Function *WrapperF =
572 WrapperCGF.CXXThisValue, WrapperFO);
574 for (
const auto *Arg : Args) {
576 auto I = LocalAddrs.find(Arg);
577 if (I != LocalAddrs.end()) {
578 LValue LV = WrapperCGF.MakeAddrLValue(
580 I->second.first ? I->second.first->getType() : Arg->getType(),
582 CallArg = WrapperCGF.EmitLoadOfScalar(LV, S.
getBeginLoc());
584 auto EI = VLASizes.find(Arg);
585 if (EI != VLASizes.end()) {
586 CallArg = EI->second.second;
588 LValue LV = WrapperCGF.MakeAddrLValue(WrapperCGF.GetAddrOfLocalVar(Arg),
591 CallArg = WrapperCGF.EmitLoadOfScalar(LV, S.
getBeginLoc());
594 CallArgs.emplace_back(WrapperCGF.EmitFromMemory(CallArg, Arg->getType()));
596 CGM.getOpenMPRuntime().emitOutlinedFunctionCall(WrapperCGF, S.
getBeginLoc(),
598 WrapperCGF.FinishFunction();
613 llvm::Value *NumElements = emitArrayLength(ArrayTy, ElementTy, DestAddr);
614 SrcAddr = Builder.CreateElementBitCast(SrcAddr, DestAddr.
getElementType());
619 llvm::Value *DestEnd = Builder.CreateGEP(DestBegin, NumElements);
621 llvm::BasicBlock *BodyBB = createBasicBlock(
"omp.arraycpy.body");
622 llvm::BasicBlock *DoneBB = createBasicBlock(
"omp.arraycpy.done");
624 Builder.CreateICmpEQ(DestBegin, DestEnd,
"omp.arraycpy.isempty");
625 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
628 llvm::BasicBlock *EntryBB = Builder.GetInsertBlock();
631 CharUnits ElementSize = getContext().getTypeSizeInChars(ElementTy);
633 llvm::PHINode *SrcElementPHI =
634 Builder.CreatePHI(SrcBegin->getType(), 2,
"omp.arraycpy.srcElementPast");
635 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
640 llvm::PHINode *DestElementPHI =
641 Builder.CreatePHI(DestBegin->getType(), 2,
"omp.arraycpy.destElementPast");
642 DestElementPHI->addIncoming(DestBegin, EntryBB);
648 CopyGen(DestElementCurrent, SrcElementCurrent);
651 llvm::Value *DestElementNext = Builder.CreateConstGEP1_32(
652 DestElementPHI, 1,
"omp.arraycpy.dest.element");
653 llvm::Value *SrcElementNext = Builder.CreateConstGEP1_32(
654 SrcElementPHI, 1,
"omp.arraycpy.src.element");
657 Builder.CreateICmpEQ(DestElementNext, DestEnd,
"omp.arraycpy.done");
658 Builder.CreateCondBr(Done, DoneBB, BodyBB);
659 DestElementPHI->addIncoming(DestElementNext, Builder.GetInsertBlock());
660 SrcElementPHI->addIncoming(SrcElementNext, Builder.GetInsertBlock());
663 EmitBlock(DoneBB,
true);
671 if (BO && BO->getOpcode() == BO_Assign) {
673 LValue Dest = MakeAddrLValue(DestAddr, OriginalType);
674 LValue Src = MakeAddrLValue(SrcAddr, OriginalType);
675 EmitAggregateAssign(Dest, Src, OriginalType);
679 EmitOMPAggregateAssign(
680 DestAddr, SrcAddr, OriginalType,
681 [
this, Copy, SrcVD, DestVD](
Address DestElement,
Address SrcElement) {
686 Remap.
addPrivate(DestVD, [DestElement]() {
return DestElement; });
687 Remap.
addPrivate(SrcVD, [SrcElement]() {
return SrcElement; });
689 EmitIgnoredExpr(Copy);
695 Remap.
addPrivate(SrcVD, [SrcAddr]() {
return SrcAddr; });
696 Remap.
addPrivate(DestVD, [DestAddr]() {
return DestAddr; });
699 EmitIgnoredExpr(Copy);
705 if (!HaveInsertPoint())
707 bool DeviceConstTarget =
708 getLangOpts().OpenMPIsDevice &&
710 bool FirstprivateIsLastprivate =
false;
713 for (
const auto *D : C->varlists())
722 bool MustEmitFirstprivateCopy =
723 CaptureRegions.size() == 1 && CaptureRegions.back() ==
OMPD_unknown;
725 auto IRef = C->varlist_begin();
726 auto InitsRef = C->inits().begin();
727 for (
const Expr *IInit : C->private_copies()) {
728 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
729 bool ThisFirstprivateIsLastprivate =
730 Lastprivates.count(OrigVD->getCanonicalDecl()) > 0;
731 const FieldDecl *FD = CapturedStmtInfo->lookup(OrigVD);
732 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
733 if (!MustEmitFirstprivateCopy && !ThisFirstprivateIsLastprivate && FD &&
735 (!VD || !VD->
hasAttr<OMPAllocateDeclAttr>())) {
736 EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl());
743 if (DeviceConstTarget && OrigVD->getType().isConstant(getContext()) &&
745 (!VD || !VD->
hasAttr<OMPAllocateDeclAttr>())) {
746 (void)CGM.getOpenMPRuntime().registerTargetFirstprivateCopy(*
this,
752 FirstprivateIsLastprivate =
753 FirstprivateIsLastprivate || ThisFirstprivateIsLastprivate;
754 if (EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()).second) {
756 cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
758 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
774 assert(!CE &&
"Expected non-constant firstprivate.");
775 OriginalLVal = EmitLValue(&DRE);
778 OriginalLVal = EmitLValue(&DRE);
786 OrigVD, [
this, VD, Type, OriginalLVal, VDInit]() {
789 if (!isa<CXXConstructExpr>(Init) ||
790 isTrivialInitializer(Init)) {
794 EmitAggregateAssign(Dest, OriginalLVal, Type);
796 EmitOMPAggregateAssign(
799 [
this, VDInit, Init](
Address DestElement,
805 setAddrOfLocalVar(VDInit, SrcElement);
806 EmitAnyExprToMem(Init, DestElement,
809 LocalDeclMap.erase(VDInit);
812 EmitAutoVarCleanups(Emission);
816 Address OriginalAddr = OriginalLVal.getAddress();
818 OrigVD, [
this, VDInit, OriginalAddr, VD]() {
822 setAddrOfLocalVar(VDInit, OriginalAddr);
824 LocalDeclMap.erase(VDInit);
825 return GetAddrOfLocalVar(VD);
828 assert(IsRegistered &&
829 "firstprivate var already registered as private");
837 return FirstprivateIsLastprivate && !EmittedAsFirstprivate.empty();
843 if (!HaveInsertPoint())
847 auto IRef = C->varlist_begin();
848 for (
const Expr *IInit : C->private_copies()) {
849 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
850 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
851 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
852 bool IsRegistered = PrivateScope.
addPrivate(OrigVD, [
this, VD]() {
855 return GetAddrOfLocalVar(VD);
857 assert(IsRegistered &&
"private var already registered as private");
867 if (!HaveInsertPoint())
874 llvm::BasicBlock *CopyBegin =
nullptr, *CopyEnd =
nullptr;
876 auto IRef = C->varlist_begin();
877 auto ISrcRef = C->source_exprs().begin();
878 auto IDestRef = C->destination_exprs().begin();
879 for (
const Expr *AssignOp : C->assignment_ops()) {
880 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
887 if (getLangOpts().OpenMPUseTLS &&
888 getContext().getTargetInfo().isTLSSupported()) {
889 assert(CapturedStmtInfo->lookup(VD) &&
890 "Copyin threadprivates should have been captured!");
891 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(VD),
true,
892 (*IRef)->getType(),
VK_LValue, (*IRef)->getExprLoc());
893 MasterAddr = EmitLValue(&DRE).getAddress();
894 LocalDeclMap.erase(VD);
898 : CGM.GetAddrOfGlobal(VD),
899 getContext().getDeclAlign(VD));
902 Address PrivateAddr = EmitLValue(*IRef).getAddress();
903 if (CopiedVars.size() == 1) {
906 CopyBegin = createBasicBlock(
"copyin.not.master");
907 CopyEnd = createBasicBlock(
"copyin.not.master.end");
908 Builder.CreateCondBr(
909 Builder.CreateICmpNE(
910 Builder.CreatePtrToInt(MasterAddr.
getPointer(), CGM.IntPtrTy),
911 Builder.CreatePtrToInt(PrivateAddr.getPointer(),
914 EmitBlock(CopyBegin);
917 cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
919 cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
920 EmitOMPCopy(Type, PrivateAddr, MasterAddr, DestVD, SrcVD, AssignOp);
929 EmitBlock(CopyEnd,
true);
937 if (!HaveInsertPoint())
939 bool HasAtLeastOneLastprivate =
false;
942 const auto *LoopDirective = cast<OMPLoopDirective>(&D);
943 for (
const Expr *C : LoopDirective->counters()) {
950 HasAtLeastOneLastprivate =
true;
952 !getLangOpts().OpenMPSimd)
954 auto IRef = C->varlist_begin();
955 auto IDestRef = C->destination_exprs().begin();
956 for (
const Expr *IInit : C->private_copies()) {
959 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
962 if (AlreadyEmittedVars.insert(OrigVD->getCanonicalDecl()).second) {
964 cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
965 PrivateScope.
addPrivate(DestVD, [
this, OrigVD, IRef]() {
966 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
968 CapturedStmtInfo->lookup(OrigVD) !=
nullptr,
969 (*IRef)->getType(),
VK_LValue, (*IRef)->getExprLoc());
970 return EmitLValue(&DRE).getAddress();
975 if (IInit && !SIMDLCVs.count(OrigVD->getCanonicalDecl())) {
976 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
977 bool IsRegistered = PrivateScope.
addPrivate(OrigVD, [
this, VD]() {
980 return GetAddrOfLocalVar(VD);
982 assert(IsRegistered &&
983 "lastprivate var already registered as private");
991 return HasAtLeastOneLastprivate;
997 if (!HaveInsertPoint())
1005 llvm::BasicBlock *ThenBB =
nullptr;
1006 llvm::BasicBlock *DoneBB =
nullptr;
1007 if (IsLastIterCond) {
1008 ThenBB = createBasicBlock(
".omp.lastprivate.then");
1009 DoneBB = createBasicBlock(
".omp.lastprivate.done");
1010 Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB);
1014 llvm::DenseMap<const VarDecl *, const Expr *> LoopCountersAndUpdates;
1015 if (
const auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) {
1016 auto IC = LoopDirective->counters().begin();
1017 for (
const Expr *F : LoopDirective->finals()) {
1021 AlreadyEmittedVars.insert(D);
1023 LoopCountersAndUpdates[D] = F;
1028 auto IRef = C->varlist_begin();
1029 auto ISrcRef = C->source_exprs().begin();
1030 auto IDestRef = C->destination_exprs().begin();
1031 for (
const Expr *AssignOp : C->assignment_ops()) {
1032 const auto *PrivateVD =
1033 cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
1035 const auto *CanonicalVD = PrivateVD->getCanonicalDecl();
1036 if (AlreadyEmittedVars.insert(CanonicalVD).second) {
1040 if (
const Expr *FinalExpr = LoopCountersAndUpdates.lookup(CanonicalVD))
1041 EmitIgnoredExpr(FinalExpr);
1043 cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
1044 const auto *DestVD =
1045 cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
1047 Address OriginalAddr = GetAddrOfLocalVar(DestVD);
1049 Address PrivateAddr = GetAddrOfLocalVar(PrivateVD);
1050 if (
const auto *RefTy = PrivateVD->getType()->getAs<
ReferenceType>())
1052 Address(Builder.CreateLoad(PrivateAddr),
1053 getNaturalTypeAlignment(RefTy->getPointeeType()));
1054 EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp);
1060 if (
const Expr *PostUpdate = C->getPostUpdateExpr())
1061 EmitIgnoredExpr(PostUpdate);
1064 EmitBlock(DoneBB,
true);
1070 if (!HaveInsertPoint())
1078 auto IPriv = C->privates().begin();
1079 auto IRed = C->reduction_ops().begin();
1080 auto ILHS = C->lhs_exprs().begin();
1081 auto IRHS = C->rhs_exprs().begin();
1082 for (
const Expr *Ref : C->varlists()) {
1083 Shareds.emplace_back(Ref);
1084 Privates.emplace_back(*IPriv);
1085 ReductionOps.emplace_back(*IRed);
1086 LHSs.emplace_back(*ILHS);
1087 RHSs.emplace_back(*IRHS);
1088 std::advance(IPriv, 1);
1089 std::advance(IRed, 1);
1090 std::advance(ILHS, 1);
1091 std::advance(IRHS, 1);
1096 auto ILHS = LHSs.begin();
1097 auto IRHS = RHSs.begin();
1098 auto IPriv = Privates.begin();
1099 for (
const Expr *IRef : Shareds) {
1100 const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl());
1102 RedCG.emitSharedLValue(*
this, Count);
1111 EmitAutoVarCleanups(Emission);
1115 RedCG.
getBaseDecl(Count), [BaseAddr]() {
return BaseAddr; });
1116 assert(IsRegistered &&
"private var already registered as private");
1120 const auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
1121 const auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
1123 bool isaOMPArraySectionExpr = isa<OMPArraySectionExpr>(IRef);
1124 if (isaOMPArraySectionExpr && Type->isVariablyModifiedType()) {
1127 PrivateScope.
addPrivate(LHSVD, [&RedCG, Count]() {
1131 RHSVD, [
this, PrivateVD]() {
return GetAddrOfLocalVar(PrivateVD); });
1132 }
else if ((isaOMPArraySectionExpr && Type->isScalarType()) ||
1133 isa<ArraySubscriptExpr>(IRef)) {
1136 PrivateScope.
addPrivate(LHSVD, [&RedCG, Count]() {
1139 PrivateScope.
addPrivate(RHSVD, [
this, PrivateVD, RHSVD]() {
1140 return Builder.CreateElementBitCast(GetAddrOfLocalVar(PrivateVD),
1141 ConvertTypeForMem(RHSVD->getType()),
1145 QualType Type = PrivateVD->getType();
1146 bool IsArray = getContext().getAsArrayType(Type) !=
nullptr;
1151 OriginalAddr = Builder.CreateElementBitCast(
1152 OriginalAddr, ConvertTypeForMem(LHSVD->getType()),
"lhs.begin");
1154 PrivateScope.
addPrivate(LHSVD, [OriginalAddr]() {
return OriginalAddr; });
1156 RHSVD, [
this, PrivateVD, RHSVD, IsArray]() {
1158 ? Builder.CreateElementBitCast(
1159 GetAddrOfLocalVar(PrivateVD),
1160 ConvertTypeForMem(RHSVD->getType()),
"rhs.begin")
1161 : GetAddrOfLocalVar(PrivateVD);
1173 if (!HaveInsertPoint())
1179 bool HasAtLeastOneReduction =
false;
1181 HasAtLeastOneReduction =
true;
1182 Privates.append(C->privates().begin(), C->privates().end());
1183 LHSExprs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
1184 RHSExprs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
1185 ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
1187 if (HasAtLeastOneReduction) {
1190 ReductionKind == OMPD_simd;
1191 bool SimpleReduction = ReductionKind == OMPD_simd;
1194 CGM.getOpenMPRuntime().emitReduction(
1196 {WithNowait, SimpleReduction, ReductionKind});
1205 llvm::BasicBlock *DoneBB =
nullptr;
1207 if (
const Expr *PostUpdate = C->getPostUpdateExpr()) {
1214 CGF.
Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1232 CodeGenBoundParametersTy;
1238 const CodeGenBoundParametersTy &CodeGenBoundParameters) {
1240 llvm::Function *OutlinedFn =
1249 CGF, NumThreads, NumThreadsClause->getBeginLoc());
1254 CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getBeginLoc());
1256 const Expr *IfCond =
nullptr;
1259 C->getNameModifier() == OMPD_parallel) {
1260 IfCond = C->getCondition();
1265 OMPParallelScope
Scope(CGF, S);
1271 CodeGenBoundParameters(CGF, S, CapturedVars);
1274 CapturedVars, IfCond);
1313 EmitIgnoredExpr(UE);
1319 for (
const Expr *UE : C->updates())
1320 EmitIgnoredExpr(UE);
1325 JumpDest Continue = getJumpDestInCurrentScope(
"omp.body.continue");
1326 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1331 BreakContinueStack.pop_back();
1335 const Stmt &S,
bool RequiresCleanup,
const Expr *LoopCond,
1336 const Expr *IncExpr,
1339 auto LoopExit = getJumpDestInCurrentScope(
"omp.inner.for.end");
1342 auto CondBlock = createBasicBlock(
"omp.inner.for.cond");
1343 EmitBlock(CondBlock);
1345 LoopStack.push(CondBlock, SourceLocToDebugLoc(R.
getBegin()),
1346 SourceLocToDebugLoc(R.
getEnd()));
1350 llvm::BasicBlock *ExitBlock =
LoopExit.getBlock();
1351 if (RequiresCleanup)
1352 ExitBlock = createBasicBlock(
"omp.inner.for.cond.cleanup");
1354 llvm::BasicBlock *LoopBody = createBasicBlock(
"omp.inner.for.body");
1357 EmitBranchOnBoolExpr(LoopCond, LoopBody, ExitBlock, getProfileCount(&S));
1358 if (ExitBlock !=
LoopExit.getBlock()) {
1359 EmitBlock(ExitBlock);
1360 EmitBranchThroughCleanup(
LoopExit);
1363 EmitBlock(LoopBody);
1364 incrementProfileCounter(&S);
1367 JumpDest Continue = getJumpDestInCurrentScope(
"omp.inner.for.inc");
1368 BreakContinueStack.push_back(BreakContinue(
LoopExit, Continue));
1374 EmitIgnoredExpr(IncExpr);
1376 BreakContinueStack.pop_back();
1377 EmitBranch(CondBlock);
1384 if (!HaveInsertPoint())
1387 bool HasLinears =
false;
1389 for (
const Expr *Init : C->inits()) {
1391 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl());
1392 if (
const auto *Ref =
1395 const auto *OrigVD = cast<VarDecl>(Ref->getDecl());
1396 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
1397 CapturedStmtInfo->lookup(OrigVD) !=
nullptr,
1403 EmitAutoVarCleanups(Emission);
1410 if (
const auto *CS = cast_or_null<BinaryOperator>(C->getCalcStep()))
1411 if (
const auto *SaveRef = cast<DeclRefExpr>(CS->getLHS())) {
1412 EmitVarDecl(*cast<VarDecl>(SaveRef->getDecl()));
1414 EmitIgnoredExpr(CS);
1423 if (!HaveInsertPoint())
1425 llvm::BasicBlock *DoneBB =
nullptr;
1428 auto IC = C->varlist_begin();
1429 for (
const Expr *F : C->finals()) {
1434 llvm::BasicBlock *ThenBB = createBasicBlock(
".omp.linear.pu");
1435 DoneBB = createBasicBlock(
".omp.linear.pu.done");
1436 Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1440 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl());
1441 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
1442 CapturedStmtInfo->lookup(OrigVD) !=
nullptr,
1443 (*IC)->getType(),
VK_LValue, (*IC)->getExprLoc());
1444 Address OrigAddr = EmitLValue(&DRE).getAddress();
1446 VarScope.
addPrivate(OrigVD, [OrigAddr]() {
return OrigAddr; });
1451 if (
const Expr *PostUpdate = C->getPostUpdateExpr())
1452 EmitIgnoredExpr(PostUpdate);
1455 EmitBlock(DoneBB,
true);
1463 unsigned ClauseAlignment = 0;
1464 if (
const Expr *AlignmentExpr = Clause->getAlignment()) {
1467 ClauseAlignment =
static_cast<unsigned>(AlignmentCI->getZExtValue());
1469 for (
const Expr *E : Clause->varlists()) {
1470 unsigned Alignment = ClauseAlignment;
1471 if (Alignment == 0) {
1478 E->getType()->getPointeeType()))
1481 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
1482 "alignment is not power of 2");
1483 if (Alignment != 0) {
1494 if (!HaveInsertPoint())
1498 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
1499 const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl());
1502 EmitAutoVarCleanups(VarEmission);
1503 LocalDeclMap.erase(PrivateVD);
1504 (void)LoopScope.
addPrivate(VD, [&VarEmission]() {
1505 return VarEmission.getAllocatedAddress();
1507 if (LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD) ||
1509 (void)LoopScope.
addPrivate(PrivateVD, [
this, VD, E]() {
1510 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(VD),
1511 LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD),
1512 E->getType(), VK_LValue, E->getExprLoc());
1513 return EmitLValue(&DRE).getAddress();
1516 (void)LoopScope.
addPrivate(PrivateVD, [&VarEmission]() {
1517 return VarEmission.getAllocatedAddress();
1524 if (!C->getNumForLoops())
1527 E = C->getLoopNumIterations().size();
1529 const auto *DRE = cast<DeclRefExpr>(C->getLoopCounter(I));
1530 const auto *VD = cast<VarDecl>(DRE->getDecl());
1533 if (DRE->refersToEnclosingVariableOrCapture()) {
1534 (void)LoopScope.
addPrivate(VD, [
this, DRE, VD]() {
1535 return CreateMemTemp(DRE->getType(), VD->getName());
1543 const Expr *Cond, llvm::BasicBlock *TrueBlock,
1544 llvm::BasicBlock *FalseBlock, uint64_t TrueCount) {
1562 if (!HaveInsertPoint())
1566 const auto *LoopDirective = cast<OMPLoopDirective>(&D);
1567 for (
const Expr *C : LoopDirective->counters()) {
1573 auto CurPrivate = C->privates().begin();
1574 for (
const Expr *E : C->varlists()) {
1575 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
1576 const auto *PrivateVD =
1577 cast<VarDecl>(cast<DeclRefExpr>(*CurPrivate)->getDecl());
1579 bool IsRegistered = PrivateScope.
addPrivate(VD, [
this, PrivateVD]() {
1581 EmitVarDecl(*PrivateVD);
1582 return GetAddrOfLocalVar(PrivateVD);
1584 assert(IsRegistered &&
"linear var already registered as private");
1588 EmitVarDecl(*PrivateVD);
1603 auto *Val = cast<llvm::ConstantInt>(Len.
getScalarVal());
1613 auto *Val = cast<llvm::ConstantInt>(Len.
getScalarVal());
1625 LoopStack.setParallel(!IsMonotonic);
1626 LoopStack.setVectorizeEnable();
1633 if (!HaveInsertPoint())
1635 llvm::BasicBlock *DoneBB =
nullptr;
1639 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl());
1640 const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>((*IPC))->getDecl());
1642 if (LocalDeclMap.count(OrigVD) || CapturedStmtInfo->lookup(OrigVD) ||
1643 OrigVD->hasGlobalStorage() || CED) {
1648 llvm::BasicBlock *ThenBB = createBasicBlock(
".omp.final.then");
1649 DoneBB = createBasicBlock(
".omp.final.done");
1650 Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1656 OrigAddr = EmitLValue(CED->getInit()->IgnoreImpCasts()).getAddress();
1658 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(PrivateVD),
1660 (*IPC)->getType(),
VK_LValue, (*IPC)->getExprLoc());
1661 OrigAddr = EmitLValue(&DRE).getAddress();
1664 VarScope.
addPrivate(OrigVD, [OrigAddr]() {
return OrigAddr; });
1672 EmitBlock(DoneBB,
true);
1685 auto VDecl = cast<VarDecl>(Helper->
getDecl());
1694 "Expected simd directive");
1695 OMPLoopScope PreInitScope(CGF, S);
1712 llvm::BasicBlock *ContBlock =
nullptr;
1727 const auto *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
1735 CGF.
EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
1763 if (HasLastprivateClause)
1782 CGM.getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_simd, CodeGen);
1785 void CodeGenFunction::EmitOMPOuterLoop(
1788 const CodeGenFunction::OMPLoopArguments &LoopArgs,
1794 const unsigned IVSize = getContext().getTypeSize(IVExpr->
getType());
1800 llvm::BasicBlock *CondBlock = createBasicBlock(
"omp.dispatch.cond");
1801 EmitBlock(CondBlock);
1803 LoopStack.push(CondBlock, SourceLocToDebugLoc(R.
getBegin()),
1804 SourceLocToDebugLoc(R.
getEnd()));
1807 if (!DynamicOrOrdered) {
1811 EmitIgnoredExpr(LoopArgs.EUB);
1813 EmitIgnoredExpr(LoopArgs.Init);
1815 BoolCondVal = EvaluateExprAsBool(LoopArgs.Cond);
1818 RT.emitForNext(*
this, S.
getBeginLoc(), IVSize, IVSigned, LoopArgs.IL,
1819 LoopArgs.LB, LoopArgs.UB, LoopArgs.ST);
1824 llvm::BasicBlock *ExitBlock = LoopExit.
getBlock();
1826 ExitBlock = createBasicBlock(
"omp.dispatch.cleanup");
1828 llvm::BasicBlock *LoopBody = createBasicBlock(
"omp.dispatch.body");
1829 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
1830 if (ExitBlock != LoopExit.
getBlock()) {
1831 EmitBlock(ExitBlock);
1832 EmitBranchThroughCleanup(LoopExit);
1834 EmitBlock(LoopBody);
1838 if (DynamicOrOrdered)
1839 EmitIgnoredExpr(LoopArgs.Init);
1842 JumpDest Continue = getJumpDestInCurrentScope(
"omp.dispatch.inc");
1843 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1848 LoopStack.setParallel(!IsMonotonic);
1850 EmitOMPSimdInit(S, IsMonotonic);
1862 CodeGenLoop(CGF, S, LoopExit);
1865 CodeGenOrdered(CGF, Loc, IVSize, IVSigned);
1869 BreakContinueStack.pop_back();
1870 if (!DynamicOrOrdered) {
1872 EmitIgnoredExpr(LoopArgs.NextLB);
1873 EmitIgnoredExpr(LoopArgs.NextUB);
1876 EmitBranch(CondBlock);
1879 EmitBlock(LoopExit.getBlock());
1883 if (!DynamicOrOrdered)
1890 void CodeGenFunction::EmitOMPForOuterLoop(
1893 const OMPLoopArguments &LoopArgs,
1898 const bool DynamicOrOrdered =
1899 Ordered || RT.isDynamic(ScheduleKind.
Schedule);
1902 !RT.isStaticNonchunked(ScheduleKind.
Schedule,
1903 LoopArgs.Chunk !=
nullptr)) &&
1904 "static non-chunked schedule does not need outer loop");
1957 const unsigned IVSize = getContext().getTypeSize(IVExpr->
getType());
1960 if (DynamicOrOrdered) {
1961 const std::pair<llvm::Value *, llvm::Value *> DispatchBounds =
1962 CGDispatchBounds(*
this, S, LoopArgs.LB, LoopArgs.UB);
1965 CGOpenMPRuntime::DispatchRTInput DipatchRTInputValues = {LBVal, UBVal,
1967 RT.emitForDispatchInit(*
this, S.
getBeginLoc(), ScheduleKind, IVSize,
1968 IVSigned, Ordered, DipatchRTInputValues);
1970 CGOpenMPRuntime::StaticRTInput StaticInit(
1971 IVSize, IVSigned, Ordered, LoopArgs.IL, LoopArgs.LB, LoopArgs.UB,
1972 LoopArgs.ST, LoopArgs.Chunk);
1974 ScheduleKind, StaticInit);
1978 const unsigned IVSize,
1979 const bool IVSigned) {
1986 OMPLoopArguments OuterLoopArgs(LoopArgs.LB, LoopArgs.UB, LoopArgs.ST,
1987 LoopArgs.IL, LoopArgs.Chunk, LoopArgs.EUB);
1988 OuterLoopArgs.IncExpr = S.
getInc();
1989 OuterLoopArgs.Init = S.
getInit();
1990 OuterLoopArgs.Cond = S.
getCond();
1993 EmitOMPOuterLoop(DynamicOrOrdered, IsMonotonic, S, LoopScope, OuterLoopArgs,
1998 const unsigned IVSize,
const bool IVSigned) {}
2000 void CodeGenFunction::EmitOMPDistributeOuterLoop(
2002 OMPPrivateScope &LoopScope,
const OMPLoopArguments &LoopArgs,
2003 const CodeGenLoopTy &CodeGenLoopContent) {
2013 const unsigned IVSize = getContext().getTypeSize(IVExpr->
getType());
2016 CGOpenMPRuntime::StaticRTInput StaticInit(
2017 IVSize, IVSigned,
false, LoopArgs.IL, LoopArgs.LB,
2018 LoopArgs.UB, LoopArgs.ST, LoopArgs.Chunk);
2019 RT.emitDistributeStaticInit(*
this, S.
getBeginLoc(), ScheduleKind, StaticInit);
2032 OMPLoopArguments OuterLoopArgs;
2033 OuterLoopArgs.LB = LoopArgs.LB;
2034 OuterLoopArgs.UB = LoopArgs.UB;
2035 OuterLoopArgs.ST = LoopArgs.ST;
2036 OuterLoopArgs.IL = LoopArgs.IL;
2037 OuterLoopArgs.Chunk = LoopArgs.Chunk;
2041 OuterLoopArgs.IncExpr = IncExpr;
2055 EmitOMPOuterLoop(
false,
false, S,
2056 LoopScope, OuterLoopArgs, CodeGenLoopContent,
2060 static std::pair<LValue, LValue>
2103 static std::pair<llvm::Value *, llvm::Value *>
2113 QualType IteratorTy = IVExpr->getType();
2118 return {LBVal, UBVal};
2124 const auto &Dir = cast<OMPLoopDirective>(S);
2126 CGF.
EmitLValue(cast<DeclRefExpr>(Dir.getCombinedLowerBoundVariable()));
2129 CapturedVars.push_back(LBCast);
2131 CGF.
EmitLValue(cast<DeclRefExpr>(Dir.getCombinedUpperBoundVariable()));
2135 CapturedVars.push_back(UBCast);
2145 bool HasCancel =
false;
2147 if (
const auto *D = dyn_cast<OMPTeamsDistributeParallelForDirective>(&S))
2148 HasCancel = D->hasCancel();
2149 else if (
const auto *D = dyn_cast<OMPDistributeParallelForDirective>(&S))
2150 HasCancel = D->hasCancel();
2151 else if (
const auto *D =
2152 dyn_cast<OMPTargetTeamsDistributeParallelForDirective>(&S))
2153 HasCancel = D->hasCancel();
2165 CGInlinedWorksharingLoop,
2175 OMPLexicalScope
Scope(*
this, S, OMPD_parallel);
2176 CGM.getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_distribute, CodeGen);
2185 OMPLexicalScope
Scope(*
this, S, OMPD_parallel);
2186 CGM.getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_distribute, CodeGen);
2195 CGM.getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_simd, CodeGen);
2205 llvm::Constant *Addr;
2208 S, ParentName, Fn, Addr,
true, CodeGen);
2209 assert(Fn && Addr &&
"Target device function emission failed.");
2221 struct ScheduleKindModifiersTy {
2228 :
Kind(Kind), M1(M1), M2(M2) {}
2238 const auto *IVDecl = cast<VarDecl>(IVExpr->getDecl());
2239 EmitVarDecl(*IVDecl);
2245 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
2252 bool HasLastprivateClause;
2255 OMPLoopScope PreInitScope(*
this, S);
2260 llvm::BasicBlock *ContBlock =
nullptr;
2261 if (ConstantFoldsToSimpleInteger(S.
getPreCond(), CondConstant)) {
2265 llvm::BasicBlock *ThenBlock = createBasicBlock(
"omp.precond.then");
2266 ContBlock = createBasicBlock(
"omp.precond.end");
2268 getProfileCount(&S));
2269 EmitBlock(ThenBlock);
2270 incrementProfileCounter(&S);
2274 bool Ordered =
false;
2276 if (OrderedClause->getNumForLoops())
2277 RT.emitDoacrossInit(*
this, S, OrderedClause->getLoopNumIterations());
2284 bool HasLinears = EmitOMPLinearClauseInit(S);
2287 std::pair<LValue, LValue> Bounds = CodeGenLoopBounds(*
this, S);
2288 LValue LB = Bounds.first;
2289 LValue UB = Bounds.second;
2298 if (EmitOMPFirstprivateClause(S, LoopScope) || HasLinears) {
2302 CGM.getOpenMPRuntime().emitBarrierCall(
2306 EmitOMPPrivateClause(S, LoopScope);
2307 HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
2308 EmitOMPReductionClauseInit(S, LoopScope);
2309 EmitOMPPrivateLoopCounters(S, LoopScope);
2310 EmitOMPLinearClause(S, LoopScope);
2313 CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(*
this, S);
2316 const Expr *ChunkExpr =
nullptr;
2319 ScheduleKind.
Schedule = C->getScheduleKind();
2320 ScheduleKind.
M1 = C->getFirstScheduleModifier();
2321 ScheduleKind.
M2 = C->getSecondScheduleModifier();
2322 ChunkExpr = C->getChunkSize();
2325 CGM.getOpenMPRuntime().getDefaultScheduleAndChunk(
2326 *
this, S, ScheduleKind.
Schedule, ChunkExpr);
2328 bool HasChunkSizeOne =
false;
2331 Chunk = EmitScalarExpr(ChunkExpr);
2332 Chunk = EmitScalarConversion(Chunk, ChunkExpr->
getType(),
2337 llvm::APSInt EvaluatedChunk = Result.Val.getInt();
2338 HasChunkSizeOne = (EvaluatedChunk.getLimitedValue() == 1);
2341 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
2342 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
2347 bool StaticChunkedOne = RT.isStaticChunked(ScheduleKind.
Schedule,
2348 Chunk !=
nullptr) && HasChunkSizeOne &&
2350 if ((RT.isStaticNonchunked(ScheduleKind.
Schedule,
2351 Chunk !=
nullptr) ||
2352 StaticChunkedOne) &&
2355 EmitOMPSimdInit(S,
true);
2361 CGOpenMPRuntime::StaticRTInput StaticInit(
2364 StaticChunkedOne ? Chunk :
nullptr);
2366 ScheduleKind, StaticInit);
2368 getJumpDestInCurrentScope(createBasicBlock(
"omp.loop.exit"));
2370 if (!StaticChunkedOne)
2403 const bool IsMonotonic =
2404 Ordered || ScheduleKind.
Schedule == OMPC_SCHEDULE_static ||
2406 ScheduleKind.
M1 == OMPC_SCHEDULE_MODIFIER_monotonic ||
2407 ScheduleKind.
M2 == OMPC_SCHEDULE_MODIFIER_monotonic;
2413 EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered,
2414 LoopArguments, CGDispatchBounds);
2418 return CGF.
Builder.CreateIsNotNull(
2422 EmitOMPReductionClauseFinal(
2424 ? OMPD_parallel_for_simd
2429 return CGF.
Builder.CreateIsNotNull(
2433 if (HasLastprivateClause)
2434 EmitOMPLastprivateClauseFinal(
2436 Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.
getBeginLoc())));
2439 return CGF.
Builder.CreateIsNotNull(
2445 EmitBranch(ContBlock);
2446 EmitBlock(ContBlock,
true);
2449 return HasLastprivateClause;
2455 static std::pair<LValue, LValue>
2457 const auto &LS = cast<OMPLoopDirective>(S);
2469 static std::pair<llvm::Value *, llvm::Value *>
2472 const auto &LS = cast<OMPLoopDirective>(S);
2473 const Expr *IVExpr = LS.getIterationVariable();
2477 return {LBVal, UBVal};
2481 bool HasLastprivates =
false;
2491 CGM.getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_for, CodeGen,
2497 CGM.getOpenMPRuntime().emitBarrierCall(*
this, S.
getBeginLoc(), OMPD_for);
2501 bool HasLastprivates =
false;
2510 CGM.getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_simd, CodeGen);
2515 CGM.getOpenMPRuntime().emitBarrierCall(*
this, S.
getBeginLoc(), OMPD_for);
2530 bool HasLastprivates =
false;
2531 auto &&CodeGen = [&S, CapturedStmt, CS,
2538 CGF.Builder.getInt32(0));
2539 llvm::ConstantInt *GlobalUBVal = CS !=
nullptr 2540 ? CGF.Builder.getInt32(CS->size() - 1)
2541 : CGF.Builder.getInt32(0);
2545 CGF.Builder.getInt32(1));
2547 CGF.Builder.getInt32(0));
2572 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(
".omp.sections.exit");
2574 CGF.Builder.CreateSwitch(CGF.EmitLoadOfScalar(IV, S.
getBeginLoc()),
2575 ExitBB, CS ==
nullptr ? 1 : CS->size());
2577 unsigned CaseNumber = 0;
2579 auto CaseBB = CGF.createBasicBlock(
".omp.sections.case");
2580 CGF.EmitBlock(CaseBB);
2581 SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB);
2582 CGF.EmitStmt(SubStmt);
2583 CGF.EmitBranch(ExitBB);
2587 llvm::BasicBlock *CaseBB = CGF.createBasicBlock(
".omp.sections.case");
2588 CGF.EmitBlock(CaseBB);
2589 SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB);
2590 CGF.EmitStmt(CapturedStmt);
2591 CGF.EmitBranch(ExitBB);
2593 CGF.EmitBlock(ExitBB,
true);
2597 if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
2601 CGF.CGM.getOpenMPRuntime().emitBarrierCall(
2605 CGF.EmitOMPPrivateClause(S, LoopScope);
2606 HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
2607 CGF.EmitOMPReductionClauseInit(S, LoopScope);
2610 CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
2614 ScheduleKind.
Schedule = OMPC_SCHEDULE_static;
2615 CGOpenMPRuntime::StaticRTInput StaticInit(
2616 32,
true,
false, IL.getAddress(),
2618 CGF.CGM.getOpenMPRuntime().emitForStaticInit(
2619 CGF, S.
getBeginLoc(), S.getDirectiveKind(), ScheduleKind, StaticInit);
2622 llvm::Value *MinUBGlobalUB = CGF.Builder.CreateSelect(
2623 CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
2624 CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
2626 CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.
getBeginLoc()), IV);
2628 CGF.EmitOMPInnerLoop(S,
false, &Cond, &Inc, BodyGen,
2632 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.
getEndLoc(),
2633 S.getDirectiveKind());
2635 CGF.OMPCancelStack.emitExit(CGF, S.getDirectiveKind(), CodeGen);
2636 CGF.EmitOMPReductionClauseFinal(S, OMPD_parallel);
2639 return CGF.
Builder.CreateIsNotNull(
2644 if (HasLastprivates)
2651 bool HasCancel =
false;
2652 if (
auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
2653 HasCancel = OSD->hasCancel();
2654 else if (
auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
2655 HasCancel = OPSD->hasCancel();
2657 CGM.getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_sections, CodeGen,
2665 CGM.getOpenMPRuntime().emitBarrierCall(*
this, S.
getBeginLoc(),
2677 CGM.getOpenMPRuntime().emitBarrierCall(*
this, S.
getBeginLoc(),
2687 CGM.getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_section, CodeGen,
2701 CopyprivateVars.append(C->varlists().begin(), C->varlists().end());
2702 DestExprs.append(C->destination_exprs().begin(),
2703 C->destination_exprs().end());
2704 SrcExprs.append(C->source_exprs().begin(), C->source_exprs().end());
2705 AssignmentOps.append(C->assignment_ops().begin(),
2706 C->assignment_ops().end());
2719 CGM.getOpenMPRuntime().emitSingleRegion(*
this, CodeGen, S.
getBeginLoc(),
2720 CopyprivateVars, DestExprs,
2721 SrcExprs, AssignmentOps);
2726 CGM.getOpenMPRuntime().emitBarrierCall(
2738 CGM.getOpenMPRuntime().emitMasterRegion(*
this, CodeGen, S.
getBeginLoc());
2746 const Expr *Hint =
nullptr;
2748 Hint = HintClause->getHint();
2750 CGM.getOpenMPRuntime().emitCriticalRegion(*
this,
2788 CGF.EmitSections(S);
2801 auto PartId = std::next(I);
2802 auto TaskT = std::next(I, 4);
2807 const Expr *Cond = Clause->getCondition();
2809 if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
2810 Data.
Final.setInt(CondConstant);
2812 Data.
Final.setPointer(EvaluateExprAsBool(Cond));
2815 Data.
Final.setInt(
false);
2819 const Expr *Prio = Clause->getPriority();
2821 Data.
Priority.setPointer(EmitScalarConversion(
2822 EmitScalarExpr(Prio), Prio->
getType(),
2823 getContext().getIntTypeForBitwidth(32, 1),
2831 auto IRef = C->varlist_begin();
2832 for (
const Expr *IInit : C->private_copies()) {
2833 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
2834 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
2841 EmittedAsPrivate.clear();
2844 auto IRef = C->varlist_begin();
2845 auto IElemInitRef = C->inits().begin();
2846 for (
const Expr *IInit : C->private_copies()) {
2847 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
2848 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
2858 llvm::DenseMap<const VarDecl *, const DeclRefExpr *> LastprivateDstsOrigs;
2860 auto IRef = C->varlist_begin();
2861 auto ID = C->destination_exprs().begin();
2862 for (
const Expr *IInit : C->private_copies()) {
2863 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
2864 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
2868 LastprivateDstsOrigs.insert(
2869 {cast<VarDecl>(cast<DeclRefExpr>(*ID)->getDecl()),
2870 cast<DeclRefExpr>(*IRef)});
2878 auto IPriv = C->privates().begin();
2879 auto IRed = C->reduction_ops().begin();
2880 auto ILHS = C->lhs_exprs().begin();
2881 auto IRHS = C->rhs_exprs().begin();
2882 for (
const Expr *Ref : C->varlists()) {
2886 LHSs.emplace_back(*ILHS);
2887 RHSs.emplace_back(*IRHS);
2888 std::advance(IPriv, 1);
2889 std::advance(IRed, 1);
2890 std::advance(ILHS, 1);
2891 std::advance(IRHS, 1);
2894 Data.
Reductions = CGM.getOpenMPRuntime().emitTaskReductionInit(
2898 for (
const Expr *IRef : C->varlists())
2899 Data.
Dependences.emplace_back(C->getDependencyKind(), IRef);
2900 auto &&CodeGen = [&Data, &S, CS, &BodyGen, &LastprivateDstsOrigs,
2907 llvm::FunctionType *CopyFnTy = llvm::FunctionType::get(
2908 CGF.Builder.getVoidTy(), {CGF.Builder.getInt8PtrTy()},
true);
2909 enum { PrivatesParam = 2, CopyFnParam = 3 };
2911 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));
2912 llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(
2913 CS->getCapturedDecl()->getParam(PrivatesParam)));
2917 CallArgs.push_back(PrivatesPtr);
2919 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
2920 Address PrivatePtr = CGF.CreateMemTemp(
2921 CGF.getContext().getPointerType(E->
getType()),
".priv.ptr.addr");
2922 PrivatePtrs.emplace_back(VD, PrivatePtr);
2923 CallArgs.push_back(PrivatePtr.getPointer());
2926 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
2928 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->
getType()),
2929 ".firstpriv.ptr.addr");
2930 PrivatePtrs.emplace_back(VD, PrivatePtr);
2931 CallArgs.push_back(PrivatePtr.getPointer());
2934 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
2936 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->
getType()),
2937 ".lastpriv.ptr.addr");
2938 PrivatePtrs.emplace_back(VD, PrivatePtr);
2939 CallArgs.push_back(PrivatePtr.getPointer());
2941 CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
2942 CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);
2943 for (
const auto &Pair : LastprivateDstsOrigs) {
2944 const auto *OrigVD = cast<VarDecl>(Pair.second->getDecl());
2947 CGF.CapturedStmtInfo->lookup(OrigVD) !=
nullptr,
2949 Pair.second->getExprLoc());
2950 Scope.
addPrivate(Pair.first, [&CGF, &DRE]() {
2951 return CGF.EmitLValue(&DRE).getAddress();
2954 for (
const auto &Pair : PrivatePtrs) {
2955 Address Replacement(CGF.Builder.CreateLoad(Pair.second),
2956 CGF.getContext().getDeclAlign(Pair.first));
2957 Scope.
addPrivate(Pair.first, [Replacement]() { return Replacement; });
2961 OMPLexicalScope LexScope(CGF, S, CapturedRegion);
2964 llvm::Value *ReductionsPtr = CGF.Builder.CreateLoad(
2965 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(9)));
2966 for (
unsigned Cnt = 0, E = Data.
ReductionVars.size(); Cnt < E; ++Cnt) {
2967 RedCG.emitSharedLValue(CGF, Cnt);
2972 CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(),
2974 Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem(
2977 Address(CGF.EmitScalarConversion(
2978 Replacement.
getPointer(), CGF.getContext().VoidPtrTy,
2979 CGF.getContext().getPointerType(
2985 [Replacement]() {
return Replacement; });
2995 auto IPriv = C->privates().begin();
2996 auto IRed = C->reduction_ops().begin();
2997 auto ITD = C->taskgroup_descriptors().begin();
2998 for (
const Expr *Ref : C->varlists()) {
2999 InRedVars.emplace_back(Ref);
3000 InRedPrivs.emplace_back(*IPriv);
3001 InRedOps.emplace_back(*IRed);
3002 TaskgroupDescriptors.emplace_back(*ITD);
3003 std::advance(IPriv, 1);
3004 std::advance(IRed, 1);
3005 std::advance(ITD, 1);
3011 if (!InRedVars.empty()) {
3013 for (
unsigned Cnt = 0, E = InRedVars.size(); Cnt < E; ++Cnt) {
3014 RedCG.emitSharedLValue(CGF, Cnt);
3021 CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(),
3024 CGF.EmitLoadOfScalar(CGF.EmitLValue(TaskgroupDescriptors[Cnt]),
3025 TaskgroupDescriptors[Cnt]->getExprLoc());
3026 Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem(
3029 CGF.EmitScalarConversion(
3030 Replacement.
getPointer(), CGF.getContext().VoidPtrTy,
3031 CGF.getContext().getPointerType(InRedPrivs[Cnt]->getType()),
3032 InRedPrivs[Cnt]->getExprLoc()),
3036 [Replacement]() {
return Replacement; });
3044 llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
3045 S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, Data.
Tied,
3047 OMPLexicalScope
Scope(*
this, S);
3048 TaskGen(*
this, OutlinedFn, Data);
3086 Address CapturedStruct = GenerateCapturedStmtArgument(*CS);
3089 auto PartId = std::next(I);
3090 auto TaskT = std::next(I, 4);
3093 Data.
Final.setInt(
false);
3096 auto IRef = C->varlist_begin();
3097 auto IElemInitRef = C->inits().begin();
3098 for (
auto *IInit : C->private_copies()) {
3112 getContext(), getContext().getTranslationUnitDecl(), 0);
3114 QualType BaseAndPointersType = getContext().getConstantArrayType(
3118 getContext(), Data, BaseAndPointersType, CD, S.
getBeginLoc());
3120 getContext(), Data, BaseAndPointersType, CD, S.
getBeginLoc());
3121 QualType SizesType = getContext().getConstantArrayType(
3122 getContext().getIntTypeForBitwidth(64, 1),
3132 [&InputInfo]() {
return InputInfo.
SizesArray; });
3137 for (
const Expr *IRef : C->varlists())
3138 Data.
Dependences.emplace_back(C->getDependencyKind(), IRef);
3139 auto &&CodeGen = [&Data, &S, CS, &BodyGen, BPVD, PVD, SVD,
3144 llvm::FunctionType *CopyFnTy = llvm::FunctionType::get(
3145 CGF.Builder.getVoidTy(), {CGF.Builder.getInt8PtrTy()},
true);
3146 enum { PrivatesParam = 2, CopyFnParam = 3 };
3148 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));
3149 llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(
3150 CS->getCapturedDecl()->getParam(PrivatesParam)));
3154 CallArgs.push_back(PrivatesPtr);
3156 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
3158 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->
getType()),
3159 ".firstpriv.ptr.addr");
3160 PrivatePtrs.emplace_back(VD, PrivatePtr);
3161 CallArgs.push_back(PrivatePtr.getPointer());
3163 CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
3164 CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);
3165 for (
const auto &Pair : PrivatePtrs) {
3166 Address Replacement(CGF.Builder.CreateLoad(Pair.second),
3167 CGF.getContext().getDeclAlign(Pair.first));
3168 Scope.
addPrivate(Pair.first, [Replacement]() { return Replacement; });
3175 CGF.GetAddrOfLocalVar(BPVD), 0);
3177 CGF.GetAddrOfLocalVar(PVD), 0);
3178 InputInfo.
SizesArray = CGF.Builder.CreateConstArrayGEP(
3179 CGF.GetAddrOfLocalVar(SVD), 0);
3183 OMPLexicalScope LexScope(CGF, S, OMPD_task,
false);
3186 llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
3187 S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen,
true,
3189 llvm::APInt TrueOrFalse(32, S.hasClausesOfKind<
OMPNowaitClause>() ? 1 : 0);
3191 getContext().getIntTypeForBitwidth(32, 0),
3194 CGM.getOpenMPRuntime().emitTaskCall(*
this, S.getBeginLoc(), S, OutlinedFn,
3195 SharedsTy, CapturedStruct, &IfCond, Data);
3201 Address CapturedStruct = GenerateCapturedStmtArgument(*CS);
3203 const Expr *IfCond =
nullptr;
3206 C->getNameModifier() == OMPD_task) {
3207 IfCond = C->getCondition();
3218 auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
3221 CGF.CGM.getOpenMPRuntime().emitTaskCall(CGF, S.
getBeginLoc(), S, OutlinedFn,
3222 SharedsTy, CapturedStruct, IfCond,
3225 EmitOMPTaskBasedDirective(S, OMPD_task, BodyGen, TaskGen, Data);
3230 CGM.getOpenMPRuntime().emitTaskyieldCall(*
this, S.
getBeginLoc());
3234 CGM.getOpenMPRuntime().emitBarrierCall(*
this, S.
getBeginLoc(), OMPD_barrier);
3238 CGM.getOpenMPRuntime().emitTaskwaitCall(*
this, S.
getBeginLoc());
3250 auto IPriv = C->privates().begin();
3251 auto IRed = C->reduction_ops().begin();
3252 auto ILHS = C->lhs_exprs().begin();
3253 auto IRHS = C->rhs_exprs().begin();
3254 for (
const Expr *Ref : C->varlists()) {
3258 LHSs.emplace_back(*ILHS);
3259 RHSs.emplace_back(*IRHS);
3260 std::advance(IPriv, 1);
3261 std::advance(IRed, 1);
3262 std::advance(ILHS, 1);
3263 std::advance(IRHS, 1);
3269 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
3277 CGM.getOpenMPRuntime().emitTaskgroupRegion(*
this, CodeGen, S.
getBeginLoc());
3281 CGM.getOpenMPRuntime().emitFlush(
3285 return llvm::makeArrayRef(FlushClause->varlist_begin(),
3286 FlushClause->varlist_end());
3297 const auto *IVDecl = cast<VarDecl>(IVExpr->getDecl());
3298 EmitVarDecl(*IVDecl);
3304 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
3311 bool HasLastprivateClause =
false;
3314 OMPLoopScope PreInitScope(*
this, S);
3319 llvm::BasicBlock *ContBlock =
nullptr;
3320 if (ConstantFoldsToSimpleInteger(S.
getPreCond(), CondConstant)) {
3324 llvm::BasicBlock *ThenBlock = createBasicBlock(
"omp.precond.then");
3325 ContBlock = createBasicBlock(
"omp.precond.end");
3327 getProfileCount(&S));
3328 EmitBlock(ThenBlock);
3329 incrementProfileCounter(&S);
3338 *
this, cast<DeclRefExpr>(
3343 *
this, cast<DeclRefExpr>(
3353 if (EmitOMPFirstprivateClause(S, LoopScope)) {
3357 CGM.getOpenMPRuntime().emitBarrierCall(
3361 EmitOMPPrivateClause(S, LoopScope);
3365 EmitOMPReductionClauseInit(S, LoopScope);
3366 HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
3367 EmitOMPPrivateLoopCounters(S, LoopScope);
3370 CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(*
this, S);
3376 ScheduleKind = C->getDistScheduleKind();
3377 if (
const Expr *Ch = C->getChunkSize()) {
3378 Chunk = EmitScalarExpr(Ch);
3379 Chunk = EmitScalarConversion(Chunk, Ch->getType(),
3385 CGM.getOpenMPRuntime().getDefaultDistScheduleAndChunk(
3386 *
this, S, ScheduleKind, Chunk);
3388 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
3389 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
3399 bool StaticChunked = RT.isStaticChunked(
3400 ScheduleKind, Chunk !=
nullptr) &&
3402 if (RT.isStaticNonchunked(ScheduleKind,
3403 Chunk !=
nullptr) ||
3406 EmitOMPSimdInit(S,
true);
3407 CGOpenMPRuntime::StaticRTInput StaticInit(
3409 LB.
getAddress(), UB.getAddress(), ST.getAddress(),
3410 StaticChunked ? Chunk :
nullptr);
3411 RT.emitDistributeStaticInit(*
this, S.
getBeginLoc(), ScheduleKind,
3414 getJumpDestInCurrentScope(createBasicBlock(
"omp.loop.exit"));
3458 CodeGenLoop(CGF, S, LoopExit);
3461 if (StaticChunked) {
3468 EmitBlock(LoopExit.getBlock());
3470 RT.emitForStaticFinish(*
this, S.getBeginLoc(), S.getDirectiveKind());
3474 const OMPLoopArguments LoopArguments = {
3477 EmitOMPDistributeOuterLoop(ScheduleKind, S, LoopScope, LoopArguments,
3482 return CGF.
Builder.CreateIsNotNull(
3489 EmitOMPReductionClauseFinal(S, OMPD_simd);
3493 return CGF.
Builder.CreateIsNotNull(
3498 if (HasLastprivateClause) {
3499 EmitOMPLastprivateClauseFinal(
3501 Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.
getBeginLoc())));
3507 EmitBranch(ContBlock);
3508 EmitBlock(ContBlock,
true);
3519 CGM.getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_distribute, CodeGen);
3528 Fn->setDoesNotRecurse();
3535 "No associated statement must be in ordered depend construct.");
3537 CGM.getOpenMPRuntime().emitDoacrossOrdered(*
this, DC);
3546 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
3548 CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, S.
getBeginLoc(),
3549 OutlinedFn, CapturedVars);
3556 CGM.getOpenMPRuntime().emitOrderedRegion(*
this, CodeGen, S.
getBeginLoc(), !C);
3563 "DestType must have scalar evaluation kind.");
3564 assert(!Val.
isAggregate() &&
"Must be a scalar or complex.");
3575 "DestType must have complex evaluation kind.");
3584 ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType()));
3586 assert(Val.
isComplex() &&
"Must be a scalar or complex.");
3591 Val.
getComplexVal().first, SrcElementType, DestElementType, Loc);
3593 Val.
getComplexVal().second, SrcElementType, DestElementType, Loc);
3604 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3605 : llvm::AtomicOrdering::Monotonic,
3612 switch (getEvaluationKind(LVal.
getType())) {
3615 *
this, RVal, RValTy, LVal.
getType(), Loc)),
3624 llvm_unreachable(
"Must be a scalar or complex.");
3632 assert(V->
isLValue() &&
"V of 'omp atomic read' is not lvalue");
3633 assert(X->
isLValue() &&
"X of 'omp atomic read' is not lvalue");
3636 RValue Res = XLValue.isGlobalReg()
3640 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3641 : llvm::AtomicOrdering::Monotonic,
3642 XLValue.isVolatile());
3656 assert(X->
isLValue() &&
"X of 'omp atomic write' is not lvalue");
3669 llvm::AtomicOrdering AO,
3670 bool IsXLHSInRHSPart) {
3675 if (BO == BO_Comma || !Update.
isScalar() ||
3683 return std::make_pair(
false,
RValue::get(
nullptr));
3685 llvm::AtomicRMWInst::BinOp RMWOp;
3688 RMWOp = llvm::AtomicRMWInst::Add;
3691 if (!IsXLHSInRHSPart)
3692 return std::make_pair(
false,
RValue::get(
nullptr));
3693 RMWOp = llvm::AtomicRMWInst::Sub;
3699 RMWOp = llvm::AtomicRMWInst::Or;
3702 RMWOp = llvm::AtomicRMWInst::Xor;
3706 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min
3707 : llvm::AtomicRMWInst::Max)
3708 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin
3709 : llvm::AtomicRMWInst::UMax);
3713 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max
3714 : llvm::AtomicRMWInst::Min)
3715 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax
3716 : llvm::AtomicRMWInst::UMin);
3719 RMWOp = llvm::AtomicRMWInst::Xchg;
3728 return std::make_pair(
false,
RValue::get(
nullptr));
3747 llvm_unreachable(
"Unsupported atomic update operation");
3750 if (
auto *IC = dyn_cast<llvm::ConstantInt>(UpdateVal)) {
3751 UpdateVal = CGF.
Builder.CreateIntCast(
3775 EmitStoreThroughLValue(CommonGen(EmitLoadOfLValue(X, Loc)), X);
3786 const Expr *UE,
bool IsXLHSInRHSPart,
3789 "Update expr in 'atomic update' must be a binary operator.");
3797 assert(X->
isLValue() &&
"X of 'omp atomic update' is not lvalue");
3800 llvm::AtomicOrdering AO = IsSeqCst
3801 ? llvm::AtomicOrdering::SequentiallyConsistent
3802 : llvm::AtomicOrdering::Monotonic;
3803 const auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
3804 const auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
3807 auto &&Gen = [&CGF, UE, ExprRValue, XRValExpr, ERValExpr](
RValue XRValue) {
3813 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
3836 llvm_unreachable(
"Must be a scalar or complex.");
3840 bool IsPostfixUpdate,
const Expr *
V,
3842 const Expr *UE,
bool IsXLHSInRHSPart,
3844 assert(X->
isLValue() &&
"X of 'omp atomic capture' is not lvalue");
3845 assert(V->
isLValue() &&
"V of 'omp atomic capture' is not lvalue");
3850 llvm::AtomicOrdering AO = IsSeqCst
3851 ? llvm::AtomicOrdering::SequentiallyConsistent
3852 : llvm::AtomicOrdering::Monotonic;
3857 "Update expr in 'atomic capture' must be a binary operator.");
3865 const auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
3866 const auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
3868 NewVValType = XRValExpr->getType();
3870 auto &&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr,
3871 IsPostfixUpdate](
RValue XRValue) {
3875 NewVVal = IsPostfixUpdate ? XRValue : Res;
3879 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
3882 if (IsPostfixUpdate) {
3884 NewVVal = Res.second;
3898 auto &&Gen = [&NewVVal, ExprRValue](
RValue XRValue) {
3904 XLValue, ExprRValue, BO_Assign,
false, AO,
3908 NewVVal = IsPostfixUpdate ? Res.second : ExprRValue;
3922 bool IsSeqCst,
bool IsPostfixUpdate,
3924 const Expr *UE,
bool IsXLHSInRHSPart,
3939 IsXLHSInRHSPart, Loc);
3943 case OMPC_num_threads:
3945 case OMPC_firstprivate:
3946 case OMPC_lastprivate:
3947 case OMPC_reduction:
3948 case OMPC_task_reduction:
3949 case OMPC_in_reduction:
3952 case OMPC_allocator:
3961 case OMPC_copyprivate:
3963 case OMPC_proc_bind:
3970 case OMPC_mergeable:
3975 case OMPC_num_teams:
3976 case OMPC_thread_limit:
3978 case OMPC_grainsize:
3980 case OMPC_num_tasks:
3982 case OMPC_dist_schedule:
3983 case OMPC_defaultmap:
3987 case OMPC_use_device_ptr:
3988 case OMPC_is_device_ptr:
3989 case OMPC_unified_address:
3990 case OMPC_unified_shared_memory:
3991 case OMPC_reverse_offload:
3992 case OMPC_dynamic_allocators:
3993 case OMPC_atomic_default_mem_order:
3994 llvm_unreachable(
"Clause is not allowed in 'omp atomic'.");
4003 if (C->getClauseKind() != OMPC_seq_cst) {
4004 Kind = C->getClauseKind();
4010 if (
const auto *FE = dyn_cast<FullExpr>(CS))
4011 enterFullExpression(FE);
4013 if (
const auto *Compound = dyn_cast<CompoundStmt>(CS)) {
4014 for (
const Stmt *C : Compound->body()) {
4015 if (
const auto *FE = dyn_cast<FullExpr>(C))
4016 enterFullExpression(FE);
4022 CGF.EmitStopPoint(CS);
4028 CGM.getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_atomic, CodeGen);
4039 OMPLexicalScope
Scope(CGF, S, OMPD_target);
4047 llvm::Function *Fn =
nullptr;
4048 llvm::Constant *FnID =
nullptr;
4050 const Expr *IfCond =
nullptr;
4054 C->getNameModifier() == OMPD_target) {
4055 IfCond = C->getCondition();
4061 const Expr *Device =
nullptr;
4063 Device = C->getDevice();
4068 bool IsOffloadEntry =
true;
4072 IsOffloadEntry =
false;
4075 IsOffloadEntry =
false;
4077 assert(CGF.
CurFuncDecl &&
"No parent declaration for target region!");
4078 StringRef ParentName;
4081 if (
const auto *D = dyn_cast<CXXConstructorDecl>(CGF.
CurFuncDecl))
4083 else if (
const auto *D = dyn_cast<CXXDestructorDecl>(CGF.
CurFuncDecl))
4091 IsOffloadEntry, CodeGen);
4092 OMPLexicalScope
Scope(CGF, S, OMPD_task);
4094 OMPLoopScope(CGF, D);
4097 NumIterations = CGF.
Builder.CreateIntCast(NumIterations, CGF.
Int64Ty,
4099 return NumIterations;
4121 StringRef ParentName,
4127 llvm::Constant *Addr;
4130 S, ParentName, Fn, Addr,
true, CodeGen);
4131 assert(Fn && Addr &&
"Target device function emission failed.");
4146 llvm::Function *OutlinedFn =
4153 const Expr *NumTeams = NT ? NT->getNumTeams() :
nullptr;
4154 const Expr *ThreadLimit = TL ? TL->getThreadLimit() :
nullptr;
4160 OMPTeamsScope
Scope(CGF, S);
4192 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
4193 CGF.EmitOMPPrivateClause(S, PrivateScope);
4194 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4197 CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
4198 CGF.EmitStmt(CS->getCapturedStmt());
4199 CGF.EmitOMPReductionClauseFinal(S, OMPD_teams);
4213 llvm::Constant *Addr;
4216 S, ParentName, Fn, Addr,
true, CodeGen);
4217 assert(Fn && Addr &&
"Target device function emission failed.");
4241 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4243 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
4245 CGF.EmitOMPReductionClauseFinal(S, OMPD_teams);
4259 llvm::Constant *Addr;
4262 S, ParentName, Fn, Addr,
true, CodeGen);
4263 assert(Fn && Addr &&
"Target device function emission failed.");
4287 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4289 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
4291 CGF.EmitOMPReductionClauseFinal(S, OMPD_teams);
4305 llvm::Constant *Addr;
4308 S, ParentName, Fn, Addr,
true, CodeGen);
4309 assert(Fn && Addr &&
"Target device function emission failed.");
4332 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4334 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
4336 CGF.EmitOMPReductionClauseFinal(S, OMPD_teams);
4354 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4356 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_simd,
4358 CGF.EmitOMPReductionClauseFinal(S, OMPD_teams);
4377 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4379 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
4381 CGF.EmitOMPReductionClauseFinal(S, OMPD_teams);
4400 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4402 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
4403 CGF, OMPD_distribute, CodeGenDistribute,
false);
4404 CGF.EmitOMPReductionClauseFinal(S, OMPD_teams);
4425 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4427 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
4428 CGF, OMPD_distribute, CodeGenDistribute,
false);
4429 CGF.EmitOMPReductionClauseFinal(S, OMPD_teams);
4447 llvm::Constant *Addr;
4450 S, ParentName, Fn, Addr,
true, CodeGen);
4451 assert(Fn && Addr &&
"Target device function emission failed.");
4477 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4479 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
4480 CGF, OMPD_distribute, CodeGenDistribute,
false);
4481 CGF.EmitOMPReductionClauseFinal(S, OMPD_teams);
4499 llvm::Constant *Addr;
4502 S, ParentName, Fn, Addr,
true, CodeGen);
4503 assert(Fn && Addr &&
"Target device function emission failed.");
4516 CGM.getOpenMPRuntime().emitCancellationPointCall(*
this, S.
getBeginLoc(),
4521 const Expr *IfCond =
nullptr;
4524 C->getNameModifier() == OMPD_cancel) {
4525 IfCond = C->getCondition();
4529 CGM.getOpenMPRuntime().emitCancelCall(*
this, S.
getBeginLoc(), IfCond,
4535 if (Kind == OMPD_parallel || Kind == OMPD_task ||
4536 Kind == OMPD_target_parallel)
4538 assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
4539 Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for ||
4540 Kind == OMPD_distribute_parallel_for ||
4541 Kind == OMPD_target_parallel_for ||
4542 Kind == OMPD_teams_distribute_parallel_for ||
4543 Kind == OMPD_target_teams_distribute_parallel_for);
4544 return OMPCancelStack.getExitBlock();
4549 const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap) {
4550 const auto &C = cast<OMPUseDevicePtrClause>(NC);
4551 auto OrigVarIt = C.varlist_begin();
4552 auto InitIt = C.inits().begin();
4553 for (
const Expr *PvtVarIt : C.private_copies()) {
4554 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*OrigVarIt)->getDecl());
4555 const auto *InitVD = cast<VarDecl>(cast<DeclRefExpr>(*InitIt)->getDecl());
4556 const auto *PvtVD = cast<VarDecl>(cast<DeclRefExpr>(PvtVarIt)->getDecl());
4562 if (
const auto *OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) {
4565 const auto *ME = cast<MemberExpr>(OED->getInit());
4566 assert(isa<CXXThisExpr>(ME->getBase()) &&
4567 "Base should be the current struct!");
4568 MatchingVD = ME->getMemberDecl();
4573 auto InitAddrIt = CaptureDeviceAddrMap.find(MatchingVD);
4574 if (InitAddrIt == CaptureDeviceAddrMap.end())
4577 bool IsRegistered = PrivateScope.
addPrivate(OrigVD, [
this, OrigVD,
4586 getContext().getPointerType(OrigVD->getType().getNonReferenceType());
4587 llvm::Type *AddrTy = ConvertTypeForMem(AddrQTy);
4588 Address InitAddr = Builder.CreateBitCast(InitAddrIt->second, AddrTy);
4589 setAddrOfLocalVar(InitVD, InitAddr);
4597 LocalDeclMap.erase(InitVD);
4600 return GetAddrOfLocalVar(PvtVD);
4602 assert(IsRegistered &&
"firstprivate var already registered as private");
4614 CGOpenMPRuntime::TargetDataInfo Info(
true);
4619 bool PrivatizeDevicePointers =
false;
4621 bool &PrivatizeDevicePointers;
4624 explicit DevicePointerPrivActionTy(
bool &PrivatizeDevicePointers)
4625 :
PrePostActionTy(), PrivatizeDevicePointers(PrivatizeDevicePointers) {}
4627 PrivatizeDevicePointers =
true;
4630 DevicePointerPrivActionTy PrivAction(PrivatizeDevicePointers);
4632 auto &&CodeGen = [&S, &Info, &PrivatizeDevicePointers](
4639 auto &&PrivCodeGen = [&S, &Info, &PrivatizeDevicePointers,
4643 PrivatizeDevicePointers =
false;
4649 if (PrivatizeDevicePointers) {
4653 CGF.EmitOMPUseDevicePtrClause(*C, PrivateScope,
4654 Info.CaptureDeviceAddrMap);
4669 OMPLexicalScope
Scope(CGF, S);
4670 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_target_data,
4678 if (CGM.getLangOpts().OMPTargetTriples.empty()) {
4684 const Expr *IfCond =
nullptr;
4686 IfCond = C->getCondition();
4689 const Expr *Device =
nullptr;
4691 Device = C->getDevice();
4697 CGM.getOpenMPRuntime().emitTargetDataCalls(*
this, S, IfCond, Device, RCG,
4705 if (CGM.getLangOpts().OMPTargetTriples.empty())
4709 const Expr *IfCond =
nullptr;
4711 IfCond = C->getCondition();
4714 const Expr *Device =
nullptr;
4716 Device = C->getDevice();
4718 OMPLexicalScope
Scope(*
this, S, OMPD_task);
4719 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*
this, S, IfCond, Device);
4726 if (CGM.getLangOpts().OMPTargetTriples.empty())
4730 const Expr *IfCond =
nullptr;
4732 IfCond = C->getCondition();
4735 const Expr *Device =
nullptr;
4737 Device = C->getDevice();
4739 OMPLexicalScope
Scope(*
this, S, OMPD_task);
4740 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*
this, S, IfCond, Device);
4752 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
4753 CGF.EmitOMPPrivateClause(S, PrivateScope);
4754 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4757 CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
4760 CGF.EmitOMPReductionClauseFinal(S, OMPD_parallel);
4775 llvm::Constant *Addr;
4778 S, ParentName, Fn, Addr,
true, CodeGen);
4779 assert(Fn && Addr &&
"Target device function emission failed.");
4799 CGF, OMPD_target_parallel_for, S.
hasCancel());
4815 llvm::Constant *Addr;
4818 S, ParentName, Fn, Addr,
true, CodeGen);
4819 assert(Fn && Addr &&
"Target device function emission failed.");
4854 llvm::Constant *Addr;
4857 S, ParentName, Fn, Addr,
true, CodeGen);
4858 assert(Fn && Addr &&
"Target device function emission failed.");
4873 const auto *VDecl = cast<VarDecl>(Helper->
getDecl());
4882 Address CapturedStruct = GenerateCapturedStmtArgument(*CS);
4884 const Expr *IfCond =
nullptr;
4887 C->getNameModifier() == OMPD_taskloop) {
4888 IfCond = C->getCondition();
4902 Data.
Schedule.setPointer(EmitScalarExpr(Clause->getGrainsize()));
4906 Data.
Schedule.setPointer(EmitScalarExpr(Clause->getNumTasks()));
4920 llvm::BasicBlock *ContBlock =
nullptr;
4921 OMPLoopScope PreInitScope(CGF, S);
4922 if (CGF.ConstantFoldsToSimpleInteger(S.
getPreCond(), CondConstant)) {
4926 llvm::BasicBlock *ThenBlock = CGF.createBasicBlock(
"taskloop.if.then");
4927 ContBlock = CGF.createBasicBlock(
"taskloop.if.end");
4929 CGF.getProfileCount(&S));
4930 CGF.EmitBlock(ThenBlock);
4931 CGF.incrementProfileCounter(&S);
4935 CGF.EmitOMPSimdInit(S);
4939 enum { LowerBound = 5, UpperBound, Stride, LastIter };
4941 auto *LBP = std::next(I, LowerBound);
4942 auto *UBP = std::next(I, UpperBound);
4943 auto *STP = std::next(I, Stride);
4944 auto *LIP = std::next(I, LastIter);
4952 CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
4953 bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
4957 const auto *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
4958 CGF.EmitVarDecl(*IVDecl);
4959 CGF.EmitIgnoredExpr(S.
getInit());
4965 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
4973 CGF.EmitOMPLoopBody(S,
JumpDest());
4974 CGF.EmitStopPoint(&S);
4979 CGF.EmitBranch(ContBlock);
4980 CGF.EmitBlock(ContBlock,
true);
4983 if (HasLastprivateClause) {
4984 CGF.EmitOMPLastprivateClauseFinal(
4986 CGF.Builder.CreateIsNotNull(CGF.EmitLoadOfScalar(
4987 CGF.GetAddrOfLocalVar(*LIP),
false,
4991 auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
4994 auto &&CodeGen = [&S, OutlinedFn, SharedsTy, CapturedStruct, IfCond,
4996 OMPLoopScope PreInitScope(CGF, S);
4997 CGF.CGM.getOpenMPRuntime().emitTaskLoopCall(CGF, S.
getBeginLoc(), S,
4998 OutlinedFn, SharedsTy,
4999 CapturedStruct, IfCond, Data);
5001 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop,
5005 EmitOMPTaskBasedDirective(S, OMPD_taskloop, BodyGen, TaskGen, Data);
5007 CGM.getOpenMPRuntime().emitTaskgroupRegion(
5020 EmitOMPTaskLoopBasedDirective(S);
5025 EmitOMPTaskLoopBasedDirective(S);
5033 if (CGM.getLangOpts().OMPTargetTriples.empty())
5037 const Expr *IfCond =
nullptr;
5039 IfCond = C->getCondition();
5042 const Expr *Device =
nullptr;
5044 Device = C->getDevice();
5046 OMPLexicalScope
Scope(*
this, S, OMPD_task);
5047 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*
this, S, IfCond, Device);
5059 if (
const auto *LD = dyn_cast<OMPLoopDirective>(&D)) {
5060 for (
const Expr *E : LD->counters()) {
5061 const auto *VD = dyn_cast<
VarDecl>(cast<DeclRefExpr>(E)->getDecl());
5065 VD, [&GlobLVal]() {
return GlobLVal.
getAddress(); });
5067 if (isa<OMPCapturedExprDecl>(VD)) {
5069 if (!CGF.LocalDeclMap.count(VD))
5074 if (!C->getNumForLoops())
5076 for (
unsigned I = LD->getCollapsedNumber(),
5077 E = C->getLoopNumIterations().size();
5079 if (
const auto *VD = dyn_cast<OMPCapturedExprDecl>(
5080 cast<DeclRefExpr>(C->getLoopCounter(I))->getDecl())) {
5082 if (!CGF.LocalDeclMap.count(VD))
5092 OMPSimdLexicalScope
Scope(*
this, D);
5093 CGM.getOpenMPRuntime().emitInlinedDirective(
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
This represents '#pragma omp distribute simd' composite directive.
Expr * getNextUpperBound() const
This represents '#pragma omp master' directive.
This represents '#pragma omp task' directive.
static const Decl * getCanonicalDecl(const Decl *D)
Represents a function declaration or definition.
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=CSK_unspecified)
Expr * getUpperBoundVariable() const
Other implicit parameter.
void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S)
LValue getReferenceLValue(CodeGenFunction &CGF, Expr *refExpr) const
void EmitOMPTargetTaskBasedDirective(const OMPExecutableDirective &S, const RegionCodeGenTy &BodyGen, OMPTargetDataInfo &InputInfo)
static void emitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst, const Expr *X, const Expr *E, SourceLocation Loc)
This represents clause 'copyin' in the '#pragma omp ...' directives.
PointerType - C99 6.7.5.1 - Pointer Declarators.
Scheduling data for loop-based OpenMP directives.
A (possibly-)qualified type.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument.
CodeGenTypes & getTypes()
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.
static void emitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst, const Expr *X, const Expr *V, SourceLocation Loc)
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
param_iterator param_begin() const
Retrieve an iterator pointing to the first parameter decl.
Address CreateMemTemp(QualType T, const Twine &Name="tmp", Address *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
void EmitOMPDistributeDirective(const OMPDistributeDirective &S)
static void EmitOMPTargetParallelForSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelForSimdDirective &S)
Emit device code for the target parallel for simd directive.
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
static std::pair< LValue, LValue > emitDistributeParallelForInnerBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S)
static OMPClauseWithPreInit * get(OMPClause *C)
Stmt - This represents one statement.
This represents clause 'in_reduction' in the '#pragma omp task' directives.
Expr * getLowerBoundVariable() const
void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst)
Store of global named registers are always calls to intrinsics.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
bool requiresCleanups() const
Determine whether this scope requires any cleanups.
void EmitOMPTargetSimdDirective(const OMPTargetSimdDirective &S)
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.
SmallVector< std::pair< OpenMPDependClauseKind, const Expr * >, 4 > Dependences
This represents '#pragma omp for simd' directive.
SmallVector< const Expr *, 4 > LastprivateCopies
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
Decl - This represents one declaration (or definition), e.g.
This represents 'grainsize' clause in the '#pragma omp ...' directive.
This represents '#pragma omp teams distribute parallel for' composite directive.
SourceLocation getBeginLoc() const
Returns starting location of directive kind.
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
static void emitOMPAtomicUpdateExpr(CodeGenFunction &CGF, bool IsSeqCst, const Expr *X, const Expr *E, const Expr *UE, bool IsXLHSInRHSPart, SourceLocation Loc)
llvm::Value * getTypeSize(QualType Ty)
Returns calculated size of the specified type.
This represents 'if' clause in the '#pragma omp ...' directive.
CapturedStmt * getInnermostCapturedStmt()
Get innermost captured statement for the construct.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
void EmitOMPOrderedDirective(const OMPOrderedDirective &S)
This represents 'priority' clause in the '#pragma omp ...' directive.
static void mapParam(CodeGenFunction &CGF, const DeclRefExpr *Helper, const ImplicitParamDecl *PVD, CodeGenFunction::OMPPrivateScope &Privates)
Emit a helper variable and return corresponding lvalue.
The base class of the type hierarchy.
This represents '#pragma omp target teams distribute' combined directive.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
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)
const RecordDecl * getCapturedRecordDecl() const
Retrieve the record declaration for captured variables.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
virtual const FieldDecl * lookup(const VarDecl *VD) const
Lookup the captured field decl for a variable.
const TargetInfo & getTargetInfo() const
Expr * getCombinedParForInDistCond() const
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const llvm::function_ref< void(CodeGenFunction &, llvm::Function *, const OMPTaskDataTy &)> TaskGenTy
static void emitCommonOMPParallelDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, const CodeGenBoundParametersTy &CodeGenBoundParameters)
Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
Floating point control options.
This represents '#pragma omp parallel for' directive.
void GenerateOpenMPCapturedVars(const CapturedStmt &S, SmallVectorImpl< llvm::Value *> &CapturedVars)
This represents '#pragma omp target teams distribute parallel for' combined directive.
Expr * getCombinedEnsureUpperBound() const
void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit)
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant, or if it does but contains a label, return false.
Represents a point when we exit a loop.
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.
SmallVector< const Expr *, 4 > ReductionCopies
SourceLocation getEndLoc() const
Returns ending location of directive.
void EmitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &S)
static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty, const Twine &Name, llvm::Value *Init=nullptr)
This represents '#pragma omp target exit data' directive.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
CanQualType getCanonicalParamType(QualType T) const
Return the canonical parameter type corresponding to the specific potentially non-canonical one...
llvm::Function * GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S)
Represents a variable declaration or definition.
This represents clause 'private' in the '#pragma omp ...' directives.
void EmitOMPCriticalDirective(const OMPCriticalDirective &S)
bool hasCancel() const
Return true if current directive has inner cancel directive.
This represents 'num_threads' clause in the '#pragma omp ...' directive.
const Stmt * getBody() const
Extra information about a function prototype.
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
Expr * getCombinedUpperBoundVariable() const
Expr * getCalcLastIteration() const
llvm::Value * getPointer() const
unsigned getContextParamPosition() const
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.
This represents implicit clause 'flush' for the '#pragma omp flush' directive.
void EmitOMPLastprivateClauseFinal(const OMPExecutableDirective &D, bool NoFinals, llvm::Value *IsLastIterCond=nullptr)
Emit final copying of lastprivate values to original variables at the end of the worksharing or simd ...
void EmitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective &S)
static void emitTargetTeamsDistributeRegion(CodeGenFunction &CGF, PrePostActionTy &Action, const OMPTargetTeamsDistributeDirective &S)
bool isXLHSInRHSPart() const
Return true if helper update expression has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and...
static void EmitOMPTargetParallelDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelDirective &S)
This represents 'nogroup' clause in the '#pragma omp ...' directive.
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
bool EmitOMPWorksharingLoop(const OMPLoopDirective &S, Expr *EUB, const CodeGenLoopBoundsTy &CodeGenLoopBounds, const CodeGenDispatchBoundsTy &CGDispatchBounds)
Emit code for the worksharing loop-based directive.
This represents 'safelen' clause in the '#pragma omp ...' directive.
void EmitOMPTargetTeamsDistributeParallelForSimdDirective(const OMPTargetTeamsDistributeParallelForSimdDirective &S)
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
void EmitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &S)
SmallVector< const Expr *, 4 > PrivateVars
Represents a struct/union/class.
llvm::DenseMap< const VarDecl *, FieldDecl * > LambdaCaptureFields
One of these records is kept for each identifier that is lexed.
void EmitOMPSimdDirective(const OMPSimdDirective &S)
This represents '#pragma omp parallel' directive.
Address getAddress() const
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
A C++ nested-name-specifier augmented with source location information.
This represents 'simd' clause in the '#pragma omp ...' directive.
llvm::IntegerType * Int64Ty
void EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S)
The scope used to remap some variables as private in the OpenMP loop body (or other captured region e...
field_range fields() const
static void emitTargetRegion(CodeGenFunction &CGF, const OMPTargetDirective &S, PrePostActionTy &Action)
Expr * getEnsureUpperBound() const
SmallVector< const Expr *, 4 > LastprivateVars
SourceLocation getBeginLoc() const LLVM_READONLY
Address EmitLoadOfReference(LValue RefLVal, LValueBaseInfo *PointeeBaseInfo=nullptr, TBAAAccessInfo *PointeeTBAAInfo=nullptr)
Represents a member of a struct/union/class.
This represents clause 'lastprivate' in the '#pragma omp ...' directives.
void EmitOMPTaskBasedDirective(const OMPExecutableDirective &S, const OpenMPDirectiveKind CapturedRegion, const RegionCodeGenTy &BodyGen, const TaskGenTy &TaskGen, OMPTaskDataTy &Data)
void EmitOMPDistributeLoop(const OMPLoopDirective &S, const CodeGenLoopTy &CodeGenLoop, Expr *IncExpr)
Emit code for the distribute loop-based directive.
CharUnits getAlignment() const
llvm::IntegerType * SizeTy
const CapturedStmt * getCapturedStmt(OpenMPDirectiveKind RegionKind) const
Returns the captured statement associated with the component region within the (combined) directive...
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
static void emitSimdlenSafelenClause(CodeGenFunction &CGF, const OMPExecutableDirective &D, bool IsMonotonic)
ArrayRef< Expr * > updates()
bool isReferenceType() const
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 EmitOMPPrivateLoopCounters(const OMPLoopDirective &S, OMPPrivateScope &LoopScope)
Emit initial code for loop counters of loop-based directives.
This represents '#pragma omp target simd' directive.
Address getAllocatedAddress() const
Returns the raw, allocated address, which is not necessarily the address of the object itself...
OpenMPDirectiveKind getDirectiveKind() const
SourceLocation getBeginLoc() const LLVM_READONLY
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.
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)
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
void EmitOMPDistributeParallelForSimdDirective(const OMPDistributeParallelForSimdDirective &S)
bool EmitOMPLastprivateClauseInit(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
Emit initial code for lastprivate variables.
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.
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
This represents '#pragma omp distribute parallel for' composite directive.
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
This represents '#pragma omp teams distribute parallel for simd' composite directive.
static bool hasScalarEvaluationKind(QualType T)
Expr *const * const_capture_init_iterator
Const iterator that walks over the capture initialization arguments.
void EmitOMPTargetTeamsDistributeSimdDirective(const OMPTargetTeamsDistributeSimdDirective &S)
ArrayRef< Expr * > finals()
Expr * getIsLastIterVariable() const
void emitOMPSimpleStore(LValue LVal, RValue RVal, QualType RValTy, SourceLocation Loc)
OpenMPScheduleClauseKind Schedule
CharUnits - This is an opaque type for sizes expressed in character units.
static void emitEmptyOrdered(CodeGenFunction &, SourceLocation Loc, const unsigned IVSize, const bool IVSigned)
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
static void emitDistributeParallelForDistributeInnerBoundParams(CodeGenFunction &CGF, const OMPExecutableDirective &S, llvm::SmallVectorImpl< llvm::Value *> &CapturedVars)
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...
llvm::function_ref< std::pair< LValue, LValue > CodeGenFunction &, const OMPExecutableDirective &S)> CodeGenLoopBoundsTy
Expr * getX()
Get 'x' part of the associated expression/statement.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type...
void EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S)
param_iterator param_end() const
Retrieve an iterator one past the last parameter decl.
CharUnits getAlignment() const
Return the alignment of this pointer.
void EmitOMPTeamsDistributeParallelForSimdDirective(const OMPTeamsDistributeParallelForSimdDirective &S)
void EmitOMPTargetDirective(const OMPTargetDirective &S)
Expr * getIterationVariable() const
A builtin binary operation expression such as "x + y" or "x <= y".
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
OpenMPScheduleClauseModifier M2
void setVectorizeWidth(unsigned W)
Set the vectorize width for the next loop pushed.
SmallVector< const Expr *, 4 > PrivateCopies
void restore(CodeGenFunction &CGF)
Restores original addresses of the variables.
static llvm::Function * emitOutlinedOrderedFunction(CodeGenModule &CGM, const CapturedStmt *S)
void EmitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &S)
This represents '#pragma omp cancellation point' directive.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
static LValue EmitOMPHelperVar(CodeGenFunction &CGF, const DeclRefExpr *Helper)
Emit a helper variable and return corresponding lvalue.
Address adjustPrivateAddress(CodeGenFunction &CGF, unsigned N, Address PrivateAddr)
Adjusts PrivatedAddr for using instead of the original variable address in normal operations...
Expr * getSizeExpr() const
Scope - A scope is a transient data structure that is used while parsing the program.
field_iterator field_begin() const
This represents 'final' clause in the '#pragma omp ...' directive.
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
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.
SmallVector< const Expr *, 4 > FirstprivateCopies
static void emitPostUpdateForReductionClause(CodeGenFunction &CGF, const OMPExecutableDirective &D, const llvm::function_ref< llvm::Value *(CodeGenFunction &)> CondGen)
This represents clause 'reduction' in the '#pragma omp ...' directives.
const VarDecl * getBaseDecl(unsigned N) const
Returns the base declaration of the reduction item.
This represents '#pragma omp teams distribute simd' combined directive.
void ForceCleanup(std::initializer_list< llvm::Value **> ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
void EmitOMPSimdFinal(const OMPLoopDirective &D, const llvm::function_ref< llvm::Value *(CodeGenFunction &)> CondGen)
An ordinary object is located at an address in memory.
SmallVector< const Expr *, 4 > ReductionOps
Controls insertion of cancellation exit blocks in worksharing constructs.
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::function_ref< std::pair< llvm::Value *, llvm::Value * > CodeGenFunction &, const OMPExecutableDirective &S, Address LB, Address UB)> CodeGenDispatchBoundsTy
Represents the body of a CapturedStmt, and serves as its DeclContext.
SmallVector< const Expr *, 4 > ReductionVars
static llvm::Value * convertToScalarValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, QualType DestType, SourceLocation Loc)
static llvm::Function * emitOutlinedFunctionPrologue(CodeGenFunction &CGF, FunctionArgList &Args, llvm::MapVector< const Decl *, std::pair< const VarDecl *, Address >> &LocalAddrs, llvm::DenseMap< const Decl *, std::pair< const Expr *, llvm::Value *>> &VLASizes, llvm::Value *&CXXThisValue, const FunctionOptions &FO)
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point...
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
static CodeGenFunction::ComplexPairTy convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, QualType DestType, SourceLocation Loc)
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
This represents '#pragma omp target parallel for simd' directive.
ArrayRef< Expr * > private_counters()
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.
ASTContext & getContext() const
bool hasCancel() const
Return true if current directive has inner cancel directive.
void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S)
This represents '#pragma omp taskgroup' directive.
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.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat)
Class intended to support codegen of all kind of the reduction clauses.
bool isGlobalVarCaptured(const VarDecl *VD) const
Checks if the global variable is captured in current function.
Expr * getCombinedLowerBoundVariable() const
The class used to assign some variables some temporarily addresses.
This represents clause 'task_reduction' in the '#pragma omp taskgroup' directives.
void EmitOMPLoopBody(const OMPLoopDirective &D, JumpDest LoopExit)
Helper for the OpenMP loop directives.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
static ImplicitParamDecl * createImplicitFirstprivateForType(ASTContext &C, OMPTaskDataTy &Data, QualType Ty, CapturedDecl *CD, SourceLocation Loc)
This represents '#pragma omp distribute' directive.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
unsigned NumberOfTargetItems
const Stmt * getAssociatedStmt() const
Returns statement associated with the directive.
bool addPrivate(const VarDecl *LocalVD, const llvm::function_ref< Address()> PrivateGen)
Registers LocalVD variable as a private and apply PrivateGen function for it to generate correspondin...
bool hasCancel() const
Return true if current directive has inner cancel directive.
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
static void emitTargetParallelForRegion(CodeGenFunction &CGF, const OMPTargetParallelForDirective &S, PrePostActionTy &Action)
Emit only debug info necessary for generating line number tables (-gline-tables-only).
void EmitAutoVarInit(const AutoVarEmission &emission)
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
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.
Stmt * IgnoreContainers(bool IgnoreCaptured=false)
Skip no-op (attributed, compound) container stmts and skip captured stmt at the top, if IgnoreCaptured is true.
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.
llvm::function_ref< void(CodeGenFunction &, SourceLocation, const unsigned, const bool)> CodeGenOrderedTy
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
void EmitOMPTeamsDirective(const OMPTeamsDirective &S)
const T * castAs() const
Member-template castAs<specific type>.
llvm::BasicBlock * getBlock() const
static void emitTargetTeamsDistributeParallelForRegion(CodeGenFunction &CGF, const OMPTargetTeamsDistributeParallelForDirective &S, PrePostActionTy &Action)
bool hasCancel() const
Return true if current directive has inner cancel directive.
static std::pair< llvm::Value *, llvm::Value * > emitDispatchForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S, Address LB, Address UB)
When dealing with dispatch schedules (e.g.
This represents '#pragma omp target teams distribute parallel for simd' combined directive.
static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S, const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount)
OpenMPClauseKind
OpenMP clauses.
llvm::PointerType * getType() const
Return the type of the pointer value.
static llvm::iterator_range< specific_clause_iterator< SpecificClause > > getClausesOfKind(ArrayRef< OMPClause *> Clauses)
This represents '#pragma omp target teams distribute simd' combined directive.
void EmitOMPSimdInit(const OMPLoopDirective &D, bool IsMonotonic=false)
Helpers for the OpenMP loop directives.
This represents 'ordered' clause in the '#pragma omp ...' directive.
Expr * getDistInc() const
Expr * getNextLowerBound() const
Expr * getPrevEnsureUpperBound() const
This represents '#pragma omp for' directive.
static void emitTargetTeamsRegion(CodeGenFunction &CGF, PrePostActionTy &Action, const OMPTargetTeamsDirective &S)
SmallVector< const Expr *, 4 > FirstprivateVars
static CapturedDecl * Create(ASTContext &C, DeclContext *DC, unsigned NumParams)
void EmitOMPMasterDirective(const OMPMasterDirective &S)
static std::pair< llvm::Value *, llvm::Value * > emitDistributeParallelForDispatchBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S, Address LB, Address UB)
if the 'for' loop has a dispatch schedule (e.g.
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 setParallel(bool Enable=true)
Set the next pushed loop as parallel.
This represents '#pragma omp target teams' directive.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
SourceLocation getEnd() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
void EmitOMPBarrierDirective(const OMPBarrierDirective &S)
bool EmitOMPLinearClauseInit(const OMPLoopDirective &D)
Emit initial code for linear variables.
This represents '#pragma omp cancel' directive.
This represents clause 'firstprivate' in the '#pragma omp ...' directives.
const LangOptions & getLangOpts() const
ASTContext & getContext() const
static void emitCommonOMPTargetDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, const RegionCodeGenTy &CodeGen)
RValue EmitAtomicLoad(LValue LV, SourceLocation SL, AggValueSlot Slot=AggValueSlot::ignored())
static std::pair< LValue, LValue > emitForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S)
The following two functions generate expressions for the loop lower and upper bounds in case of stati...
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
GlobalDecl - represents a global declaration.
void EmitSimpleOMPExecutableDirective(const OMPExecutableDirective &D)
Emit simple code for OpenMP directives in Simd-only mode.
This represents '#pragma omp flush' directive.
bool hasClausesOfKind() const
Returns true if the current directive has one or more clauses of a specific kind. ...
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.
virtual bool hasBody() const
Returns true if this Decl represents a declaration for a body of code, such as a function or method d...
static void emitAlignedClause(CodeGenFunction &CGF, const OMPExecutableDirective &D)
The l-value was considered opaque, so the alignment was determined from a type.
llvm::function_ref< void(CodeGenFunction &, const OMPLoopDirective &, JumpDest)> CodeGenLoopTy
Expr * getLastIteration() const
const SpecificClause * getSingleClause() const
Gets a single clause of the specified kind associated with the current directive iff there is only on...
bool isPostfixUpdate() const
Return true if 'v' expression must be updated to original value of 'x', false if 'v' must be updated ...
This represents '#pragma omp target enter data' directive.
void EmitOMPFlushDirective(const OMPFlushDirective &S)
Expr * getStrideVariable() const
This represents 'num_teams' clause in the '#pragma omp ...' directive.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
Expr * getCombinedDistCond() const
const Stmt * getPreInits() const
This captures a statement into a function.
static void emitTargetParallelRegion(CodeGenFunction &CGF, const OMPTargetParallelDirective &S, PrePostActionTy &Action)
static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S, PrePostActionTy &Action)
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)
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
Pseudo declaration for capturing expressions.
llvm::PointerIntPair< llvm::Value *, 1, bool > Final
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
static void emitInnerParallelForWhenCombined(CodeGenFunction &CGF, const OMPLoopDirective &S, CodeGenFunction::JumpDest LoopExit)
static void emitTargetParallelForSimdRegion(CodeGenFunction &CGF, const OMPTargetParallelForSimdDirective &S, PrePostActionTy &Action)
This is a basic class for representing single OpenMP executable directive.
This represents 'schedule' clause in the '#pragma omp ...' directive.
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
OpenMPDirectiveKind
OpenMP directives.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
void EmitStmt(const Stmt *S, ArrayRef< const Attr *> Attrs=None)
EmitStmt - Emit the code for the statement.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
C-style initialization with assignment.
This represents '#pragma omp taskwait' directive.
void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S)
This file defines OpenMP nodes for declarative directives.
void EmitOMPTargetParallelForSimdDirective(const OMPTargetParallelForSimdDirective &S)
static void EmitOMPTargetSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetSimdDirective &S)
Emit device code for the target simd directive.
This is a basic class for representing single OpenMP clause.
void EmitOMPTeamsDistributeSimdDirective(const OMPTeamsDistributeSimdDirective &S)
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of the composite or combined directives that need loop ...
void emitAggregateType(CodeGenFunction &CGF, unsigned N)
Emits the code for the variable-modified type, if required.
static void EmitOMPTargetTeamsDistributeParallelForDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeParallelForDirective &S)
bool isAnyPointerType() const
virtual void Enter(CodeGenFunction &CGF)
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.
Stmt * getCapturedStmt()
Retrieve the statement being captured.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
This represents '#pragma omp target' directive.
void EmitOMPForSimdDirective(const OMPForSimdDirective &S)
Expr * getV()
Get 'v' part of the associated expression/statement.
constexpr XRayInstrMask None
void EmitOMPAtomicDirective(const OMPAtomicDirective &S)
void EmitOMPSectionDirective(const OMPSectionDirective &S)
void EmitOMPSectionsDirective(const OMPSectionsDirective &S)
This represents '#pragma omp ordered' directive.
This represents '#pragma omp target update' directive.
void EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S)
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
static void EmitOMPTargetTeamsDistributeDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeDirective &S)
Emit device code for the target teams distribute directive.
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...
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
void setAction(PrePostActionTy &Action) const
CGFunctionInfo - Class to encapsulate the information about a function definition.
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.
LValue EmitOMPSharedLValue(const Expr *E)
Emits the lvalue for the expression with possibly captured variable.
void EmitOMPTargetTeamsDirective(const OMPTargetTeamsDirective &S)
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Dataflow Directional Tag Classes.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
Expr * getPrevUpperBoundVariable() const
Class provides a way to call simple version of codegen for OpenMP region, or an advanced with possibl...
This represents 'device' clause in the '#pragma omp ...' directive.
static void emitEmptyBoundParameters(CodeGenFunction &, const OMPExecutableDirective &, llvm::SmallVectorImpl< llvm::Value *> &)
void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
EvalResult is a struct with detailed info about an evaluated expression.
void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S)
static Address castValueFromUintptr(CodeGenFunction &CGF, SourceLocation Loc, QualType DstType, StringRef Name, LValue AddrLV)
static AggValueSlot ignored()
ignored - Returns an aggregate value slot indicating that the aggregate value is being ignored...
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...
OpenMPScheduleClauseModifier M1
This represents '#pragma omp teams distribute' directive.
A basic class for pre|post-action for advanced codegen sequence for OpenMP region.
static void emitOMPLoopBodyWithStopPoint(CodeGenFunction &CGF, const OMPLoopDirective &S, CodeGenFunction::JumpDest LoopExit)
void EmitOMPPrivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
LValue getSharedLValue(unsigned N) const
Returns LValue for the reduction item.
void EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S)
const Expr * getInit() const
This represents '#pragma omp simd' directive.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)
The name of a declaration.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
const Expr * getReductionRef() const
Returns reference to the task_reduction return variable.
llvm::PointerIntPair< llvm::Value *, 1, bool > Priority
static RValue convertToType(CodeGenFunction &CGF, RValue Value, QualType SourceType, QualType ResType, SourceLocation Loc)
void EmitOMPLinearClause(const OMPLoopDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope)
Emit initial code for linear clauses.
void EmitOMPTeamsDistributeParallelForDirective(const OMPTeamsDistributeParallelForDirective &S)
SourceLocation getEndLoc() const LLVM_READONLY
This represents clause 'linear' in the '#pragma omp ...' directives.
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...
SourceLocation getBeginLoc() const LLVM_READONLY
llvm::Module & getModule() const
This represents '#pragma omp atomic' directive.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
Expr * getCombinedInit() const
unsigned getCollapsedNumber() const
Get number of collapsed loops.
Expr * getCombinedNextLowerBound() const
ArrayRef< Expr * > counters()
static void emitTargetTeamsDistributeSimdRegion(CodeGenFunction &CGF, PrePostActionTy &Action, const OMPTargetTeamsDistributeSimdDirective &S)
void emitInitialization(CodeGenFunction &CGF, unsigned N, Address PrivateAddr, LValue SharedLVal, llvm::function_ref< bool(CodeGenFunction &)> DefaultInit)
Performs initialization of the private copy for the reduction item.
void EmitOMPReductionClauseFinal(const OMPExecutableDirective &D, const OpenMPDirectiveKind ReductionKind)
Emit final update of reduction values to original variables at the end of the directive.
SwitchStmt - This represents a 'switch' stmt.
Expr * getCombinedNextUpperBound() const
void EmitAutoVarCleanups(const AutoVarEmission &emission)
API for captured statement code generation.
void getOpenMPCaptureRegions(llvm::SmallVectorImpl< OpenMPDirectiveKind > &CaptureRegions, OpenMPDirectiveKind DKind)
Return the captured regions of an OpenMP directive.
Complex values, per C99 6.2.5p11.
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
static void emitSimpleAtomicStore(CodeGenFunction &CGF, bool IsSeqCst, LValue LVal, RValue RVal)
This file defines OpenMP AST classes for executable directives and clauses.
ArrayRef< Expr * > inits()
static void EmitOMPTargetTeamsDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDirective &S)
Emit device code for the target teams directive.
llvm::Type * getElementType() const
Return the type of the values stored in this address.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
Expr * getNumIterations() const
Base for LValueReferenceType and RValueReferenceType.
void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
StringRef getMangledName(GlobalDecl GD)
Address BasePointersArray
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
bool setVarAddr(CodeGenFunction &CGF, const VarDecl *LocalVD, Address TempAddr)
Sets the address of the variable LocalVD to be TempAddr in function CGF.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S)
bool hasAssociatedStmt() const
Returns true if directive has associated statement.
Expr * getPrevLowerBoundVariable() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
void EmitOMPDistributeSimdDirective(const OMPDistributeSimdDirective &S)
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitStopPoint(const Stmt *S)
EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool isLValueReferenceType() const
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
TranslationUnitDecl * getTranslationUnitDecl() const
void EmitOMPReductionClauseInit(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
Emit initial code for reduction variables.
This represents '#pragma omp target parallel' directive.
void EmitOMPTargetTeamsDistributeDirective(const OMPTargetTeamsDistributeDirective &S)
static QualType getCanonicalParamType(ASTContext &C, QualType T)
This represents 'nowait' clause in the '#pragma omp ...' directive.
llvm::PointerIntPair< llvm::Value *, 1, bool > Schedule
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.
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.
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
Privates[]
Gets the list of initial values for linear variables.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Expr * getCombinedCond() const
void EmitOMPLinearClauseFinal(const OMPLoopDirective &D, const llvm::function_ref< llvm::Value *(CodeGenFunction &)> CondGen)
Emit final code for linear clauses.
void EmitOMPUseDevicePtrClause(const OMPClause &C, OMPPrivateScope &PrivateScope, const llvm::DenseMap< const ValueDecl *, Address > &CaptureDeviceAddrMap)
LValue EmitLValue(const Expr *E)
EmitLValue - Emit code to compute a designator that specifies the location of the expression...
static void emitTargetTeamsDistributeParallelForSimdRegion(CodeGenFunction &CGF, const OMPTargetTeamsDistributeParallelForSimdDirective &S, PrePostActionTy &Action)
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
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.
Expr * getPreCond() const
This represents 'dist_schedule' clause in the '#pragma omp ...' 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...
const VariableArrayType * getAsVariableArrayType(QualType T) const
This represents '#pragma omp sections' directive.
This represents '#pragma omp target data' directive.
void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S)
OpenMPDirectiveKind getCancelRegion() const
Get cancellation region for the current cancellation point.
A reference to a declared variable, function, enum, etc.
static RValue get(llvm::Value *V)
bool isPointerType() const
static void EmitOMPTargetDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetDirective &S)
Emit device code for the target directive.
void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S)
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static void EmitOMPTargetParallelForDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelForDirective &S)
Emit device code for the target parallel for directive.
void EmitOMPDistributeParallelForDirective(const OMPDistributeParallelForDirective &S)
void EmitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
An l-value expression is a reference to an object with independent storage.
A trivial tuple used to represent a source range.
LValue - This represents an lvalue references.
This represents '#pragma omp taskyield' directive.
This represents '#pragma omp distribute parallel for simd' composite directive.
Represents a C array with a specified size that is not an integer-constant-expression.
This represents '#pragma omp parallel sections' directive.
bool apply(CodeGenFunction &CGF)
Applies new addresses to the list of the variables.
SourceLocation getBegin() const
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument.
llvm::Value * getPointer() const
void EmitOMPTaskDirective(const OMPTaskDirective &S)
SourceLocation getBodyRBrace() const
getBodyRBrace - Gets the right brace of the body, if a body exists.
This represents '#pragma omp target parallel for' directive.
SmallVector< const Expr *, 4 > FirstprivateInits
SourceLocation getLocation() const
This represents clause 'use_device_ptr' in the '#pragma omp ...' directives.
static void EmitOMPTargetTeamsDistributeSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeSimdDirective &S)
Emit device code for the target teams distribute simd directive.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth, signed/unsigned.
void EmitOMPTargetTeamsDistributeParallelForDirective(const OMPTargetTeamsDistributeParallelForDirective &S)
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, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
bool Privatize()
Privatizes local variables previously registered as private.
static void EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeParallelForSimdDirective &S)
Emit device code for the target teams distribute parallel for simd directive.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
This represents '#pragma omp taskloop' directive.