;
41using namespaceCodeGen;
42using namespacellvm::omp;
44#define TTL_CODEGEN_TYPE "target-teams-loop-codegen" 53classOMPLexicalScope :
publicCodeGenFunction::LexicalScope {
55 for(
const auto*
C: S.clauses()) {
57 if(
const auto*PreInit =
58cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {
59 for(
const auto*I : PreInit->decls()) {
60 if(!I->hasAttr<OMPCaptureNoInitAttr>()) {
63CodeGenFunction::AutoVarEmission Emission =
72CodeGenFunction::OMPPrivateScope InlinedShareds;
78cast<BlockDecl>(CGF.
CurCodeDecl)->capturesVariable(VD));
84 conststd::optional<OpenMPDirectiveKind> CapturedRegion = std::nullopt,
85 const boolEmitPreInitStmt =
true)
89emitPreInitStmt(CGF, S);
92assert(S.hasAssociatedStmt() &&
93 "Expected associated statement for inlined directive.");
94 const CapturedStmt*CS = S.getCapturedStmt(*CapturedRegion);
95 for(
const auto&
C: CS->
captures()) {
96 if(
C.capturesVariable() ||
C.capturesVariableByCopy()) {
97 auto*VD =
C.getCapturedVar();
99 "Canonical decl must be captured.");
103InlinedShareds.isGlobalVarCaptured(VD)),
108(void)InlinedShareds.Privatize();
114classOMPParallelScope final :
publicOMPLexicalScope {
124: OMPLexicalScope(CGF, S,
std::nullopt,
125EmitPreInitStmt(S)) {}
130classOMPTeamsScope final :
publicOMPLexicalScope {
139: OMPLexicalScope(CGF, S,
std::nullopt,
140EmitPreInitStmt(S)) {}
145classOMPLoopScope :
publicCodeGenFunction::RunCleanupsScope {
147 const Stmt*PreInits;
148CodeGenFunction::OMPMapVars PreCondVars;
149 if(
auto*LD = dyn_cast<OMPLoopDirective>(&S)) {
150llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
151 for(
const auto*
E: LD->counters()) {
152 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
154(void)PreCondVars.setVarAddr(
159 for(
const Expr*IRef :
C->varlist()) {
161cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl());
162 if(EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
163 QualTypeOrigVDTy = OrigVD->getType().getNonReferenceType();
164(void)PreCondVars.setVarAddr(
173(void)PreCondVars.apply(CGF);
176LD->getInnermostCapturedStmt()->getCapturedStmt(),
177 true, LD->getLoopsNumber(),
178[&CGF](
unsignedCnt,
const Stmt*CurStmt) {
179 if(
const auto*CXXFor = dyn_cast<CXXForRangeStmt>(CurStmt)) {
180 if(
const Stmt*
Init= CXXFor->getInit())
182CGF.
EmitStmt(CXXFor->getRangeStmt());
183CGF.
EmitStmt(CXXFor->getEndStmt());
187PreInits = LD->getPreInits();
188}
else if(
const auto*
Tile= dyn_cast<OMPTileDirective>(&S)) {
189PreInits =
Tile->getPreInits();
190}
else if(
const auto*Unroll = dyn_cast<OMPUnrollDirective>(&S)) {
191PreInits = Unroll->getPreInits();
192}
else if(
const auto*Reverse = dyn_cast<OMPReverseDirective>(&S)) {
193PreInits = Reverse->getPreInits();
194}
else if(
const auto*Interchange =
195dyn_cast<OMPInterchangeDirective>(&S)) {
196PreInits = Interchange->getPreInits();
198llvm_unreachable(
"Unknown loop-based directive kind.");
205 if(
auto*PreInitCompound = dyn_cast<CompoundStmt>(PreInits))
206llvm::append_range(PreInitStmts, PreInitCompound->body());
208PreInitStmts.push_back(PreInits);
210 for(
const Stmt*S : PreInitStmts) {
213 if(
auto*PreInitDecl = dyn_cast<DeclStmt>(S)) {
214 for(
Decl*I : PreInitDecl->decls())
221PreCondVars.restore(CGF);
227emitPreInitStmt(CGF, S);
231classOMPSimdLexicalScope :
publicCodeGenFunction::LexicalScope {
232CodeGenFunction::OMPPrivateScope InlinedShareds;
238cast<BlockDecl>(CGF.
CurCodeDecl)->capturesVariable(VD));
244InlinedShareds(CGF) {
245 for(
const auto*
C: S.clauses()) {
247 if(
const auto*PreInit =
248cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {
249 for(
const auto*I : PreInit->decls()) {
250 if(!I->hasAttr<OMPCaptureNoInitAttr>()) {
253CodeGenFunction::AutoVarEmission Emission =
259}
else if(
const auto*UDP = dyn_cast<OMPUseDevicePtrClause>(
C)) {
260 for(
const Expr*
E: UDP->varlist()) {
261 const Decl*
D= cast<DeclRefExpr>(
E)->getDecl();
262 if(
const auto*OED = dyn_cast<OMPCapturedExprDecl>(
D))
265}
else if(
const auto*UDP = dyn_cast<OMPUseDeviceAddrClause>(
C)) {
266 for(
const Expr*
E: UDP->varlist()) {
268 if(
const auto*OED = dyn_cast<OMPCapturedExprDecl>(
D))
275 if(
const auto*TG = dyn_cast<OMPTaskgroupDirective>(&S)) {
276 if(
const Expr*
E= TG->getReductionRef())
277CGF.
EmitVarDecl(*cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl()));
281llvm::DenseSet<CanonicalDeclPtr<const Decl>> CopyArrayTemps;
283 if(
C->getModifier() != OMPC_REDUCTION_inscan)
285 for(
const Expr*
E:
C->copy_array_temps())
286CopyArrayTemps.insert(cast<DeclRefExpr>(
E)->getDecl());
288 const auto*CS = cast_or_null<CapturedStmt>(S.getAssociatedStmt());
291 if(
C.capturesVariable() ||
C.capturesVariableByCopy()) {
292 auto*VD =
C.getCapturedVar();
293 if(CopyArrayTemps.contains(VD))
296 "Canonical decl must be captured.");
298isCapturedVar(CGF, VD) ||
300InlinedShareds.isGlobalVarCaptured(VD)),
308(void)InlinedShareds.Privatize();
319 if(Kind != OMPD_loop)
324BindKind =
C->getBindKind();
327 caseOMPC_BIND_parallel:
329 caseOMPC_BIND_teams:
330 returnOMPD_distribute;
331 caseOMPC_BIND_thread:
342LValueCodeGenFunction::EmitOMPSharedLValue(
const Expr*
E) {
343 if(
const auto*OrigDRE = dyn_cast<DeclRefExpr>(
E)) {
344 if(
const auto*OrigVD = dyn_cast<VarDecl>(OrigDRE->getDecl())) {
345OrigVD = OrigVD->getCanonicalDecl();
360llvm::Value *
Size=
nullptr;
361 autoSizeInChars =
C.getTypeSizeInChars(Ty);
362 if(SizeInChars.isZero()) {
368 Size?
Builder.CreateNUWMul(Size, VlaSize.NumElts) : VlaSize.NumElts;
370SizeInChars =
C.getTypeSizeInChars(Ty);
371 if(SizeInChars.isZero())
372 returnllvm::ConstantInt::get(
SizeTy,
0);
380 const RecordDecl*RD = S.getCapturedRecordDecl();
382 autoCurCap = S.captures().begin();
384 E= S.capture_init_end();
385I !=
E; ++I, ++CurField, ++CurCap) {
386 if(CurField->hasCapturedVLAType()) {
388llvm::Value *Val = VLASizeMap[VAT->
getSizeExpr()];
389CapturedVars.push_back(Val);
390}
else if(CurCap->capturesThis()) {
391CapturedVars.push_back(CXXThisValue);
392}
else if(CurCap->capturesVariableByCopy()) {
397 if(!CurField->getType()->isAnyPointerType()) {
401Twine(CurCap->getCapturedVar()->getName(),
".casted"));
407Ctx.
getPointerType(CurField->getType()), CurCap->getLocation());
417CapturedVars.push_back(CV);
419assert(CurCap->capturesVariable() &&
"Expected capture by reference.");
441 return C.getLValueReferenceType(
447 if(
const auto*VLA = dyn_cast<VariableArrayType>(A))
449 if(!A->isVariablyModifiedType())
450 return C.getCanonicalType(
T);
452 return C.getCanonicalParamType(
T);
457structFunctionOptions {
462 const boolUIntPtrCastRequired =
true;
465 const boolRegisterCastedArgsOnly =
false;
467 constStringRef FunctionName;
470 explicitFunctionOptions(
const CapturedStmt*S,
boolUIntPtrCastRequired,
471 boolRegisterCastedArgsOnly, StringRef FunctionName,
473: S(S), UIntPtrCastRequired(UIntPtrCastRequired),
474RegisterCastedArgsOnly(UIntPtrCastRequired && RegisterCastedArgsOnly),
475FunctionName(FunctionName),
Loc(
Loc) {}
481llvm::MapVector<
const Decl*, std::pair<const VarDecl *, Address>>
483llvm::DenseMap<
const Decl*, std::pair<const Expr *, llvm::Value *>>
485llvm::Value *&CXXThisValue,
constFunctionOptions &FO) {
487 const RecordDecl*RD = FO.S->getCapturedRecordDecl();
488assert(CD->
hasBody() &&
"missing CapturedDecl body");
490CXXThisValue =
nullptr;
500 autoI = FO.S->captures().begin();
502 if(!FO.UIntPtrCastRequired) {
522 if(FO.UIntPtrCastRequired &&
524I->capturesVariableArrayType()))
527 if(I->capturesVariable() || I->capturesVariableByCopy()) {
528CapVar = I->getCapturedVar();
530}
else if(I->capturesThis()) {
533assert(I->capturesVariableArrayType());
543}
else if(DebugFunctionDecl && (CapVar || I->capturesThis())) {
545Ctx, DebugFunctionDecl,
546CapVar ? CapVar->
getBeginLoc() : FD->getBeginLoc(),
547CapVar ? CapVar->
getLocation() : FD->getLocation(), II, ArgType,
553Args.emplace_back(Arg);
555TargetArgs.emplace_back(
556FO.UIntPtrCastRequired
573llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
577F->setDoesNotThrow();
578F->setDoesNotRecurse();
582F->removeFnAttr(llvm::Attribute::NoInline);
583F->addFnAttr(llvm::Attribute::AlwaysInline);
588FO.UIntPtrCastRequired ? FO.Loc : FO.S->getBeginLoc(),
589FO.UIntPtrCastRequired ? FO.Loc
592I = FO.S->captures().begin();
596 if(!FO.UIntPtrCastRequired && Args[Cnt] != TargetArgs[Cnt]) {
604 if(I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) {
605 const VarDecl*CurVD = I->getCapturedVar();
606 if(!FO.RegisterCastedArgsOnly)
607LocalAddrs.insert({Args[Cnt], {CurVD, LocalAddr}});
615 if(FD->hasCapturedVLAType()) {
616 if(FO.UIntPtrCastRequired) {
619Args[Cnt]->getName(), ArgLVal),
624VLASizes.try_emplace(Args[Cnt], VAT->
getSizeExpr(), ExprArg);
625}
else if(I->capturesVariable()) {
626 const VarDecl*Var = I->getCapturedVar();
636 if(!FO.RegisterCastedArgsOnly) {
640}
else if(I->capturesVariableByCopy()) {
641assert(!FD->getType()->isAnyPointerType() &&
642 "Not expecting a captured pointer.");
643 const VarDecl*Var = I->getCapturedVar();
644LocalAddrs.insert({Args[Cnt],
645{Var, FO.UIntPtrCastRequired
647CGF, I->getLocation(), FD->getType(),
648Args[Cnt]->getName(), ArgLVal)
652assert(I->capturesThis());
654LocalAddrs.insert({Args[Cnt], {
nullptr, ArgLVal.
getAddress()}});
668 "CapturedStmtInfo should be set when generating the captured function");
671 boolNeedWrapperFunction =
674llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>> LocalAddrs,
676llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> VLASizes,
679llvm::raw_svector_ostream Out(Buffer);
683llvm::Function *WrapperF =
nullptr;
684 if(NeedWrapperFunction) {
687FunctionOptions WrapperFO(&S,
true,
693WrapperCGF.CXXThisValue, WrapperFO);
696FunctionOptions FO(&S, !NeedWrapperFunction,
false,
699*
this, WrapperArgs, WrapperLocalAddrs, WrapperVLASizes, CXXThisValue, FO);
700CodeGenFunction::OMPPrivateScope LocalScope(*
this);
701 for(
const auto&LocalAddrPair : WrapperLocalAddrs) {
702 if(LocalAddrPair.second.first) {
703LocalScope.addPrivate(LocalAddrPair.second.first,
704LocalAddrPair.second.second);
707(void)LocalScope.Privatize();
708 for(
const auto&VLASizePair : WrapperVLASizes)
709VLASizeMap[VLASizePair.second.first] = VLASizePair.second.second;
712(void)LocalScope.ForceCleanup();
714 if(!NeedWrapperFunction)
718WrapperF->removeFromParent();
719F->getParent()->getFunctionList().insertAfter(F->getIterator(), WrapperF);
722 auto*PI = F->arg_begin();
723 for(
const auto*Arg : Args) {
725 autoI = LocalAddrs.find(Arg);
726 if(I != LocalAddrs.end()) {
727 LValueLV = WrapperCGF.MakeAddrLValue(
729I->second.first ? I->second.first->getType() : Arg->getType(),
733 CallArg= WrapperCGF.EmitLoadOfScalar(LV, S.getBeginLoc());
735 autoEI = VLASizes.find(Arg);
736 if(EI != VLASizes.end()) {
740WrapperCGF.MakeAddrLValue(WrapperCGF.GetAddrOfLocalVar(Arg),
742 CallArg= WrapperCGF.EmitLoadOfScalar(LV, S.getBeginLoc());
745CallArgs.emplace_back(WrapperCGF.EmitFromMemory(
CallArg, Arg->
getType()));
749WrapperCGF.FinishFunction();
764llvm::Value *NumElements =
emitArrayLength(ArrayTy, ElementTy, DestAddr);
771DestBegin, NumElements);
776llvm::Value *IsEmpty =
777 Builder.CreateICmpEQ(DestBegin, DestEnd,
"omp.arraycpy.isempty");
778 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
781llvm::BasicBlock *EntryBB =
Builder.GetInsertBlock();
786llvm::PHINode *SrcElementPHI =
787 Builder.CreatePHI(SrcBegin->getType(), 2,
"omp.arraycpy.srcElementPast");
788SrcElementPHI->addIncoming(SrcBegin, EntryBB);
793llvm::PHINode *DestElementPHI =
Builder.CreatePHI(
794DestBegin->getType(), 2,
"omp.arraycpy.destElementPast");
795DestElementPHI->addIncoming(DestBegin, EntryBB);
801CopyGen(DestElementCurrent, SrcElementCurrent);
804llvm::Value *DestElementNext =
8061,
"omp.arraycpy.dest.element");
807llvm::Value *SrcElementNext =
8091,
"omp.arraycpy.src.element");
812 Builder.CreateICmpEQ(DestElementNext, DestEnd,
"omp.arraycpy.done");
813 Builder.CreateCondBr(Done, DoneBB, BodyBB);
814DestElementPHI->addIncoming(DestElementNext,
Builder.GetInsertBlock());
815SrcElementPHI->addIncoming(SrcElementNext,
Builder.GetInsertBlock());
825 const auto*BO = dyn_cast<BinaryOperator>(
Copy);
826 if(BO && BO->getOpcode() == BO_Assign) {
835DestAddr, SrcAddr, OriginalType,
840CodeGenFunction::OMPPrivateScope Remap(*
this);
841Remap.addPrivate(DestVD, DestElement);
842Remap.addPrivate(SrcVD, SrcElement);
843(void)Remap.Privatize();
849CodeGenFunction::OMPPrivateScope Remap(*
this);
850Remap.addPrivate(SrcVD, SrcAddr);
851Remap.addPrivate(DestVD, DestAddr);
852(void)Remap.Privatize();
859OMPPrivateScope &PrivateScope) {
863 boolDeviceConstTarget =
getLangOpts().OpenMPIsTargetDevice &&
865 boolFirstprivateIsLastprivate =
false;
866llvm::DenseMap<const VarDecl *, OpenMPLastprivateModifier> Lastprivates;
868 for(
const auto*
D:
C->varlist())
869Lastprivates.try_emplace(
873llvm::DenseSet<const VarDecl *> EmittedAsFirstprivate;
878 boolMustEmitFirstprivateCopy =
879CaptureRegions.size() == 1 && CaptureRegions.back() == OMPD_unknown;
881 const auto*IRef =
C->varlist_begin();
882 const auto*InitsRef =
C->inits().begin();
883 for(
const Expr*IInit :
C->private_copies()) {
884 const auto*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
885 boolThisFirstprivateIsLastprivate =
886Lastprivates.count(OrigVD->getCanonicalDecl()) > 0;
888 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
889 if(!MustEmitFirstprivateCopy && !ThisFirstprivateIsLastprivate && FD &&
891(!VD || !VD->
hasAttr<OMPAllocateDeclAttr>())) {
892EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl());
899 if(DeviceConstTarget && OrigVD->getType().isConstant(
getContext()) &&
901(!VD || !VD->
hasAttr<OMPAllocateDeclAttr>())) {
902EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl());
907FirstprivateIsLastprivate =
908FirstprivateIsLastprivate || ThisFirstprivateIsLastprivate;
909 if(EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()).second) {
911cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
920 if(CE && !CE.isReference()) {
926 if(CE && CE.isReference()) {
927OriginalLVal = CE.getReferenceLValue(*
this, &DRE);
929assert(!CE &&
"Expected non-constant firstprivate.");
948Emission.getAllocatedAddress(), OriginalLVal.
getAddress(),
Type,
952RunCleanupsScope InitScope(*this);
954setAddrOfLocalVar(VDInit, SrcElement);
955EmitAnyExprToMem(Init, DestElement,
956Init->getType().getQualifiers(),
958LocalDeclMap.erase(VDInit);
963PrivateScope.addPrivate(OrigVD, Emission.getAllocatedAddress());
969setAddrOfLocalVar(VDInit, OriginalAddr);
971LocalDeclMap.erase(VDInit);
973 if(ThisFirstprivateIsLastprivate &&
974Lastprivates[OrigVD->getCanonicalDecl()] ==
975OMPC_LASTPRIVATE_conditional) {
980(*IRef)->getExprLoc());
985LocalDeclMap.erase(VD);
986setAddrOfLocalVar(VD, VDAddr);
988IsRegistered = PrivateScope.addPrivate(OrigVD, VDAddr);
990assert(IsRegistered &&
991 "firstprivate var already registered as private");
999 returnFirstprivateIsLastprivate && !EmittedAsFirstprivate.empty();
1004CodeGenFunction::OMPPrivateScope &PrivateScope) {
1007llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
1009 autoIRef =
C->varlist_begin();
1010 for(
const Expr*IInit :
C->private_copies()) {
1011 const auto*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
1012 if(EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
1013 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
1018assert(IsRegistered &&
"private var already registered as private");
1034llvm::DenseSet<const VarDecl *> CopiedVars;
1035llvm::BasicBlock *CopyBegin =
nullptr, *CopyEnd =
nullptr;
1037 autoIRef =
C->varlist_begin();
1038 autoISrcRef =
C->source_exprs().begin();
1039 autoIDestRef =
C->destination_exprs().begin();
1040 for(
const Expr*AssignOp :
C->assignment_ops()) {
1041 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
1049 getContext().getTargetInfo().isTLSSupported()) {
1051 "Copyin threadprivates should have been captured!");
1055LocalDeclMap.erase(VD);
1065 if(CopiedVars.size() == 1) {
1071 auto*MasterAddrInt =
Builder.CreatePtrToInt(
1073 auto*PrivateAddrInt =
Builder.CreatePtrToInt(
1076 Builder.CreateICmpNE(MasterAddrInt, PrivateAddrInt), CopyBegin,
1081cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
1082 const auto*DestVD =
1083cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
1084 EmitOMPCopy(
Type, PrivateAddr, MasterAddr, DestVD, SrcVD, AssignOp);
1103 boolHasAtLeastOneLastprivate =
false;
1105llvm::DenseSet<const VarDecl *> SIMDLCVs;
1107 const auto*LoopDirective = cast<OMPLoopDirective>(&
D);
1108 for(
const Expr*
C: LoopDirective->counters()) {
1113llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
1115HasAtLeastOneLastprivate =
true;
1118 const auto*IRef =
C->varlist_begin();
1119 const auto*IDestRef =
C->destination_exprs().begin();
1120 for(
const Expr*IInit :
C->private_copies()) {
1123 const auto*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
1126 if(AlreadyEmittedVars.insert(OrigVD->getCanonicalDecl()).second) {
1127 const auto*DestVD =
1128cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
1133PrivateScope.addPrivate(DestVD,
EmitLValue(&DRE).getAddress());
1137 if(IInit && !SIMDLCVs.count(OrigVD->getCanonicalDecl())) {
1138 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
1140 if(
C->getKind() == OMPC_LASTPRIVATE_conditional) {
1143setAddrOfLocalVar(VD, VDAddr);
1149 boolIsRegistered = PrivateScope.addPrivate(OrigVD, VDAddr);
1150assert(IsRegistered &&
1151 "lastprivate var already registered as private");
1159 returnHasAtLeastOneLastprivate;
1164llvm::Value *IsLastIterCond) {
1173llvm::BasicBlock *ThenBB =
nullptr;
1174llvm::BasicBlock *DoneBB =
nullptr;
1175 if(IsLastIterCond) {
1181return C->getKind() == OMPC_LASTPRIVATE_conditional;
1190 Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB);
1193llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
1194llvm::DenseMap<const VarDecl *, const Expr *> LoopCountersAndUpdates;
1195 if(
const auto*LoopDirective = dyn_cast<OMPLoopDirective>(&
D)) {
1196 autoIC = LoopDirective->counters().begin();
1197 for(
const Expr*F : LoopDirective->finals()) {
1201AlreadyEmittedVars.insert(
D);
1203LoopCountersAndUpdates[
D] = F;
1208 autoIRef =
C->varlist_begin();
1209 autoISrcRef =
C->source_exprs().begin();
1210 autoIDestRef =
C->destination_exprs().begin();
1211 for(
const Expr*AssignOp :
C->assignment_ops()) {
1212 const auto*PrivateVD =
1213cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
1215 const auto*CanonicalVD = PrivateVD->getCanonicalDecl();
1216 if(AlreadyEmittedVars.insert(CanonicalVD).second) {
1220 if(
const Expr*FinalExpr = LoopCountersAndUpdates.lookup(CanonicalVD))
1223cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
1224 const auto*DestVD =
1225cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
1228 if(
const auto*RefTy = PrivateVD->getType()->getAs<
ReferenceType>())
1234 if(
C->getKind() == OMPC_LASTPRIVATE_conditional)
1236*
this,
MakeAddrLValue(PrivateAddr, (*IRef)->getType()), PrivateVD,
1237(*IRef)->getExprLoc());
1240 EmitOMPCopy(
Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp);
1246 if(
const Expr*PostUpdate =
C->getPostUpdateExpr())
1255CodeGenFunction::OMPPrivateScope &PrivateScope,
boolForInscan) {
1267 if(ForInscan != (
C->getModifier() == OMPC_REDUCTION_inscan))
1269Shareds.append(
C->varlist_begin(),
C->varlist_end());
1270Privates.append(
C->privates().begin(),
C->privates().end());
1271ReductionOps.append(
C->reduction_ops().begin(),
C->reduction_ops().end());
1272LHSs.append(
C->lhs_exprs().begin(),
C->lhs_exprs().end());
1273RHSs.append(
C->rhs_exprs().begin(),
C->rhs_exprs().end());
1274 if(
C->getModifier() == OMPC_REDUCTION_task) {
1275 Data.ReductionVars.append(
C->privates().begin(),
C->privates().end());
1276 Data.ReductionOrigs.append(
C->varlist_begin(),
C->varlist_end());
1277 Data.ReductionCopies.append(
C->privates().begin(),
C->privates().end());
1278 Data.ReductionOps.append(
C->reduction_ops().begin(),
1279 C->reduction_ops().end());
1280TaskLHSs.append(
C->lhs_exprs().begin(),
C->lhs_exprs().end());
1281TaskRHSs.append(
C->rhs_exprs().begin(),
C->rhs_exprs().end());
1286 auto*ILHS = LHSs.begin();
1287 auto*IRHS = RHSs.begin();
1288 auto*IPriv = Privates.begin();
1289 for(
const Expr*IRef : Shareds) {
1290 const auto*PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl());
1292RedCG.emitSharedOrigLValue(*
this, Count);
1293RedCG.emitAggregateType(*
this, Count);
1295RedCG.emitInitialization(*
this, Count, Emission.getAllocatedAddress(),
1296RedCG.getSharedLValue(Count).getAddress(),
1298CGF.EmitAutoVarInit(Emission);
1302 AddressBaseAddr = RedCG.adjustPrivateAddress(
1303*
this, Count, Emission.getAllocatedAddress());
1305PrivateScope.addPrivate(RedCG.getBaseDecl(Count), BaseAddr);
1306assert(IsRegistered &&
"private var already registered as private");
1310 const auto*LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
1311 const auto*RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
1313 boolisaOMPArraySectionExpr = isa<ArraySectionExpr>(IRef);
1317PrivateScope.addPrivate(LHSVD, RedCG.getSharedLValue(Count).getAddress());
1320isa<ArraySubscriptExpr>(IRef)) {
1323PrivateScope.addPrivate(LHSVD, RedCG.getSharedLValue(Count).getAddress());
1324PrivateScope.addPrivate(RHSVD,
1330 AddressOriginalAddr = RedCG.getSharedLValue(Count).getAddress();
1337PrivateScope.addPrivate(LHSVD, OriginalAddr);
1338PrivateScope.addPrivate(
1348 if(!
Data.ReductionVars.empty()) {
1350 Data.IsReductionWithTaskMod =
true;
1354 const Expr*TaskRedRef =
nullptr;
1357TaskRedRef = cast<OMPParallelDirective>(
D).getTaskReductionRefExpr();
1360TaskRedRef = cast<OMPForDirective>(
D).getTaskReductionRefExpr();
1363TaskRedRef = cast<OMPSectionsDirective>(
D).getTaskReductionRefExpr();
1365 caseOMPD_parallel_for:
1366TaskRedRef = cast<OMPParallelForDirective>(
D).getTaskReductionRefExpr();
1368 caseOMPD_parallel_master:
1370cast<OMPParallelMasterDirective>(
D).getTaskReductionRefExpr();
1372 caseOMPD_parallel_sections:
1374cast<OMPParallelSectionsDirective>(
D).getTaskReductionRefExpr();
1376 caseOMPD_target_parallel:
1378cast<OMPTargetParallelDirective>(
D).getTaskReductionRefExpr();
1380 caseOMPD_target_parallel_for:
1382cast<OMPTargetParallelForDirective>(
D).getTaskReductionRefExpr();
1384 caseOMPD_distribute_parallel_for:
1386cast<OMPDistributeParallelForDirective>(
D).getTaskReductionRefExpr();
1388 caseOMPD_teams_distribute_parallel_for:
1389TaskRedRef = cast<OMPTeamsDistributeParallelForDirective>(
D)
1390.getTaskReductionRefExpr();
1392 caseOMPD_target_teams_distribute_parallel_for:
1393TaskRedRef = cast<OMPTargetTeamsDistributeParallelForDirective>(
D)
1394.getTaskReductionRefExpr();
1402 caseOMPD_parallel_for_simd:
1404 caseOMPD_taskyield:
1408 caseOMPD_taskgroup:
1416 caseOMPD_cancellation_point:
1418 caseOMPD_target_data:
1419 caseOMPD_target_enter_data:
1420 caseOMPD_target_exit_data:
1422 caseOMPD_taskloop_simd:
1423 caseOMPD_master_taskloop:
1424 caseOMPD_master_taskloop_simd:
1425 caseOMPD_parallel_master_taskloop:
1426 caseOMPD_parallel_master_taskloop_simd:
1427 caseOMPD_distribute:
1428 caseOMPD_target_update:
1429 caseOMPD_distribute_parallel_for_simd:
1430 caseOMPD_distribute_simd:
1431 caseOMPD_target_parallel_for_simd:
1432 caseOMPD_target_simd:
1433 caseOMPD_teams_distribute:
1434 caseOMPD_teams_distribute_simd:
1435 caseOMPD_teams_distribute_parallel_for_simd:
1436 caseOMPD_target_teams:
1437 caseOMPD_target_teams_distribute:
1438 caseOMPD_target_teams_distribute_parallel_for_simd:
1439 caseOMPD_target_teams_distribute_simd:
1440 caseOMPD_declare_target:
1441 caseOMPD_end_declare_target:
1442 caseOMPD_threadprivate:
1444 caseOMPD_declare_reduction:
1445 caseOMPD_declare_mapper:
1446 caseOMPD_declare_simd:
1448 caseOMPD_declare_variant:
1449 caseOMPD_begin_declare_variant:
1450 caseOMPD_end_declare_variant:
1453llvm_unreachable(
"Unexpected directive with task reductions.");
1456 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(TaskRedRef)->getDecl());
1459 false, TaskRedRef->
getType());
1471 boolHasAtLeastOneReduction =
false;
1472 boolIsReductionWithTaskMod =
false;
1475 if(
C->getModifier() == OMPC_REDUCTION_inscan)
1477HasAtLeastOneReduction =
true;
1478Privates.append(
C->privates().begin(),
C->privates().end());
1479LHSExprs.append(
C->lhs_exprs().begin(),
C->lhs_exprs().end());
1480RHSExprs.append(
C->rhs_exprs().begin(),
C->rhs_exprs().end());
1481ReductionOps.append(
C->reduction_ops().begin(),
C->reduction_ops().end());
1482IsReductionWithTaskMod =
1483IsReductionWithTaskMod ||
C->getModifier() == OMPC_REDUCTION_task;
1485 if(HasAtLeastOneReduction) {
1487 if(IsReductionWithTaskMod) {
1491 boolTeamsLoopCanBeParallel =
false;
1492 if(
auto*TTLD = dyn_cast<OMPTargetTeamsGenericLoopDirective>(&
D))
1493TeamsLoopCanBeParallel = TTLD->canBeParallelFor();
1496TeamsLoopCanBeParallel || ReductionKind == OMPD_simd;
1497 boolSimpleReduction = ReductionKind == OMPD_simd;
1501*
this,
D.
getEndLoc(), Privates, LHSExprs, RHSExprs, ReductionOps,
1502{WithNowait, SimpleReduction, ReductionKind});
1508 constllvm::function_ref<llvm::Value *(
CodeGenFunction&)> CondGen) {
1511llvm::BasicBlock *DoneBB =
nullptr;
1513 if(
const Expr*PostUpdate =
C->getPostUpdateExpr()) {
1515 if(llvm::Value *Cond = CondGen(CGF)) {
1520CGF.
Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1538CodeGenBoundParametersTy;
1546llvm::DenseSet<CanonicalDeclPtr<const VarDecl>> PrivateDecls;
1548 for(
const Expr*Ref :
C->varlist()) {
1549 if(!Ref->getType()->isScalarType())
1551 const auto*DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
1554PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));
1559 for(
const Expr*Ref :
C->varlist()) {
1560 if(!Ref->getType()->isScalarType())
1562 const auto*DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
1565PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));
1570 for(
const Expr*Ref :
C->varlist()) {
1571 if(!Ref->getType()->isScalarType())
1573 const auto*DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
1576PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));
1585 for(
const Expr*Ref :
C->varlist()) {
1586 if(!Ref->getType()->isScalarType())
1588 const auto*DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
1591PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));
1595CGF, S, PrivateDecls);
1601 constCodeGenBoundParametersTy &CodeGenBoundParameters) {
1602 const CapturedStmt*CS = S.getCapturedStmt(OMPD_parallel);
1603llvm::Value *NumThreads =
nullptr;
1604llvm::Function *OutlinedFn =
1609CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
1610NumThreads = CGF.
EmitScalarExpr(NumThreadsClause->getNumThreads(),
1613CGF, NumThreads, NumThreadsClause->getBeginLoc());
1616CodeGenFunction::RunCleanupsScope ProcBindScope(CGF);
1618CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getBeginLoc());
1620 const Expr*IfCond =
nullptr;
1621 for(
const auto*
C: S.getClausesOfKind<
OMPIfClause>()) {
1622 if(
C->getNameModifier() == OMPD_unknown ||
1623 C->getNameModifier() == OMPD_parallel) {
1624IfCond =
C->getCondition();
1629OMPParallelScope
Scope(CGF, S);
1635CodeGenBoundParameters(CGF, S, CapturedVars);
1638CapturedVars, IfCond, NumThreads);
1643 if(!CVD->
hasAttr<OMPAllocateDeclAttr>())
1645 const auto*AA = CVD->
getAttr<OMPAllocateDeclAttr>();
1647 return!((AA->getAllocatorType() == OMPAllocateDeclAttr::OMPDefaultMemAlloc ||
1648AA->getAllocatorType() == OMPAllocateDeclAttr::OMPNullMemAlloc) &&
1649!AA->getAllocator());
1664CGF, S.getBeginLoc(), OMPD_unknown,
false,
1684Size = CGF.
Builder.CreateNUWAdd(
1693 const auto*AA = CVD->
getAttr<OMPAllocateDeclAttr>();
1694assert(AA->getAllocator() &&
1695 "Expected allocator expression for non-default allocator.");
1696llvm::Value *Allocator = CGF.
EmitScalarExpr(AA->getAllocator());
1699 if(Allocator->getType()->isIntegerTy())
1701 else if(Allocator->getType()->isPointerTy())
1705llvm::Value *Addr = OMPBuilder.createOMPAlloc(
1706CGF.
Builder, Size, Allocator,
1708llvm::CallInst *FreeCI =
1709OMPBuilder.createOMPFree(CGF.
Builder, Addr, Allocator);
1730llvm::Value *
Data=
1733std::string Suffix = getNameWithSeparators({
"cache",
""});
1736llvm::CallInst *ThreadPrivateCacheCall =
1737OMPBuilder.createCachedThreadPrivate(CGF.
Builder,
Data, Size, CacheName);
1745llvm::raw_svector_ostream OS(Buffer);
1746StringRef Sep = FirstSeparator;
1747 for(StringRef Part : Parts) {
1751 returnOS.str().str();
1758 Builder.restoreIP(CodeGenIP);
1759llvm::BasicBlock *FiniBB = splitBBWithSuffix(
Builder,
false,
1760 "."+ RegionName +
".after");
1767 if(
Builder.saveIP().isSet())
1775 Builder.restoreIP(CodeGenIP);
1776llvm::BasicBlock *FiniBB = splitBBWithSuffix(
Builder,
false,
1777 "."+ RegionName +
".after");
1784 if(
Builder.saveIP().isSet())
1792llvm::Value *IfCond =
nullptr;
1793 if(
const auto*
C= S.getSingleClause<
OMPIfClause>())
1797llvm::Value *NumThreads =
nullptr;
1802ProcBindKind ProcBind = OMP_PROC_BIND_default;
1804ProcBind = ProcBindClause->getProcBindKind();
1806 usingInsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
1810 autoFiniCB = [
this](InsertPointTy IP) {
1812 returnllvm::Error::success();
1819 autoPrivCB = [](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
1820llvm::Value &, llvm::Value &Val, llvm::Value *&ReplVal) {
1828 const CapturedStmt*CS = S.getCapturedStmt(OMPD_parallel);
1831 autoBodyGenCB = [&,
this](InsertPointTy AllocaIP,
1832InsertPointTy CodeGenIP) {
1834*
this, ParallelRegionBodyStmt, AllocaIP, CodeGenIP,
"parallel");
1835 returnllvm::Error::success();
1838CGCapturedStmtInfo CGSI(*CS,
CR_OpenMP);
1839CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*
this, &CGSI);
1840llvm::OpenMPIRBuilder::InsertPointTy AllocaIP(
1842llvm::OpenMPIRBuilder::InsertPointTy AfterIP = cantFail(
1843OMPBuilder.createParallel(
Builder, AllocaIP, BodyGenCB, PrivCB, FiniCB,
1844IfCond, NumThreads, ProcBind, S.hasCancel()));
1852OMPPrivateScope PrivateScope(CGF);
1857(void)PrivateScope.Privatize();
1858CGF.
EmitStmt(S.getCapturedStmt(OMPD_parallel)->getCapturedStmt());
1879classOMPTransformDirectiveScopeRAII {
1880OMPLoopScope *
Scope=
nullptr;
1881CodeGenFunction::CGCapturedStmtInfo *CGSI =
nullptr;
1882CodeGenFunction::CGCapturedStmtRAII *CapInfoRAII =
nullptr;
1884OMPTransformDirectiveScopeRAII(
constOMPTransformDirectiveScopeRAII &) =
1886OMPTransformDirectiveScopeRAII &
1887operator=(
constOMPTransformDirectiveScopeRAII &) =
delete;
1891 if(
const auto*Dir = dyn_cast<OMPLoopBasedDirective>(S)) {
1892 Scope=
newOMPLoopScope(CGF, *Dir);
1893CGSI =
newCodeGenFunction::CGCapturedStmtInfo(
CR_OpenMP);
1894CapInfoRAII =
newCodeGenFunction::CGCapturedStmtRAII(CGF, CGSI);
1897~OMPTransformDirectiveScopeRAII() {
1908 intMaxLevel,
intLevel = 0) {
1909assert(Level < MaxLevel &&
"Too deep lookup during loop body codegen.");
1910 const Stmt*SimplifiedS = S->IgnoreContainers();
1911 if(
const auto*CS = dyn_cast<CompoundStmt>(SimplifiedS)) {
1914 "LLVM IR generation of compound statement ('{}')");
1917CodeGenFunction::LexicalScope
Scope(CGF, S->getSourceRange());
1918 for(
const Stmt*CurStmt : CS->body())
1919 emitBody(CGF, CurStmt, NextLoop, MaxLevel, Level);
1922 if(SimplifiedS == NextLoop) {
1923 if(
auto*Dir = dyn_cast<OMPLoopTransformationDirective>(SimplifiedS))
1924SimplifiedS = Dir->getTransformedStmt();
1925 if(
const auto*CanonLoop = dyn_cast<OMPCanonicalLoop>(SimplifiedS))
1926SimplifiedS = CanonLoop->getLoopStmt();
1927 if(
const auto*For = dyn_cast<ForStmt>(SimplifiedS)) {
1930assert(isa<CXXForRangeStmt>(SimplifiedS) &&
1931 "Expected canonical for loop or range-based for loop.");
1932 const auto*CXXFor = cast<CXXForRangeStmt>(SimplifiedS);
1933CGF.
EmitStmt(CXXFor->getLoopVarStmt());
1934S = CXXFor->getBody();
1936 if(Level + 1 < MaxLevel) {
1939 emitBody(CGF, S, NextLoop, MaxLevel, Level + 1);
1948RunCleanupsScope BodyScope(*
this);
1950 for(
const Expr*UE :
D.updates())
1958 for(
const Expr*UE :
C->updates())
1965BreakContinueStack.push_back(BreakContinue(
LoopExit, Continue));
1966 for(
const Expr*
E:
D.finals_conditions()) {
1977OMPPrivateScope InscanScope(*
this);
1979 boolIsInscanRegion = InscanScope.Privatize();
1980 if(IsInscanRegion) {
1990 if(EKind != OMPD_simd && !
getLangOpts().OpenMPSimd)
1999 D.getInnermostCapturedStmt()->getCapturedStmt()->IgnoreContainers();
2004 D.getLoopsNumber());
2012BreakContinueStack.pop_back();
2023std::unique_ptr<CodeGenFunction::CGCapturedStmtInfo> CSI =
2024std::make_unique<CodeGenFunction::CGCapturedStmtInfo>(*S);
2025CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, CSI.get());
2032staticllvm::CallInst *
2037EffectiveArgs.reserve(Args.size() + 1);
2038llvm::append_range(EffectiveArgs, Args);
2039EffectiveArgs.push_back(Cap.second);
2044llvm::CanonicalLoopInfo *
2046assert(Depth == 1 &&
"Nested loops with OpenMPIRBuilder not yet implemented");
2058assert(
OMPLoopNestStack.size() >= (
size_t)Depth &&
"Found too few loops");
2072 const Stmt*SyntacticalLoop = S->getLoopStmt();
2079LexicalScope ForScope(*
this, S->getSourceRange());
2083 const Stmt*BodyStmt;
2084 if(
const auto*For = dyn_cast<ForStmt>(SyntacticalLoop)) {
2085 if(
const Stmt*InitStmt = For->getInit())
2087BodyStmt = For->getBody();
2088}
else if(
const auto*RangeFor =
2089dyn_cast<CXXForRangeStmt>(SyntacticalLoop)) {
2090 if(
const DeclStmt*RangeStmt = RangeFor->getRangeStmt())
2092 if(
const DeclStmt*BeginStmt = RangeFor->getBeginStmt())
2094 if(
const DeclStmt*EndStmt = RangeFor->getEndStmt())
2096 if(
const DeclStmt*LoopVarStmt = RangeFor->getLoopVarStmt())
2098BodyStmt = RangeFor->getBody();
2100llvm_unreachable(
"Expected for-stmt or range-based for-stmt");
2103 const CapturedStmt*DistanceFunc = S->getDistanceFunc();
2120 autoBodyGen = [&,
this](llvm::OpenMPIRBuilder::InsertPointTy CodeGenIP,
2121llvm::Value *IndVar) {
2122 Builder.restoreIP(CodeGenIP);
2126 const DeclRefExpr*LoopVarRef = S->getLoopVarRef();
2132RunCleanupsScope BodyScope(*
this);
2134 returnllvm::Error::success();
2137llvm::CanonicalLoopInfo *CL =
2138cantFail(OMPBuilder.createCanonicalLoop(
Builder, BodyGen, DistVal));
2141 Builder.restoreIP(CL->getAfterIP());
2142ForScope.ForceCleanup();
2150 const Expr*IncExpr,
2161 const auto&OMPED = cast<OMPExecutableDirective>(S);
2162 const CapturedStmt*ICS = OMPED.getInnermostCapturedStmt();
2176llvm::BasicBlock *ExitBlock =
LoopExit.getBlock();
2177 if(RequiresCleanup)
2184 if(ExitBlock !=
LoopExit.getBlock()) {
2194BreakContinueStack.push_back(BreakContinue(
LoopExit, Continue));
2201PostIncGen(*
this);
2202BreakContinueStack.pop_back();
2213 boolHasLinears =
false;
2215 for(
const Expr*
Init:
C->inits()) {
2217 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(
Init)->getDecl());
2218 if(
const auto*Ref =
2221 const auto*OrigVD = cast<VarDecl>(Ref->getDecl());
2237 if(
const auto*CS = cast_or_null<BinaryOperator>(
C->getCalcStep()))
2238 if(
const auto*SaveRef = cast<DeclRefExpr>(CS->getLHS())) {
2249 constllvm::function_ref<llvm::Value *(
CodeGenFunction&)> CondGen) {
2252llvm::BasicBlock *DoneBB =
nullptr;
2255 autoIC =
C->varlist_begin();
2256 for(
const Expr*F :
C->finals()) {
2258 if(llvm::Value *Cond = CondGen(*
this)) {
2263 Builder.CreateCondBr(Cond, ThenBB, DoneBB);
2267 const auto*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl());
2272CodeGenFunction::OMPPrivateScope VarScope(*
this);
2273VarScope.addPrivate(OrigVD, OrigAddr);
2274(void)VarScope.Privatize();
2278 if(
const Expr*PostUpdate =
C->getPostUpdateExpr())
2290llvm::APInt ClauseAlignment(64, 0);
2291 if(
const Expr*AlignmentExpr = Clause->getAlignment()) {
2294ClauseAlignment = AlignmentCI->getValue();
2296 for(
const Expr*
E: Clause->varlist()) {
2297llvm::APInt Alignment(ClauseAlignment);
2298 if(Alignment == 0) {
2308assert((Alignment == 0 || Alignment.isPowerOf2()) &&
2309 "alignment is not power of 2");
2310 if(Alignment != 0) {
2324 autoI = S.private_counters().begin();
2325 for(
const Expr*
E: S.counters()) {
2326 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
2327 const auto*PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl());
2331LocalDeclMap.erase(PrivateVD);
2332(void)LoopScope.addPrivate(VD, VarEmission.getAllocatedAddress());
2340(void)LoopScope.addPrivate(PrivateVD, VarEmission.getAllocatedAddress());
2346 if(!
C->getNumForLoops())
2348 for(
unsignedI = S.getLoopsNumber(),
E=
C->getLoopNumIterations().size();
2350 const auto*DRE = cast<DeclRefExpr>(
C->getLoopCounter(I));
2351 const auto*VD = cast<VarDecl>(DRE->getDecl());
2354 if(DRE->refersToEnclosingVariableOrCapture()) {
2355(void)LoopScope.addPrivate(
2363 const Expr*Cond, llvm::BasicBlock *TrueBlock,
2364llvm::BasicBlock *FalseBlock, uint64_t TrueCount) {
2368CodeGenFunction::OMPPrivateScope PreCondScope(CGF);
2370(void)PreCondScope.Privatize();
2372 for(
const Expr*I : S.inits()) {
2378CodeGenFunction::OMPMapVars PreCondVars;
2379 for(
const Expr*
E: S.dependent_counters()) {
2383 "dependent counter must not be an iterator.");
2384 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
2387(void)PreCondVars.setVarAddr(CGF, VD, CounterAddr);
2389(void)PreCondVars.apply(CGF);
2390 for(
const Expr*
E: S.dependent_inits()) {
2397PreCondVars.restore(CGF);
2404llvm::DenseSet<const VarDecl *> SIMDLCVs;
2407 const auto*LoopDirective = cast<OMPLoopDirective>(&
D);
2408 for(
const Expr*
C: LoopDirective->counters()) {
2414 autoCurPrivate =
C->privates().begin();
2415 for(
const Expr*
E:
C->varlist()) {
2416 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
2417 const auto*PrivateVD =
2418cast<VarDecl>(cast<DeclRefExpr>(*CurPrivate)->getDecl());
2424assert(IsRegistered &&
"linear var already registered as private");
2442 auto*Val = cast<llvm::ConstantInt>(Len.
getScalarVal());
2451 auto*Val = cast<llvm::ConstantInt>(Len.
getScalarVal());
2466 if(
C->getKind() == OMPC_ORDER_concurrent)
2469 if((EKind == OMPD_simd ||
2473return C->getModifier() == OMPC_REDUCTION_inscan;
2481 constllvm::function_ref<llvm::Value *(
CodeGenFunction&)> CondGen) {
2484llvm::BasicBlock *DoneBB =
nullptr;
2485 autoIC =
D.counters().begin();
2486 autoIPC =
D.private_counters().begin();
2487 for(
const Expr*F :
D.finals()) {
2488 const auto*OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl());
2489 const auto*PrivateVD = cast<VarDecl>(cast<DeclRefExpr>((*IPC))->getDecl());
2490 const auto*CED = dyn_cast<OMPCapturedExprDecl>(OrigVD);
2492OrigVD->hasGlobalStorage() || CED) {
2494 if(llvm::Value *Cond = CondGen(*
this)) {
2499 Builder.CreateCondBr(Cond, ThenBB, DoneBB);
2512OMPPrivateScope VarScope(*
this);
2513VarScope.addPrivate(OrigVD, OrigAddr);
2514(void)VarScope.Privatize();
2526CodeGenFunction::JumpDest
LoopExit) {
2534 autoVDecl = cast<VarDecl>(Helper->
getDecl());
2542 auto&&ThenGen = [&S, &SimdInitGen, &BodyCodeGen](
CodeGenFunction&CGF,
2545CodeGenFunction::OMPLocalDeclMapRAII
Scope(CGF);
2551CodeGenFunction::OMPLocalDeclMapRAII
Scope(CGF);
2556 const Expr*IfCond =
nullptr;
2559 for(
const auto*
C: S.getClausesOfKind<
OMPIfClause>()) {
2561(
C->getNameModifier() == OMPD_unknown ||
2562 C->getNameModifier() == OMPD_simd)) {
2563IfCond =
C->getCondition();
2578Action.
Enter(CGF);
2579OMPLoopScope PreInitScope(CGF, S);
2592(void)
EmitOMPHelperVar(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()));
2593(void)
EmitOMPHelperVar(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()));
2601llvm::BasicBlock *ContBlock =
nullptr;
2608 emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
2615 const Expr*IVExpr = S.getIterationVariable();
2616 const auto*IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
2623 if(
const auto*LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
2624CGF.
EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
2632CodeGenFunction::OMPPrivateScope LoopScope(CGF);
2638CGF, S, CGF.
EmitLValue(S.getIterationVariable()));
2640(void)LoopScope.Privatize();
2651S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(),
2653emitOMPLoopBodyWithStopPoint(CGF, S,
2654CodeGenFunction::JumpDest());
2660 if(HasLastprivateClause)
2665LoopScope.restoreMap();
2681 if(!(isa<OMPSimdlenClause>(
C) || isa<OMPSafelenClause>(
C) ||
2682isa<OMPOrderClause>(
C) || isa<OMPAlignedClause>(
C)))
2689 if(
const auto*CanonLoop = dyn_cast<OMPCanonicalLoop>(S.getRawStmt())) {
2690 if(
const Stmt*SyntacticalLoop = CanonLoop->getLoopStmt()) {
2691 for(
const Stmt*SubStmt : SyntacticalLoop->
children()) {
2694 if(
const CompoundStmt*CS = dyn_cast<CompoundStmt>(SubStmt)) {
2698 if(isa<OMPOrderedDirective>(CSSubStmt)) {
2709staticllvm::MapVector<llvm::Value *, llvm::Value *>
2711llvm::MapVector<llvm::Value *, llvm::Value *> AlignedVars;
2713llvm::APInt ClauseAlignment(64, 0);
2714 if(
const Expr*AlignmentExpr = Clause->getAlignment()) {
2717ClauseAlignment = AlignmentCI->getValue();
2719 for(
const Expr*
E: Clause->varlist()) {
2720llvm::APInt Alignment(ClauseAlignment);
2721 if(Alignment == 0) {
2731assert((Alignment == 0 || Alignment.isPowerOf2()) &&
2732 "alignment is not power of 2");
2734AlignedVars[PtrValue] = CGF.
Builder.getInt64(Alignment.getSExtValue());
2744 boolUseOMPIRBuilder =
2746 if(UseOMPIRBuilder) {
2750 if(UseOMPIRBuilder) {
2751llvm::MapVector<llvm::Value *, llvm::Value *> AlignedVars =
2754 const Stmt*Inner = S.getRawStmt();
2755llvm::CanonicalLoopInfo *CLI =
2756CGF.EmitOMPCollapsedCanonicalLoopNest(Inner, 1);
2758llvm::OpenMPIRBuilder &OMPBuilder =
2761llvm::ConstantInt *Simdlen =
nullptr;
2765 auto*Val = cast<llvm::ConstantInt>(Len.
getScalarVal());
2768llvm::ConstantInt *Safelen =
nullptr;
2772 auto*Val = cast<llvm::ConstantInt>(Len.
getScalarVal());
2775llvm::omp::OrderKind Order = llvm::omp::OrderKind::OMP_ORDER_unknown;
2777 if(
C->getKind() == OpenMPOrderClauseKind::OMPC_ORDER_concurrent) {
2778Order = llvm::omp::OrderKind::OMP_ORDER_concurrent;
2783OMPBuilder.applySimd(CLI, AlignedVars,
2784 nullptr, Order, Simdlen, Safelen);
2791OMPLexicalScope
Scope(CGF, S, OMPD_unknown);
2798CodeGenFunction::ParentLoopDirectiveForScanRegion ScanRegion(CGF, S);
2806OMPLexicalScope
Scope(CGF, S, OMPD_unknown);
2819OMPTransformDirectiveScopeRAII TileScope(*
this, &S);
2825OMPTransformDirectiveScopeRAII ReverseScope(*
this, &S);
2832OMPTransformDirectiveScopeRAII InterchangeScope(*
this, &S);
2839 if(UseOMPIRBuilder) {
2841 const Stmt*Inner = S.getRawStmt();
2852llvm::CanonicalLoopInfo *UnrolledCLI =
nullptr;
2856OMPBuilder.unrollLoopFull(DL, CLI);
2857}
else if(
auto*PartialClause = S.getSingleClause<
OMPPartialClause>()) {
2859 if(
Expr*FactorExpr = PartialClause->getFactor()) {
2860Factor = FactorExpr->EvaluateKnownConstInt(
getContext()).getZExtValue();
2861assert(Factor >= 1 &&
"Only positive factors are valid");
2863OMPBuilder.unrollLoopPartial(DL, CLI, Factor,
2864NeedsUnrolledCLI ? &UnrolledCLI :
nullptr);
2866OMPBuilder.unrollLoopHeuristic(DL, CLI);
2869assert((!NeedsUnrolledCLI || UnrolledCLI) &&
2870 "NeedsUnrolledCLI implies UnrolledCLI to be set");
2886}
else if(
auto*PartialClause = S.getSingleClause<
OMPPartialClause>()) {
2887 if(
Expr*FactorExpr = PartialClause->getFactor()) {
2889FactorExpr->EvaluateKnownConstInt(
getContext()).getZExtValue();
2890assert(Factor >= 1 &&
"Only positive factors are valid");
2898voidCodeGenFunction::EmitOMPOuterLoop(
2900CodeGenFunction::OMPPrivateScope &LoopScope,
2901 constCodeGenFunction::OMPLoopArguments &LoopArgs,
2906 const Expr*IVExpr = S.getIterationVariable();
2920llvm::Value *BoolCondVal =
nullptr;
2921 if(!DynamicOrOrdered) {
2932RT.
emitForNext(*
this, S.getBeginLoc(), IVSize, IVSigned, LoopArgs.IL,
2933LoopArgs.LB, LoopArgs.UB, LoopArgs.ST);
2938llvm::BasicBlock *ExitBlock =
LoopExit.getBlock();
2939 if(LoopScope.requiresCleanups())
2943 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
2944 if(ExitBlock !=
LoopExit.getBlock()) {
2952 if(DynamicOrOrdered)
2957BreakContinueStack.push_back(BreakContinue(
LoopExit, Continue));
2968 if(
C->getKind() == OMPC_ORDER_concurrent)
2974[&S, &LoopArgs,
LoopExit, &CodeGenLoop, IVSize, IVSigned, &CodeGenOrdered,
2982CGF.EmitOMPInnerLoop(
2983S, LoopScope.requiresCleanups(), LoopArgs.Cond, LoopArgs.IncExpr,
2985CodeGenLoop(CGF, S, LoopExit);
2988CodeGenOrdered(CGF, Loc, IVSize, IVSigned);
2993BreakContinueStack.pop_back();
2994 if(!DynamicOrOrdered) {
3007 auto&&CodeGen = [DynamicOrOrdered, &S, &LoopArgs](
CodeGenFunction&CGF) {
3008 if(!DynamicOrOrdered)
3009CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),
3012OMPCancelStack.emitExit(*
this, EKind, CodeGen);
3015voidCodeGenFunction::EmitOMPForOuterLoop(
3018 constOMPLoopArguments &LoopArgs,
3023 const boolDynamicOrOrdered = Ordered || RT.
isDynamic(ScheduleKind.
Schedule);
3026LoopArgs.Chunk !=
nullptr)) &&
3027 "static non-chunked schedule does not need outer loop");
3081 const Expr*IVExpr = S.getIterationVariable();
3085 if(DynamicOrOrdered) {
3086 conststd::pair<llvm::Value *, llvm::Value *> DispatchBounds =
3087CGDispatchBounds(*
this, S, LoopArgs.LB, LoopArgs.UB);
3088llvm::Value *LBVal = DispatchBounds.first;
3089llvm::Value *UBVal = DispatchBounds.second;
3093IVSigned, Ordered, DipatchRTInputValues);
3096IVSize, IVSigned, Ordered, LoopArgs.IL, LoopArgs.LB, LoopArgs.UB,
3097LoopArgs.ST, LoopArgs.Chunk);
3104 const unsignedIVSize,
3105 const boolIVSigned) {
3112OMPLoopArguments OuterLoopArgs(LoopArgs.LB, LoopArgs.UB, LoopArgs.ST,
3113LoopArgs.IL, LoopArgs.Chunk, LoopArgs.EUB);
3114OuterLoopArgs.IncExpr = S.getInc();
3115OuterLoopArgs.Init = S.getInit();
3116OuterLoopArgs.Cond = S.getCond();
3117OuterLoopArgs.NextLB = S.getNextLowerBound();
3118OuterLoopArgs.NextUB = S.getNextUpperBound();
3119OuterLoopArgs.DKind = LoopArgs.DKind;
3120EmitOMPOuterLoop(DynamicOrOrdered, IsMonotonic, S, LoopScope, OuterLoopArgs,
3122 if(DynamicOrOrdered) {
3128 const unsignedIVSize,
const boolIVSigned) {}
3130voidCodeGenFunction::EmitOMPDistributeOuterLoop(
3132OMPPrivateScope &LoopScope,
constOMPLoopArguments &LoopArgs,
3142 const Expr*IVExpr = S.getIterationVariable();
3148IVSize, IVSigned,
false, LoopArgs.IL, LoopArgs.LB,
3149LoopArgs.UB, LoopArgs.ST, LoopArgs.Chunk);
3156IncExpr = S.getDistInc();
3158IncExpr = S.getInc();
3163OMPLoopArguments OuterLoopArgs;
3164OuterLoopArgs.LB = LoopArgs.LB;
3165OuterLoopArgs.UB = LoopArgs.UB;
3166OuterLoopArgs.ST = LoopArgs.ST;
3167OuterLoopArgs.IL = LoopArgs.IL;
3168OuterLoopArgs.Chunk = LoopArgs.Chunk;
3170? S.getCombinedEnsureUpperBound()
3171: S.getEnsureUpperBound();
3172OuterLoopArgs.IncExpr = IncExpr;
3174? S.getCombinedInit()
3177? S.getCombinedCond()
3180? S.getCombinedNextLowerBound()
3181: S.getNextLowerBound();
3183? S.getCombinedNextUpperBound()
3184: S.getNextUpperBound();
3185OuterLoopArgs.DKind = OMPD_distribute;
3187EmitOMPOuterLoop(
false,
false, S,
3188LoopScope, OuterLoopArgs, CodeGenLoopContent,
3192staticstd::pair<LValue, LValue>
3235staticstd::pair<llvm::Value *, llvm::Value *>
3246llvm::Value *LBVal =
3248llvm::Value *UBVal =
3250 return{LBVal, UBVal};
3256 const auto&Dir = cast<OMPLoopDirective>(S);
3258CGF.
EmitLValue(cast<DeclRefExpr>(Dir.getCombinedLowerBoundVariable()));
3259llvm::Value *LBCast = CGF.
Builder.CreateIntCast(
3261CapturedVars.push_back(LBCast);
3263CGF.
EmitLValue(cast<DeclRefExpr>(Dir.getCombinedUpperBoundVariable()));
3265llvm::Value *UBCast = CGF.
Builder.CreateIntCast(
3267CapturedVars.push_back(UBCast);
3273CodeGenFunction::JumpDest
LoopExit) {
3278 boolHasCancel =
false;
3280 if(
const auto*
D= dyn_cast<OMPTeamsDistributeParallelForDirective>(&S))
3281HasCancel =
D->hasCancel();
3282 else if(
const auto*
D= dyn_cast<OMPDistributeParallelForDirective>(&S))
3283HasCancel =
D->hasCancel();
3284 else if(
const auto*
D=
3285dyn_cast<OMPTargetTeamsDistributeParallelForDirective>(&S))
3286HasCancel =
D->hasCancel();
3288CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, EKind, HasCancel);
3296CGInlinedWorksharingLoop,
3306OMPLexicalScope
Scope(*
this, S, OMPD_parallel);
3316OMPLexicalScope
Scope(*
this, S, OMPD_parallel);
3325OMPLexicalScope
Scope(*
this, S, OMPD_unknown);
3335llvm::Function *
Fn;
3336llvm::Constant *Addr;
3339S, ParentName, Fn, Addr,
true, CodeGen);
3340assert(Fn && Addr &&
"Target device function emission failed.");
3352structScheduleKindModifiersTy {
3368 const auto*IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
3369 const auto*IVDecl = cast<VarDecl>(IVExpr->getDecl());
3375 if(
const auto*LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
3383 boolHasLastprivateClause;
3386OMPLoopScope PreInitScope(*
this, S);
3391llvm::BasicBlock *ContBlock =
nullptr;
3398 emitPreCond(*
this, S, S.getPreCond(), ThenBlock, ContBlock,
3404RunCleanupsScope DoacrossCleanupScope(*
this);
3405 boolOrdered =
false;
3406 if(
const auto*OrderedClause = S.getSingleClause<
OMPOrderedClause>()) {
3407 if(OrderedClause->getNumForLoops())
3413llvm::DenseSet<const Expr *> EmittedFinals;
3418std::pair<LValue, LValue> Bounds = CodeGenLoopBounds(*
this, S);
3419 LValueLB = Bounds.first;
3420 LValueUB = Bounds.second;
3429OMPPrivateScope LoopScope(*
this);
3435*
this, S.getBeginLoc(), OMPD_unknown,
false,
3440*
this, S,
EmitLValue(S.getIterationVariable()));
3445(void)LoopScope.Privatize();
3450 const Expr*ChunkExpr =
nullptr;
3453ScheduleKind.
Schedule=
C->getScheduleKind();
3454ScheduleKind.
M1=
C->getFirstScheduleModifier();
3455ScheduleKind.
M2=
C->getSecondScheduleModifier();
3456ChunkExpr =
C->getChunkSize();
3460*
this, S, ScheduleKind.
Schedule, ChunkExpr);
3462 boolHasChunkSizeOne =
false;
3463llvm::Value *Chunk =
nullptr;
3467S.getIterationVariable()->getType(),
3471llvm::APSInt EvaluatedChunk =
Result.Val.getInt();
3472HasChunkSizeOne = (EvaluatedChunk.getLimitedValue() == 1);
3481 boolStaticChunkedOne =
3483Chunk !=
nullptr) &&
3487(ScheduleKind.
Schedule== OMPC_SCHEDULE_static &&
3488!(ScheduleKind.
M1== OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
3489ScheduleKind.
M2== OMPC_SCHEDULE_MODIFIER_nonmonotonic)) ||
3490ScheduleKind.
M1== OMPC_SCHEDULE_MODIFIER_monotonic ||
3491ScheduleKind.
M2== OMPC_SCHEDULE_MODIFIER_monotonic;
3493Chunk !=
nullptr) ||
3494StaticChunkedOne) &&
3504if (C->getKind() == OMPC_ORDER_concurrent)
3505CGF.LoopStack.setParallel(
true);
3508[IVSize, IVSigned, Ordered, IL, LB, UB, ST, StaticChunkedOne, Chunk,
3509&S, ScheduleKind,
LoopExit, EKind,
3517IVSize, IVSigned, Ordered, IL.getAddress(), LB.getAddress(),
3518UB.getAddress(), ST.getAddress(),
3519StaticChunkedOne ? Chunk :
nullptr);
3520CGF.CGM.getOpenMPRuntime().emitForStaticInit(
3521CGF, S.getBeginLoc(), EKind, ScheduleKind, StaticInit);
3523 if(!StaticChunkedOne)
3524CGF.EmitIgnoredExpr(S.getEnsureUpperBound());
3526CGF.EmitIgnoredExpr(S.getInit());
3540CGF.EmitOMPInnerLoop(
3541S, LoopScope.requiresCleanups(),
3542StaticChunkedOne ? S.getCombinedParForInDistCond()
3544StaticChunkedOne ? S.getDistInc() : S.getInc(),
3546emitOMPLoopBodyWithStopPoint(CGF, S, LoopExit);
3553CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),
3556OMPCancelStack.emitExit(*
this, EKind, CodeGen);
3560OMPLoopArguments LoopArguments(LB.getAddress(), UB.getAddress(),
3561ST.getAddress(), IL.getAddress(), Chunk,
3563LoopArguments.DKind = OMPD_for;
3564EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered,
3565LoopArguments, CGDispatchBounds);
3569 returnCGF.
Builder.CreateIsNotNull(
3575?
OMPD_parallel_for_simd
3580 returnCGF.
Builder.CreateIsNotNull(
3584 if(HasLastprivateClause)
3588LoopScope.restoreMap();
3590 returnCGF.
Builder.CreateIsNotNull(
3594DoacrossCleanupScope.ForceCleanup();
3601 returnHasLastprivateClause;
3607staticstd::pair<LValue, LValue>
3609 const auto&LS = cast<OMPLoopDirective>(S);
3621staticstd::pair<llvm::Value *, llvm::Value *>
3624 const auto&LS = cast<OMPLoopDirective>(S);
3625 const Expr*IVExpr = LS.getIterationVariable();
3627llvm::Value *LBVal = CGF.
Builder.getIntN(IVSize, 0);
3628llvm::Value *UBVal = CGF.
EmitScalarExpr(LS.getLastIteration());
3629 return{LBVal, UBVal};
3641llvm::function_ref<llvm::Value *(
CodeGenFunction&)> NumIteratorsGen) {
3642llvm::Value *OMPScanNumIterations = CGF.
Builder.CreateIntCast(
3643NumIteratorsGen(CGF), CGF.
SizeTy,
false);
3649assert(
C->getModifier() == OMPC_REDUCTION_inscan &&
3650 "Only inscan reductions are expected.");
3651Shareds.append(
C->varlist_begin(),
C->varlist_end());
3652Privates.append(
C->privates().begin(),
C->privates().end());
3653ReductionOps.append(
C->reduction_ops().begin(),
C->reduction_ops().end());
3654CopyArrayTemps.append(
C->copy_array_temps().begin(),
3655 C->copy_array_temps().end());
3663 auto*ITA = CopyArrayTemps.begin();
3664 for(
const Expr*IRef : Privates) {
3665 const auto*PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl());
3668 if(PrivateVD->getType()->isVariablyModifiedType()) {
3672CodeGenFunction::OpaqueValueMapping DimMapping(
3674cast<OpaqueValueExpr>(
3675cast<VariableArrayType>((*ITA)->getType()->getAsArrayTypeUnsafe())
3679CGF.
EmitVarDecl(*cast<VarDecl>(cast<DeclRefExpr>(*ITA)->getDecl()));
3693llvm::function_ref<llvm::Value *(
CodeGenFunction&)> NumIteratorsGen) {
3694llvm::Value *OMPScanNumIterations = CGF.
Builder.CreateIntCast(
3695NumIteratorsGen(CGF), CGF.
SizeTy,
false);
3703assert(
C->getModifier() == OMPC_REDUCTION_inscan &&
3704 "Only inscan reductions are expected.");
3705Shareds.append(
C->varlist_begin(),
C->varlist_end());
3706LHSs.append(
C->lhs_exprs().begin(),
C->lhs_exprs().end());
3707RHSs.append(
C->rhs_exprs().begin(),
C->rhs_exprs().end());
3708Privates.append(
C->privates().begin(),
C->privates().end());
3709CopyOps.append(
C->copy_ops().begin(),
C->copy_ops().end());
3710CopyArrayElems.append(
C->copy_array_elems().begin(),
3711 C->copy_array_elems().end());
3715llvm::Value *OMPLast = CGF.
Builder.CreateNSWSub(
3716OMPScanNumIterations,
3717llvm::ConstantInt::get(CGF.
SizeTy, 1,
false));
3718 for(
unsignedI = 0,
E= CopyArrayElems.size(); I <
E; ++I) {
3719 const Expr*PrivateExpr = Privates[I];
3720 const Expr*OrigExpr = Shareds[I];
3721 const Expr*CopyArrayElem = CopyArrayElems[I];
3722CodeGenFunction::OpaqueValueMapping IdxMapping(
3724cast<OpaqueValueExpr>(
3725cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),
3731cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),
3732cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()), CopyOps[I]);
3757llvm::function_ref<llvm::Value *(
CodeGenFunction&)> NumIteratorsGen,
3760llvm::Value *OMPScanNumIterations = CGF.
Builder.CreateIntCast(
3761NumIteratorsGen(CGF), CGF.
SizeTy,
false);
3768assert(
C->getModifier() == OMPC_REDUCTION_inscan &&
3769 "Only inscan reductions are expected.");
3770Privates.append(
C->privates().begin(),
C->privates().end());
3771ReductionOps.append(
C->reduction_ops().begin(),
C->reduction_ops().end());
3772LHSs.append(
C->lhs_exprs().begin(),
C->lhs_exprs().end());
3773RHSs.append(
C->rhs_exprs().begin(),
C->rhs_exprs().end());
3774CopyArrayElems.append(
C->copy_array_elems().begin(),
3775 C->copy_array_elems().end());
3777CodeGenFunction::ParentLoopDirectiveForScanRegion ScanRegion(CGF, S);
3786CodeGenFunction::OMPLocalDeclMapRAII
Scope(CGF);
3790 auto&&CodeGen = [&S, OMPScanNumIterations, &LHSs, &RHSs, &CopyArrayElems,
3797llvm::BasicBlock *InputBB = CGF.Builder.GetInsertBlock();
3798llvm::BasicBlock *LoopBB = CGF.createBasicBlock(
"omp.outer.log.scan.body");
3799llvm::BasicBlock *ExitBB = CGF.createBasicBlock(
"omp.outer.log.scan.exit");
3801CGF.CGM.getIntrinsic(llvm::Intrinsic::log2, CGF.DoubleTy);
3803CGF.Builder.CreateUIToFP(OMPScanNumIterations, CGF.DoubleTy);
3804llvm::Value *LogVal = CGF.EmitNounwindRuntimeCall(F, Arg);
3805F = CGF.CGM.getIntrinsic(llvm::Intrinsic::ceil, CGF.DoubleTy);
3806LogVal = CGF.EmitNounwindRuntimeCall(F, LogVal);
3807LogVal = CGF.Builder.CreateFPToUI(LogVal, CGF.IntTy);
3808llvm::Value *NMin1 = CGF.Builder.CreateNUWSub(
3809OMPScanNumIterations, llvm::ConstantInt::get(CGF.SizeTy, 1));
3811CGF.EmitBlock(LoopBB);
3812 auto*Counter = CGF.Builder.CreatePHI(CGF.IntTy, 2);
3814 auto*Pow2K = CGF.Builder.CreatePHI(CGF.SizeTy, 2);
3815Counter->addIncoming(llvm::ConstantInt::get(CGF.IntTy, 0), InputBB);
3816Pow2K->addIncoming(llvm::ConstantInt::get(CGF.SizeTy, 1), InputBB);
3819llvm::BasicBlock *InnerLoopBB =
3820CGF.createBasicBlock(
"omp.inner.log.scan.body");
3821llvm::BasicBlock *InnerExitBB =
3822CGF.createBasicBlock(
"omp.inner.log.scan.exit");
3823llvm::Value *CmpI = CGF.Builder.CreateICmpUGE(NMin1, Pow2K);
3824CGF.Builder.CreateCondBr(CmpI, InnerLoopBB, InnerExitBB);
3825CGF.EmitBlock(InnerLoopBB);
3826 auto*IVal = CGF.Builder.CreatePHI(CGF.SizeTy, 2);
3827IVal->addIncoming(NMin1, LoopBB);
3829CodeGenFunction::OMPPrivateScope PrivScope(CGF);
3830 auto*ILHS = LHSs.begin();
3831 auto*IRHS = RHSs.begin();
3832 for(
const Expr*CopyArrayElem : CopyArrayElems) {
3833 const auto*LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
3834 const auto*RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
3837CodeGenFunction::OpaqueValueMapping IdxMapping(
3839cast<OpaqueValueExpr>(
3840cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),
3842LHSAddr = CGF.EmitLValue(CopyArrayElem).getAddress();
3844PrivScope.addPrivate(LHSVD, LHSAddr);
3847llvm::Value *OffsetIVal = CGF.Builder.CreateNUWSub(IVal, Pow2K);
3848CodeGenFunction::OpaqueValueMapping IdxMapping(
3850cast<OpaqueValueExpr>(
3851cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),
3853RHSAddr = CGF.EmitLValue(CopyArrayElem).getAddress();
3855PrivScope.addPrivate(RHSVD, RHSAddr);
3859PrivScope.Privatize();
3860CGF.CGM.getOpenMPRuntime().emitReduction(
3861CGF, S.getEndLoc(), Privates, LHSs, RHSs, ReductionOps,
3862{
true,
true, OMPD_unknown});
3864llvm::Value *NextIVal =
3865CGF.Builder.CreateNUWSub(IVal, llvm::ConstantInt::get(CGF.SizeTy, 1));
3866IVal->addIncoming(NextIVal, CGF.Builder.GetInsertBlock());
3867CmpI = CGF.Builder.CreateICmpUGE(NextIVal, Pow2K);
3868CGF.Builder.CreateCondBr(CmpI, InnerLoopBB, InnerExitBB);
3869CGF.EmitBlock(InnerExitBB);
3871CGF.Builder.CreateNUWAdd(Counter, llvm::ConstantInt::get(CGF.IntTy, 1));
3872Counter->addIncoming(Next, CGF.Builder.GetInsertBlock());
3874llvm::Value *NextPow2K =
3875CGF.Builder.CreateShl(Pow2K, 1,
"",
true);
3876Pow2K->addIncoming(NextPow2K, CGF.Builder.GetInsertBlock());
3877llvm::Value *Cmp = CGF.Builder.CreateICmpNE(Next, LogVal);
3878CGF.Builder.CreateCondBr(Cmp, LoopBB, ExitBB);
3880CGF.EmitBlock(ExitBB);
3884CGF.CGM.getOpenMPRuntime().emitMasterRegion(CGF, CodeGen, S.getBeginLoc());
3885CGF.CGM.getOpenMPRuntime().emitBarrierCall(
3886CGF, S.getBeginLoc(), OMPD_unknown,
false,
3893CGF.OMPFirstScanLoop =
false;
3900 boolHasLastprivates;
3904return C->getModifier() == OMPC_REDUCTION_inscan;
3907CodeGenFunction::OMPLocalDeclMapRAII
Scope(CGF);
3908OMPLoopScope LoopScope(CGF, S);
3911 const auto&&FirstGen = [&S, HasCancel, EKind](
CodeGenFunction&CGF) {
3912CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, EKind, HasCancel);
3920 const auto&&SecondGen = [&S, HasCancel, EKind,
3922CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, EKind, HasCancel);
3933CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, EKind, HasCancel);
3938 returnHasLastprivates;
3948 if(isa<OMPNowaitClause, OMPBindClause>(
C))
3951 if(
auto*SC = dyn_cast<OMPScheduleClause>(
C)) {
3956 switch(SC->getScheduleKind()) {
3957 caseOMPC_SCHEDULE_auto:
3958 caseOMPC_SCHEDULE_dynamic:
3959 caseOMPC_SCHEDULE_runtime:
3960 caseOMPC_SCHEDULE_guided:
3961 caseOMPC_SCHEDULE_static:
3974staticllvm::omp::ScheduleKind
3976 switch(ScheduleClauseKind) {
3978 returnllvm::omp::OMP_SCHEDULE_Default;
3979 caseOMPC_SCHEDULE_auto:
3980 returnllvm::omp::OMP_SCHEDULE_Auto;
3981 caseOMPC_SCHEDULE_dynamic:
3982 returnllvm::omp::OMP_SCHEDULE_Dynamic;
3983 caseOMPC_SCHEDULE_guided:
3984 returnllvm::omp::OMP_SCHEDULE_Guided;
3985 caseOMPC_SCHEDULE_runtime:
3986 returnllvm::omp::OMP_SCHEDULE_Runtime;
3987 caseOMPC_SCHEDULE_static:
3988 returnllvm::omp::OMP_SCHEDULE_Static;
3990llvm_unreachable(
"Unhandled schedule kind");
3997 boolHasLastprivates =
false;
4000 auto&&CodeGen = [&S, &
CGM, HasCancel, &HasLastprivates,
4003 if(UseOMPIRBuilder) {
4006llvm::omp::ScheduleKind SchedKind = llvm::omp::OMP_SCHEDULE_Default;
4007llvm::Value *ChunkSize =
nullptr;
4011 if(
const Expr*ChunkSizeExpr = SchedClause->getChunkSize())
4016 const Stmt*Inner = S.getRawStmt();
4017llvm::CanonicalLoopInfo *CLI =
4020llvm::OpenMPIRBuilder &OMPBuilder =
4022llvm::OpenMPIRBuilder::InsertPointTy AllocaIP(
4024cantFail(OMPBuilder.applyWorkshareLoop(
4025CGF.
Builder.getCurrentDebugLocation(), CLI, AllocaIP, NeedsBarrier,
4026SchedKind, ChunkSize,
false,
4037OMPLexicalScope
Scope(CGF, S, OMPD_unknown);
4042 if(!UseOMPIRBuilder) {
4056 boolHasLastprivates =
false;
4064OMPLexicalScope
Scope(*
this, S, OMPD_unknown);
4077llvm::Value *
Init=
nullptr) {
4085 const Stmt*
CapturedStmt= S.getInnermostCapturedStmt()->getCapturedStmt();
4086 const auto*CS = dyn_cast<CompoundStmt>(
CapturedStmt);
4087 boolHasLastprivates =
false;
4093 C.getIntTypeForBitwidth(
32,
1);
4096CGF.Builder.getInt32(0));
4097llvm::ConstantInt *GlobalUBVal = CS !=
nullptr 4098? CGF.Builder.getInt32(CS->size() - 1)
4099: CGF.Builder.getInt32(0);
4103CGF.Builder.getInt32(1));
4105CGF.Builder.getInt32(0));
4109CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV);
4111CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
4132llvm::BasicBlock *ExitBB = CGF.createBasicBlock(
".omp.sections.exit");
4134CGF.Builder.CreateSwitch(CGF.EmitLoadOfScalar(IV, S.getBeginLoc()),
4135ExitBB, CS ==
nullptr? 1 : CS->size());
4137 unsignedCaseNumber = 0;
4139 autoCaseBB = CGF.createBasicBlock(
".omp.sections.case");
4140CGF.EmitBlock(CaseBB);
4141 SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB);
4142CGF.EmitStmt(SubStmt);
4143CGF.EmitBranch(ExitBB);
4147llvm::BasicBlock *CaseBB = CGF.createBasicBlock(
".omp.sections.case");
4148CGF.EmitBlock(CaseBB);
4149 SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB);
4151CGF.EmitBranch(ExitBB);
4153CGF.EmitBlock(ExitBB,
true);
4156CodeGenFunction::OMPPrivateScope LoopScope(CGF);
4157 if(CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
4161CGF.CGM.getOpenMPRuntime().emitBarrierCall(
4162CGF, S.getBeginLoc(), OMPD_unknown,
false,
4165CGF.EmitOMPPrivateClause(S, LoopScope);
4167HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
4168CGF.EmitOMPReductionClauseInit(S, LoopScope);
4169(void)LoopScope.Privatize();
4171CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
4175ScheduleKind.
Schedule= OMPC_SCHEDULE_static;
4179CGF.CGM.getOpenMPRuntime().emitForStaticInit(CGF, S.getBeginLoc(), EKind,
4180ScheduleKind, StaticInit);
4182llvm::Value *UBVal = CGF.EmitLoadOfScalar(UB, S.getBeginLoc());
4183llvm::Value *MinUBGlobalUB = CGF.Builder.CreateSelect(
4184CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
4185CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
4187CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getBeginLoc()), IV);
4189CGF.EmitOMPInnerLoop(S,
false, Cond, Inc, BodyGen,
4193CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),
4196CGF.OMPCancelStack.emitExit(CGF, EKind, CodeGen);
4197CGF.EmitOMPReductionClauseFinal(S,
OMPD_parallel);
4200 returnCGF.
Builder.CreateIsNotNull(
4205 if(HasLastprivates)
4208CGF.
Builder.CreateIsNotNull(
4212 boolHasCancel =
false;
4213 if(
auto*OSD = dyn_cast<OMPSectionsDirective>(&S))
4214HasCancel = OSD->hasCancel();
4215 else if(
auto*OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
4216HasCancel = OPSD->hasCancel();
4217OMPCancelStackRAII CancelRegion(*
this, EKind, HasCancel);
4236OMPPrivateScope PrivateScope(CGF);
4240(void)PrivateScope.Privatize();
4241CGF.
EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
4246OMPLexicalScope
Scope(*
this, S, OMPD_unknown);
4260 usingInsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
4261 usingBodyGenCallbackTy = llvm::OpenMPIRBuilder::StorableBodyGenCallbackTy;
4263 autoFiniCB = [
this](InsertPointTy IP) {
4265 returnllvm::Error::success();
4268 const CapturedStmt*ICS = S.getInnermostCapturedStmt();
4269 const Stmt*
CapturedStmt= S.getInnermostCapturedStmt()->getCapturedStmt();
4270 const auto*CS = dyn_cast<CompoundStmt>(
CapturedStmt);
4274 autoSectionCB = [
this, SubStmt](InsertPointTy AllocaIP,
4275InsertPointTy CodeGenIP) {
4277*
this, SubStmt, AllocaIP, CodeGenIP,
"section");
4278 returnllvm::Error::success();
4280SectionCBVector.push_back(SectionCB);
4283 autoSectionCB = [
this,
CapturedStmt](InsertPointTy AllocaIP,
4284InsertPointTy CodeGenIP) {
4286*
this,
CapturedStmt, AllocaIP, CodeGenIP,
"section");
4287 returnllvm::Error::success();
4289SectionCBVector.push_back(SectionCB);
4296 autoPrivCB = [](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
4297llvm::Value &, llvm::Value &Val, llvm::Value *&ReplVal) {
4305CGCapturedStmtInfo CGSI(*ICS,
CR_OpenMP);
4306CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*
this, &CGSI);
4307llvm::OpenMPIRBuilder::InsertPointTy AllocaIP(
4309llvm::OpenMPIRBuilder::InsertPointTy AfterIP =
4310cantFail(OMPBuilder.createSections(
4311 Builder, AllocaIP, SectionCBVector, PrivCB, FiniCB, S.hasCancel(),
4319OMPLexicalScope
Scope(*
this, S, OMPD_unknown);
4334 usingInsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
4336 const Stmt*SectionRegionBodyStmt = S.getAssociatedStmt();
4337 autoFiniCB = [
this](InsertPointTy IP) {
4339 returnllvm::Error::success();
4342 autoBodyGenCB = [SectionRegionBodyStmt,
this](InsertPointTy AllocaIP,
4343InsertPointTy CodeGenIP) {
4345*
this, SectionRegionBodyStmt, AllocaIP, CodeGenIP,
"section");
4346 returnllvm::Error::success();
4349LexicalScope
Scope(*
this, S.getSourceRange());
4351llvm::OpenMPIRBuilder::InsertPointTy AfterIP =
4352cantFail(OMPBuilder.createSection(
Builder, BodyGenCB, FiniCB));
4357LexicalScope
Scope(*
this, S.getSourceRange());
4372CopyprivateVars.append(
C->varlist_begin(),
C->varlist_end());
4373DestExprs.append(
C->destination_exprs().begin(),
4374 C->destination_exprs().end());
4375SrcExprs.append(
C->source_exprs().begin(),
C->source_exprs().end());
4376AssignmentOps.append(
C->assignment_ops().begin(),
4377 C->assignment_ops().end());
4386CGF.
EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
4391OMPLexicalScope
Scope(*
this, S, OMPD_unknown);
4393CopyprivateVars, DestExprs,
4394SrcExprs, AssignmentOps);
4398 if(!S.getSingleClause<
OMPNowaitClause>() && CopyprivateVars.empty()) {
4400*
this, S.getBeginLoc(),
4418 usingInsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
4420 const Stmt*MasterRegionBodyStmt = S.getAssociatedStmt();
4422 autoFiniCB = [
this](InsertPointTy IP) {
4424 returnllvm::Error::success();
4427 autoBodyGenCB = [MasterRegionBodyStmt,
this](InsertPointTy AllocaIP,
4428InsertPointTy CodeGenIP) {
4430*
this, MasterRegionBodyStmt, AllocaIP, CodeGenIP,
"master");
4431 returnllvm::Error::success();
4434LexicalScope
Scope(*
this, S.getSourceRange());
4436llvm::OpenMPIRBuilder::InsertPointTy AfterIP =
4437cantFail(OMPBuilder.createMaster(
Builder, BodyGenCB, FiniCB));
4442LexicalScope
Scope(*
this, S.getSourceRange());
4452 Expr*Filter =
nullptr;
4453 if(
const auto*FilterClause = S.getSingleClause<
OMPFilterClause>())
4454Filter = FilterClause->getThreadID();
4462 usingInsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
4464 const Stmt*MaskedRegionBodyStmt = S.getAssociatedStmt();
4466 if(
const auto*FilterClause = S.getSingleClause<
OMPFilterClause>())
4467 Filter= FilterClause->getThreadID();
4468llvm::Value *FilterVal =
Filter 4472 autoFiniCB = [
this](InsertPointTy IP) {
4474 returnllvm::Error::success();
4477 autoBodyGenCB = [MaskedRegionBodyStmt,
this](InsertPointTy AllocaIP,
4478InsertPointTy CodeGenIP) {
4480*
this, MaskedRegionBodyStmt, AllocaIP, CodeGenIP,
"masked");
4481 returnllvm::Error::success();
4484LexicalScope
Scope(*
this, S.getSourceRange());
4486llvm::OpenMPIRBuilder::InsertPointTy AfterIP = cantFail(
4487OMPBuilder.createMasked(
Builder, BodyGenCB, FiniCB, FilterVal));
4492LexicalScope
Scope(*
this, S.getSourceRange());
4500 usingInsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
4502 const Stmt*CriticalRegionBodyStmt = S.getAssociatedStmt();
4503 const Expr*Hint =
nullptr;
4504 if(
const auto*HintClause = S.getSingleClause<
OMPHintClause>())
4505Hint = HintClause->getHint();
4510llvm::Value *HintInst =
nullptr;
4515 autoFiniCB = [
this](InsertPointTy IP) {
4517 returnllvm::Error::success();
4520 autoBodyGenCB = [CriticalRegionBodyStmt,
this](InsertPointTy AllocaIP,
4521InsertPointTy CodeGenIP) {
4523*
this, CriticalRegionBodyStmt, AllocaIP, CodeGenIP,
"critical");
4524 returnllvm::Error::success();
4527LexicalScope
Scope(*
this, S.getSourceRange());
4529llvm::OpenMPIRBuilder::InsertPointTy AfterIP =
4530cantFail(OMPBuilder.createCritical(
Builder, BodyGenCB, FiniCB,
4531S.getDirectiveName().getAsString(),
4540CGF.
EmitStmt(S.getAssociatedStmt());
4542 const Expr*Hint =
nullptr;
4543 if(
const auto*HintClause = S.getSingleClause<
OMPHintClause>())
4544Hint = HintClause->getHint();
4545LexicalScope
Scope(*
this, S.getSourceRange());
4548S.getDirectiveName().getAsString(),
4549CodeGen, S.getBeginLoc(), Hint);
4563CodeGenFunction::OMPLocalDeclMapRAII
Scope(CGF);
4565CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGSI);
4566OMPLoopScope LoopScope(CGF, S);
4571return C->getModifier() == OMPC_REDUCTION_inscan;
4597CodeGenFunction::OMPLocalDeclMapRAII
Scope(CGF);
4599CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGSI);
4600OMPLoopScope LoopScope(CGF, S);
4605return C->getModifier() == OMPC_REDUCTION_inscan;
4626OMPPrivateScope PrivateScope(CGF);
4631(void)PrivateScope.Privatize();
4653OMPPrivateScope PrivateScope(CGF);
4658(void)PrivateScope.Privatize();
4681CGF.EmitSections(S);
4695classCheckVarsEscapingUntiedTaskDeclContext final
4700 explicitCheckVarsEscapingUntiedTaskDeclContext() =
default;
4701 virtual~CheckVarsEscapingUntiedTaskDeclContext() =
default;
4702 voidVisitDeclStmt(
const DeclStmt*S) {
4706 for(
const Decl*
D: S->decls()) {
4707 if(
const auto*VD = dyn_cast_or_null<VarDecl>(
D))
4709PrivateDecls.push_back(VD);
4715 voidVisitBlockExpr(
const BlockExpr*) {}
4716 voidVisitStmt(
const Stmt*S) {
4719 for(
const Stmt*Child : S->children())
4733 boolOmpAllMemory =
false;
4736return C->getDependencyKind() == OMPC_DEPEND_outallmemory ||
4737C->getDependencyKind() == OMPC_DEPEND_inoutallmemory;
4739OmpAllMemory =
true;
4744 Data.Dependences.emplace_back(OMPC_DEPEND_outallmemory,
4747DD.
DepExprs.push_back(
nullptr);
4753 if(Kind == OMPC_DEPEND_outallmemory || Kind == OMPC_DEPEND_inoutallmemory)
4755 if(OmpAllMemory && (Kind == OMPC_DEPEND_out || Kind == OMPC_DEPEND_inout))
4758 Data.Dependences.emplace_back(
C->getDependencyKind(),
C->getModifier());
4759DD.
DepExprs.append(
C->varlist_begin(),
C->varlist_end());
4768 const CapturedStmt*CS = S.getCapturedStmt(CapturedRegion);
4770 autoPartId = std::next(I);
4771 autoTaskT = std::next(I, 4);
4773 if(
const auto*Clause = S.getSingleClause<
OMPFinalClause>()) {
4776 const Expr*Cond = Clause->getCondition();
4779 Data.Final.setInt(CondConstant);
4784 Data.Final.setInt(
false);
4788 const Expr*Prio = Clause->getPriority();
4789 Data.Priority.setInt(
true);
4797llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
4800 autoIRef =
C->varlist_begin();
4801 for(
const Expr*IInit :
C->private_copies()) {
4802 const auto*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
4803 if(EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
4804 Data.PrivateVars.push_back(*IRef);
4805 Data.PrivateCopies.push_back(IInit);
4810EmittedAsPrivate.clear();
4813 autoIRef =
C->varlist_begin();
4814 autoIElemInitRef =
C->inits().begin();
4815 for(
const Expr*IInit :
C->private_copies()) {
4816 const auto*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
4817 if(EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
4818 Data.FirstprivateVars.push_back(*IRef);
4819 Data.FirstprivateCopies.push_back(IInit);
4820 Data.FirstprivateInits.push_back(*IElemInitRef);
4827llvm::MapVector<const VarDecl *, const DeclRefExpr *> LastprivateDstsOrigs;
4829 autoIRef =
C->varlist_begin();
4830 auto ID=
C->destination_exprs().begin();
4831 for(
const Expr*IInit :
C->private_copies()) {
4832 const auto*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
4833 if(EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
4834 Data.LastprivateVars.push_back(*IRef);
4835 Data.LastprivateCopies.push_back(IInit);
4837LastprivateDstsOrigs.insert(
4838std::make_pair(cast<VarDecl>(cast<DeclRefExpr>(*ID)->getDecl()),
4839cast<DeclRefExpr>(*IRef)));
4847 Data.ReductionVars.append(
C->varlist_begin(),
C->varlist_end());
4848 Data.ReductionOrigs.append(
C->varlist_begin(),
C->varlist_end());
4849 Data.ReductionCopies.append(
C->privates().begin(),
C->privates().end());
4850 Data.ReductionOps.append(
C->reduction_ops().begin(),
4851 C->reduction_ops().end());
4852LHSs.append(
C->lhs_exprs().begin(),
C->lhs_exprs().end());
4853RHSs.append(
C->rhs_exprs().begin(),
C->rhs_exprs().end());
4856*
this, S.getBeginLoc(), LHSs, RHSs,
Data);
4861CheckVarsEscapingUntiedTaskDeclContext Checker;
4862Checker.Visit(S.getInnermostCapturedStmt()->getCapturedStmt());
4863 Data.PrivateLocals.append(Checker.getPrivateDecls().begin(),
4864Checker.getPrivateDecls().end());
4866 auto&&CodeGen = [&
Data, &S, CS, &BodyGen, &LastprivateDstsOrigs,
4869llvm::MapVector<CanonicalDeclPtr<const VarDecl>,
4870std::pair<Address, Address>>
4873OMPPrivateScope
Scope(CGF);
4875 if(
auto*DI = CGF.getDebugInfo()) {
4876llvm::SmallDenseMap<const VarDecl *, FieldDecl *> CaptureFields =
4877CGF.CapturedStmtInfo->getCaptureFields();
4878llvm::Value *ContextValue = CGF.CapturedStmtInfo->getContextValue();
4879 if(CaptureFields.size() && ContextValue) {
4880 unsignedCharWidth = CGF.getContext().getCharWidth();
4894 for(
autoIt = CaptureFields.begin(); It != CaptureFields.end(); ++It) {
4895 const VarDecl*SharedVar = It->first;
4898CGF.getContext().getASTRecordLayout(CaptureRecord);
4900Layout.
getFieldOffset(It->second->getFieldIndex()) / CharWidth;
4901 if(CGF.CGM.getCodeGenOpts().hasReducedDebugInfo())
4902(void)DI->EmitDeclareOfAutoVariable(SharedVar, ContextValue,
4903CGF.Builder,
false);
4906 autoUpdateExpr = [](llvm::LLVMContext &Ctx,
auto*
Declare,
4911Ops.push_back(llvm::dwarf::DW_OP_plus_uconst);
4912Ops.push_back(Offset);
4914Ops.push_back(llvm::dwarf::DW_OP_deref);
4915 Declare->setExpression(llvm::DIExpression::get(Ctx, Ops));
4917llvm::Instruction &
Last= CGF.Builder.GetInsertBlock()->back();
4918 if(
autoDDI = dyn_cast<llvm::DbgVariableIntrinsic>(&
Last))
4919UpdateExpr(DDI->getContext(), DDI, Offset);
4922assert(!
Last.isTerminator() &&
"unexpected terminator");
4924CGF.Builder.GetInsertBlock()->getTrailingDbgRecords()) {
4925 for(llvm::DbgVariableRecord &DVR : llvm::reverse(
4926llvm::filterDbgVars(Marker->getDbgRecordRange()))) {
4927UpdateExpr(
Last.getContext(), &DVR, Offset);
4935 if(!
Data.PrivateVars.empty() || !
Data.FirstprivateVars.empty() ||
4936!
Data.LastprivateVars.empty() || !
Data.PrivateLocals.empty()) {
4937 enum{ PrivatesParam = 2, CopyFnParam = 3 };
4938llvm::Value *CopyFn = CGF.Builder.CreateLoad(
4939CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));
4940llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(
4941CS->getCapturedDecl()->getParam(PrivatesParam)));
4946CallArgs.push_back(PrivatesPtr);
4947ParamTypes.push_back(PrivatesPtr->getType());
4948 for(
const Expr*
E:
Data.PrivateVars) {
4949 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
4951CGF.getContext().getPointerType(
E->
getType()),
".priv.ptr.addr");
4952PrivatePtrs.emplace_back(VD, PrivatePtr);
4953CallArgs.push_back(PrivatePtr.
getPointer());
4954ParamTypes.push_back(PrivatePtr.
getType());
4956 for(
const Expr*
E:
Data.FirstprivateVars) {
4957 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
4959CGF.CreateMemTemp(CGF.getContext().getPointerType(
E->
getType()),
4960 ".firstpriv.ptr.addr");
4961PrivatePtrs.emplace_back(VD, PrivatePtr);
4962FirstprivatePtrs.emplace_back(VD, PrivatePtr);
4963CallArgs.push_back(PrivatePtr.
getPointer());
4964ParamTypes.push_back(PrivatePtr.
getType());
4966 for(
const Expr*
E:
Data.LastprivateVars) {
4967 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
4969CGF.CreateMemTemp(CGF.getContext().getPointerType(
E->
getType()),
4970 ".lastpriv.ptr.addr");
4971PrivatePtrs.emplace_back(VD, PrivatePtr);
4972CallArgs.push_back(PrivatePtr.
getPointer());
4973ParamTypes.push_back(PrivatePtr.
getType());
4978Ty = CGF.getContext().getPointerType(Ty);
4980Ty = CGF.getContext().getPointerType(Ty);
4982CGF.getContext().getPointerType(Ty),
".local.ptr.addr");
4983 auto Result= UntiedLocalVars.insert(
4986 if(
Result.second ==
false)
4987*
Result.first = std::make_pair(
4989CallArgs.push_back(PrivatePtr.
getPointer());
4990ParamTypes.push_back(PrivatePtr.
getType());
4992 auto*CopyFnTy = llvm::FunctionType::get(CGF.Builder.getVoidTy(),
4993ParamTypes,
false);
4994CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
4995CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);
4996 for(
const auto&Pair : LastprivateDstsOrigs) {
4997 const auto*OrigVD = cast<VarDecl>(Pair.second->getDecl());
5000CGF.CapturedStmtInfo->lookup(OrigVD) !=
nullptr,
5002Pair.second->getExprLoc());
5003 Scope.addPrivate(Pair.first, CGF.EmitLValue(&DRE).getAddress());
5005 for(
const auto&Pair : PrivatePtrs) {
5007CGF.Builder.CreateLoad(Pair.second),
5008CGF.ConvertTypeForMem(Pair.first->getType().getNonReferenceType()),
5009CGF.getContext().getDeclAlign(Pair.first));
5010 Scope.addPrivate(Pair.first, Replacement);
5011 if(
auto*DI = CGF.getDebugInfo())
5012 if(CGF.CGM.getCodeGenOpts().hasReducedDebugInfo())
5013(void)DI->EmitDeclareOfAutoVariable(
5014Pair.first, Pair.second.getBasePointer(), CGF.Builder,
5019 for(
auto&Pair : UntiedLocalVars) {
5020 QualTypeVDType = Pair.first->getType().getNonReferenceType();
5021 if(Pair.first->getType()->isLValueReferenceType())
5022VDType = CGF.getContext().getPointerType(VDType);
5024llvm::Value *Ptr = CGF.Builder.CreateLoad(Pair.second.first);
5027CGF.ConvertTypeForMem(CGF.getContext().getPointerType(VDType)),
5028CGF.getPointerAlign());
5029Pair.second.first = Replacement;
5030Ptr = CGF.Builder.CreateLoad(Replacement);
5031Replacement =
Address(Ptr, CGF.ConvertTypeForMem(VDType),
5032CGF.getContext().getDeclAlign(Pair.first));
5033Pair.second.second = Replacement;
5035llvm::Value *Ptr = CGF.Builder.CreateLoad(Pair.second.first);
5036 AddressReplacement(Ptr, CGF.ConvertTypeForMem(VDType),
5037CGF.getContext().getDeclAlign(Pair.first));
5038Pair.second.first = Replacement;
5042 if(
Data.Reductions) {
5043OMPPrivateScope FirstprivateScope(CGF);
5044 for(
const auto&Pair : FirstprivatePtrs) {
5046CGF.Builder.CreateLoad(Pair.second),
5047CGF.ConvertTypeForMem(Pair.first->getType().getNonReferenceType()),
5048CGF.getContext().getDeclAlign(Pair.first));
5049FirstprivateScope.addPrivate(Pair.first, Replacement);
5051(void)FirstprivateScope.Privatize();
5052OMPLexicalScope LexScope(CGF, S, CapturedRegion);
5054 Data.ReductionCopies,
Data.ReductionOps);
5055llvm::Value *ReductionsPtr = CGF.Builder.CreateLoad(
5056CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(9)));
5057 for(
unsignedCnt = 0,
E=
Data.ReductionVars.size(); Cnt <
E; ++Cnt) {
5058RedCG.emitSharedOrigLValue(CGF, Cnt);
5059RedCG.emitAggregateType(CGF, Cnt);
5063CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(),
5065 AddressReplacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem(
5066CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));
5068CGF.EmitScalarConversion(Replacement.emitRawPointer(CGF),
5069CGF.getContext().VoidPtrTy,
5070CGF.getContext().getPointerType(
5071 Data.ReductionCopies[Cnt]->getType()),
5072 Data.ReductionCopies[Cnt]->getExprLoc()),
5073CGF.ConvertTypeForMem(
Data.ReductionCopies[Cnt]->getType()),
5074Replacement.getAlignment());
5075Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);
5076 Scope.addPrivate(RedCG.getBaseDecl(Cnt), Replacement);
5080(void)
Scope.Privatize();
5086 autoIPriv =
C->privates().begin();
5087 autoIRed =
C->reduction_ops().begin();
5088 autoITD =
C->taskgroup_descriptors().begin();
5089 for(
const Expr*Ref :
C->varlist()) {
5090InRedVars.emplace_back(Ref);
5091InRedPrivs.emplace_back(*IPriv);
5092InRedOps.emplace_back(*IRed);
5093TaskgroupDescriptors.emplace_back(*ITD);
5094std::advance(IPriv, 1);
5095std::advance(IRed, 1);
5096std::advance(ITD, 1);
5101OMPPrivateScope InRedScope(CGF);
5102 if(!InRedVars.empty()) {
5104 for(
unsignedCnt = 0,
E= InRedVars.size(); Cnt <
E; ++Cnt) {
5105RedCG.emitSharedOrigLValue(CGF, Cnt);
5106RedCG.emitAggregateType(CGF, Cnt);
5112CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(),
5114llvm::Value *ReductionsPtr;
5115 if(
const Expr*TRExpr = TaskgroupDescriptors[Cnt]) {
5116ReductionsPtr = CGF.EmitLoadOfScalar(CGF.EmitLValue(TRExpr),
5117TRExpr->getExprLoc());
5119ReductionsPtr = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
5121 AddressReplacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem(
5122CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));
5124CGF.EmitScalarConversion(
5125Replacement.emitRawPointer(CGF), CGF.getContext().VoidPtrTy,
5126CGF.getContext().getPointerType(InRedPrivs[Cnt]->getType()),
5127InRedPrivs[Cnt]->getExprLoc()),
5128CGF.ConvertTypeForMem(InRedPrivs[Cnt]->getType()),
5129Replacement.getAlignment());
5130Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);
5131InRedScope.addPrivate(RedCG.getBaseDecl(Cnt), Replacement);
5134(void)InRedScope.Privatize();
5143S, *I, *PartId, *TaskT, EKind, CodeGen,
Data.Tied,
Data.NumberOfParts);
5144OMPLexicalScope
Scope(*
this, S, std::nullopt,
5147TaskGen(*
this, OutlinedFn,
Data);
5164 QualTypeElemType =
C.getBaseElementType(Ty);
5174 Data.FirstprivateVars.emplace_back(OrigRef);
5175 Data.FirstprivateCopies.emplace_back(PrivateRef);
5176 Data.FirstprivateInits.emplace_back(InitRef);
5182OMPTargetDataInfo &InputInfo) {
5188 autoPartId = std::next(I);
5189 autoTaskT = std::next(I, 4);
5192 Data.Final.setInt(
false);
5195 autoIRef =
C->varlist_begin();
5196 autoIElemInitRef =
C->inits().begin();
5197 for(
auto*IInit :
C->private_copies()) {
5198 Data.FirstprivateVars.push_back(*IRef);
5199 Data.FirstprivateCopies.push_back(IInit);
5200 Data.FirstprivateInits.push_back(*IElemInitRef);
5208 Data.ReductionVars.append(
C->varlist_begin(),
C->varlist_end());
5209 Data.ReductionOrigs.append(
C->varlist_begin(),
C->varlist_end());
5210 Data.ReductionCopies.append(
C->privates().begin(),
C->privates().end());
5211 Data.ReductionOps.append(
C->reduction_ops().begin(),
5212 C->reduction_ops().end());
5213LHSs.append(
C->lhs_exprs().begin(),
C->lhs_exprs().end());
5214RHSs.append(
C->rhs_exprs().begin(),
C->rhs_exprs().end());
5216OMPPrivateScope TargetScope(*
this);
5221 if(InputInfo.NumberOfTargetItems > 0) {
5224llvm::APInt ArrSize(
32, InputInfo.NumberOfTargetItems);
5229 getContext(),
Data, BaseAndPointerAndMapperType, CD, S.getBeginLoc());
5231 getContext(),
Data, BaseAndPointerAndMapperType, CD, S.getBeginLoc());
5238TargetScope.addPrivate(BPVD, InputInfo.BasePointersArray);
5239TargetScope.addPrivate(PVD, InputInfo.PointersArray);
5240TargetScope.addPrivate(SVD, InputInfo.SizesArray);
5243 if(!isa_and_nonnull<llvm::ConstantPointerNull>(
5244InputInfo.MappersArray.emitRawPointer(*
this))) {
5246 getContext(),
Data, BaseAndPointerAndMapperType, CD, S.getBeginLoc());
5247TargetScope.addPrivate(MVD, InputInfo.MappersArray);
5250(void)TargetScope.Privatize();
5253 auto&&CodeGen = [&
Data, &S, CS, &BodyGen, BPVD, PVD, SVD, MVD, EKind,
5256OMPPrivateScope
Scope(CGF);
5257 if(!
Data.FirstprivateVars.empty()) {
5258 enum{ PrivatesParam = 2, CopyFnParam = 3 };
5259llvm::Value *CopyFn = CGF.Builder.CreateLoad(
5260CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));
5261llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(
5262CS->getCapturedDecl()->getParam(PrivatesParam)));
5267CallArgs.push_back(PrivatesPtr);
5268ParamTypes.push_back(PrivatesPtr->getType());
5269 for(
const Expr*
E:
Data.FirstprivateVars) {
5270 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
5272CGF.CreateMemTemp(CGF.getContext().getPointerType(
E->
getType()),
5273 ".firstpriv.ptr.addr");
5274PrivatePtrs.emplace_back(VD, PrivatePtr);
5275CallArgs.push_back(PrivatePtr.
getPointer());
5276ParamTypes.push_back(PrivatePtr.
getType());
5278 auto*CopyFnTy = llvm::FunctionType::get(CGF.Builder.getVoidTy(),
5279ParamTypes,
false);
5280CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
5281CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);
5282 for(
const auto&Pair : PrivatePtrs) {
5284CGF.Builder.CreateLoad(Pair.second),
5285CGF.ConvertTypeForMem(Pair.first->getType().getNonReferenceType()),
5286CGF.getContext().getDeclAlign(Pair.first));
5287 Scope.addPrivate(Pair.first, Replacement);
5290CGF.processInReduction(S,
Data, CGF, CS,
Scope);
5291 if(InputInfo.NumberOfTargetItems > 0) {
5292InputInfo.BasePointersArray = CGF.Builder.CreateConstArrayGEP(
5293CGF.GetAddrOfLocalVar(BPVD),
0);
5294InputInfo.PointersArray = CGF.Builder.CreateConstArrayGEP(
5295CGF.GetAddrOfLocalVar(PVD),
0);
5296InputInfo.SizesArray = CGF.Builder.CreateConstArrayGEP(
5297CGF.GetAddrOfLocalVar(SVD),
0);
5300InputInfo.MappersArray = CGF.Builder.CreateConstArrayGEP(
5301CGF.GetAddrOfLocalVar(MVD),
0);
5305OMPLexicalScope LexScope(CGF, S, OMPD_task,
false);
5307 if(CGF.CGM.getLangOpts().OpenMP >= 51 &&
5312CGF.CGM.getOpenMPRuntime().emitThreadLimitClause(
5313CGF, TL->getThreadLimit().front(), S.getBeginLoc());
5318S, *I, *PartId, *TaskT, EKind, CodeGen,
true,
5319 Data.NumberOfParts);
5320llvm::APInt TrueOrFalse(32, S.hasClausesOfKind<
OMPNowaitClause>() ? 1 : 0);
5325SharedsTy, CapturedStruct, &IfCond,
Data);
5332OMPPrivateScope &
Scope) {
5334 if(
Data.Reductions) {
5336OMPLexicalScope LexScope(CGF, S, CapturedRegion);
5338 Data.ReductionCopies,
Data.ReductionOps);
5341 for(
unsignedCnt = 0,
E=
Data.ReductionVars.size(); Cnt <
E; ++Cnt) {
5342RedCG.emitSharedOrigLValue(CGF, Cnt);
5343RedCG.emitAggregateType(CGF, Cnt);
5350CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));
5355 Data.ReductionCopies[Cnt]->getType()),
5356 Data.ReductionCopies[Cnt]->getExprLoc()),
5358Replacement.getAlignment());
5359Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);
5360 Scope.addPrivate(RedCG.getBaseDecl(Cnt), Replacement);
5363(void)
Scope.Privatize();
5369 autoIPriv =
C->privates().begin();
5370 autoIRed =
C->reduction_ops().begin();
5371 autoITD =
C->taskgroup_descriptors().begin();
5372 for(
const Expr*Ref :
C->varlist()) {
5373InRedVars.emplace_back(Ref);
5374InRedPrivs.emplace_back(*IPriv);
5375InRedOps.emplace_back(*IRed);
5376TaskgroupDescriptors.emplace_back(*ITD);
5377std::advance(IPriv, 1);
5378std::advance(IRed, 1);
5379std::advance(ITD, 1);
5382OMPPrivateScope InRedScope(CGF);
5383 if(!InRedVars.empty()) {
5385 for(
unsignedCnt = 0,
E= InRedVars.size(); Cnt <
E; ++Cnt) {
5386RedCG.emitSharedOrigLValue(CGF, Cnt);
5387RedCG.emitAggregateType(CGF, Cnt);
5393llvm::Value *ReductionsPtr;
5394 if(
const Expr*TRExpr = TaskgroupDescriptors[Cnt]) {
5398ReductionsPtr = llvm::ConstantPointerNull::get(CGF.
VoidPtrTy);
5401CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));
5406InRedPrivs[Cnt]->getExprLoc()),
5408Replacement.getAlignment());
5409Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);
5410InRedScope.addPrivate(RedCG.getBaseDecl(Cnt), Replacement);
5413(void)InRedScope.Privatize();
5421 const Expr*IfCond =
nullptr;
5422 for(
const auto*
C: S.getClausesOfKind<
OMPIfClause>()) {
5423 if(
C->getNameModifier() == OMPD_unknown ||
5424 C->getNameModifier() == OMPD_task) {
5425IfCond =
C->getCondition();
5436 auto&&TaskGen = [&S, SharedsTy, CapturedStruct,
5439CGF.CGM.getOpenMPRuntime().emitTaskCall(CGF, S.getBeginLoc(), S, OutlinedFn,
5440SharedsTy, CapturedStruct, IfCond,
5457 boolIsFatal =
false;
5476 return T.clauses().empty();
5481OMPLexicalScope
Scope(*
this, S, OMPD_unknown);
5484 usingInsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
5488 autoBodyGenCB = [&,
this](InsertPointTy AllocaIP,
5489InsertPointTy CodeGenIP) {
5490 Builder.restoreIP(CodeGenIP);
5491 EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
5492 returnllvm::Error::success();
5494CodeGenFunction::CGCapturedStmtInfo CapStmtInfo;
5497llvm::OpenMPIRBuilder::InsertPointTy AfterIP =
5498cantFail(OMPBuilder.createTaskgroup(
Builder, AllocaIP, BodyGenCB));
5504 if(
const Expr*
E= S.getReductionRef()) {
5509 Data.ReductionVars.append(
C->varlist_begin(),
C->varlist_end());
5510 Data.ReductionOrigs.append(
C->varlist_begin(),
C->varlist_end());
5511 Data.ReductionCopies.append(
C->privates().begin(),
C->privates().end());
5512 Data.ReductionOps.append(
C->reduction_ops().begin(),
5513 C->reduction_ops().end());
5514LHSs.append(
C->lhs_exprs().begin(),
C->lhs_exprs().end());
5515RHSs.append(
C->rhs_exprs().begin(),
C->rhs_exprs().end());
5517llvm::Value *ReductionDesc =
5520 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
5525CGF.
EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
5532? llvm::AtomicOrdering::NotAtomic
5533: llvm::AtomicOrdering::AcquireRelease;
5537 if(
const auto*FlushClause = S.getSingleClause<
OMPFlushClause>())
5539FlushClause->varlist_end());
5542S.getBeginLoc(), AO);
5552 for(
auto&Dep :
Data.Dependences) {
5554*
this, Dep, DC->getBeginLoc());
5565*
this, DOLVal, UC->getDependencyKind(), UC->getBeginLoc());
5584 if(
C->getModifier() != OMPC_REDUCTION_inscan)
5586Shareds.append(
C->varlist_begin(),
C->varlist_end());
5587Privates.append(
C->privates().begin(),
C->privates().end());
5588LHSs.append(
C->lhs_exprs().begin(),
C->lhs_exprs().end());
5589RHSs.append(
C->rhs_exprs().begin(),
C->rhs_exprs().end());
5590ReductionOps.append(
C->reduction_ops().begin(),
C->reduction_ops().end());
5591CopyOps.append(
C->copy_ops().begin(),
C->copy_ops().end());
5592CopyArrayTemps.append(
C->copy_array_temps().begin(),
5593 C->copy_array_temps().end());
5594CopyArrayElems.append(
C->copy_array_elems().begin(),
5595 C->copy_array_elems().end());
5636llvm::BasicBlock *OMPScanReduce =
createBasicBlock(
"omp.inscan.reduce");
5639: BreakContinueStack.back().ContinueBlock.getBlock());
5644LexicalScope
Scope(*
this, S.getSourceRange());
5650 for(
unsignedI = 0,
E= CopyArrayElems.size(); I <
E; ++I) {
5651 const Expr*PrivateExpr = Privates[I];
5652 const Expr*TempExpr = CopyArrayTemps[I];
5654*cast<VarDecl>(cast<DeclRefExpr>(TempExpr)->getDecl()));
5659cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),
5660cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()),
5665*
this, ParentDir.
getEndLoc(), Privates, LHSs, RHSs, ReductionOps,
5666{
true,
true, OMPD_simd});
5667 for(
unsignedI = 0,
E= CopyArrayElems.size(); I <
E; ++I) {
5668 const Expr*PrivateExpr = Privates[I];
5675 const Expr*TempExpr = CopyArrayTemps[I];
5681cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),
5682cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()), CopyOps[I]);
5687? BreakContinueStack.back().ContinueBlock.getBlock()
5693 EmitBranch(BreakContinueStack.back().ContinueBlock.getBlock());
5698 const auto*IVExpr = cast<OMPLoopDirective>(ParentDir)
5699.getIterationVariable()
5704 for(
unsignedI = 0,
E= CopyArrayElems.size(); I <
E; ++I) {
5705 const Expr*PrivateExpr = Privates[I];
5706 const Expr*OrigExpr = Shareds[I];
5707 const Expr*CopyArrayElem = CopyArrayElems[I];
5708OpaqueValueMapping IdxMapping(
5710cast<OpaqueValueExpr>(
5711cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),
5717cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),
5718cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()), CopyOps[I]);
5721 EmitBranch(BreakContinueStack.back().ContinueBlock.getBlock());
5724 EmitBranch(BreakContinueStack.back().ContinueBlock.getBlock());
5729 const auto*IVExpr = cast<OMPLoopDirective>(ParentDir)
5730.getIterationVariable()
5735llvm::BasicBlock *ExclusiveExitBB =
nullptr;
5740 Builder.CreateCondBr(Cmp, ExclusiveExitBB, ContBB);
5743IdxVal =
Builder.CreateNUWSub(IdxVal, llvm::ConstantInt::get(
SizeTy, 1));
5745 for(
unsignedI = 0,
E= CopyArrayElems.size(); I <
E; ++I) {
5746 const Expr*PrivateExpr = Privates[I];
5747 const Expr*OrigExpr = Shareds[I];
5748 const Expr*CopyArrayElem = CopyArrayElems[I];
5749OpaqueValueMapping IdxMapping(
5751cast<OpaqueValueExpr>(
5752cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),
5758cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),
5759cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()), CopyOps[I]);
5774 const auto*IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
5775 const auto*IVDecl = cast<VarDecl>(IVExpr->getDecl());
5781 if(
const auto*LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
5789 boolHasLastprivateClause =
false;
5792OMPLoopScope PreInitScope(*
this, S);
5797llvm::BasicBlock *ContBlock =
nullptr;
5804 emitPreCond(*
this, S, S.getPreCond(), ThenBlock, ContBlock,
5816*
this, cast<DeclRefExpr>(
5818? S.getCombinedLowerBoundVariable()
5819: S.getLowerBoundVariable())));
5821*
this, cast<DeclRefExpr>(
5823? S.getCombinedUpperBoundVariable()
5824: S.getUpperBoundVariable())));
5830OMPPrivateScope LoopScope(*
this);
5836*
this, S.getBeginLoc(), OMPD_unknown,
false,
5846(void)LoopScope.Privatize();
5851llvm::Value *Chunk =
nullptr;
5854ScheduleKind =
C->getDistScheduleKind();
5855 if(
const Expr*Ch =
C->getChunkSize()) {
5858S.getIterationVariable()->getType(),
5864*
this, S, ScheduleKind, Chunk);
5877 boolStaticChunked =
5881Chunk !=
nullptr) ||
5886StaticChunked ? Chunk :
nullptr);
5893? S.getCombinedEnsureUpperBound()
5894: S.getEnsureUpperBound());
5897? S.getCombinedInit()
5902? S.getCombinedCond()
5906Cond = S.getCombinedDistCond();
5938[&S, &LoopScope, Cond, IncExpr,
LoopExit, &CodeGenLoop,
5940CGF.EmitOMPInnerLoop(
5941S, LoopScope.requiresCleanups(), Cond, IncExpr,
5943CodeGenLoop(CGF, S, LoopExit);
5946if (StaticChunked) {
5947CGF.EmitIgnoredExpr(S.getCombinedNextLowerBound());
5948CGF.EmitIgnoredExpr(S.getCombinedNextUpperBound());
5949CGF.EmitIgnoredExpr(S.getCombinedEnsureUpperBound());
5950CGF.EmitIgnoredExpr(S.getCombinedInit());
5960 constOMPLoopArguments LoopArguments = {
5963EmitOMPDistributeOuterLoop(ScheduleKind, S, LoopScope, LoopArguments,
5968 returnCGF.
Builder.CreateIsNotNull(
5979 returnCGF.
Builder.CreateIsNotNull(
5984 if(HasLastprivateClause) {
6007OMPLexicalScope
Scope(CGF, S, OMPD_unknown);
6020CodeGenFunction::CGCapturedStmtInfo CapStmtInfo;
6023Fn->setDoesNotRecurse();
6027template<
typenameT>
6029llvm::OpenMPIRBuilder::InsertPointTy AllocaIP,
6030llvm::OpenMPIRBuilder &OMPBuilder) {
6032 unsignedNumLoops =
C->getNumLoops();
6036 for(
unsignedI = 0; I < NumLoops; I++) {
6037 const Expr*CounterVal =
C->getLoopData(I);
6042StoreValues.emplace_back(StoreValue);
6044OMPDoacrossKind<T> ODK;
6045 boolIsDependSource = ODK.isSource(
C);
6047OMPBuilder.createOrderedDepend(CGF.
Builder, AllocaIP, NumLoops,
6048StoreValues,
".cnt.addr", IsDependSource));
6054 usingInsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
6059assert(!S.hasAssociatedStmt() &&
"No associated statement must be in " 6060 "ordered depend|doacross construct.");
6072 autoFiniCB = [
this](InsertPointTy IP) {
6074 returnllvm::Error::success();
6077 autoBodyGenCB = [&S,
C,
this](InsertPointTy AllocaIP,
6078InsertPointTy CodeGenIP) {
6079 Builder.restoreIP(CodeGenIP);
6083llvm::BasicBlock *FiniBB = splitBBWithSuffix(
6084 Builder,
false,
".ordered.after");
6087llvm::Function *OutlinedFn =
6089assert(S.getBeginLoc().isValid() &&
6090 "Outlined function call location must be valid.");
6093OutlinedFn, CapturedVars);
6098 returnllvm::Error::success();
6101OMPLexicalScope
Scope(*
this, S, OMPD_unknown);
6102llvm::OpenMPIRBuilder::InsertPointTy AfterIP = cantFail(
6103OMPBuilder.createOrderedThreadsSimd(
Builder, BodyGenCB, FiniCB, !
C));
6110assert(!S.hasAssociatedStmt() &&
6111 "No associated statement must be in ordered depend construct.");
6117assert(!S.hasAssociatedStmt() &&
6118 "No associated statement must be in ordered doacross construct.");
6129CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
6130llvm::Function *OutlinedFn =
6133OutlinedFn, CapturedVars);
6139OMPLexicalScope
Scope(*
this, S, OMPD_unknown);
6147 "DestType must have scalar evaluation kind.");
6148assert(!Val.
isAggregate() &&
"Must be a scalar or complex.");
6159 "DestType must have complex evaluation kind.");
6168ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType()));
6170assert(Val.
isComplex() &&
"Must be a scalar or complex.");
6191llvm::AtomicOrdering AO,
LValueLVal,
6196LVal,
Loc, llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO),
6205*
this, RVal, RValTy, LVal.
getType(),
Loc)),
6214llvm_unreachable(
"Must be a scalar or complex.");
6222assert(
V->isLValue() &&
"V of 'omp atomic read' is not lvalue");
6223assert(
X->isLValue() &&
"X of 'omp atomic read' is not lvalue");
6232 casellvm::AtomicOrdering::Acquire:
6233 casellvm::AtomicOrdering::AcquireRelease:
6234 casellvm::AtomicOrdering::SequentiallyConsistent:
6236llvm::AtomicOrdering::Acquire);
6238 casellvm::AtomicOrdering::Monotonic:
6239 casellvm::AtomicOrdering::Release:
6241 casellvm::AtomicOrdering::NotAtomic:
6242 casellvm::AtomicOrdering::Unordered:
6243llvm_unreachable(
"Unexpected ordering.");
6250llvm::AtomicOrdering AO,
const Expr*
X,
6253assert(
X->isLValue() &&
"X of 'omp atomic write' is not lvalue");
6261 casellvm::AtomicOrdering::Release:
6262 casellvm::AtomicOrdering::AcquireRelease:
6263 casellvm::AtomicOrdering::SequentiallyConsistent:
6265llvm::AtomicOrdering::Release);
6267 casellvm::AtomicOrdering::Acquire:
6268 casellvm::AtomicOrdering::Monotonic:
6270 casellvm::AtomicOrdering::NotAtomic:
6271 casellvm::AtomicOrdering::Unordered:
6272llvm_unreachable(
"Unexpected ordering.");
6279llvm::AtomicOrdering AO,
6280 boolIsXLHSInRHSPart) {
6285 if(BO == BO_Comma || !
Update.isScalar() || !
X.isSimple() ||
6286(!isa<llvm::ConstantInt>(
Update.getScalarVal()) &&
6287(
Update.getScalarVal()->getType() !=
X.getAddress().getElementType())) ||
6290 returnstd::make_pair(
false,
RValue::get(
nullptr));
6293 if(
T->isIntegerTy())
6296 if(
T->isFloatingPointTy() && (BO == BO_Add || BO == BO_Sub))
6302 if(!CheckAtomicSupport(
Update.getScalarVal()->getType(), BO) ||
6303!CheckAtomicSupport(
X.getAddress().getElementType(), BO))
6304 returnstd::make_pair(
false,
RValue::get(
nullptr));
6306 boolIsInteger =
X.getAddress().getElementType()->isIntegerTy();
6307llvm::AtomicRMWInst::BinOp RMWOp;
6310RMWOp = IsInteger ? llvm::AtomicRMWInst::Add : llvm::AtomicRMWInst::FAdd;
6313 if(!IsXLHSInRHSPart)
6314 returnstd::make_pair(
false,
RValue::get(
nullptr));
6315RMWOp = IsInteger ? llvm::AtomicRMWInst::Sub : llvm::AtomicRMWInst::FSub;
6318RMWOp = llvm::AtomicRMWInst::And;
6321RMWOp = llvm::AtomicRMWInst::Or;
6324RMWOp = llvm::AtomicRMWInst::Xor;
6328RMWOp =
X.getType()->hasSignedIntegerRepresentation()
6329? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min
6330: llvm::AtomicRMWInst::Max)
6331: (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin
6332: llvm::AtomicRMWInst::UMax);
6334RMWOp = IsXLHSInRHSPart ? llvm::AtomicRMWInst::FMin
6335: llvm::AtomicRMWInst::FMax;
6339RMWOp =
X.getType()->hasSignedIntegerRepresentation()
6340? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max
6341: llvm::AtomicRMWInst::Min)
6342: (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax
6343: llvm::AtomicRMWInst::UMin);
6345RMWOp = IsXLHSInRHSPart ? llvm::AtomicRMWInst::FMax
6346: llvm::AtomicRMWInst::FMin;
6349RMWOp = llvm::AtomicRMWInst::Xchg;
6358 returnstd::make_pair(
false,
RValue::get(
nullptr));
6377llvm_unreachable(
"Unsupported atomic update operation");
6379llvm::Value *UpdateVal =
Update.getScalarVal();
6380 if(
auto*IC = dyn_cast<llvm::ConstantInt>(UpdateVal)) {
6382UpdateVal = CGF.
Builder.CreateIntCast(
6383IC,
X.getAddress().getElementType(),
6384 X.getType()->hasSignedIntegerRepresentation());
6386UpdateVal = CGF.
Builder.CreateCast(llvm::Instruction::CastOps::UIToFP, IC,
6387 X.getAddress().getElementType());
6389llvm::AtomicRMWInst *Res =
6397 constllvm::function_ref<
RValue(
RValue)> CommonGen) {
6406 if(
X.isGlobalReg()) {
6419llvm::AtomicOrdering AO,
const Expr*
X,
6423 "Update expr in 'atomic update' must be a binary operator.");
6431assert(
X->isLValue() &&
"X of 'omp atomic update' is not lvalue");
6434 const auto*LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
6435 const auto*RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
6438 auto&&Gen = [&CGF, UE, ExprRValue, XRValExpr, ERValExpr](
RValueXRValue) {
6439CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
6440CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);
6444XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO,
Loc, Gen);
6451 casellvm::AtomicOrdering::Release:
6452 casellvm::AtomicOrdering::AcquireRelease:
6453 casellvm::AtomicOrdering::SequentiallyConsistent:
6455llvm::AtomicOrdering::Release);
6457 casellvm::AtomicOrdering::Acquire:
6458 casellvm::AtomicOrdering::Monotonic:
6460 casellvm::AtomicOrdering::NotAtomic:
6461 casellvm::AtomicOrdering::Unordered:
6462llvm_unreachable(
"Unexpected ordering.");
6480llvm_unreachable(
"Must be a scalar or complex.");
6484llvm::AtomicOrdering AO,
6485 boolIsPostfixUpdate,
const Expr*
V,
6487 const Expr*UE,
boolIsXLHSInRHSPart,
6489assert(
X->isLValue() &&
"X of 'omp atomic capture' is not lvalue");
6490assert(
V->isLValue() &&
"V of 'omp atomic capture' is not lvalue");
6499 "Update expr in 'atomic capture' must be a binary operator.");
6507 const auto*LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
6508 const auto*RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
6510NewVValType = XRValExpr->
getType();
6512 auto&&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr,
6513IsPostfixUpdate](
RValueXRValue) {
6514CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
6515CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);
6517NewVVal = IsPostfixUpdate ? XRValue : Res;
6521XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO,
Loc, Gen);
6525 if(IsPostfixUpdate) {
6527NewVVal = Res.second;
6531CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
6532CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, Res.second);
6538NewVValType =
X->getType().getNonReferenceType();
6540 X->getType().getNonReferenceType(),
Loc);
6541 auto&&Gen = [&NewVVal, ExprRValue](
RValueXRValue) {
6547XLValue, ExprRValue,
BO_Assign,
false, AO,
6552NewVVal = IsPostfixUpdate ? Res.
second: ExprRValue;
6568 casellvm::AtomicOrdering::Release:
6570llvm::AtomicOrdering::Release);
6572 casellvm::AtomicOrdering::Acquire:
6574llvm::AtomicOrdering::Acquire);
6576 casellvm::AtomicOrdering::AcquireRelease:
6577 casellvm::AtomicOrdering::SequentiallyConsistent:
6579CGF, {},
Loc, llvm::AtomicOrdering::AcquireRelease);
6581 casellvm::AtomicOrdering::Monotonic:
6583 casellvm::AtomicOrdering::NotAtomic:
6584 casellvm::AtomicOrdering::Unordered:
6585llvm_unreachable(
"Unexpected ordering.");
6591 CodeGenFunction&CGF, llvm::AtomicOrdering AO, llvm::AtomicOrdering FailAO,
6593 const Expr*CE,
boolIsXBinopExpr,
boolIsPostfixUpdate,
boolIsFailOnly,
6595llvm::OpenMPIRBuilder &OMPBuilder =
6598OMPAtomicCompareOp Op;
6599assert(isa<BinaryOperator>(CE) &&
"CE is not a BinaryOperator");
6600 switch(cast<BinaryOperator>(CE)->getOpcode()) {
6602Op = OMPAtomicCompareOp::EQ;
6605Op = OMPAtomicCompareOp::MIN;
6608Op = OMPAtomicCompareOp::MAX;
6611llvm_unreachable(
"unsupported atomic compare binary operator");
6617 autoEmitRValueWithCastIfNeeded = [&CGF,
Loc](
const Expr*
X,
const Expr*
E) {
6622 if(NewE->
getType() ==
X->getType())
6627llvm::Value *EVal = EmitRValueWithCastIfNeeded(
X,
E);
6628llvm::Value *DVal =
D? EmitRValueWithCastIfNeeded(
X,
D) :
nullptr;
6629 if(
auto*CI = dyn_cast<llvm::ConstantInt>(EVal))
6630EVal = CGF.
Builder.CreateIntCast(
6634 if(
auto*CI = dyn_cast<llvm::ConstantInt>(DVal))
6635DVal = CGF.
Builder.CreateIntCast(
6637 D->getType()->hasSignedIntegerRepresentation());
6639llvm::OpenMPIRBuilder::AtomicOpValue XOpVal{
6641 X->getType()->hasSignedIntegerRepresentation(),
6642 X->getType().isVolatileQualified()};
6643llvm::OpenMPIRBuilder::AtomicOpValue VOpVal, ROpVal;
6648 V->getType()->hasSignedIntegerRepresentation(),
6649 V->getType().isVolatileQualified()};
6659 if(FailAO == llvm::AtomicOrdering::NotAtomic) {
6662CGF.
Builder.restoreIP(OMPBuilder.createAtomicCompare(
6663CGF.
Builder, XOpVal, VOpVal, ROpVal, EVal, DVal, AO, Op, IsXBinopExpr,
6664IsPostfixUpdate, IsFailOnly));
6666CGF.
Builder.restoreIP(OMPBuilder.createAtomicCompare(
6667CGF.
Builder, XOpVal, VOpVal, ROpVal, EVal, DVal, AO, Op, IsXBinopExpr,
6668IsPostfixUpdate, IsFailOnly, FailAO));
6672llvm::AtomicOrdering AO,
6673llvm::AtomicOrdering FailAO,
boolIsPostfixUpdate,
6676 const Expr*CE,
boolIsXLHSInRHSPart,
6691IsXLHSInRHSPart,
Loc);
6693 caseOMPC_compare: {
6695IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly,
Loc);
6699llvm_unreachable(
"Clause is not allowed in 'omp atomic'.");
6706llvm::AtomicOrdering FailAO = llvm::AtomicOrdering::NotAtomic;
6707 boolMemOrderingSpecified =
false;
6709AO = llvm::AtomicOrdering::SequentiallyConsistent;
6710MemOrderingSpecified =
true;
6712AO = llvm::AtomicOrdering::AcquireRelease;
6713MemOrderingSpecified =
true;
6715AO = llvm::AtomicOrdering::Acquire;
6716MemOrderingSpecified =
true;
6718AO = llvm::AtomicOrdering::Release;
6719MemOrderingSpecified =
true;
6721AO = llvm::AtomicOrdering::Monotonic;
6722MemOrderingSpecified =
true;
6724llvm::SmallSet<OpenMPClauseKind, 2> KindsEncountered;
6733 if(K == OMPC_seq_cst || K == OMPC_acq_rel || K == OMPC_acquire ||
6734K == OMPC_release || K == OMPC_relaxed || K == OMPC_hint)
6737KindsEncountered.insert(K);
6742 if(KindsEncountered.contains(OMPC_compare) &&
6743KindsEncountered.contains(OMPC_capture))
6744 Kind= OMPC_compare;
6745 if(!MemOrderingSpecified) {
6746llvm::AtomicOrdering DefaultOrder =
6748 if(DefaultOrder == llvm::AtomicOrdering::Monotonic ||
6749DefaultOrder == llvm::AtomicOrdering::SequentiallyConsistent ||
6750(DefaultOrder == llvm::AtomicOrdering::AcquireRelease &&
6751Kind == OMPC_capture)) {
6753}
else if(DefaultOrder == llvm::AtomicOrdering::AcquireRelease) {
6754 if(Kind == OMPC_unknown || Kind == OMPC_update || Kind == OMPC_write) {
6755AO = llvm::AtomicOrdering::Release;
6756}
else if(Kind == OMPC_read) {
6757assert(Kind == OMPC_read &&
"Unexpected atomic kind.");
6758AO = llvm::AtomicOrdering::Acquire;
6763 if(KindsEncountered.contains(OMPC_compare) &&
6764KindsEncountered.contains(OMPC_fail)) {
6765 Kind= OMPC_compare;
6766 const auto*FailClause = S.getSingleClause<
OMPFailClause>();
6769 if(FailParameter == llvm::omp::OMPC_relaxed)
6770FailAO = llvm::AtomicOrdering::Monotonic;
6771 else if(FailParameter == llvm::omp::OMPC_acquire)
6772FailAO = llvm::AtomicOrdering::Acquire;
6773 else if(FailParameter == llvm::omp::OMPC_seq_cst)
6774FailAO = llvm::AtomicOrdering::SequentiallyConsistent;
6778LexicalScope
Scope(*
this, S.getSourceRange());
6781S.getV(), S.getR(), S.getExpr(), S.getUpdateExpr(),
6782S.getD(), S.getCondExpr(), S.isXLHSInRHSPart(),
6783S.isFailOnly(), S.getBeginLoc());
6794OMPLexicalScope
Scope(CGF, S, OMPD_target);
6797CGF.
EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
6803llvm::Function *Fn =
nullptr;
6804llvm::Constant *FnID =
nullptr;
6806 const Expr*IfCond =
nullptr;
6808 for(
const auto*
C: S.getClausesOfKind<
OMPIfClause>()) {
6809 if(
C->getNameModifier() == OMPD_unknown ||
6810 C->getNameModifier() == OMPD_target) {
6811IfCond =
C->getCondition();
6817llvm::PointerIntPair<const Expr *, 2, OpenMPDeviceClauseModifier>
Device(
6820 Device.setPointerAndInt(
C->getDevice(),
C->getModifier());
6825 boolIsOffloadEntry =
true;
6829IsOffloadEntry =
false;
6832IsOffloadEntry =
false;
6834 if(
CGM.
getLangOpts().OpenMPOffloadMandatory && !IsOffloadEntry) {
6837 "No offloading entry generated while offloading is mandatory.");
6841assert(CGF.
CurFuncDecl&&
"No parent declaration for target region!");
6842StringRef ParentName;
6845 if(
const auto*
D= dyn_cast<CXXConstructorDecl>(CGF.
CurFuncDecl))
6847 else if(
const auto*
D= dyn_cast<CXXDestructorDecl>(CGF.
CurFuncDecl))
6855IsOffloadEntry, CodeGen);
6856OMPLexicalScope
Scope(CGF, S, OMPD_task);
6857 auto&&SizeEmitter =
6860 if(IsOffloadEntry) {
6861OMPLoopScope(CGF,
D);
6863llvm::Value *NumIterations = CGF.
EmitScalarExpr(
D.getNumIterations());
6864NumIterations = CGF.
Builder.CreateIntCast(NumIterations, CGF.
Int64Ty,
6866 returnNumIterations;
6876Action.
Enter(CGF);
6877CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
6880(void)PrivateScope.Privatize();
6884CGF.
EmitStmt(S.getCapturedStmt(OMPD_target)->getCapturedStmt());
6889StringRef ParentName,
6894llvm::Function *
Fn;
6895llvm::Constant *Addr;
6898S, ParentName, Fn, Addr,
true, CodeGen);
6899assert(Fn && Addr &&
"Target device function emission failed.");
6913 const CapturedStmt*CS = S.getCapturedStmt(OMPD_teams);
6914llvm::Function *OutlinedFn =
6922 const Expr*NumTeams = NT ? NT->getNumTeams().front() :
nullptr;
6923 const Expr*ThreadLimit = TL ? TL->getThreadLimit().front() :
nullptr;
6929OMPTeamsScope
Scope(CGF, S);
6940OMPPrivateScope PrivateScope(CGF);
6944(void)PrivateScope.Privatize();
6945CGF.
EmitStmt(S.getCapturedStmt(OMPD_teams)->getCapturedStmt());
6955 auto*CS = S.getCapturedStmt(OMPD_teams);
6956Action.
Enter(CGF);
6959Action.
Enter(CGF);
6960CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
6964(void)PrivateScope.Privatize();
6981llvm::Function *
Fn;
6982llvm::Constant *Addr;
6985S, ParentName, Fn, Addr,
true, CodeGen);
6986assert(Fn && Addr &&
"Target device function emission failed.");
7000Action.
Enter(CGF);
7008Action.
Enter(CGF);
7009CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
7011(void)PrivateScope.Privatize();
7027llvm::Function *
Fn;
7028llvm::Constant *Addr;
7031S, ParentName, Fn, Addr,
true, CodeGen);
7032assert(Fn && Addr &&
"Target device function emission failed.");
7046Action.
Enter(CGF);
7054Action.
Enter(CGF);
7055CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
7057(void)PrivateScope.Privatize();
7073llvm::Function *
Fn;
7074llvm::Constant *Addr;
7077S, ParentName, Fn, Addr,
true, CodeGen);
7078assert(Fn && Addr &&
"Target device function emission failed.");
7100OMPPrivateScope PrivateScope(CGF);
7101CGF.EmitOMPReductionClauseInit(S, PrivateScope);
7102(void)PrivateScope.Privatize();
7103CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
7105CGF.EmitOMPReductionClauseFinal(S,
OMPD_teams);
7122OMPPrivateScope PrivateScope(CGF);
7123CGF.EmitOMPReductionClauseInit(S, PrivateScope);
7124(void)PrivateScope.Privatize();
7125CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_simd,
7127CGF.EmitOMPReductionClauseFinal(S,
OMPD_teams);
7145OMPPrivateScope PrivateScope(CGF);
7146CGF.EmitOMPReductionClauseInit(S, PrivateScope);
7147(void)PrivateScope.Privatize();
7148CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
7150CGF.EmitOMPReductionClauseFinal(S,
OMPD_teams);
7168OMPPrivateScope PrivateScope(CGF);
7169CGF.EmitOMPReductionClauseInit(S, PrivateScope);
7170(void)PrivateScope.Privatize();
7171CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
7172CGF, OMPD_distribute, CodeGenDistribute,
false);
7173CGF.EmitOMPReductionClauseFinal(S,
OMPD_teams);
7183llvm::Value *
Device=
nullptr;
7184llvm::Value *NumDependences =
nullptr;
7185llvm::Value *DependenceList =
nullptr;
7193 if(!
Data.Dependences.empty()) {
7195std::tie(NumDependences, DependenciesArray) =
7205 "OMPNowaitClause clause is used separately in OMPInteropDirective.");
7207 autoItOMPInitClause = S.getClausesOfKind<
OMPInitClause>();
7208 if(!ItOMPInitClause.empty()) {
7211llvm::Value *InteropvarPtr =
7213llvm::omp::OMPInteropType InteropType =
7214llvm::omp::OMPInteropType::Unknown;
7215 if(
C->getIsTarget()) {
7216InteropType = llvm::omp::OMPInteropType::Target;
7218assert(
C->getIsTargetSync() &&
7219 "Expected interop-type target/targetsync");
7220InteropType = llvm::omp::OMPInteropType::TargetSync;
7222OMPBuilder.createOMPInteropInit(
Builder, InteropvarPtr, InteropType,
7223 Device, NumDependences, DependenceList,
7224 Data.HasNowaitClause);
7228 if(!ItOMPDestroyClause.empty()) {
7231llvm::Value *InteropvarPtr =
7233OMPBuilder.createOMPInteropDestroy(
Builder, InteropvarPtr,
Device,
7234NumDependences, DependenceList,
7235 Data.HasNowaitClause);
7238 autoItOMPUseClause = S.getClausesOfKind<
OMPUseClause>();
7239 if(!ItOMPUseClause.empty()) {
7242llvm::Value *InteropvarPtr =
7244OMPBuilder.createOMPInteropUse(
Builder, InteropvarPtr,
Device,
7245NumDependences, DependenceList,
7246 Data.HasNowaitClause);
7254Action.
Enter(CGF);
7263Action.
Enter(CGF);
7264CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
7266(void)PrivateScope.Privatize();
7268CGF, OMPD_distribute, CodeGenDistribute,
false);
7286llvm::Function *
Fn;
7287llvm::Constant *Addr;
7290S, ParentName, Fn, Addr,
true, CodeGen);
7291assert(Fn && Addr &&
"Target device function emission failed.");
7306Action.
Enter(CGF);
7315Action.
Enter(CGF);
7316CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
7318(void)PrivateScope.Privatize();
7320CGF, OMPD_distribute, CodeGenDistribute,
false);
7338llvm::Function *
Fn;
7339llvm::Constant *Addr;
7342S, ParentName, Fn, Addr,
true, CodeGen);
7343assert(Fn && Addr &&
"Target device function emission failed.");
7357S.getCancelRegion());
7361 const Expr*IfCond =
nullptr;
7362 for(
const auto*
C: S.getClausesOfKind<
OMPIfClause>()) {
7363 if(
C->getNameModifier() == OMPD_unknown ||
7364 C->getNameModifier() == OMPD_cancel) {
7365IfCond =
C->getCondition();
7373 if(S.getCancelRegion() == OMPD_parallel ||
7374S.getCancelRegion() == OMPD_sections ||
7375S.getCancelRegion() == OMPD_section) {
7376llvm::Value *IfCondition =
nullptr;
7380llvm::OpenMPIRBuilder::InsertPointTy AfterIP = cantFail(
7381OMPBuilder.createCancel(
Builder, IfCondition, S.getCancelRegion()));
7382 return Builder.restoreIP(AfterIP);
7387S.getCancelRegion());
7390CodeGenFunction::JumpDest
7392 if(Kind == OMPD_parallel || Kind == OMPD_task ||
7393Kind == OMPD_target_parallel || Kind == OMPD_taskloop ||
7394Kind == OMPD_master_taskloop || Kind == OMPD_parallel_master_taskloop)
7396assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
7397Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for ||
7398Kind == OMPD_distribute_parallel_for ||
7399Kind == OMPD_target_parallel_for ||
7400Kind == OMPD_teams_distribute_parallel_for ||
7401Kind == OMPD_target_teams_distribute_parallel_for);
7402 returnOMPCancelStack.getExitBlock();
7407 constllvm::DenseMap<const ValueDecl *, llvm::Value *>
7408CaptureDeviceAddrMap) {
7409llvm::SmallDenseSet<CanonicalDeclPtr<const Decl>, 4> Processed;
7410 for(
const Expr*OrigVarIt :
C.varlist()) {
7411 const auto*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(OrigVarIt)->getDecl());
7412 if(!Processed.insert(OrigVD).second)
7419 if(
const auto*OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) {
7422 const auto*ME = cast<MemberExpr>(OED->getInit());
7423assert(isa<CXXThisExpr>(ME->getBase()->IgnoreImpCasts()) &&
7424 "Base should be the current struct!");
7425MatchingVD = ME->getMemberDecl();
7430 autoInitAddrIt = CaptureDeviceAddrMap.find(MatchingVD);
7431 if(InitAddrIt == CaptureDeviceAddrMap.end())
7437 boolIsRegistered = PrivateScope.addPrivate(
7439 Address(InitAddrIt->second, Ty,
7441assert(IsRegistered &&
"firstprivate var already registered as private");
7449 while(
const auto*OASE = dyn_cast<ArraySectionExpr>(
Base))
7450 Base= OASE->getBase()->IgnoreParenImpCasts();
7451 while(
const auto*ASE = dyn_cast<ArraySubscriptExpr>(
Base))
7452 Base= ASE->getBase()->IgnoreParenImpCasts();
7453 returncast<VarDecl>(cast<DeclRefExpr>(
Base)->getDecl());
7458 constllvm::DenseMap<const ValueDecl *, llvm::Value *>
7459CaptureDeviceAddrMap) {
7460llvm::SmallDenseSet<CanonicalDeclPtr<const Decl>, 4> Processed;
7461 for(
const Expr*Ref :
C.varlist()) {
7463 if(!Processed.insert(OrigVD).second)
7469 if(
const auto*OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) {
7472 const auto*ME = cast<MemberExpr>(OED->getInit());
7473assert(isa<CXXThisExpr>(ME->getBase()) &&
7474 "Base should be the current struct!");
7475MatchingVD = ME->getMemberDecl();
7480 autoInitAddrIt = CaptureDeviceAddrMap.find(MatchingVD);
7481 if(InitAddrIt == CaptureDeviceAddrMap.end())
7487 Address(InitAddrIt->second, Ty,
7491 if(isa<DeclRefExpr>(Ref->IgnoreParenImpCasts()) ||
7500(void)PrivateScope.addPrivate(OrigVD, PrivAddr);
7513 boolPrivatizeDevicePointers =
false;
7515 bool&PrivatizeDevicePointers;
7518 explicitDevicePointerPrivActionTy(
bool&PrivatizeDevicePointers)
7519: PrivatizeDevicePointers(PrivatizeDevicePointers) {}
7521PrivatizeDevicePointers =
true;
7524DevicePointerPrivActionTy PrivAction(PrivatizeDevicePointers);
7528CGF.
EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
7534PrivatizeDevicePointers =
false;
7540 if(PrivatizeDevicePointers) {
7541OMPPrivateScope PrivateScope(CGF);
7545Info.CaptureDeviceAddrMap);
7548Info.CaptureDeviceAddrMap);
7549(void)PrivateScope.Privatize();
7554std::optional<OpenMPDirectiveKind> CaptureRegion;
7558 for(
const Expr*
E:
C->varlist()) {
7559 const Decl*
D= cast<DeclRefExpr>(
E)->getDecl();
7560 if(
const auto*OED = dyn_cast<OMPCapturedExprDecl>(
D))
7564 for(
const Expr*
E:
C->varlist()) {
7566 if(
const auto*OED = dyn_cast<OMPCapturedExprDecl>(
D))
7570CaptureRegion = OMPD_unknown;
7573OMPLexicalScope
Scope(CGF, S, CaptureRegion);
7580PrivRCG.setAction(Action);
7585OMPLexicalScope
Scope(CGF, S);
7600 const Expr*IfCond =
nullptr;
7601 if(
const auto*
C= S.getSingleClause<
OMPIfClause>())
7602IfCond =
C->getCondition();
7610RCG.setAction(PrivAction);
7625 const Expr*IfCond =
nullptr;
7626 if(
const auto*
C= S.getSingleClause<
OMPIfClause>())
7627IfCond =
C->getCondition();
7634OMPLexicalScope
Scope(*
this, S, OMPD_task);
7646 const Expr*IfCond =
nullptr;
7647 if(
const auto*
C= S.getSingleClause<
OMPIfClause>())
7648IfCond =
C->getCondition();
7655OMPLexicalScope
Scope(*
this, S, OMPD_task);
7663 const CapturedStmt*CS = S.getCapturedStmt(OMPD_parallel);
7664Action.
Enter(CGF);
7666Action.
Enter(CGF);
7667CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
7671(void)PrivateScope.Privatize();
7690llvm::Function *
Fn;
7691llvm::Constant *Addr;
7694S, ParentName, Fn, Addr,
true, CodeGen);
7695assert(Fn && Addr &&
"Target device function emission failed.");
7709Action.
Enter(CGF);
7713Action.
Enter(CGF);
7714CodeGenFunction::OMPCancelStackRAII CancelRegion(
7715CGF, OMPD_target_parallel_for, S.hasCancel());
7730llvm::Function *
Fn;
7731llvm::Constant *Addr;
7734S, ParentName, Fn, Addr,
true, CodeGen);
7735assert(Fn && Addr &&
"Target device function emission failed.");
7750Action.
Enter(CGF);
7754Action.
Enter(CGF);
7769llvm::Function *
Fn;
7770llvm::Constant *Addr;
7773S, ParentName, Fn, Addr,
true, CodeGen);
7774assert(Fn && Addr &&
"Target device function emission failed.");
7788CodeGenFunction::OMPPrivateScope &Privates) {
7789 const auto*VDecl = cast<VarDecl>(Helper->
getDecl());
7796 const CapturedStmt*CS = S.getCapturedStmt(OMPD_taskloop);
7799OMPLexicalScope
Scope(*
this, S, OMPD_taskloop,
false);
7803 const Expr*IfCond =
nullptr;
7804 for(
const auto*
C: S.getClausesOfKind<
OMPIfClause>()) {
7805 if(
C->getNameModifier() == OMPD_unknown ||
7806 C->getNameModifier() == OMPD_taskloop) {
7807IfCond =
C->getCondition();
7820 Data.Schedule.setInt(
false);
7823(Clause->getModifier() == OMPC_GRAINSIZE_strict) ?
true:
false;
7826 Data.Schedule.setInt(
true);
7829(Clause->getModifier() == OMPC_NUMTASKS_strict) ?
true:
false;
7843llvm::BasicBlock *ContBlock =
nullptr;
7844OMPLoopScope PreInitScope(CGF, S);
7845 if(CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
7849llvm::BasicBlock *ThenBlock = CGF.createBasicBlock(
"taskloop.if.then");
7850ContBlock = CGF.createBasicBlock(
"taskloop.if.end");
7851 emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
7852CGF.getProfileCount(&S));
7853CGF.EmitBlock(ThenBlock);
7854CGF.incrementProfileCounter(&S);
7857(void)CGF.EmitOMPLinearClauseInit(S);
7859OMPPrivateScope LoopScope(CGF);
7861 enum{ LowerBound = 5, UpperBound, Stride, LastIter };
7863 auto*LBP = std::next(I, LowerBound);
7864 auto*UBP = std::next(I, UpperBound);
7865 auto*STP = std::next(I, Stride);
7866 auto*LIP = std::next(I, LastIter);
7867 mapParam(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()), *LBP,
7869 mapParam(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()), *UBP,
7871 mapParam(CGF, cast<DeclRefExpr>(S.getStrideVariable()), *STP, LoopScope);
7872 mapParam(CGF, cast<DeclRefExpr>(S.getIsLastIterVariable()), *LIP,
7874CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
7875CGF.EmitOMPLinearClause(S, LoopScope);
7876 boolHasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
7877(void)LoopScope.Privatize();
7879 const Expr*IVExpr = S.getIterationVariable();
7880 const auto*IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
7881CGF.EmitVarDecl(*IVDecl);
7882CGF.EmitIgnoredExpr(S.getInit());
7887 if(
const auto*LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
7888CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
7890CGF.EmitIgnoredExpr(S.getCalcLastIteration());
7894OMPLexicalScope
Scope(CGF, S, OMPD_taskloop,
false);
7902CGF.EmitOMPInnerLoop(
7903S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(),
7905emitOMPLoopBodyWithStopPoint(CGF, S,
7906CodeGenFunction::JumpDest());
7913CGF.EmitBranch(ContBlock);
7914CGF.EmitBlock(ContBlock,
true);
7917 if(HasLastprivateClause) {
7918CGF.EmitOMPLastprivateClauseFinal(
7920CGF.Builder.CreateIsNotNull(CGF.EmitLoadOfScalar(
7921CGF.GetAddrOfLocalVar(*LIP),
false,
7922(*LIP)->getType(), S.getBeginLoc())));
7924LoopScope.restoreMap();
7926 returnCGF.
Builder.CreateIsNotNull(
7928(*LIP)->
getType(), S.getBeginLoc()));
7931 auto&&TaskGen = [&S, SharedsTy, CapturedStruct,
7934 auto&&CodeGen = [&S, OutlinedFn, SharedsTy, CapturedStruct, IfCond,
7936OMPLoopScope PreInitScope(CGF, S);
7937CGF.CGM.getOpenMPRuntime().emitTaskLoopCall(CGF, S.getBeginLoc(), S,
7938OutlinedFn, SharedsTy,
7939CapturedStruct, IfCond,
Data);
7941CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop,
7944 if(
Data.Nogroup) {
7951Action.
Enter(CGF);
7969OMPLexicalScope
Scope(*
this, S);
7976Action.
Enter(CGF);
7981OMPLexicalScope
Scope(*
this, S, std::nullopt,
false);
7988Action.
Enter(CGF);
7993OMPLexicalScope
Scope(*
this, S, std::nullopt,
false);
8000Action.
Enter(CGF);
8005OMPLexicalScope
Scope(*
this, S);
8012Action.
Enter(CGF);
8017OMPLexicalScope
Scope(*
this, S);
8026Action.
Enter(CGF);
8029OMPLexicalScope
Scope(CGF, S, OMPD_parallel,
false);
8044Action.
Enter(CGF);
8047OMPLexicalScope
Scope(CGF, S, OMPD_parallel,
false);
8062Action.
Enter(CGF);
8065OMPLexicalScope
Scope(CGF, S, OMPD_parallel,
false);
8080Action.
Enter(CGF);
8083OMPLexicalScope
Scope(CGF, S, OMPD_parallel,
false);
8102 const Expr*IfCond =
nullptr;
8103 if(
const auto*
C= S.getSingleClause<
OMPIfClause>())
8104IfCond =
C->getCondition();
8111OMPLexicalScope
Scope(*
this, S, OMPD_task);
8122BindKind =
C->getBindKind();
8125 caseOMPC_BIND_parallel:
8127 caseOMPC_BIND_teams:
8129 caseOMPC_BIND_thread:
8140 const auto*ForS = dyn_cast<ForStmt>(CS);
8141 if(ForS && !isa<DeclStmt>(ForS->getInit())) {
8142OMPPrivateScope LoopScope(CGF);
8144(void)LoopScope.Privatize();
8146LoopScope.restoreMap();
8151OMPLexicalScope
Scope(*
this, S, OMPD_unknown);
8160Action.
Enter(CGF);
8185Action.
Enter(CGF);
8186OMPPrivateScope PrivateScope(CGF);
8187CGF.EmitOMPReductionClauseInit(S, PrivateScope);
8188(void)PrivateScope.Privatize();
8189CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
8191CGF.EmitOMPReductionClauseFinal(S,
OMPD_teams);
8200std::string StatusMsg,
8204StatusMsg +=
": DEVICE";
8206StatusMsg +=
": HOST";
8213llvm::dbgs() << StatusMsg <<
": "<<
FileName<<
": "<< LineNo <<
"\n";
8220Action.
Enter(CGF);
8231Action.
Enter(CGF);
8232CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
8234(void)PrivateScope.Privatize();
8236CGF, OMPD_distribute, CodeGenDistribute,
false);
8251Action.
Enter(CGF);
8260Action.
Enter(CGF);
8261CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
8263(void)PrivateScope.Privatize();
8265CGF, OMPD_distribute, CodeGenDistribute,
false);
8279 if(S.canBeParallelFor())
8292 if(S.canBeParallelFor())
8297llvm::Function *
Fn;
8298llvm::Constant *Addr;
8301S, ParentName, Fn, Addr,
true, CodeGen);
8302assert(Fn && Addr &&
8303 "Target device function emission failed for 'target teams loop'.");
8309Action.
Enter(CGF);
8312Action.
Enter(CGF);
8313CodeGenFunction::OMPCancelStackRAII CancelRegion(
8314CGF, OMPD_target_parallel_loop,
false);
8329llvm::Function *
Fn;
8330llvm::Constant *Addr;
8333S, ParentName, Fn, Addr,
true, CodeGen);
8334assert(Fn && Addr &&
"Target device function emission failed.");
8349 if(
const auto*SD = dyn_cast<OMPScanDirective>(&
D)) {
8353 if(!
D.hasAssociatedStmt() || !
D.getAssociatedStmt())
8356OMPPrivateScope GlobalsScope(CGF);
8360 for(
const Expr*Ref :
C->varlist()) {
8361 const auto*DRE = cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
8364 const auto*VD = dyn_cast<VarDecl>(DRE->getDecl());
8367 if(!CGF.LocalDeclMap.count(VD)) {
8369GlobalsScope.addPrivate(VD, GlobLVal.
getAddress());
8375(void)GlobalsScope.Privatize();
8376ParentLoopDirectiveForScanRegion ScanRegion(CGF,
D);
8379 if(
const auto*LD = dyn_cast<OMPLoopDirective>(&
D)) {
8380 for(
const Expr*
E: LD->counters()) {
8381 const auto*VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
8384GlobalsScope.addPrivate(VD, GlobLVal.
getAddress());
8386 if(isa<OMPCapturedExprDecl>(VD)) {
8388 if(!CGF.LocalDeclMap.count(VD))
8393 if(!
C->getNumForLoops())
8395 for(
unsignedI = LD->getLoopsNumber(),
8396 E=
C->getLoopNumIterations().size();
8398 if(
const auto*VD = dyn_cast<OMPCapturedExprDecl>(
8399cast<DeclRefExpr>(
C->getLoopCounter(I))->getDecl())) {
8401 if(!CGF.LocalDeclMap.count(VD))
8407(void)GlobalsScope.Privatize();
8408CGF.
EmitStmt(
D.getInnermostCapturedStmt()->getCapturedStmt());
8411 if(
D.getDirectiveKind() == OMPD_atomic ||
8412 D.getDirectiveKind() == OMPD_critical ||
8413 D.getDirectiveKind() == OMPD_section ||
8414 D.getDirectiveKind() == OMPD_master ||
8415 D.getDirectiveKind() == OMPD_masked ||
8416 D.getDirectiveKind() == OMPD_unroll ||
8417 D.getDirectiveKind() == OMPD_assume) {
8422OMPSimdLexicalScope
Scope(*
this,
D);
8426:
D.getDirectiveKind(),
Defines the clang::ASTContext interface.
static bool isAllocatableDecl(const VarDecl *VD)
static const VarDecl * getBaseDecl(const Expr *Ref, const DeclRefExpr *&DE)
static void emitTargetRegion(CodeGenFunction &CGF, const OMPTargetDirective &S, PrePostActionTy &Action)
static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S, PrePostActionTy &Action)
static llvm::Function * emitOutlinedOrderedFunction(CodeGenModule &CGM, const CapturedStmt *S, SourceLocation Loc)
static const VarDecl * getBaseDecl(const Expr *Ref)
static void emitTargetTeamsGenericLoopRegionAsParallel(CodeGenFunction &CGF, PrePostActionTy &Action, const OMPTargetTeamsGenericLoopDirective &S)
static void emitOMPAtomicReadExpr(CodeGenFunction &CGF, llvm::AtomicOrdering AO, const Expr *X, const Expr *V, SourceLocation Loc)
static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF, llvm::AtomicOrdering AO, bool IsPostfixUpdate, const Expr *V, const Expr *X, const Expr *E, const Expr *UE, bool IsXLHSInRHSPart, SourceLocation Loc)
static void emitScanBasedDirective(CodeGenFunction &CGF, const OMPLoopDirective &S, llvm::function_ref< llvm::Value *(CodeGenFunction &)> NumIteratorsGen, llvm::function_ref< void(CodeGenFunction &)> FirstGen, llvm::function_ref< void(CodeGenFunction &)> SecondGen)
Emits the code for the directive with inscan reductions.
static void emitSimpleAtomicStore(CodeGenFunction &CGF, llvm::AtomicOrdering AO, LValue LVal, RValue RVal)
static bool isSupportedByOpenMPIRBuilder(const OMPTaskgroupDirective &T)
static Address castValueFromUintptr(CodeGenFunction &CGF, SourceLocation Loc, QualType DstType, StringRef Name, LValue AddrLV)
static void emitDistributeParallelForDistributeInnerBoundParams(CodeGenFunction &CGF, const OMPExecutableDirective &S, llvm::SmallVectorImpl< llvm::Value * > &CapturedVars)
static void emitScanBasedDirectiveFinals(CodeGenFunction &CGF, const OMPLoopDirective &S, llvm::function_ref< llvm::Value *(CodeGenFunction &)> NumIteratorsGen)
Copies final inscan reductions values to the original variables.
static void checkForLastprivateConditionalUpdate(CodeGenFunction &CGF, const OMPExecutableDirective &S)
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...
static void emitTargetParallelForRegion(CodeGenFunction &CGF, const OMPTargetParallelForDirective &S, PrePostActionTy &Action)
static LValue EmitOMPHelperVar(CodeGenFunction &CGF, const DeclRefExpr *Helper)
Emit a helper variable and return corresponding lvalue.
static void emitOMPAtomicUpdateExpr(CodeGenFunction &CGF, llvm::AtomicOrdering AO, const Expr *X, const Expr *E, const Expr *UE, bool IsXLHSInRHSPart, SourceLocation Loc)
static llvm::Value * convertToScalarValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, QualType DestType, SourceLocation Loc)
static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S, const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount)
static std::pair< bool, RValue > emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X, RValue Update, BinaryOperatorKind BO, llvm::AtomicOrdering AO, bool IsXLHSInRHSPart)
static std::pair< LValue, LValue > emitDistributeParallelForInnerBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S)
static void emitTargetTeamsGenericLoopRegionAsDistribute(CodeGenFunction &CGF, PrePostActionTy &Action, const OMPTargetTeamsGenericLoopDirective &S)
static void emitTargetParallelRegion(CodeGenFunction &CGF, const OMPTargetParallelDirective &S, PrePostActionTy &Action)
static std::pair< llvm::Value *, llvm::Value * > emitDispatchForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S, Address LB, Address UB)
When dealing with dispatch schedules (e.g.
static void emitMaster(CodeGenFunction &CGF, const OMPExecutableDirective &S)
static void emitRestoreIP(CodeGenFunction &CGF, const T *C, llvm::OpenMPIRBuilder::InsertPointTy AllocaIP, llvm::OpenMPIRBuilder &OMPBuilder)
static void emitCommonOMPTargetDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, const RegionCodeGenTy &CodeGen)
static void emitSimdlenSafelenClause(CodeGenFunction &CGF, const OMPExecutableDirective &D)
static void emitAlignedClause(CodeGenFunction &CGF, const OMPExecutableDirective &D)
static bool isSimdSupportedByOpenMPIRBuilder(const OMPLoopDirective &S)
static void emitCommonOMPParallelDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, const CodeGenBoundParametersTy &CodeGenBoundParameters)
static bool emitWorksharingDirective(CodeGenFunction &CGF, const OMPLoopDirective &S, bool HasCancel)
static void emitPostUpdateForReductionClause(CodeGenFunction &CGF, const OMPExecutableDirective &D, const llvm::function_ref< llvm::Value *(CodeGenFunction &)> CondGen)
static void emitEmptyOrdered(CodeGenFunction &, SourceLocation Loc, const unsigned IVSize, const bool IVSigned)
static void emitTargetTeamsLoopCodegenStatus(CodeGenFunction &CGF, std::string StatusMsg, const OMPExecutableDirective &D)
static bool isForSupportedByOpenMPIRBuilder(const OMPLoopDirective &S, bool HasCancel)
static RValue emitSimpleAtomicLoad(CodeGenFunction &CGF, llvm::AtomicOrdering AO, LValue LVal, SourceLocation Loc)
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.
static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, llvm::AtomicOrdering AO, llvm::AtomicOrdering FailAO, bool IsPostfixUpdate, const Expr *X, const Expr *V, const Expr *R, const Expr *E, const Expr *UE, const Expr *D, const Expr *CE, bool IsXLHSInRHSPart, bool IsFailOnly, SourceLocation Loc)
static CodeGenFunction::ComplexPairTy convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, QualType DestType, SourceLocation Loc)
static ImplicitParamDecl * createImplicitFirstprivateForType(ASTContext &C, OMPTaskDataTy &Data, QualType Ty, CapturedDecl *CD, SourceLocation Loc)
static EmittedClosureTy emitCapturedStmtFunc(CodeGenFunction &ParentCGF, const CapturedStmt *S)
Emit a captured statement and return the function as well as its captured closure context.
static void emitOMPLoopBodyWithStopPoint(CodeGenFunction &CGF, const OMPLoopDirective &S, CodeGenFunction::JumpDest LoopExit)
static void emitOMPDistributeDirective(const OMPLoopDirective &S, CodeGenFunction &CGF, CodeGenModule &CGM)
static void emitOMPCopyinClause(CodeGenFunction &CGF, const OMPExecutableDirective &S)
static void emitTargetTeamsDistributeParallelForRegion(CodeGenFunction &CGF, const OMPTargetTeamsDistributeParallelForDirective &S, PrePostActionTy &Action)
static llvm::CallInst * emitCapturedStmtCall(CodeGenFunction &ParentCGF, EmittedClosureTy Cap, llvm::ArrayRef< llvm::Value * > Args)
Emit a call to a previously captured closure.
static void emitMasked(CodeGenFunction &CGF, const OMPExecutableDirective &S)
static void emitBody(CodeGenFunction &CGF, const Stmt *S, const Stmt *NextLoop, int MaxLevel, int Level=0)
static void emitOMPForDirective(const OMPLoopDirective &S, CodeGenFunction &CGF, CodeGenModule &CGM, bool HasCancel)
static void emitEmptyBoundParameters(CodeGenFunction &, const OMPExecutableDirective &, llvm::SmallVectorImpl< llvm::Value * > &)
static void emitTargetParallelForSimdRegion(CodeGenFunction &CGF, const OMPTargetParallelForSimdDirective &S, PrePostActionTy &Action)
static void emitOMPSimdDirective(const OMPLoopDirective &S, CodeGenFunction &CGF, CodeGenModule &CGM)
static void emitOMPAtomicCompareExpr(CodeGenFunction &CGF, llvm::AtomicOrdering AO, llvm::AtomicOrdering FailAO, const Expr *X, const Expr *V, const Expr *R, const Expr *E, const Expr *D, const Expr *CE, bool IsXBinopExpr, bool IsPostfixUpdate, bool IsFailOnly, SourceLocation Loc)
std::pair< llvm::Function *, llvm::Value * > EmittedClosureTy
static OpenMPDirectiveKind getEffectiveDirectiveKind(const OMPExecutableDirective &S)
static void emitTargetTeamsRegion(CodeGenFunction &CGF, PrePostActionTy &Action, const OMPTargetTeamsDirective &S)
static void buildDependences(const OMPExecutableDirective &S, OMPTaskDataTy &Data)
static RValue convertToType(CodeGenFunction &CGF, RValue Value, QualType SourceType, QualType ResType, SourceLocation Loc)
static void emitScanBasedDirectiveDecls(CodeGenFunction &CGF, const OMPLoopDirective &S, llvm::function_ref< llvm::Value *(CodeGenFunction &)> NumIteratorsGen)
Emits internal temp array declarations for the directive with inscan reductions.
static void emitTargetTeamsDistributeParallelForSimdRegion(CodeGenFunction &CGF, const OMPTargetTeamsDistributeParallelForSimdDirective &S, PrePostActionTy &Action)
static void emitTargetTeamsDistributeSimdRegion(CodeGenFunction &CGF, PrePostActionTy &Action, const OMPTargetTeamsDistributeSimdDirective &S)
static llvm::MapVector< llvm::Value *, llvm::Value * > GetAlignedMapping(const OMPLoopDirective &S, CodeGenFunction &CGF)
static llvm::omp::ScheduleKind convertClauseKindToSchedKind(OpenMPScheduleClauseKind ScheduleClauseKind)
static void mapParam(CodeGenFunction &CGF, const DeclRefExpr *Helper, const ImplicitParamDecl *PVD, CodeGenFunction::OMPPrivateScope &Privates)
Emit a helper variable and return corresponding lvalue.
static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)
static void emitTargetParallelGenericLoopRegion(CodeGenFunction &CGF, const OMPTargetParallelGenericLoopDirective &S, PrePostActionTy &Action)
static QualType getCanonicalParamType(ASTContext &C, QualType T)
static void emitCommonSimdLoop(CodeGenFunction &CGF, const OMPLoopDirective &S, const RegionCodeGenTy &SimdInitGen, const RegionCodeGenTy &BodyCodeGen)
static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty, const Twine &Name, llvm::Value *Init=nullptr)
static void emitOMPAtomicWriteExpr(CodeGenFunction &CGF, llvm::AtomicOrdering AO, const Expr *X, const Expr *E, 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)
static void emitInnerParallelForWhenCombined(CodeGenFunction &CGF, const OMPLoopDirective &S, CodeGenFunction::JumpDest LoopExit)
static void emitTargetTeamsDistributeRegion(CodeGenFunction &CGF, PrePostActionTy &Action, const OMPTargetTeamsDistributeDirective &S)
enum clang::sema::@1704::IndirectLocalPathEntry::EntryKind Kind
This file defines OpenMP nodes for declarative directives.
static const Decl * getCanonicalDecl(const Decl *D)
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
Defines the SourceManager interface.
This file defines OpenMP AST classes for executable directives and clauses.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
TranslationUnitDecl * getTranslationUnitDecl() const
QualType getRecordType(const RecordDecl *Decl) const
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Represents an attribute applied to a statement.
ArrayRef< const Attr * > getAttrs() const
A builtin binary operation expression such as "x + y" or "x <= y".
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Represents the body of a CapturedStmt, and serves as its DeclContext.
unsigned getContextParamPosition() const
static CapturedDecl * Create(ASTContext &C, DeclContext *DC, unsigned NumParams)
param_iterator param_end() const
Retrieve an iterator one past the last parameter decl.
param_iterator param_begin() const
Retrieve an iterator pointing to the first parameter decl.
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
ImplicitParamDecl * getParam(unsigned i) const
This captures a statement into a function.
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
const RecordDecl * getCapturedRecordDecl() const
Retrieve the record declaration for captured variables.
Stmt * getCapturedStmt()
Retrieve the statement being captured.
Expr *const * const_capture_init_iterator
Const iterator that walks over the capture initialization arguments.
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
bool hasReducedDebugInfo() const
Check if type and variable info should be emitted.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
Address withAlignment(CharUnits NewAlignment) const
Return address with different alignment, but same pointer and element type.
llvm::PointerType * getType() const
Return the type of the pointer value.
static AggValueSlot ignored()
ignored - Returns an aggregate value slot indicating that the aggregate value is being ignored.
static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)
Apply TemporaryLocation if it is valid.
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, llvm::Type *ElementTy, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
CGFunctionInfo - Class to encapsulate the information about a function definition.
Manages list of lastprivate conditional decls for the specified directive.
static LastprivateConditionalRAII disable(CodeGenFunction &CGF, const OMPExecutableDirective &S)
Manages list of nontemporal decls for the specified directive.
Struct that keeps all the relevant information that should be kept throughout a 'target data' region.
Manages list of nontemporal decls for the specified directive.
virtual void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D, llvm::Function *TaskFunction, QualType SharedsTy, Address Shareds, const Expr *IfCond, const OMPTaskDataTy &Data)
Emit task region for the task directive.
virtual llvm::Value * emitForNext(CodeGenFunction &CGF, SourceLocation Loc, unsigned IVSize, bool IVSigned, Address IL, Address LB, Address UB, Address ST)
Call __kmpc_dispatch_next( ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter, kmp_int[32|64] *p_lowe...
virtual void emitTargetDataStandAloneCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond, const Expr *Device)
Emit the data mapping/movement code associated with the directive D that should be of the form 'targe...
virtual void emitNumThreadsClause(CodeGenFunction &CGF, llvm::Value *NumThreads, SourceLocation Loc)
Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid, kmp_int32 num_threads)...
virtual void emitSingleRegion(CodeGenFunction &CGF, const RegionCodeGenTy &SingleOpGen, SourceLocation Loc, ArrayRef< const Expr * > CopyprivateVars, ArrayRef< const Expr * > DestExprs, ArrayRef< const Expr * > SrcExprs, ArrayRef< const Expr * > AssignmentOps)
Emits a single region.
virtual Address getTaskReductionItem(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *ReductionsPtr, LValue SharedLVal)
Get the address of void * type of the privatue copy of the reduction item specified by the SharedLVal...
virtual void emitForDispatchDeinit(CodeGenFunction &CGF, SourceLocation Loc)
This is used for non static scheduled types and when the ordered clause is present on the loop constr...
virtual void getDefaultScheduleAndChunk(CodeGenFunction &CGF, const OMPLoopDirective &S, OpenMPScheduleClauseKind &ScheduleKind, const Expr *&ChunkExpr) const
Choose default schedule type and chunk value for the schedule clause.
virtual void emitTeamsCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, SourceLocation Loc, llvm::Function *OutlinedFn, ArrayRef< llvm::Value * > CapturedVars)
Emits code for teams call of the OutlinedFn with variables captured in a record which address is stor...
virtual void emitCancellationPointCall(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind CancelRegion)
Emit code for 'cancellation point' construct.
virtual const VarDecl * translateParameter(const FieldDecl *FD, const VarDecl *NativeParam) const
Translates the native parameter of outlined function if this is required for target.
virtual llvm::Function * emitTeamsOutlinedFunction(CodeGenFunction &CGF, const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)
Emits outlined function for the specified OpenMP teams directive D.
virtual void emitDoacrossInit(CodeGenFunction &CGF, const OMPLoopDirective &D, ArrayRef< Expr * > NumIterations)
Emit initialization for doacross loop nesting support.
virtual void adjustTargetSpecificDataForLambdas(CodeGenFunction &CGF, const OMPExecutableDirective &D) const
Adjust some parameters for the target-based directives, like addresses of the variables captured by r...
virtual void emitTargetDataCalls(CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond, const Expr *Device, const RegionCodeGenTy &CodeGen, CGOpenMPRuntime::TargetDataInfo &Info)
Emit the target data mapping code associated with D.
virtual Address getParameterAddress(CodeGenFunction &CGF, const VarDecl *NativeParam, const VarDecl *TargetParam) const
Gets the address of the native argument basing on the address of the target-specific parameter.
virtual void emitTaskgroupRegion(CodeGenFunction &CGF, const RegionCodeGenTy &TaskgroupOpGen, SourceLocation Loc)
Emit a taskgroup region.
virtual void emitNumTeamsClause(CodeGenFunction &CGF, const Expr *NumTeams, const Expr *ThreadLimit, SourceLocation Loc)
Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32 global_tid, kmp_int32 num_teams,...
virtual llvm::Value * emitTaskReductionInit(CodeGenFunction &CGF, SourceLocation Loc, ArrayRef< const Expr * > LHSExprs, ArrayRef< const Expr * > RHSExprs, const OMPTaskDataTy &Data)
Emit a code for initialization of task reduction clause.
void emitUpdateClause(CodeGenFunction &CGF, LValue DepobjLVal, OpenMPDependClauseKind NewDepKind, SourceLocation Loc)
Updates the dependency kind in the specified depobj object.
virtual void emitLastprivateConditionalFinalUpdate(CodeGenFunction &CGF, LValue PrivLVal, const VarDecl *VD, SourceLocation Loc)
Gets the address of the global copy used for lastprivate conditional update, if any.
virtual void emitErrorCall(CodeGenFunction &CGF, SourceLocation Loc, Expr *ME, bool IsFatal)
Emit __kmpc_error call for error directive extern void __kmpc_error(ident_t *loc, int severity,...
virtual void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc)
Emits code for a taskyield directive.
virtual void emitFlush(CodeGenFunction &CGF, ArrayRef< const Expr * > Vars, SourceLocation Loc, llvm::AtomicOrdering AO)
Emit flush of the variables specified in 'omp flush' directive.
virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc, const OMPTaskDataTy &Data)
Emit code for 'taskwait' directive.
virtual void emitProcBindClause(CodeGenFunction &CGF, llvm::omp::ProcBindKind ProcBind, SourceLocation Loc)
Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid, int proc_bind) to generat...
virtual void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind Kind, bool EmitChecks=true, bool ForceSimpleCall=false)
Emit an implicit/explicit barrier for OpenMP threads.
virtual void emitDistributeStaticInit(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDistScheduleClauseKind SchedKind, const StaticRTInput &Values)
virtual void emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind)
Call the appropriate runtime routine to notify that we finished all the work with current loop.
void emitIfClause(CodeGenFunction &CGF, const Expr *Cond, const RegionCodeGenTy &ThenGen, const RegionCodeGenTy &ElseGen)
Emits code for OpenMP 'if' clause using specified CodeGen function.
Address emitDepobjDependClause(CodeGenFunction &CGF, const OMPTaskDataTy::DependData &Dependencies, SourceLocation Loc)
Emits list of dependecies based on the provided data (array of dependence/expression pairs) for depob...
virtual llvm::Function * emitParallelOutlinedFunction(CodeGenFunction &CGF, const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)
Emits outlined function for the specified OpenMP parallel directive D.
virtual void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind, const OpenMPScheduleTy &ScheduleKind, const StaticRTInput &Values)
Call the appropriate runtime routine to initialize it before start of loop.
llvm::AtomicOrdering getDefaultMemoryOrdering() const
Gets default memory ordering as specified in requires directive.
virtual bool isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind, bool Chunked) const
Check if the specified ScheduleKind is static non-chunked.
virtual void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, const Expr *IfCond, OpenMPDirectiveKind CancelRegion)
Emit code for 'cancel' construct.
virtual void emitMasterRegion(CodeGenFunction &CGF, const RegionCodeGenTy &MasterOpGen, SourceLocation Loc)
Emits a master region.
virtual llvm::Function * emitTaskOutlinedFunction(const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, const VarDecl *PartIDVar, const VarDecl *TaskTVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, bool Tied, unsigned &NumberOfParts)
Emits outlined function for the OpenMP task directive D.
void emitDestroyClause(CodeGenFunction &CGF, LValue DepobjLVal, SourceLocation Loc)
Emits the code to destroy the dependency object provided in depobj directive.
virtual void emitTaskReductionFixups(CodeGenFunction &CGF, SourceLocation Loc, ReductionCodeGen &RCG, unsigned N)
Required to resolve existing problems in the runtime.
virtual void emitDoacrossOrdered(CodeGenFunction &CGF, const OMPDependClause *C)
Emit code for doacross ordered directive with 'depend' clause.
virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, const Expr *LHS)
Checks if the provided LVal is lastprivate conditional and emits the code to update the value of the ...
virtual void getDefaultDistScheduleAndChunk(CodeGenFunction &CGF, const OMPLoopDirective &S, OpenMPDistScheduleClauseKind &ScheduleKind, llvm::Value *&Chunk) const
Choose default schedule type and chunk value for the dist_schedule clause.
llvm::OpenMPIRBuilder & getOMPBuilder()
virtual void emitTargetOutlinedFunction(const OMPExecutableDirective &D, StringRef ParentName, llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID, bool IsOffloadEntry, const RegionCodeGenTy &CodeGen)
Emit outilined function for 'target' directive.
virtual void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName, const RegionCodeGenTy &CriticalOpGen, SourceLocation Loc, const Expr *Hint=nullptr)
Emits a critical region.
virtual void emitForOrderedIterationEnd(CodeGenFunction &CGF, SourceLocation Loc, unsigned IVSize, bool IVSigned)
Call the appropriate runtime routine to notify that we finished iteration of the ordered loop with th...
virtual void emitOutlinedFunctionCall(CodeGenFunction &CGF, SourceLocation Loc, llvm::FunctionCallee OutlinedFn, ArrayRef< llvm::Value * > Args={}) const
Emits call of the outlined function with the provided arguments, translating these arguments to corre...
virtual void checkAndEmitSharedLastprivateConditional(CodeGenFunction &CGF, const OMPExecutableDirective &D, const llvm::DenseSet< CanonicalDeclPtr< const VarDecl > > &IgnoredDecls)
Checks if the lastprivate conditional was updated in inner region and writes the value.
virtual void emitInlinedDirective(CodeGenFunction &CGF, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, bool HasCancel=false)
Emit code for the directive that does not require outlining.
virtual void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, llvm::Function *OutlinedFn, ArrayRef< llvm::Value * > CapturedVars, const Expr *IfCond, llvm::Value *NumThreads)
Emits code for parallel or serial call of the OutlinedFn with variables captured in a record which ad...
virtual bool isStaticChunked(OpenMPScheduleClauseKind ScheduleKind, bool Chunked) const
Check if the specified ScheduleKind is static chunked.
virtual void emitTargetCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, llvm::Function *OutlinedFn, llvm::Value *OutlinedFnID, const Expr *IfCond, llvm::PointerIntPair< const Expr *, 2, OpenMPDeviceClauseModifier > Device, llvm::function_ref< llvm::Value *(CodeGenFunction &CGF, const OMPLoopDirective &D)> SizeEmitter)
Emit the target offloading code associated with D.
virtual void emitReduction(CodeGenFunction &CGF, SourceLocation Loc, ArrayRef< const Expr * > Privates, ArrayRef< const Expr * > LHSExprs, ArrayRef< const Expr * > RHSExprs, ArrayRef< const Expr * > ReductionOps, ReductionOptionsTy Options)
Emit a code for reduction clause.
std::pair< llvm::Value *, Address > emitDependClause(CodeGenFunction &CGF, ArrayRef< OMPTaskDataTy::DependData > Dependencies, SourceLocation Loc)
Emits list of dependecies based on the provided data (array of dependence/expression pairs).
virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const
Check if the specified ScheduleKind is dynamic.
Address emitLastprivateConditionalInit(CodeGenFunction &CGF, const VarDecl *VD)
Create specialized alloca to handle lastprivate conditionals.
virtual void emitOrderedRegion(CodeGenFunction &CGF, const RegionCodeGenTy &OrderedOpGen, SourceLocation Loc, bool IsThreads)
Emit an ordered region.
virtual void emitTaskReductionFini(CodeGenFunction &CGF, SourceLocation Loc, bool IsWorksharingReduction)
Emits the following code for reduction clause with task modifier:
virtual void emitMaskedRegion(CodeGenFunction &CGF, const RegionCodeGenTy &MaskedOpGen, SourceLocation Loc, const Expr *Filter=nullptr)
Emits a masked region.
virtual void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc, const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned, bool Ordered, const DispatchRTInput &DispatchValues)
Call the appropriate runtime routine to initialize it before start of loop.
virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S)
Emit the captured statement body.
virtual StringRef getHelperName() const
Get the name of the capture helper.
virtual const FieldDecl * lookup(const VarDecl *VD) const
Lookup the captured field decl for a variable.
RAII for preserving necessary info during inlined region body codegen.
Cleanup action for allocate support.
RAII for preserving necessary info during Outlined region body codegen.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitOMPTaskBasedDirective(const OMPExecutableDirective &S, const OpenMPDirectiveKind CapturedRegion, const RegionCodeGenTy &BodyGen, const TaskGenTy &TaskGen, OMPTaskDataTy &Data)
void EmitOMPTargetTeamsDirective(const OMPTargetTeamsDirective &S)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void EmitOMPParallelGenericLoopDirective(const OMPLoopDirective &S)
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 EmitOMPMaskedTaskLoopSimdDirective(const OMPMaskedTaskLoopSimdDirective &S)
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
void EmitOMPCopy(QualType OriginalType, Address DestAddr, Address SrcAddr, const VarDecl *DestVD, const VarDecl *SrcVD, const Expr *Copy)
Emit proper copying of data from one variable to another.
void EmitOMPOrderedDirective(const OMPOrderedDirective &S)
void EmitOMPTargetDirective(const OMPTargetDirective &S)
bool EmitOMPFirstprivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
void EmitOMPReductionClauseInit(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope, bool ForInscan=false)
Emit initial code for reduction variables.
void EmitOMPAtomicDirective(const OMPAtomicDirective &S)
void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S)
void EmitOMPParallelMasterTaskLoopDirective(const OMPParallelMasterTaskLoopDirective &S)
void EmitAutoVarDecl(const VarDecl &D)
EmitAutoVarDecl - Emit an auto variable declaration.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
static void EmitOMPTargetTeamsDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDirective &S)
Emit device code for the target teams directive.
void EmitOMPReverseDirective(const OMPReverseDirective &S)
static bool hasScalarEvaluationKind(QualType T)
llvm::function_ref< std::pair< llvm::Value *, llvm::Value * >(CodeGenFunction &, const OMPExecutableDirective &S, Address LB, Address UB)> CodeGenDispatchBoundsTy
CGCapturedStmtInfo * CapturedStmtInfo
void EmitDecl(const Decl &D)
EmitDecl - Emit a declaration.
static void EmitOMPTargetTeamsDistributeDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeDirective &S)
Emit device code for the target teams distribute directive.
Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
Load a pointer with type PtrTy stored at address Ptr.
static void EmitOMPTargetParallelForSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelForSimdDirective &S)
Emit device code for the target parallel for simd directive.
llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)
emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
const OMPExecutableDirective * OMPParentLoopDirectiveForScan
Parent loop-based directive for scan directive.
void EmitOMPTeamsDistributeParallelForDirective(const OMPTeamsDistributeParallelForDirective &S)
void EmitOMPTaskDirective(const OMPTaskDirective &S)
void EmitOMPScanDirective(const OMPScanDirective &S)
void EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S)
JumpDest getOMPCancelDestination(OpenMPDirectiveKind Kind)
void EmitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective &S)
void EmitOMPUseDevicePtrClause(const OMPUseDevicePtrClause &C, OMPPrivateScope &PrivateScope, const llvm::DenseMap< const ValueDecl *, llvm::Value * > CaptureDeviceAddrMap)
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
RValue EmitAtomicLoad(LValue LV, SourceLocation SL, AggValueSlot Slot=AggValueSlot::ignored())
void EmitOMPDistributeLoop(const OMPLoopDirective &S, const CodeGenLoopTy &CodeGenLoop, Expr *IncExpr)
Emit code for the distribute loop-based directive.
void EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S)
static void EmitOMPTargetDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetDirective &S)
Emit device code for the target directive.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitAtomicUpdate(LValue LVal, llvm::AtomicOrdering AO, const llvm::function_ref< RValue(RValue)> &UpdateOp, bool IsVolatile)
const LangOptions & getLangOpts() const
static void EmitOMPTargetSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetSimdDirective &S)
Emit device code for the target simd directive.
void EmitOMPDistributeSimdDirective(const OMPDistributeSimdDirective &S)
void EmitOMPPrivateLoopCounters(const OMPLoopDirective &S, OMPPrivateScope &LoopScope)
Emit initial code for loop counters of loop-based directives.
void EmitOMPDistributeParallelForDirective(const OMPDistributeParallelForDirective &S)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
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 EmitOMPInterchangeDirective(const OMPInterchangeDirective &S)
void EmitOMPTeamsGenericLoopDirective(const OMPTeamsGenericLoopDirective &S)
void EmitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective &S)
Address EmitLoadOfReference(LValue RefLVal, LValueBaseInfo *PointeeBaseInfo=nullptr, TBAAAccessInfo *PointeeTBAAInfo=nullptr)
void EmitOMPParallelMaskedTaskLoopDirective(const OMPParallelMaskedTaskLoopDirective &S)
void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
EmitExprAsInit - Emits the code necessary to initialize a location in memory with the given initializ...
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
void EmitOMPParallelDirective(const OMPParallelDirective &S)
void EmitOMPSimdFinal(const OMPLoopDirective &D, const llvm::function_ref< llvm::Value *(CodeGenFunction &)> CondGen)
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
llvm::Type * ConvertTypeForMem(QualType T)
void EmitOMPDistributeParallelForSimdDirective(const OMPDistributeParallelForSimdDirective &S)
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
void EmitOMPForSimdDirective(const OMPForSimdDirective &S)
llvm::AssertingVH< llvm::Instruction > AllocaInsertPt
AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...
void EmitAggregateAssign(LValue Dest, LValue Src, QualType EltTy)
Emit an aggregate assignment.
void GenerateOpenMPCapturedVars(const CapturedStmt &S, SmallVectorImpl< llvm::Value * > &CapturedVars)
CodeGenFunction * ParentCGF
JumpDest ReturnBlock
ReturnBlock - Unified return block.
const llvm::function_ref< void(CodeGenFunction &, llvm::Function *, const OMPTaskDataTy &)> TaskGenTy
static void EmitOMPTargetTeamsGenericLoopDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsGenericLoopDirective &S)
Emit device code for the target teams loop directive.
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
void EmitOMPFlushDirective(const OMPFlushDirective &S)
void EmitOMPMaskedTaskLoopDirective(const OMPMaskedTaskLoopDirective &S)
llvm::BasicBlock * OMPBeforeScanBlock
void EmitOMPCancelDirective(const OMPCancelDirective &S)
void EmitOMPGenericLoopDirective(const OMPGenericLoopDirective &S)
void EmitOMPTargetTeamsDistributeDirective(const OMPTargetTeamsDistributeDirective &S)
ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr)
void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S)
static void EmitOMPTargetTeamsDistributeParallelForDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeParallelForDirective &S)
void emitOMPSimpleStore(LValue LVal, RValue RVal, QualType RValTy, SourceLocation Loc)
void EmitOMPInnerLoop(const OMPExecutableDirective &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.
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location)
Converts Location to a DebugLoc, if debug information is enabled.
llvm::Value * getTypeSize(QualType Ty)
Returns calculated size of the specified type.
void EmitOMPDepobjDirective(const OMPDepobjDirective &S)
void EmitOMPSingleDirective(const OMPSingleDirective &S)
void EmitOMPTargetTeamsGenericLoopDirective(const OMPTargetTeamsGenericLoopDirective &S)
llvm::CanonicalLoopInfo * EmitOMPCollapsedCanonicalLoopNest(const Stmt *S, int Depth)
Emit the Stmt S and return its topmost canonical loop, if any.
void EmitSimpleOMPExecutableDirective(const OMPExecutableDirective &D)
Emit simple code for OpenMP directives in Simd-only mode.
void EmitOMPDistributeDirective(const OMPDistributeDirective &S)
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
void EmitOMPParallelForDirective(const OMPParallelForDirective &S)
void EmitOMPTeamsDirective(const OMPTeamsDirective &S)
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
void EmitOMPUnrollDirective(const OMPUnrollDirective &S)
void EmitOMPParallelMasterTaskLoopSimdDirective(const OMPParallelMasterTaskLoopSimdDirective &S)
void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S)
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
bool isTrivialInitializer(const Expr *Init)
Determine whether the given initializer is trivial in the sense that it requires no code to be genera...
CGDebugInfo * getDebugInfo()
void EmitOMPTargetTeamsDistributeParallelForSimdDirective(const OMPTargetTeamsDistributeParallelForSimdDirective &S)
void EmitOMPTeamsDistributeParallelForSimdDirective(const OMPTeamsDistributeParallelForSimdDirective &S)
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
llvm::Function * GenerateCapturedStmtFunction(const CapturedStmt &S)
void EmitOMPInteropDirective(const OMPInteropDirective &S)
void EmitOMPReductionClauseFinal(const OMPExecutableDirective &D, const OpenMPDirectiveKind ReductionKind)
Emit final update of reduction values to original variables at the end of the directive.
llvm::BasicBlock * OMPScanDispatch
llvm::function_ref< std::pair< LValue, LValue >(CodeGenFunction &, const OMPExecutableDirective &S)> CodeGenLoopBoundsTy
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
void EmitOMPTargetTaskBasedDirective(const OMPExecutableDirective &S, const RegionCodeGenTy &BodyGen, OMPTargetDataInfo &InputInfo)
void EmitOMPScopeDirective(const OMPScopeDirective &S)
void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S)
void EmitOMPParallelMaskedDirective(const OMPParallelMaskedDirective &S)
static void EmitOMPTargetParallelForDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelForDirective &S)
Emit device code for the target parallel for directive.
void EmitOMPSimdInit(const OMPLoopDirective &D)
Helpers for the OpenMP loop directives.
int ExpectedOMPLoopDepth
Number of nested loop to be consumed by the last surrounding loop-associated directive.
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
void EmitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &S)
ASTContext & getContext() const
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...
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
static void EmitOMPTargetTeamsDistributeSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeSimdDirective &S)
Emit device code for the target teams distribute simd directive.
SmallVector< llvm::CanonicalLoopInfo *, 4 > OMPLoopNestStack
List of recently emitted OMPCanonicalLoops.
bool EmitOMPWorksharingLoop(const OMPLoopDirective &S, Expr *EUB, const CodeGenLoopBoundsTy &CodeGenLoopBounds, const CodeGenDispatchBoundsTy &CGDispatchBounds)
Emit code for the worksharing loop-based directive.
void EmitOMPLinearClause(const OMPLoopDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope)
Emit initial code for linear clauses.
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void EmitOMPTileDirective(const OMPTileDirective &S)
bool EmitOMPLinearClauseInit(const OMPLoopDirective &D)
Emit initial code for linear variables.
llvm::DenseMap< const ValueDecl *, FieldDecl * > LambdaCaptureFields
void EmitOMPParallelMaskedTaskLoopSimdDirective(const OMPParallelMaskedTaskLoopSimdDirective &S)
void EmitOMPLoopBody(const OMPLoopDirective &D, JumpDest LoopExit)
Helper for the OpenMP loop directives.
void EmitOMPLinearClauseFinal(const OMPLoopDirective &D, const llvm::function_ref< llvm::Value *(CodeGenFunction &)> CondGen)
Emit final code for linear clauses.
void EmitOMPSectionsDirective(const OMPSectionsDirective &S)
llvm::BasicBlock * OMPScanExitBlock
static void EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeParallelForSimdDirective &S)
Emit device code for the target teams distribute parallel for simd directive.
void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst)
void EmitOMPUseDeviceAddrClause(const OMPUseDeviceAddrClause &C, OMPPrivateScope &PrivateScope, const llvm::DenseMap< const ValueDecl *, llvm::Value * > CaptureDeviceAddrMap)
void EmitOMPTargetSimdDirective(const OMPTargetSimdDirective &S)
void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S)
void EmitOMPSimdDirective(const OMPSimdDirective &S)
void EmitOMPCriticalDirective(const OMPCriticalDirective &S)
void EmitOMPForDirective(const OMPForDirective &S)
void EmitOMPMetaDirective(const OMPMetaDirective &S)
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
void EmitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &S)
LValue InitCapturedStruct(const CapturedStmt &S)
void EmitOMPParallelMasterDirective(const OMPParallelMasterDirective &S)
void EmitOMPTargetTeamsDistributeSimdDirective(const OMPTargetTeamsDistributeSimdDirective &S)
void processInReduction(const OMPExecutableDirective &S, OMPTaskDataTy &Data, CodeGenFunction &CGF, const CapturedStmt *CS, OMPPrivateScope &Scope)
void EmitOMPMasterDirective(const OMPMasterDirective &S)
void EmitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective &S)
void EmitOMPTargetParallelGenericLoopDirective(const OMPTargetParallelGenericLoopDirective &S)
void EmitOMPAssumeDirective(const OMPAssumeDirective &S)
bool EmitOMPCopyinClause(const OMPExecutableDirective &D)
Emit code for copyin clause in D directive.
void EmitOMPMaskedDirective(const OMPMaskedDirective &S)
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
void EmitOMPPrivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S)
llvm::Function * GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S, SourceLocation Loc)
void EmitOMPTargetParallelForSimdDirective(const OMPTargetParallelForSimdDirective &S)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
Address GenerateCapturedStmtArgument(const CapturedStmt &S)
static void EmitOMPTargetParallelGenericLoopDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelGenericLoopDirective &S)
Emit device code for the target parallel loop directive.
llvm::function_ref< void(CodeGenFunction &, SourceLocation, const unsigned, const bool)> CodeGenOrderedTy
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit)
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...
llvm::BasicBlock * OMPAfterScanBlock
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S)
void EmitOMPErrorDirective(const OMPErrorDirective &S)
void EmitOMPSectionDirective(const OMPSectionDirective &S)
static void EmitOMPTargetParallelDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelDirective &S)
llvm::AtomicRMWInst * emitAtomicRMWInst(llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val, llvm::AtomicOrdering Order=llvm::AtomicOrdering::SequentiallyConsistent, llvm::SyncScope::ID SSID=llvm::SyncScope::System, const AtomicExpr *AE=nullptr)
Emit an atomicrmw instruction, and applying relevant metadata when applicable.
void EmitOMPBarrierDirective(const OMPBarrierDirective &S)
void EmitStopPoint(const Stmt *S)
EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
void EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S)
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
void EmitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &S)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void EmitOMPTargetTeamsDistributeParallelForDirective(const OMPTargetTeamsDistributeParallelForDirective &S)
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
bool EmitOMPLastprivateClauseInit(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
Emit initial code for lastprivate variables.
void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S)
llvm::function_ref< void(CodeGenFunction &, const OMPLoopDirective &, JumpDest)> CodeGenLoopTy
void EmitOMPCanonicalLoop(const OMPCanonicalLoop *S)
Emit an OMPCanonicalLoop using the OpenMPIRBuilder.
void EmitOMPTeamsDistributeSimdDirective(const OMPTeamsDistributeSimdDirective &S)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
void EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S)
std::pair< bool, RValue > EmitOMPAtomicSimpleUpdateExpr(LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart, llvm::AtomicOrdering AO, SourceLocation Loc, const llvm::function_ref< RValue(RValue)> CommonGen)
Emit atomic update code for constructs: X = X BO E or X = E BO E.
This class organizes the cross-function state that is used while generating LLVM code.
void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
llvm::Module & getModule() const
CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const
Return the store size, in character units, of the given LLVM type.
DiagnosticsEngine & getDiags() const
const LangOptions & getLangOpts() const
CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)
CodeGenTypes & getTypes()
const llvm::DataLayout & getDataLayout() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
llvm::Constant * GetAddrOfGlobal(GlobalDecl GD, ForDefinition_t IsForDefinition=NotForDefinition)
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
StringRef getMangledName(GlobalDecl GD)
llvm::Constant * getStaticLocalDeclAddress(const VarDecl *D)
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn)
Assign counters to regions and configure them for PGO of a given function.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
llvm::Value * getPointer(CodeGenFunction &CGF) const
Address getAddress() const
void setAddress(Address address)
void setUnrollCount(unsigned C)
Set the unroll count for the next loop pushed.
void setVectorizeWidth(unsigned W)
Set the vectorize width for the next loop pushed.
void setParallel(bool Enable=true)
Set the next pushed loop as parallel.
void setUnrollState(const LoopAttributes::LVEnableState &State)
Set the next pushed loop unroll state.
void pop()
End the current loop.
void push(llvm::BasicBlock *Header, const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
Begin a new structured loop.
void setVectorizeEnable(bool Enable=true)
Set the next pushed loop 'vectorize.enable'.
A basic class for pre|post-action for advanced codegen sequence for OpenMP region.
virtual void Enter(CodeGenFunction &CGF)
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
An abstract representation of an aligned address.
llvm::PointerType * getType() const
Return the type of the pointer value.
llvm::Value * getPointer() const
Class intended to support codegen of all kind of the reduction clauses.
void emitAggregateType(CodeGenFunction &CGF, unsigned N)
Emits the code for the variable-modified type, if required.
void emitSharedOrigLValue(CodeGenFunction &CGF, unsigned N)
Emits lvalue for the shared and original reduction item.
Class provides a way to call simple version of codegen for OpenMP region, or an advanced with possibl...
Complex values, per C99 6.2.5p11.
CompoundStmt - This represents a group of statements like { stmt stmt }.
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
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)
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
SourceLocation getBodyRBrace() const
getBodyRBrace - Gets the right brace of the body, if a body exists.
virtual bool hasBody() const
Returns true if this Decl represents a declaration for a body of code, such as a function or method d...
SourceLocation getLocation() const
SourceLocation getBeginLoc() const LLVM_READONLY
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
The name of a declaration.
SourceLocation getBeginLoc() const LLVM_READONLY
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
Represents a function declaration or definition.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, Expr *TrailingRequiresClause=nullptr)
GlobalDecl - represents a global declaration.
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
std::vector< llvm::Triple > OMPTargetTriples
Triples of the OpenMP targets that the host code codegen should take into account in order to generat...
Represents a point when we exit a loop.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
A C++ nested-name-specifier augmented with source location information.
This represents 'acq_rel' clause in the '#pragma omp atomic|flush' directives.
This represents 'acquire' clause in the '#pragma omp atomic|flush' directives.
This represents clause 'aligned' in the '#pragma omp ...' directives.
This represents '#pragma omp atomic' directive.
This represents '#pragma omp barrier' directive.
This represents 'bind' clause in the '#pragma omp ...' directives.
This represents '#pragma omp cancel' directive.
This represents '#pragma omp cancellation point' directive.
Representation of an OpenMP canonical loop.
static OMPClauseWithPreInit * get(OMPClause *C)
This is a basic class for representing single OpenMP clause.
This represents clause 'copyin' in the '#pragma omp ...' directives.
This represents clause 'copyprivate' in the '#pragma omp ...' directives.
This represents '#pragma omp critical' directive.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
This represents implicit clause 'depobj' for the '#pragma omp depobj' directive.
This represents '#pragma omp depobj' directive.
This represents 'destroy' clause in the '#pragma omp depobj' directive or the '#pragma omp interop' d...
This represents 'device' clause in the '#pragma omp ...' directive.
This represents 'dist_schedule' clause in the '#pragma omp ...' directive.
This represents '#pragma omp distribute' directive.
This represents '#pragma omp distribute parallel for' composite directive.
This represents '#pragma omp distribute parallel for simd' composite directive.
This represents '#pragma omp distribute simd' composite directive.
This represents the 'doacross' clause for the '#pragma omp ordered' directive.
This represents '#pragma omp error' directive.
This is a basic class for representing single OpenMP executable directive.
OpenMPDirectiveKind getDirectiveKind() const
SourceLocation getEndLoc() const
Returns ending location of directive.
static llvm::iterator_range< specific_clause_iterator< SpecificClause > > getClausesOfKind(ArrayRef< OMPClause * > Clauses)
This represents 'fail' clause in the '#pragma omp atomic' directive.
OpenMPClauseKind getFailParameter() const
Gets the parameter (type memory-order-clause) in Fail clause.
This represents 'filter' clause in the '#pragma omp ...' directive.
This represents 'final' clause in the '#pragma omp ...' directive.
This represents clause 'firstprivate' in the '#pragma omp ...' directives.
This represents implicit clause 'flush' for the '#pragma omp flush' directive.
This represents '#pragma omp flush' directive.
This represents '#pragma omp for' directive.
This represents '#pragma omp for simd' directive.
Representation of the 'full' clause of the '#pragma omp unroll' directive.
This represents '#pragma omp loop' directive.
This represents 'grainsize' clause in the '#pragma omp ...' directive.
This represents 'hint' clause in the '#pragma omp ...' directive.
This represents 'if' clause in the '#pragma omp ...' directive.
This represents clause 'in_reduction' in the '#pragma omp task' directives.
This represents clause 'inclusive' in the '#pragma omp scan' directive.
This represents the 'init' clause in '#pragma omp ...' directives.
Represents the '#pragma omp interchange' loop transformation directive.
This represents '#pragma omp interop' directive.
This represents clause 'lastprivate' in the '#pragma omp ...' directives.
This represents clause 'linear' in the '#pragma omp ...' directives.
The base class for all loop-based directives, including loop transformation directives.
static Stmt * tryToFindNextInnerLoop(Stmt *CurStmt, bool TryImperfectlyNestedLoops)
Try to find the next loop sub-statement in the specified statement CurStmt.
static bool doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, llvm::function_ref< bool(unsigned, Stmt *)> Callback, llvm::function_ref< void(OMPLoopTransformationDirective *)> OnTransformationCallback)
Calls the specified callback function for all the loops in CurStmt, from the outermost to the innermo...
This is a common base class for loop directives ('omp simd', 'omp for', 'omp for simd' etc....
Expr * getPrevUpperBoundVariable() const
Expr * getPrevLowerBoundVariable() const
Expr * getIterationVariable() const
Expr * getUpperBoundVariable() const
Expr * getLowerBoundVariable() const
This represents '#pragma omp masked' directive.
This represents '#pragma omp masked taskloop' directive.
This represents '#pragma omp masked taskloop simd' directive.
This represents '#pragma omp master' directive.
This represents '#pragma omp master taskloop' directive.
This represents '#pragma omp master taskloop simd' directive.
This represents 'message' clause in the '#pragma omp error' directive.
Expr * getMessageString() const
Returns message string of the clause.
This represents 'nogroup' clause in the '#pragma omp ...' directive.
This represents 'nowait' clause in the '#pragma omp ...' directive.
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
This represents 'num_teams' clause in the '#pragma omp ...' directive.
This represents 'num_threads' clause in the '#pragma omp ...' directive.
This represents 'order' clause in the '#pragma omp ...' directive.
This represents 'ordered' clause in the '#pragma omp ...' directive.
This represents '#pragma omp ordered' directive.
This represents '#pragma omp parallel' directive.
This represents '#pragma omp parallel for' directive.
This represents '#pragma omp parallel for simd' directive.
This represents '#pragma omp parallel masked' directive.
This represents '#pragma omp parallel masked taskloop' directive.
This represents '#pragma omp parallel masked taskloop simd' directive.
This represents '#pragma omp parallel master' directive.
This represents '#pragma omp parallel master taskloop' directive.
This represents '#pragma omp parallel master taskloop simd' directive.
This represents '#pragma omp parallel sections' directive.
Representation of the 'partial' clause of the '#pragma omp unroll' directive.
This represents 'priority' clause in the '#pragma omp ...' directive.
This represents clause 'private' in the '#pragma omp ...' directives.
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
This represents clause 'reduction' in the '#pragma omp ...' directives.
This represents 'relaxed' clause in the '#pragma omp atomic' directives.
This represents 'release' clause in the '#pragma omp atomic|flush' directives.
Represents the '#pragma omp reverse' loop transformation directive.
This represents 'simd' clause in the '#pragma omp ...' directive.
This represents 'safelen' clause in the '#pragma omp ...' directive.
This represents '#pragma omp scan' directive.
This represents 'schedule' clause in the '#pragma omp ...' directive.
This represents '#pragma omp scope' directive.
This represents '#pragma omp section' directive.
This represents '#pragma omp sections' directive.
This represents 'seq_cst' clause in the '#pragma omp atomic|flush' directives.
This represents 'severity' clause in the '#pragma omp error' directive.
OpenMPSeverityClauseKind getSeverityKind() const
Returns kind of the clause.
This represents '#pragma omp simd' directive.
This represents 'simdlen' clause in the '#pragma omp ...' directive.
This represents '#pragma omp single' directive.
This represents '#pragma omp target data' directive.
This represents '#pragma omp target' directive.
This represents '#pragma omp target enter data' directive.
This represents '#pragma omp target exit data' directive.
This represents '#pragma omp target parallel' directive.
This represents '#pragma omp target parallel for' directive.
This represents '#pragma omp target parallel for simd' directive.
This represents '#pragma omp target parallel loop' directive.
This represents '#pragma omp target simd' directive.
This represents '#pragma omp target teams' directive.
This represents '#pragma omp target teams distribute' combined directive.
This represents '#pragma omp target teams distribute parallel for' combined directive.
This represents '#pragma omp target teams distribute parallel for simd' combined directive.
This represents '#pragma omp target teams distribute simd' combined directive.
This represents '#pragma omp target teams loop' directive.
This represents '#pragma omp target update' directive.
This represents '#pragma omp task' directive.
This represents '#pragma omp taskloop' directive.
This represents '#pragma omp taskloop simd' directive.
This represents clause 'task_reduction' in the '#pragma omp taskgroup' directives.
This represents '#pragma omp taskgroup' directive.
This represents '#pragma omp taskwait' directive.
This represents '#pragma omp taskyield' directive.
This represents '#pragma omp teams' directive.
This represents '#pragma omp teams distribute' directive.
This represents '#pragma omp teams distribute parallel for' composite directive.
This represents '#pragma omp teams distribute parallel for simd' composite directive.
This represents '#pragma omp teams distribute simd' combined directive.
This represents '#pragma omp teams loop' directive.
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
This represents the '#pragma omp tile' loop transformation directive.
This represents the '#pragma omp unroll' loop transformation directive.
This represents 'untied' clause in the '#pragma omp ...' directive.
This represents 'update' clause in the '#pragma omp atomic' directive.
This represents the 'use' clause in '#pragma omp ...' directives.
This represents clause 'use_device_addr' in the '#pragma omp ...' directives.
This represents clause 'use_device_ptr' in the '#pragma omp ...' directives.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
PointerType - C99 6.7.5.1 - Pointer Declarators.
Represents an unpacked "presumed" location which can be presented to the user.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
If a crash happens while one of these objects are live, the message is printed out along with the spe...
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Represents a struct/union/class.
field_range fields() const
field_iterator field_begin() const
Base for LValueReferenceType and RValueReferenceType.
Scope - A scope is a transient data structure that is used while parsing the program.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getBeginLoc() const LLVM_READONLY
SwitchStmt - This represents a 'switch' stmt.
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...
bool isTLSSupported() const
Whether the target supports thread-local storage.
The base class of the type hierarchy.
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isScalarType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isLValueReferenceType() const
bool isAnyComplexType() const
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isAnyPointerType() const
bool isRecordType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
TLSKind getTLSKind() const
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
@ CInit
C-style initialization with assignment.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
const Expr * getInit() const
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
@ TLS_None
Not a TLS variable.
Represents a C array with a specified size that is not an integer-constant-expression.
Expr * getSizeExpr() const
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
bool Inc(InterpState &S, CodePtr OpPC)
1) Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...
The JSON file list parser is used to communicate input to InstallAPI.
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
bool needsTaskBasedThreadLimit(OpenMPDirectiveKind DKind)
Checks if the specified target directive, combined or not, needs task based thread_limit.
@ Ctor_Complete
Complete object ctor.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
@ OK_Ordinary
An ordinary object is located at an address in memory.
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
@ Tile
'tile' clause, allowed on 'loop' and Combined constructs.
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
@ OMPC_SCHEDULE_MODIFIER_unknown
llvm::omp::Clause OpenMPClauseKind
OpenMP clauses.
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
@ OMPC_DIST_SCHEDULE_unknown
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop,...
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
@ Result
The result type of a method or function.
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
bool isOpenMPGenericLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive constitutes a 'loop' directive in the outermost nest.
OpenMPBindClauseKind
OpenMP bindings for the 'bind' clause.
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
@ Dtor_Complete
Complete object dtor.
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of the composite or combined directives that need loop ...
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
const FunctionProtoType * T
void getOpenMPCaptureRegions(llvm::SmallVectorImpl< OpenMPDirectiveKind > &CaptureRegions, OpenMPDirectiveKind DKind)
Return the captured regions of an OpenMP directive.
@ ThreadPrivateVar
Parameter for Thread private variable.
@ Other
Other implicit parameter.
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
Diagnostic wrappers for TextAPI types for error reporting.
struct with the values to be passed to the dispatch runtime function
llvm::Value * Chunk
Chunk size specified using 'schedule' clause (nullptr if chunk was not specified)
Struct with the values to be passed to the static runtime function.
static Address getAddrOfThreadPrivate(CodeGenFunction &CGF, const VarDecl *VD, Address VDAddr, SourceLocation Loc)
Returns address of the threadprivate variable for the current thread.
llvm::OpenMPIRBuilder::InsertPointTy InsertPointTy
static void EmitOMPOutlinedRegionBody(CodeGenFunction &CGF, const Stmt *RegionBodyStmt, InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Twine RegionName)
Emit the body of an OMP region that will be outlined in OpenMPIRBuilder::finalize().
static Address getAddressOfLocalVariable(CodeGenFunction &CGF, const VarDecl *VD)
Gets the OpenMP-specific address of the local variable /p VD.
static void EmitCaptureStmt(CodeGenFunction &CGF, InsertPointTy CodeGenIP, llvm::BasicBlock &FiniBB, llvm::Function *Fn, ArrayRef< llvm::Value * > Args)
static std::string getNameWithSeparators(ArrayRef< StringRef > Parts, StringRef FirstSeparator=".", StringRef Separator=".")
Get the platform-specific name separator.
static void FinalizeOMPRegion(CodeGenFunction &CGF, InsertPointTy IP)
Emit the Finalization for an OMP region.
static void EmitOMPInlinedRegionBody(CodeGenFunction &CGF, const Stmt *RegionBodyStmt, InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Twine RegionName)
Emit the body of an OMP region.
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::PointerType * Int8PtrTy
SmallVector< const Expr *, 4 > DepExprs
EvalResult is a struct with detailed info about an evaluated expression.
Extra information about a function prototype.
Scheduling data for loop-based OpenMP directives.
OpenMPScheduleClauseModifier M2
OpenMPScheduleClauseModifier M1
OpenMPScheduleClauseKind Schedule
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4