22 #include "llvm/IR/CallSite.h"
23 using namespace clang;
24 using namespace CodeGen;
31 for (
const auto *C : S.
clauses()) {
33 if (
auto *PreInit = cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {
34 for (
const auto *
I : PreInit->decls()) {
35 if (!
I->hasAttr<OMPCaptureNoInitAttr>())
57 bool AsInlined =
false,
bool EmitPreInitStmt =
true)
61 emitPreInitStmt(CGF, S);
65 for (
auto &C : CS->captures()) {
66 if (
C.capturesVariable() ||
C.capturesVariableByCopy()) {
67 auto *VD =
C.getCapturedVar();
69 isCapturedVar(CGF, VD) ||
71 InlinedShareds.isGlobalVarCaptured(VD)),
74 InlinedShareds.addPrivate(VD, [&CGF, &DRE]() ->
Address {
79 (void)InlinedShareds.Privatize();
87 class OMPParallelScope final :
public OMPLexicalScope {
97 : OMPLexicalScope(CGF, S,
99 EmitPreInitStmt(S)) {}
104 class OMPTeamsScope final :
public OMPLexicalScope {
113 : OMPLexicalScope(CGF, S,
115 EmitPreInitStmt(S)) {}
122 if (
auto *LD = dyn_cast<OMPLoopDirective>(&S)) {
123 if (
auto *PreInits = cast_or_null<DeclStmt>(LD->getPreInits())) {
124 for (
const auto *
I : PreInits->decls())
133 emitPreInitStmt(CGF, S);
142 auto SizeInChars = C.getTypeSizeInChars(Ty);
143 if (SizeInChars.isZero()) {
145 while (
auto *VAT = C.getAsVariableArrayType(Ty)) {
148 Size = Size ?
Builder.CreateNUWMul(Size, ArraySize) : ArraySize;
150 SizeInChars = C.getTypeSizeInChars(Ty);
151 if (SizeInChars.isZero())
152 return llvm::ConstantInt::get(
SizeTy, 0);
166 I !=
E; ++
I, ++CurField, ++CurCap) {
167 if (CurField->hasCapturedVLAType()) {
168 auto VAT = CurField->getCapturedVLAType();
169 auto *Val = VLASizeMap[VAT->getSizeExpr()];
170 CapturedVars.push_back(Val);
171 }
else if (CurCap->capturesThis())
172 CapturedVars.push_back(CXXThisValue);
173 else if (CurCap->capturesVariableByCopy()) {
179 if (!CurField->getType()->isAnyPointerType()) {
182 Ctx.getUIntPtrType(),
183 Twine(CurCap->getCapturedVar()->getName()) +
".casted");
187 DstAddr.getPointer(), Ctx.getPointerType(Ctx.getUIntPtrType()),
198 CapturedVars.push_back(CV);
200 assert(CurCap->capturesVariable() &&
"Expected capture by reference.");
208 bool isReferenceType =
false) {
220 if (isReferenceType) {
222 auto *RefVal = TmpAddr.getPointer();
244 struct FunctionOptions {
249 bool UIntPtrCastRequired =
true;
252 bool RegisterCastedArgsOnly =
false;
254 StringRef FunctionName;
255 explicit FunctionOptions(
const CapturedStmt *S,
bool UIntPtrCastRequired,
256 bool RegisterCastedArgsOnly,
257 StringRef FunctionName)
258 : S(S), UIntPtrCastRequired(UIntPtrCastRequired),
259 RegisterCastedArgsOnly(UIntPtrCastRequired && RegisterCastedArgsOnly),
260 FunctionName(FunctionName) {}
266 llvm::DenseMap<
const Decl *, std::pair<const VarDecl *, Address>>
268 llvm::DenseMap<
const Decl *, std::pair<const Expr *, llvm::Value *>>
270 llvm::Value *&CXXThisValue,
const FunctionOptions &FO) {
272 const RecordDecl *RD = FO.S->getCapturedRecordDecl();
273 assert(CD->
hasBody() &&
"missing CapturedDecl body");
275 CXXThisValue =
nullptr;
279 bool HasUIntPtrArgs =
false;
282 auto I = FO.S->captures().begin();
283 for (
auto *FD : RD->
fields()) {
294 I->capturesVariableArrayType()) {
295 HasUIntPtrArgs =
true;
296 if (FO.UIntPtrCastRequired)
300 if (
I->capturesVariable() ||
I->capturesVariableByCopy()) {
301 CapVar =
I->getCapturedVar();
303 }
else if (
I->capturesThis())
306 assert(
I->capturesVariableArrayType());
312 FD->getLocation(), II, ArgType,
331 F->addFnAttr(llvm::Attribute::NoUnwind);
337 I = FO.S->captures().begin();
338 for (
auto *FD : RD->
fields()) {
341 if (
I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) {
342 const VarDecl *CurVD =
I->getCapturedVar();
352 if (!FO.RegisterCastedArgsOnly)
353 LocalAddrs.insert({Args[Cnt], {CurVD, LocalAddr}});
361 Args[Cnt]->getType(), BaseInfo);
362 if (FD->hasCapturedVLAType()) {
363 if (FO.UIntPtrCastRequired) {
365 Args[Cnt]->getName(),
371 auto VAT = FD->getCapturedVLAType();
372 VLASizes.insert({Args[Cnt], {VAT->getSizeExpr(), ExprArg}});
373 }
else if (
I->capturesVariable()) {
374 auto *Var =
I->getCapturedVar();
387 if (!FO.RegisterCastedArgsOnly) {
392 }
else if (
I->capturesVariableByCopy()) {
393 assert(!FD->getType()->isAnyPointerType() &&
394 "Not expecting a captured pointer.");
395 auto *Var =
I->getCapturedVar();
400 FO.UIntPtrCastRequired
406 assert(
I->capturesThis());
409 LocalAddrs.insert({Args[Cnt], {
nullptr, ArgLVal.
getAddress()}});
415 return {F, HasUIntPtrArgs};
422 "CapturedStmtInfo should be set when generating the captured function");
425 bool NeedWrapperFunction =
429 llvm::DenseMap<const Decl *, std::pair<const VarDecl *, Address>> LocalAddrs;
430 llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> VLASizes;
431 FunctionOptions FO(&S, !NeedWrapperFunction,
false,
436 *
this, Args, LocalAddrs, VLASizes, CXXThisValue, FO);
437 for (
const auto &LocalAddrPair : LocalAddrs) {
438 if (LocalAddrPair.second.first) {
439 setAddrOfLocalVar(LocalAddrPair.second.first,
440 LocalAddrPair.second.second);
443 for (
const auto &VLASizePair : VLASizes)
444 VLASizeMap[VLASizePair.second.first] = VLASizePair.second.second;
448 if (!NeedWrapperFunction || !HasUIntPtrArgs)
451 FunctionOptions WrapperFO(&S,
true,
453 ".nondebug_wrapper.");
459 llvm::Function *WrapperF =
461 WrapperCGF.CXXThisValue, WrapperFO).first;
464 for (
const auto *Arg : Args) {
466 auto I = LocalAddrs.find(Arg);
467 if (
I != LocalAddrs.end()) {
472 auto EI = VLASizes.find(Arg);
473 if (EI != VLASizes.end())
474 CallArg = EI->second.second;
481 CallArgs.emplace_back(
CallArg);
483 WrapperCGF.Builder.CreateCall(F, CallArgs);
484 WrapperCGF.FinishFunction();
505 auto DestEnd =
Builder.CreateGEP(DestBegin, NumElements);
510 Builder.CreateICmpEQ(DestBegin, DestEnd,
"omp.arraycpy.isempty");
511 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
514 auto EntryBB =
Builder.GetInsertBlock();
519 llvm::PHINode *SrcElementPHI =
520 Builder.CreatePHI(SrcBegin->getType(), 2,
"omp.arraycpy.srcElementPast");
521 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
526 llvm::PHINode *DestElementPHI =
527 Builder.CreatePHI(DestBegin->getType(), 2,
"omp.arraycpy.destElementPast");
528 DestElementPHI->addIncoming(DestBegin, EntryBB);
534 CopyGen(DestElementCurrent, SrcElementCurrent);
537 auto DestElementNext =
Builder.CreateConstGEP1_32(
538 DestElementPHI, 1,
"omp.arraycpy.dest.element");
539 auto SrcElementNext =
Builder.CreateConstGEP1_32(
540 SrcElementPHI, 1,
"omp.arraycpy.src.element");
543 Builder.CreateICmpEQ(DestElementNext, DestEnd,
"omp.arraycpy.done");
544 Builder.CreateCondBr(Done, DoneBB, BodyBB);
545 DestElementPHI->addIncoming(DestElementNext,
Builder.GetInsertBlock());
546 SrcElementPHI->addIncoming(SrcElementNext,
Builder.GetInsertBlock());
557 if (BO && BO->getOpcode() == BO_Assign) {
564 DestAddr, SrcAddr, OriginalType,
565 [
this, Copy, SrcVD, DestVD](
Address DestElement,
Address SrcElement) {
574 SrcVD, [SrcElement]() ->
Address {
return SrcElement; });
594 bool FirstprivateIsLastprivate =
false;
597 for (
const auto *D : C->varlists())
604 auto IRef = C->varlist_begin();
605 auto InitsRef = C->inits().begin();
606 for (
auto IInit : C->private_copies()) {
607 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
608 bool ThisFirstprivateIsLastprivate =
609 Lastprivates.count(OrigVD->getCanonicalDecl()) > 0;
610 auto *CapFD = CapturesInfo.
lookup(OrigVD);
612 if (!ThisFirstprivateIsLastprivate && FD && (FD == CapFD) &&
613 !FD->getType()->isReferenceType()) {
614 EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl());
619 FirstprivateIsLastprivate =
620 FirstprivateIsLastprivate || ThisFirstprivateIsLastprivate;
621 if (EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()).second) {
622 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
623 auto *VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
627 (*IRef)->getType(),
VK_LValue, (*IRef)->getExprLoc());
643 Emission.getAllocatedAddress(), OriginalAddr,
Type,
644 [
this, VDInit, Init](
Address DestElement,
649 setAddrOfLocalVar(VDInit, SrcElement);
651 Init->getType().getQualifiers(),
653 LocalDeclMap.erase(VDInit);
657 return Emission.getAllocatedAddress();
665 setAddrOfLocalVar(VDInit, OriginalAddr);
667 LocalDeclMap.erase(VDInit);
671 assert(IsRegistered &&
672 "firstprivate var already registered as private");
680 return FirstprivateIsLastprivate && !EmittedAsFirstprivate.empty();
690 auto IRef = C->varlist_begin();
691 for (
auto IInit : C->private_copies()) {
692 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
693 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
694 auto VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
701 assert(IsRegistered &&
"private var already registered as private");
718 llvm::BasicBlock *CopyBegin =
nullptr, *CopyEnd =
nullptr;
720 auto IRef = C->varlist_begin();
721 auto ISrcRef = C->source_exprs().begin();
722 auto IDestRef = C->destination_exprs().begin();
723 for (
auto *AssignOp : C->assignment_ops()) {
724 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
732 getContext().getTargetInfo().isTLSSupported()) {
734 "Copyin threadprivates should have been captured!");
735 DeclRefExpr DRE(const_cast<VarDecl *>(VD),
true, (*IRef)->getType(),
738 LocalDeclMap.erase(VD);
747 if (CopiedVars.size() == 1) {
759 auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
760 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
761 EmitOMPCopy(Type, PrivateAddr, MasterAddr, DestVD, SrcVD, AssignOp);
780 bool HasAtLeastOneLastprivate =
false;
783 auto *LoopDirective = cast<OMPLoopDirective>(&D);
784 for (
auto *C : LoopDirective->counters()) {
791 HasAtLeastOneLastprivate =
true;
794 auto IRef = C->varlist_begin();
795 auto IDestRef = C->destination_exprs().begin();
796 for (
auto *IInit : C->private_copies()) {
799 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
802 if (AlreadyEmittedVars.insert(OrigVD->getCanonicalDecl()).second) {
803 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
806 const_cast<VarDecl *>(OrigVD),
815 if (IInit && !SIMDLCVs.count(OrigVD->getCanonicalDecl())) {
816 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
822 assert(IsRegistered &&
823 "lastprivate var already registered as private");
831 return HasAtLeastOneLastprivate;
845 llvm::BasicBlock *ThenBB =
nullptr;
846 llvm::BasicBlock *DoneBB =
nullptr;
847 if (IsLastIterCond) {
850 Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB);
854 llvm::DenseMap<const VarDecl *, const Expr *> LoopCountersAndUpdates;
855 if (
auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) {
856 auto IC = LoopDirective->counters().begin();
857 for (
auto F : LoopDirective->finals()) {
861 AlreadyEmittedVars.insert(D);
863 LoopCountersAndUpdates[D] = F;
868 auto IRef = C->varlist_begin();
869 auto ISrcRef = C->source_exprs().begin();
870 auto IDestRef = C->destination_exprs().begin();
871 for (
auto *AssignOp : C->assignment_ops()) {
872 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
874 auto *CanonicalVD = PrivateVD->getCanonicalDecl();
875 if (AlreadyEmittedVars.insert(CanonicalVD).second) {
879 if (
auto *FinalExpr = LoopCountersAndUpdates.lookup(CanonicalVD))
881 auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
882 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
887 if (
auto RefTy = PrivateVD->getType()->getAs<
ReferenceType>())
891 EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp);
897 if (
auto *PostUpdate = C->getPostUpdateExpr())
915 auto IPriv = C->privates().begin();
916 auto IRed = C->reduction_ops().begin();
917 auto ILHS = C->lhs_exprs().begin();
918 auto IRHS = C->rhs_exprs().begin();
919 for (
const auto *Ref : C->varlists()) {
920 Shareds.emplace_back(Ref);
921 Privates.emplace_back(*IPriv);
922 ReductionOps.emplace_back(*IRed);
923 LHSs.emplace_back(*ILHS);
924 RHSs.emplace_back(*IRHS);
925 std::advance(IPriv, 1);
926 std::advance(IRed, 1);
927 std::advance(ILHS, 1);
928 std::advance(IRHS, 1);
933 auto ILHS = LHSs.begin();
934 auto IRHS = RHSs.begin();
935 auto IPriv = Privates.begin();
936 for (
const auto *IRef : Shareds) {
937 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl());
939 RedCG.emitSharedLValue(*
this, Count);
950 *
this, Count, Emission.getAllocatedAddress());
953 assert(IsRegistered &&
"private var already registered as private");
957 auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
958 auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
959 if (isa<OMPArraySectionExpr>(IRef)) {
968 }
else if (isa<ArraySubscriptExpr>(IRef)) {
990 LHSVD, [OriginalAddr]() ->
Address {
return OriginalAddr; });
992 RHSVD, [
this, PrivateVD, RHSVD, IsArray]() ->
Address {
1015 bool HasAtLeastOneReduction =
false;
1017 HasAtLeastOneReduction =
true;
1018 Privates.append(C->privates().begin(), C->privates().end());
1019 LHSExprs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
1020 RHSExprs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
1021 ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
1023 if (HasAtLeastOneReduction) {
1032 {WithNowait, SimpleReduction, ReductionKind});
1041 llvm::BasicBlock *DoneBB =
nullptr;
1043 if (
auto *PostUpdate = C->getPostUpdateExpr()) {
1045 if (
auto *Cond = CondGen(CGF)) {
1050 CGF.
Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1068 CodeGenBoundParametersTy;
1074 const CodeGenBoundParametersTy &CodeGenBoundParameters) {
1080 auto NumThreads = CGF.
EmitScalarExpr(NumThreadsClause->getNumThreads(),
1083 CGF, NumThreads, NumThreadsClause->getLocStart());
1088 CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getLocStart());
1090 const Expr *IfCond =
nullptr;
1093 C->getNameModifier() == OMPD_parallel) {
1094 IfCond = C->getCondition();
1099 OMPParallelScope
Scope(CGF, S);
1105 CodeGenBoundParameters(CGF, S, CapturedVars);
1108 CapturedVars, IfCond);
1150 for (
auto *U : C->updates())
1156 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1161 BreakContinueStack.pop_back();
1165 const Stmt &S,
bool RequiresCleanup,
const Expr *LoopCond,
1166 const Expr *IncExpr,
1180 auto ExitBlock = LoopExit.getBlock();
1181 if (RequiresCleanup)
1188 if (ExitBlock != LoopExit.getBlock()) {
1198 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1206 BreakContinueStack.pop_back();
1218 for (
auto *Init : C->inits()) {
1219 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl());
1222 auto *OrigVD = cast<VarDecl>(Ref->getDecl());
1236 if (
auto CS = cast_or_null<BinaryOperator>(C->getCalcStep()))
1237 if (
auto SaveRef = cast<DeclRefExpr>(CS->getLHS())) {
1250 llvm::BasicBlock *DoneBB =
nullptr;
1253 auto IC = C->varlist_begin();
1254 for (
auto *F : C->finals()) {
1256 if (
auto *Cond = CondGen(*
this)) {
1261 Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1265 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl());
1276 if (
auto *PostUpdate = C->getPostUpdateExpr())
1288 unsigned ClauseAlignment = 0;
1289 if (
auto AlignmentExpr = Clause->getAlignment()) {
1292 ClauseAlignment =
static_cast<unsigned>(AlignmentCI->getZExtValue());
1294 for (
auto E : Clause->varlists()) {
1295 unsigned Alignment = ClauseAlignment;
1296 if (Alignment == 0) {
1303 E->getType()->getPointeeType()))
1306 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
1307 "alignment is not power of 2");
1308 if (Alignment != 0) {
1322 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
1323 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl());
1326 if (!LocalDeclMap.count(PrivateVD)) {
1332 (*I)->getType(),
VK_LValue, (*I)->getExprLoc());
1349 const Expr *Cond, llvm::BasicBlock *TrueBlock,
1350 llvm::BasicBlock *FalseBlock, uint64_t TrueCount) {
1358 for (
auto I : S.
inits()) {
1366 void CodeGenFunction::EmitOMPLinearClause(
1368 if (!HaveInsertPoint())
1372 auto *LoopDirective = cast<OMPLoopDirective>(&D);
1373 for (
auto *C : LoopDirective->counters()) {
1379 auto CurPrivate = C->privates().begin();
1380 for (
auto *
E : C->varlists()) {
1381 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
1383 cast<VarDecl>(cast<DeclRefExpr>(*CurPrivate)->getDecl());
1387 EmitVarDecl(*PrivateVD);
1388 return GetAddrOfLocalVar(PrivateVD);
1390 assert(IsRegistered &&
"linear var already registered as private");
1394 EmitVarDecl(*PrivateVD);
1408 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.
getScalarVal());
1418 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.
getScalarVal());
1430 LoopStack.setParallel(!IsMonotonic);
1431 LoopStack.setVectorizeEnable(
true);
1435 void CodeGenFunction::EmitOMPSimdFinal(
1438 if (!HaveInsertPoint())
1440 llvm::BasicBlock *DoneBB =
nullptr;
1443 for (
auto F : D.
finals()) {
1444 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl());
1445 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>((*IPC))->getDecl());
1447 if (LocalDeclMap.count(OrigVD) || CapturedStmtInfo->lookup(OrigVD) ||
1448 OrigVD->hasGlobalStorage() || CED) {
1450 if (
auto *Cond = CondGen(*
this)) {
1453 auto *ThenBB = createBasicBlock(
".omp.final.then");
1454 DoneBB = createBasicBlock(
".omp.final.done");
1455 Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1459 Address OrigAddr = Address::invalid();
1461 OrigAddr = EmitLValue(CED->getInit()->IgnoreImpCasts()).getAddress();
1465 (*IPC)->getType(),
VK_LValue, (*IPC)->getExprLoc());
1466 OrigAddr = EmitLValue(&DRE).getAddress();
1468 OMPPrivateScope VarScope(*
this);
1469 VarScope.addPrivate(OrigVD,
1470 [OrigAddr]() ->
Address {
return OrigAddr; });
1471 (void)VarScope.Privatize();
1478 EmitBlock(DoneBB,
true);
1490 OMPLoopScope PreInitScope(CGF, S);
1501 llvm::BasicBlock *ContBlock =
nullptr;
1516 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
1524 CGF.
EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
1529 CGF.EmitOMPSimdInit(S);
1539 bool HasLastprivateClause =
1549 CGF.EmitOMPSimdFinal(
1552 if (HasLastprivateClause)
1566 OMPLexicalScope
Scope(*
this, S,
true);
1570 void CodeGenFunction::EmitOMPOuterLoop(
1573 const CodeGenFunction::OMPLoopArguments &LoopArgs,
1579 const unsigned IVSize = getContext().getTypeSize(IVExpr->
getType());
1582 auto LoopExit = getJumpDestInCurrentScope(
"omp.dispatch.end");
1585 auto CondBlock = createBasicBlock(
"omp.dispatch.cond");
1586 EmitBlock(CondBlock);
1588 LoopStack.push(CondBlock, SourceLocToDebugLoc(R.
getBegin()),
1589 SourceLocToDebugLoc(R.
getEnd()));
1592 if (!DynamicOrOrdered) {
1596 EmitIgnoredExpr(LoopArgs.EUB);
1598 EmitIgnoredExpr(LoopArgs.Init);
1600 BoolCondVal = EvaluateExprAsBool(LoopArgs.Cond);
1603 RT.emitForNext(*
this, S.
getLocStart(), IVSize, IVSigned, LoopArgs.IL,
1604 LoopArgs.LB, LoopArgs.UB, LoopArgs.ST);
1609 auto ExitBlock = LoopExit.getBlock();
1611 ExitBlock = createBasicBlock(
"omp.dispatch.cleanup");
1613 auto LoopBody = createBasicBlock(
"omp.dispatch.body");
1614 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
1615 if (ExitBlock != LoopExit.getBlock()) {
1616 EmitBlock(ExitBlock);
1617 EmitBranchThroughCleanup(LoopExit);
1619 EmitBlock(LoopBody);
1623 if (DynamicOrOrdered)
1624 EmitIgnoredExpr(LoopArgs.Init);
1627 auto Continue = getJumpDestInCurrentScope(
"omp.dispatch.inc");
1628 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1633 LoopStack.setParallel(!IsMonotonic);
1635 EmitOMPSimdInit(S, IsMonotonic);
1647 CodeGenLoop(CGF, S, LoopExit);
1650 CodeGenOrdered(CGF, Loc, IVSize, IVSigned);
1653 EmitBlock(Continue.getBlock());
1654 BreakContinueStack.pop_back();
1655 if (!DynamicOrOrdered) {
1657 EmitIgnoredExpr(LoopArgs.NextLB);
1658 EmitIgnoredExpr(LoopArgs.NextUB);
1661 EmitBranch(CondBlock);
1664 EmitBlock(LoopExit.getBlock());
1668 if (!DynamicOrOrdered)
1674 void CodeGenFunction::EmitOMPForOuterLoop(
1677 const OMPLoopArguments &LoopArgs,
1678 const CodeGenDispatchBoundsTy &CGDispatchBounds) {
1682 const bool DynamicOrOrdered =
1683 Ordered || RT.isDynamic(ScheduleKind.
Schedule);
1686 !RT.isStaticNonchunked(ScheduleKind.
Schedule,
1687 LoopArgs.Chunk !=
nullptr)) &&
1688 "static non-chunked schedule does not need outer loop");
1741 const unsigned IVSize = getContext().getTypeSize(IVExpr->
getType());
1744 if (DynamicOrOrdered) {
1745 auto DispatchBounds = CGDispatchBounds(*
this, S, LoopArgs.LB, LoopArgs.UB);
1748 CGOpenMPRuntime::DispatchRTInput DipatchRTInputValues = {LBVal, UBVal,
1750 RT.emitForDispatchInit(*
this, S.
getLocStart(), ScheduleKind, IVSize,
1751 IVSigned, Ordered, DipatchRTInputValues);
1753 RT.emitForStaticInit(*
this, S.
getLocStart(), ScheduleKind, IVSize, IVSigned,
1754 Ordered, LoopArgs.IL, LoopArgs.LB, LoopArgs.UB,
1755 LoopArgs.ST, LoopArgs.Chunk);
1759 const unsigned IVSize,
1760 const bool IVSigned) {
1767 OMPLoopArguments OuterLoopArgs(LoopArgs.LB, LoopArgs.UB, LoopArgs.ST,
1768 LoopArgs.IL, LoopArgs.Chunk, LoopArgs.EUB);
1769 OuterLoopArgs.IncExpr = S.
getInc();
1770 OuterLoopArgs.Init = S.
getInit();
1771 OuterLoopArgs.Cond = S.
getCond();
1774 EmitOMPOuterLoop(DynamicOrOrdered, IsMonotonic, S, LoopScope, OuterLoopArgs,
1779 const unsigned IVSize,
const bool IVSigned) {}
1781 void CodeGenFunction::EmitOMPDistributeOuterLoop(
1783 OMPPrivateScope &LoopScope,
const OMPLoopArguments &LoopArgs,
1784 const CodeGenLoopTy &CodeGenLoopContent) {
1794 const unsigned IVSize = getContext().getTypeSize(IVExpr->
getType());
1797 RT.emitDistributeStaticInit(*
this, S.
getLocStart(), ScheduleKind, IVSize,
1798 IVSigned,
false, LoopArgs.IL,
1799 LoopArgs.LB, LoopArgs.UB, LoopArgs.ST,
1813 OMPLoopArguments OuterLoopArgs;
1814 OuterLoopArgs.LB = LoopArgs.LB;
1815 OuterLoopArgs.UB = LoopArgs.UB;
1816 OuterLoopArgs.ST = LoopArgs.ST;
1817 OuterLoopArgs.IL = LoopArgs.IL;
1818 OuterLoopArgs.Chunk = LoopArgs.Chunk;
1822 OuterLoopArgs.IncExpr = IncExpr;
1836 EmitOMPOuterLoop(
false,
false, S,
1837 LoopScope, OuterLoopArgs, CodeGenLoopContent,
1844 auto VDecl = cast<VarDecl>(Helper->
getDecl());
1849 static std::pair<LValue, LValue>
1888 static std::pair<llvm::Value *, llvm::Value *>
1898 QualType IteratorTy = IVExpr->getType();
1903 return {LBVal, UBVal};
1909 const auto &Dir = cast<OMPLoopDirective>(
S);
1911 CGF.
EmitLValue(cast<DeclRefExpr>(Dir.getCombinedLowerBoundVariable()));
1912 auto LBCast = CGF.
Builder.CreateIntCast(
1914 CapturedVars.push_back(LBCast);
1916 CGF.
EmitLValue(cast<DeclRefExpr>(Dir.getCombinedUpperBoundVariable()));
1918 auto UBCast = CGF.
Builder.CreateIntCast(
1920 CapturedVars.push_back(UBCast);
1935 CGF, S, OMPD_for, CGInlinedWorksharingLoop,
1939 void CodeGenFunction::EmitOMPDistributeParallelForDirective(
1945 OMPLexicalScope
Scope(*
this, S,
true);
1946 OMPCancelStackRAII CancelRegion(*
this, OMPD_distribute_parallel_for,
1948 CGM.
getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_distribute, CodeGen,
1952 void CodeGenFunction::EmitOMPDistributeParallelForSimdDirective(
1954 OMPLexicalScope
Scope(*
this, S,
true);
1956 *
this, OMPD_distribute_parallel_for_simd,
1958 OMPLoopScope PreInitScope(CGF, S);
1964 void CodeGenFunction::EmitOMPDistributeSimdDirective(
1966 OMPLexicalScope
Scope(*
this, S,
true);
1968 *
this, OMPD_distribute_simd,
1970 OMPLoopScope PreInitScope(CGF, S);
1976 void CodeGenFunction::EmitOMPTargetParallelForSimdDirective(
1978 OMPLexicalScope
Scope(*
this, S,
true);
1980 *
this, OMPD_target_parallel_for_simd,
1982 OMPLoopScope PreInitScope(CGF, S);
1988 void CodeGenFunction::EmitOMPTargetSimdDirective(
1990 OMPLexicalScope
Scope(*
this, S,
true);
1993 OMPLoopScope PreInitScope(CGF, S);
1999 void CodeGenFunction::EmitOMPTeamsDistributeDirective(
2001 OMPLexicalScope
Scope(*
this, S,
true);
2003 *
this, OMPD_teams_distribute,
2005 OMPLoopScope PreInitScope(CGF, S);
2011 void CodeGenFunction::EmitOMPTeamsDistributeSimdDirective(
2013 OMPLexicalScope
Scope(*
this, S,
true);
2015 *
this, OMPD_teams_distribute_simd,
2017 OMPLoopScope PreInitScope(CGF, S);
2023 void CodeGenFunction::EmitOMPTeamsDistributeParallelForSimdDirective(
2025 OMPLexicalScope
Scope(*
this, S,
true);
2027 *
this, OMPD_teams_distribute_parallel_for_simd,
2029 OMPLoopScope PreInitScope(CGF, S);
2035 void CodeGenFunction::EmitOMPTeamsDistributeParallelForDirective(
2037 OMPLexicalScope
Scope(*
this, S,
true);
2039 *
this, OMPD_teams_distribute_parallel_for,
2041 OMPLoopScope PreInitScope(CGF, S);
2047 void CodeGenFunction::EmitOMPTargetTeamsDistributeDirective(
2050 *
this, OMPD_target_teams_distribute,
2057 void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDirective(
2060 *
this, OMPD_target_teams_distribute_parallel_for,
2067 void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDirective(
2070 *
this, OMPD_target_teams_distribute_parallel_for_simd,
2077 void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDirective(
2080 *
this, OMPD_target_teams_distribute_simd,
2088 struct ScheduleKindModifiersTy {
2095 : Kind(Kind), M1(M1), M2(M2) {}
2099 bool CodeGenFunction::EmitOMPWorksharingLoop(
2105 auto IVDecl = cast<VarDecl>(IVExpr->getDecl());
2106 EmitVarDecl(*IVDecl);
2112 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
2119 bool HasLastprivateClause;
2122 OMPLoopScope PreInitScope(*
this, S);
2127 llvm::BasicBlock *ContBlock =
nullptr;
2128 if (ConstantFoldsToSimpleInteger(S.
getPreCond(), CondConstant)) {
2132 auto *ThenBlock = createBasicBlock(
"omp.precond.then");
2133 ContBlock = createBasicBlock(
"omp.precond.end");
2135 getProfileCount(&S));
2136 EmitBlock(ThenBlock);
2137 incrementProfileCounter(&S);
2140 bool Ordered =
false;
2142 if (OrderedClause->getNumForLoops())
2143 RT.emitDoacrossInit(*
this, S);
2150 EmitOMPLinearClauseInit(S);
2153 std::pair<LValue, LValue> Bounds = CodeGenLoopBounds(*
this, S);
2154 LValue LB = Bounds.first;
2155 LValue UB = Bounds.second;
2164 if (EmitOMPFirstprivateClause(S, LoopScope)) {
2172 EmitOMPPrivateClause(S, LoopScope);
2173 HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
2174 EmitOMPReductionClauseInit(S, LoopScope);
2175 EmitOMPPrivateLoopCounters(S, LoopScope);
2176 EmitOMPLinearClause(S, LoopScope);
2183 ScheduleKind.
Schedule = C->getScheduleKind();
2184 ScheduleKind.
M1 = C->getFirstScheduleModifier();
2185 ScheduleKind.
M2 = C->getSecondScheduleModifier();
2186 if (
const auto *Ch = C->getChunkSize()) {
2187 Chunk = EmitScalarExpr(Ch);
2188 Chunk = EmitScalarConversion(Chunk, Ch->getType(),
2193 const unsigned IVSize = getContext().getTypeSize(IVExpr->
getType());
2199 if (RT.isStaticNonchunked(ScheduleKind.
Schedule,
2200 Chunk !=
nullptr) &&
2203 EmitOMPSimdInit(S,
true);
2209 RT.emitForStaticInit(*
this, S.
getLocStart(), ScheduleKind,
2210 IVSize, IVSigned, Ordered,
2214 getJumpDestInCurrentScope(createBasicBlock(
"omp.loop.exit"));
2227 EmitBlock(LoopExit.getBlock());
2234 const bool IsMonotonic =
2235 Ordered || ScheduleKind.
Schedule == OMPC_SCHEDULE_static ||
2237 ScheduleKind.
M1 == OMPC_SCHEDULE_MODIFIER_monotonic ||
2238 ScheduleKind.
M2 == OMPC_SCHEDULE_MODIFIER_monotonic;
2244 EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered,
2245 LoopArguments, CGDispatchBounds);
2250 return CGF.
Builder.CreateIsNotNull(
2254 EmitOMPReductionClauseFinal(
2256 ? OMPD_parallel_for_simd
2261 return CGF.
Builder.CreateIsNotNull(
2265 if (HasLastprivateClause)
2266 EmitOMPLastprivateClauseFinal(
2271 return CGF.
Builder.CreateIsNotNull(
2276 EmitBranch(ContBlock);
2277 EmitBlock(ContBlock,
true);
2280 return HasLastprivateClause;
2286 static std::pair<LValue, LValue>
2300 static std::pair<llvm::Value *, llvm::Value *>
2308 return {LBVal, UBVal};
2312 bool HasLastprivates =
false;
2315 OMPCancelStackRAII CancelRegion(CGF, OMPD_for, S.
hasCancel());
2321 OMPLexicalScope
Scope(*
this, S,
true);
2333 bool HasLastprivates =
false;
2341 OMPLexicalScope
Scope(*
this, S,
true);
2363 bool HasLastprivates =
false;
2366 auto &
C = CGF.CGM.getContext();
2367 auto KmpInt32Ty =
C.getIntTypeForBitwidth(32, 1);
2370 CGF.Builder.getInt32(0));
2371 auto *GlobalUBVal = CS !=
nullptr ? CGF.Builder.getInt32(CS->size() - 1)
2372 : CGF.Builder.getInt32(0);
2376 CGF.Builder.getInt32(1));
2378 CGF.Builder.getInt32(0));
2403 auto *ExitBB = CGF.createBasicBlock(
".omp.sections.exit");
2405 CGF.EmitLoadOfLValue(IV, S.
getLocStart()).getScalarVal(), ExitBB,
2406 CS ==
nullptr ? 1 : CS->size());
2408 unsigned CaseNumber = 0;
2409 for (
auto *SubStmt : CS->children()) {
2410 auto CaseBB = CGF.createBasicBlock(
".omp.sections.case");
2411 CGF.EmitBlock(CaseBB);
2412 SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB);
2413 CGF.EmitStmt(SubStmt);
2414 CGF.EmitBranch(ExitBB);
2418 auto CaseBB = CGF.createBasicBlock(
".omp.sections.case");
2419 CGF.EmitBlock(CaseBB);
2420 SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB);
2422 CGF.EmitBranch(ExitBB);
2424 CGF.EmitBlock(ExitBB,
true);
2428 if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
2432 CGF.CGM.getOpenMPRuntime().emitBarrierCall(
2436 CGF.EmitOMPPrivateClause(S, LoopScope);
2437 HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
2438 CGF.EmitOMPReductionClauseInit(S, LoopScope);
2439 (void)LoopScope.Privatize();
2443 ScheduleKind.
Schedule = OMPC_SCHEDULE_static;
2444 CGF.CGM.getOpenMPRuntime().emitForStaticInit(
2446 true,
false, IL.getAddress(), LB.
getAddress(),
2449 auto *UBVal = CGF.EmitLoadOfScalar(UB, S.
getLocStart());
2450 auto *MinUBGlobalUB = CGF.Builder.CreateSelect(
2451 CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
2452 CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
2454 CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.
getLocStart()), IV);
2456 CGF.EmitOMPInnerLoop(S,
false, &Cond, &Inc, BodyGen,
2460 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.
getLocEnd());
2462 CGF.OMPCancelStack.emitExit(CGF, S.getDirectiveKind(), CodeGen);
2463 CGF.EmitOMPReductionClauseFinal(S, OMPD_parallel);
2467 return CGF.
Builder.CreateIsNotNull(
2472 if (HasLastprivates)
2479 bool HasCancel =
false;
2480 if (
auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
2481 HasCancel = OSD->hasCancel();
2482 else if (
auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
2483 HasCancel = OPSD->hasCancel();
2484 OMPCancelStackRAII CancelRegion(*
this, S.getDirectiveKind(), HasCancel);
2500 OMPLexicalScope
Scope(*
this, S,
true);
2514 OMPLexicalScope
Scope(*
this, S,
true);
2529 CopyprivateVars.append(C->varlists().begin(), C->varlists().end());
2530 DestExprs.append(C->destination_exprs().begin(),
2531 C->destination_exprs().end());
2532 SrcExprs.append(C->source_exprs().begin(), C->source_exprs().end());
2533 AssignmentOps.append(C->assignment_ops().begin(),
2534 C->assignment_ops().end());
2546 OMPLexicalScope
Scope(*
this, S,
true);
2548 CopyprivateVars, DestExprs,
2549 SrcExprs, AssignmentOps);
2565 OMPLexicalScope
Scope(*
this, S,
true);
2574 Expr *Hint =
nullptr;
2576 Hint = HintClause->getHint();
2577 OMPLexicalScope
Scope(*
this, S,
true);
2583 void CodeGenFunction::EmitOMPParallelForDirective(
2588 OMPCancelStackRAII CancelRegion(CGF, OMPD_parallel_for, S.
hasCancel());
2596 void CodeGenFunction::EmitOMPParallelForSimdDirective(
2608 void CodeGenFunction::EmitOMPParallelSectionsDirective(
2613 CGF.EmitSections(S);
2625 auto *
I = CS->getCapturedDecl()->param_begin();
2626 auto *PartId = std::next(I);
2627 auto *TaskT = std::next(I, 4);
2632 auto *Cond = Clause->getCondition();
2634 if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
2635 Data.
Final.setInt(CondConstant);
2637 Data.
Final.setPointer(EvaluateExprAsBool(Cond));
2640 Data.
Final.setInt(
false);
2644 auto *Prio = Clause->getPriority();
2646 Data.
Priority.setPointer(EmitScalarConversion(
2647 EmitScalarExpr(Prio), Prio->getType(),
2648 getContext().getIntTypeForBitwidth(32, 1),
2649 Prio->getExprLoc()));
2656 auto IRef = C->varlist_begin();
2657 for (
auto *IInit : C->private_copies()) {
2658 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
2659 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
2666 EmittedAsPrivate.clear();
2669 auto IRef = C->varlist_begin();
2670 auto IElemInitRef = C->inits().begin();
2671 for (
auto *IInit : C->private_copies()) {
2672 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
2673 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
2683 llvm::DenseMap<const VarDecl *, const DeclRefExpr *> LastprivateDstsOrigs;
2685 auto IRef = C->varlist_begin();
2686 auto ID = C->destination_exprs().begin();
2687 for (
auto *IInit : C->private_copies()) {
2688 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
2689 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
2693 LastprivateDstsOrigs.insert(
2694 {cast<VarDecl>(cast<DeclRefExpr>(*ID)->getDecl()),
2695 cast<DeclRefExpr>(*IRef)});
2703 auto IPriv = C->privates().begin();
2704 auto IRed = C->reduction_ops().begin();
2705 auto ILHS = C->lhs_exprs().begin();
2706 auto IRHS = C->rhs_exprs().begin();
2707 for (
const auto *Ref : C->varlists()) {
2711 LHSs.emplace_back(*ILHS);
2712 RHSs.emplace_back(*IRHS);
2713 std::advance(IPriv, 1);
2714 std::advance(IRed, 1);
2715 std::advance(ILHS, 1);
2716 std::advance(IRHS, 1);
2723 for (
auto *IRef : C->varlists())
2724 Data.
Dependences.push_back(std::make_pair(C->getDependencyKind(), IRef));
2725 auto &&CodeGen = [&Data, &
S, CS, &BodyGen, &LastprivateDstsOrigs](
2731 auto *CopyFn = CGF.Builder.CreateLoad(
2732 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(3)));
2733 auto *PrivatesPtr = CGF.Builder.CreateLoad(
2734 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(2)));
2738 CallArgs.push_back(PrivatesPtr);
2740 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
2741 Address PrivatePtr = CGF.CreateMemTemp(
2742 CGF.getContext().getPointerType(
E->getType()),
".priv.ptr.addr");
2743 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
2744 CallArgs.push_back(PrivatePtr.getPointer());
2747 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
2749 CGF.CreateMemTemp(CGF.getContext().getPointerType(
E->getType()),
2750 ".firstpriv.ptr.addr");
2751 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
2752 CallArgs.push_back(PrivatePtr.getPointer());
2755 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl());
2757 CGF.CreateMemTemp(CGF.getContext().getPointerType(
E->getType()),
2758 ".lastpriv.ptr.addr");
2759 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
2760 CallArgs.push_back(PrivatePtr.getPointer());
2762 CGF.EmitRuntimeCall(CopyFn, CallArgs);
2763 for (
auto &&Pair : LastprivateDstsOrigs) {
2764 auto *OrigVD = cast<VarDecl>(Pair.second->getDecl());
2766 const_cast<VarDecl *>(OrigVD),
2767 CGF.CapturedStmtInfo->lookup(
2769 Pair.second->getType(),
VK_LValue, Pair.second->getExprLoc());
2770 Scope.
addPrivate(Pair.first, [&CGF, &DRE]() {
2771 return CGF.EmitLValue(&DRE).getAddress();
2774 for (
auto &&Pair : PrivatePtrs) {
2776 CGF.getContext().getDeclAlign(Pair.first));
2780 if (Data.Reductions) {
2781 OMPLexicalScope LexScope(CGF, S,
true);
2786 for (
unsigned Cnt = 0,
E = Data.ReductionVars.size(); Cnt <
E; ++Cnt) {
2787 RedCG.emitSharedLValue(CGF, Cnt);
2788 RedCG.emitAggregateType(CGF, Cnt);
2790 CGF, S.
getLocStart(), ReductionsPtr, RedCG.getSharedLValue(Cnt));
2795 Data.ReductionCopies[Cnt]->getType()),
2798 Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);
2799 Scope.addPrivate(RedCG.getBaseDecl(Cnt),
2808 (void)
Scope.Privatize();
2814 S, *
I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, Data.Tied,
2815 Data.NumberOfParts);
2816 OMPLexicalScope
Scope(*
this, S);
2817 TaskGen(*
this, OutlinedFn, Data);
2825 const Expr *IfCond =
nullptr;
2828 C->getNameModifier() == OMPD_task) {
2829 IfCond = C->getCondition();
2838 CGF.
EmitStmt(CS->getCapturedStmt());
2840 auto &&TaskGen = [&
S, SharedsTy, CapturedStruct,
2843 CGF.CGM.getOpenMPRuntime().emitTaskCall(CGF, S.
getLocStart(),
S, OutlinedFn,
2844 SharedsTy, CapturedStruct, IfCond,
2869 OMPLexicalScope
Scope(*
this, S,
true);
2876 return llvm::makeArrayRef(FlushClause->varlist_begin(),
2877 FlushClause->varlist_end());
2884 const CodeGenLoopTy &CodeGenLoop,
2888 auto IVDecl = cast<VarDecl>(IVExpr->getDecl());
2902 bool HasLastprivateClause =
false;
2905 OMPLoopScope PreInitScope(*
this, S);
2910 llvm::BasicBlock *ContBlock =
nullptr;
2928 *
this, cast<DeclRefExpr>(
2933 *
this, cast<DeclRefExpr>(
2942 OMPPrivateScope LoopScope(*
this);
2954 (void)LoopScope.Privatize();
2960 ScheduleKind =
C->getDistScheduleKind();
2961 if (
const auto *Ch =
C->getChunkSize()) {
2979 if (RT.isStaticNonchunked(ScheduleKind,
2980 Chunk !=
nullptr)) {
2981 RT.emitDistributeStaticInit(*
this, S.
getLocStart(), ScheduleKind,
2982 IVSize, IVSigned,
false,
2984 UB.getAddress(), ST.getAddress());
3006 CodeGenLoop(CGF, S, LoopExit);
3011 RT.emitForStaticFinish(*
this, S.getLocStart());
3015 const OMPLoopArguments LoopArguments = {
3018 EmitOMPDistributeOuterLoop(ScheduleKind, S, LoopScope, LoopArguments,
3023 if (HasLastprivateClause)
3044 OMPLexicalScope
Scope(*
this, S,
true);
3045 CGM.
getOpenMPRuntime().emitInlinedDirective(*
this, OMPD_distribute, CodeGen,
3055 Fn->addFnAttr(llvm::Attribute::NoInline);
3071 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
3073 CGF.EmitNounwindRuntimeCall(OutlinedFn, CapturedVars);
3080 OMPLexicalScope
Scope(*
this, S,
true);
3088 "DestType must have scalar evaluation kind.");
3089 assert(!Val.
isAggregate() &&
"Must be a scalar or complex.");
3101 "DestType must have complex evaluation kind.");
3107 DestElementType, Loc);
3109 ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType()));
3111 assert(Val.
isComplex() &&
"Must be a scalar or complex.");
3115 Val.
getComplexVal().first, SrcElementType, DestElementType, Loc);
3117 Val.
getComplexVal().second, SrcElementType, DestElementType, Loc);
3128 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3129 : llvm::AtomicOrdering::Monotonic,
3139 *
this, RVal, RValTy, LVal.
getType(), Loc)),
3148 llvm_unreachable(
"Must be a scalar or complex.");
3156 assert(V->
isLValue() &&
"V of 'omp atomic read' is not lvalue");
3157 assert(X->
isLValue() &&
"X of 'omp atomic read' is not lvalue");
3160 RValue Res = XLValue.isGlobalReg()
3164 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3165 : llvm::AtomicOrdering::Monotonic,
3166 XLValue.isVolatile());
3180 assert(X->
isLValue() &&
"X of 'omp atomic write' is not lvalue");
3193 llvm::AtomicOrdering AO,
3194 bool IsXLHSInRHSPart) {
3199 if (BO == BO_Comma || !Update.
isScalar() ||
3207 return std::make_pair(
false,
RValue::get(
nullptr));
3209 llvm::AtomicRMWInst::BinOp RMWOp;
3212 RMWOp = llvm::AtomicRMWInst::Add;
3215 if (!IsXLHSInRHSPart)
3216 return std::make_pair(
false,
RValue::get(
nullptr));
3217 RMWOp = llvm::AtomicRMWInst::Sub;
3223 RMWOp = llvm::AtomicRMWInst::Or;
3226 RMWOp = llvm::AtomicRMWInst::Xor;
3230 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min
3231 : llvm::AtomicRMWInst::Max)
3232 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin
3233 : llvm::AtomicRMWInst::UMax);
3237 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max
3238 : llvm::AtomicRMWInst::Min)
3239 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax
3240 : llvm::AtomicRMWInst::UMin);
3243 RMWOp = llvm::AtomicRMWInst::Xchg;
3252 return std::make_pair(
false,
RValue::get(
nullptr));
3270 llvm_unreachable(
"Unsupported atomic update operation");
3273 if (
auto *IC = dyn_cast<llvm::ConstantInt>(UpdateVal)) {
3274 UpdateVal = CGF.
Builder.CreateIntCast(
3308 const Expr *UE,
bool IsXLHSInRHSPart,
3311 "Update expr in 'atomic update' must be a binary operator.");
3319 assert(X->
isLValue() &&
"X of 'omp atomic update' is not lvalue");
3322 auto AO = IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3323 : llvm::AtomicOrdering::Monotonic;
3324 auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
3325 auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
3326 auto *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
3327 auto *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
3329 [&CGF, UE, ExprRValue, XRValExpr, ERValExpr](
RValue XRValue) ->
RValue {
3335 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
3358 llvm_unreachable(
"Must be a scalar or complex.");
3362 bool IsPostfixUpdate,
const Expr *V,
3364 const Expr *UE,
bool IsXLHSInRHSPart,
3366 assert(X->
isLValue() &&
"X of 'omp atomic capture' is not lvalue");
3367 assert(V->
isLValue() &&
"V of 'omp atomic capture' is not lvalue");
3372 auto AO = IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3373 : llvm::AtomicOrdering::Monotonic;
3378 "Update expr in 'atomic capture' must be a binary operator.");
3386 auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
3387 auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
3388 auto *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
3389 NewVValType = XRValExpr->getType();
3390 auto *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
3391 auto &&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr,
3396 NewVVal = IsPostfixUpdate ? XRValue : Res;
3400 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
3403 if (IsPostfixUpdate) {
3405 NewVVal = Res.second;
3419 auto &&Gen = [&NewVVal, ExprRValue](
RValue XRValue) ->
RValue {
3425 XLValue, ExprRValue, BO_Assign,
false, AO,
3429 NewVVal = IsPostfixUpdate ? Res.second : ExprRValue;
3443 bool IsSeqCst,
bool IsPostfixUpdate,
3445 const Expr *UE,
bool IsXLHSInRHSPart,
3460 IsXLHSInRHSPart, Loc);
3464 case OMPC_num_threads:
3466 case OMPC_firstprivate:
3467 case OMPC_lastprivate:
3468 case OMPC_reduction:
3469 case OMPC_task_reduction:
3479 case OMPC_copyprivate:
3481 case OMPC_proc_bind:
3488 case OMPC_mergeable:
3493 case OMPC_num_teams:
3494 case OMPC_thread_limit:
3496 case OMPC_grainsize:
3498 case OMPC_num_tasks:
3500 case OMPC_dist_schedule:
3501 case OMPC_defaultmap:
3505 case OMPC_use_device_ptr:
3506 case OMPC_is_device_ptr:
3507 llvm_unreachable(
"Clause is not allowed in 'omp atomic'.");
3516 if (C->getClauseKind() != OMPC_seq_cst) {
3517 Kind = C->getClauseKind();
3524 if (
const auto *EWC = dyn_cast<ExprWithCleanups>(CS)) {
3528 if (
const auto *Compound = dyn_cast<CompoundStmt>(CS)) {
3529 for (
const auto *C : Compound->body()) {
3530 if (
const auto *EWC = dyn_cast<ExprWithCleanups>(C)) {
3538 CGF.EmitStopPoint(CS);
3543 OMPLexicalScope
Scope(*
this, S,
true);
3554 llvm::Function *Fn =
nullptr;
3555 llvm::Constant *FnID =
nullptr;
3557 const Expr *IfCond =
nullptr;
3561 C->getNameModifier() == OMPD_target) {
3562 IfCond = C->getCondition();
3568 const Expr *Device =
nullptr;
3570 Device = C->getDevice();
3576 bool IsOffloadEntry =
true;
3580 IsOffloadEntry =
false;
3583 IsOffloadEntry =
false;
3585 assert(CGF.
CurFuncDecl &&
"No parent declaration for target region!");
3586 StringRef ParentName;
3589 if (
auto *D = dyn_cast<CXXConstructorDecl>(CGF.
CurFuncDecl))
3591 else if (
auto *D = dyn_cast<CXXDestructorDecl>(CGF.
CurFuncDecl))
3599 IsOffloadEntry, CodeGen);
3600 OMPLexicalScope
Scope(CGF, S);
3619 StringRef ParentName,
3625 llvm::Constant *Addr;
3628 S, ParentName, Fn, Addr,
true, CodeGen);
3629 assert(Fn && Addr &&
"Target device function emission failed.");
3651 Expr *ThreadLimit = (TL) ? TL->getThreadLimit() :
nullptr;
3657 OMPTeamsScope
Scope(CGF, S);
3686 CGF.
EmitStmt(CS->getCapturedStmt());
3698 llvm::Constant *Addr;
3701 S, ParentName, Fn, Addr,
true, CodeGen);
3702 assert(Fn && Addr &&
"Target device function emission failed.");
3720 const Expr *IfCond =
nullptr;
3723 C->getNameModifier() == OMPD_cancel) {
3724 IfCond = C->getCondition();
3734 if (Kind == OMPD_parallel || Kind == OMPD_task ||
3735 Kind == OMPD_target_parallel)
3737 assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
3738 Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for ||
3739 Kind == OMPD_distribute_parallel_for ||
3740 Kind == OMPD_target_parallel_for);
3741 return OMPCancelStack.getExitBlock();
3746 const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap) {
3747 const auto &C = cast<OMPUseDevicePtrClause>(NC);
3748 auto OrigVarIt = C.varlist_begin();
3749 auto InitIt = C.inits().begin();
3750 for (
auto PvtVarIt : C.private_copies()) {
3751 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*OrigVarIt)->getDecl());
3752 auto *InitVD = cast<VarDecl>(cast<DeclRefExpr>(*InitIt)->getDecl());
3753 auto *PvtVD = cast<VarDecl>(cast<DeclRefExpr>(PvtVarIt)->getDecl());
3759 if (
auto *OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) {
3762 auto *ME = cast<MemberExpr>(OED->getInit());
3763 assert(isa<CXXThisExpr>(ME->getBase()) &&
3764 "Base should be the current struct!");
3765 MatchingVD = ME->getMemberDecl();
3770 auto InitAddrIt = CaptureDeviceAddrMap.find(MatchingVD);
3771 if (InitAddrIt == CaptureDeviceAddrMap.end())
3784 setAddrOfLocalVar(InitVD, InitAddr);
3792 LocalDeclMap.erase(InitVD);
3797 assert(IsRegistered &&
"firstprivate var already registered as private");
3809 CGOpenMPRuntime::TargetDataInfo Info(
true);
3814 bool PrivatizeDevicePointers =
false;
3816 bool &PrivatizeDevicePointers;
3819 explicit DevicePointerPrivActionTy(
bool &PrivatizeDevicePointers)
3820 :
PrePostActionTy(), PrivatizeDevicePointers(PrivatizeDevicePointers) {}
3822 PrivatizeDevicePointers =
true;
3825 DevicePointerPrivActionTy PrivAction(PrivatizeDevicePointers);
3827 auto &&CodeGen = [&
S, &Info, &PrivatizeDevicePointers](
3835 auto &&PrivCodeGen = [&
S, &Info, &PrivatizeDevicePointers,
3839 PrivatizeDevicePointers =
false;
3845 if (PrivatizeDevicePointers) {
3849 CGF.EmitOMPUseDevicePtrClause(*C, PrivateScope,
3850 Info.CaptureDeviceAddrMap);
3864 OMPLexicalScope
Scope(CGF, S);
3865 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_target_data,
3879 const Expr *IfCond =
nullptr;
3881 IfCond = C->getCondition();
3884 const Expr *Device =
nullptr;
3886 Device = C->getDevice();
3904 const Expr *IfCond =
nullptr;
3906 IfCond = C->getCondition();
3909 const Expr *Device =
nullptr;
3911 Device = C->getDevice();
3913 CGM.
getOpenMPRuntime().emitTargetDataStandAloneCall(*
this, S, IfCond, Device);
3924 const Expr *IfCond =
nullptr;
3926 IfCond = C->getCondition();
3929 const Expr *Device =
nullptr;
3931 Device = C->getDevice();
3933 CGM.
getOpenMPRuntime().emitTargetDataStandAloneCall(*
this, S, IfCond, Device);
3944 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
3945 CGF.EmitOMPPrivateClause(S, PrivateScope);
3946 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
3949 CGF.EmitStmt(CS->getCapturedStmt());
3950 CGF.EmitOMPReductionClauseFinal(S, OMPD_parallel);
3965 llvm::Constant *Addr;
3968 S, ParentName, Fn, Addr,
true, CodeGen);
3969 assert(Fn && Addr &&
"Target device function emission failed.");
3989 auto *VDecl = cast<VarDecl>(Helper->
getDecl());
4000 const Expr *IfCond =
nullptr;
4003 C->getNameModifier() == OMPD_taskloop) {
4004 IfCond = C->getCondition();
4036 llvm::BasicBlock *ContBlock =
nullptr;
4037 OMPLoopScope PreInitScope(CGF, S);
4038 if (CGF.ConstantFoldsToSimpleInteger(S.
getPreCond(), CondConstant)) {
4042 auto *ThenBlock = CGF.createBasicBlock(
"taskloop.if.then");
4043 ContBlock = CGF.createBasicBlock(
"taskloop.if.end");
4045 CGF.getProfileCount(&S));
4046 CGF.EmitBlock(ThenBlock);
4047 CGF.incrementProfileCounter(&S);
4051 CGF.EmitOMPSimdInit(S);
4055 enum { LowerBound = 5, UpperBound, Stride, LastIter };
4056 auto *
I = CS->getCapturedDecl()->param_begin();
4057 auto *LBP = std::next(
I, LowerBound);
4058 auto *UBP = std::next(
I, UpperBound);
4059 auto *STP = std::next(
I, Stride);
4060 auto *LIP = std::next(
I, LastIter);
4068 CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
4069 bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
4073 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
4074 CGF.EmitVarDecl(*IVDecl);
4075 CGF.EmitIgnoredExpr(S.
getInit());
4081 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
4089 CGF.EmitOMPLoopBody(S,
JumpDest());
4090 CGF.EmitStopPoint(&S);
4095 CGF.EmitBranch(ContBlock);
4096 CGF.EmitBlock(ContBlock,
true);
4099 if (HasLastprivateClause) {
4100 CGF.EmitOMPLastprivateClauseFinal(
4102 CGF.Builder.CreateIsNotNull(CGF.EmitLoadOfScalar(
4103 CGF.GetAddrOfLocalVar(*LIP),
false,
4107 auto &&TaskGen = [&
S, SharedsTy, CapturedStruct,
4111 OMPLoopScope PreInitScope(CGF, S);
4113 OutlinedFn, SharedsTy,
4114 CapturedStruct, IfCond, Data);
4151 const Expr *IfCond =
nullptr;
4153 IfCond = C->getCondition();
4156 const Expr *Device =
nullptr;
4158 Device = C->getDevice();
4160 CGM.
getOpenMPRuntime().emitTargetDataStandAloneCall(*
this, S, IfCond, Device);
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
Expr * getCombinedInit() const
This represents '#pragma omp distribute simd' composite directive.
This represents '#pragma omp master' directive.
SourceLocation getEnd() const
virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S)
Emit the captured statement body.
static Address castValueFromUintptr(CodeGenFunction &CGF, QualType DstType, StringRef Name, LValue AddrLV, bool isReferenceType=false)
CapturedStmt * getCapturedStmt(OpenMPDirectiveKind RegionKind) const
Returns the captured statement associated with the component region within the (combined) directive...
This represents '#pragma omp task' directive.
static const Decl * getCanonicalDecl(const Decl *D)
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
Parameter for captured context.
bool isXLHSInRHSPart() const
Return true if helper update expression has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and...
void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S)
This represents clause 'copyin' in the '#pragma omp ...' directives.
Expr * getCombinedEnsureUpperBound() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
Scheduling data for loop-based OpenMP directives.
A (possibly-)qualified type.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument.
llvm::Value * getPointer() const
CodeGenTypes & getTypes()
ArrayRef< OMPClause * > clauses()
llvm::Type * ConvertTypeForMem(QualType T)
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
Address getAllocatedAddress() const
Returns the raw, allocated address, which is not necessarily the address of the object itself...
llvm::Module & getModule() const
void EmitOMPDistributeDirective(const OMPDistributeDirective &S)
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
static std::pair< LValue, LValue > emitDistributeParallelForInnerBounds(CodeGenFunction &CGF, const OMPExecutableDirective &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...
static OMPClauseWithPreInit * get(OMPClause *C)
Stmt - This represents one statement.
void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst)
Store of global named registers are always calls to intrinsics.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
SmallVector< std::pair< OpenMPDependClauseKind, const Expr * >, 4 > Dependences
This represents '#pragma omp for simd' directive.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
SmallVector< const Expr *, 4 > LastprivateCopies
Decl - This represents one declaration (or definition), e.g.
This represents 'grainsize' clause in the '#pragma omp ...' directive.
This represents '#pragma omp teams distribute parallel for' composite directive.
Address getAddress() const
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
llvm::Value * getTypeSize(QualType Ty)
Returns calculated size of the specified type.
This represents 'if' clause in the '#pragma omp ...' directive.
void EmitOMPOrderedDirective(const OMPOrderedDirective &S)
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
This represents 'priority' clause in the '#pragma omp ...' directive.
static void mapParam(CodeGenFunction &CGF, const DeclRefExpr *Helper, const ImplicitParamDecl *PVD, CodeGenFunction::OMPPrivateScope &Privates)
Emit a helper variable and return corresponding lvalue.
The base class of the type hierarchy.
This represents '#pragma omp target teams distribute' combined directive.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
Address GenerateCapturedStmtArgument(const CapturedStmt &S)
QualType getRecordType(const RecordDecl *Decl) const
const Expr * getInit() const
static void emitEmptyBoundParameters(CodeGenFunction &, const OMPExecutableDirective &, llvm::SmallVectorImpl< llvm::Value * > &)
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, bool forPointeeType=false)
static void emitCommonOMPParallelDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, const CodeGenBoundParametersTy &CodeGenBoundParameters)
Floating point control options.
This represents '#pragma omp parallel for' directive.
const LangOptions & getLangOpts() const
This represents '#pragma omp target teams distribute parallel for' combined directive.
void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit)
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant, or if it does but contains a label, return false.
void EmitOMPCopy(QualType OriginalType, Address DestAddr, Address SrcAddr, const VarDecl *DestVD, const VarDecl *SrcVD, const Expr *Copy)
Emit proper copying of data from one variable to another.
SmallVector< const Expr *, 4 > ReductionCopies
static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty, const Twine &Name, llvm::Value *Init=nullptr)
This represents '#pragma omp target exit data' directive.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
llvm::Function * GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S)
VarDecl - An instance of this class is created to represent a variable declaration or definition...
This represents clause 'private' in the '#pragma omp ...' directives.
llvm::Type * getElementType() const
Return the type of the values stored in this address.
This represents 'num_threads' clause in the '#pragma omp ...' directive.
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
field_iterator field_begin() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
This represents implicit clause 'flush' for the '#pragma omp flush' directive.
void EmitOMPLastprivateClauseFinal(const OMPExecutableDirective &D, bool NoFinals, llvm::Value *IsLastIterCond=nullptr)
Emit final copying of lastprivate values to original variables at the end of the worksharing or simd ...
static std::pair< llvm::Function *, bool > emitOutlinedFunctionPrologue(CodeGenFunction &CGF, FunctionArgList &Args, llvm::DenseMap< 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 EmitOMPTargetParallelDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelDirective &S)
This represents 'nogroup' clause in the '#pragma omp ...' directive.
Expr * getPrevUpperBoundVariable() const
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
bool EmitOMPWorksharingLoop(const OMPLoopDirective &S, Expr *EUB, const CodeGenLoopBoundsTy &CodeGenLoopBounds, const CodeGenDispatchBoundsTy &CGDispatchBounds)
Emit code for the worksharing loop-based directive.
This represents 'safelen' clause in the '#pragma omp ...' directive.
LValue getSharedLValue(unsigned N) const
Returns LValue for the reduction item.
OpenMPDirectiveKind getDirectiveKind() const
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
void EmitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &S)
SmallVector< const Expr *, 4 > PrivateVars
RecordDecl - Represents a struct/union/class.
llvm::DenseMap< const VarDecl *, FieldDecl * > LambdaCaptureFields
One of these records is kept for each identifier that is lexed.
bool hasCancel() const
Return true if current directive has inner cancel directive.
This represents '#pragma omp parallel' directive.
CGDebugInfo * getDebugInfo()
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
This represents 'simd' clause in the '#pragma omp ...' directive.
void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
EmitExprAsInit - Emits the code necessary to initialize a location in memory with the given initializ...
void EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S)
The scope used to remap some variables as private in the OpenMP loop body (or other captured region e...
static void emitTargetRegion(CodeGenFunction &CGF, const OMPTargetDirective &S, PrePostActionTy &Action)
bool isReferenceType() const
SmallVector< const Expr *, 4 > LastprivateVars
This represents clause 'lastprivate' in the '#pragma omp ...' directives.
bool isAnyPointerType() const
Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, LValueBaseInfo *BaseInfo=nullptr)
llvm::IntegerType * SizeTy
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
static void emitSimdlenSafelenClause(CodeGenFunction &CGF, const OMPExecutableDirective &D, bool IsMonotonic)
ArrayRef< Expr * > updates()
void EmitAtomicUpdate(LValue LVal, llvm::AtomicOrdering AO, const llvm::function_ref< RValue(RValue)> &UpdateOp, bool IsVolatile)
void EmitOMPPrivateLoopCounters(const OMPLoopDirective &S, OMPPrivateScope &LoopScope)
Emit initial code for loop counters of loop-based directives.
This represents '#pragma omp target simd' directive.
virtual const FieldDecl * lookup(const VarDecl *VD) const
Lookup the captured field decl for a variable.
This represents '#pragma omp barrier' directive.
This is a common base class for loop directives ('omp simd', 'omp for', 'omp for simd' etc...
Expr * getNumTeams()
Return NumTeams number.
This represents '#pragma omp critical' directive.
static std::pair< bool, RValue > emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X, RValue Update, BinaryOperatorKind BO, llvm::AtomicOrdering AO, bool IsXLHSInRHSPart)
OpenMPDirectiveKind getCancelRegion() const
Get cancellation region for the current cancellation point.
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
bool EmitOMPLastprivateClauseInit(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
Emit initial code for lastprivate variables.
static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, bool IsSeqCst, bool IsPostfixUpdate, const Expr *X, const Expr *V, const Expr *E, const Expr *UE, bool IsXLHSInRHSPart, SourceLocation Loc)
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
This represents clause 'copyprivate' in the '#pragma omp ...' directives.
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, LValueBaseInfo BaseInfo=LValueBaseInfo(AlignmentSource::Type), llvm::MDNode *TBAAInfo=nullptr, QualType TBAABaseTy=QualType(), uint64_t TBAAOffset=0, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
This represents '#pragma omp distribute parallel for' composite directive.
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
This represents '#pragma omp teams distribute parallel for simd' composite directive.
static bool hasScalarEvaluationKind(QualType T)
ArrayRef< Expr * > finals()
CharUnits getAlignment() const
const TargetInfo & getTargetInfo() const
void emitOMPSimpleStore(LValue LVal, RValue RVal, QualType RValTy, SourceLocation Loc)
OpenMPScheduleClauseKind Schedule
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
CharUnits - This is an opaque type for sizes expressed in character units.
static void emitEmptyOrdered(CodeGenFunction &, SourceLocation Loc, const unsigned IVSize, const bool IVSigned)
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
llvm::function_ref< std::pair< LValue, LValue > CodeGenFunction &, const OMPExecutableDirective &S)> CodeGenLoopBoundsTy
void pop()
End the current loop.
Expr * getX()
Get 'x' part of the associated expression/statement.
void EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S)
field_range fields() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
void EmitOMPTargetDirective(const OMPTargetDirective &S)
Expr * getCombinedUpperBoundVariable() const
A builtin binary operation expression such as "x + y" or "x <= y".
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
OpenMPScheduleClauseModifier M2
void setVectorizeWidth(unsigned W)
Set the vectorize width for the next loop pushed.
SmallVector< const Expr *, 4 > PrivateCopies
Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy, LValueBaseInfo *BaseInfo=nullptr)
static llvm::Function * emitOutlinedOrderedFunction(CodeGenModule &CGM, const CapturedStmt *S)
virtual bool hasBuiltinAtomic(uint64_t AtomicSizeInBits, uint64_t AlignmentInBits) const
Returns true if the given target supports lock-free atomic operations at the specified width and alig...
void EmitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &S)
This represents '#pragma omp cancellation point' directive.
void EmitAggregateAssign(Address DestPtr, Address SrcPtr, QualType EltTy)
EmitAggregateCopy - Emit an aggregate assignment.
static LValue EmitOMPHelperVar(CodeGenFunction &CGF, const DeclRefExpr *Helper)
Emit a helper variable and return corresponding lvalue.
Address adjustPrivateAddress(CodeGenFunction &CGF, unsigned N, Address PrivateAddr)
Adjusts PrivatedAddr for using instead of the original variable address in normal operations...
Scope - A scope is a transient data structure that is used while parsing the program.
This represents 'final' clause in the '#pragma omp ...' directive.
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
void EmitStmt(const Stmt *S)
EmitStmt - Emit the code for the statement.
void EmitOMPParallelDirective(const OMPParallelDirective &S)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
This represents '#pragma omp teams' directive.
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn)
Assign counters to regions and configure them for PGO of a given function.
SmallVector< const Expr *, 4 > FirstprivateCopies
This represents clause 'reduction' in the '#pragma omp ...' directives.
bool requiresCleanups() const
Determine whether this scope requires any cleanups.
This represents '#pragma omp teams distribute simd' combined directive.
bool isStaticLocal() const
isStaticLocal - Returns true if a variable with function scope is a static local variable.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
bool hasCancel() const
Return true if current directive has inner cancel directive.
const RecordDecl * getCapturedRecordDecl() const
Retrieve the record declaration for captured variables.
An ordinary object is located at an address in memory.
SmallVector< const Expr *, 4 > ReductionOps
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::function_ref< std::pair< llvm::Value *, llvm::Value * > CodeGenFunction &, const OMPExecutableDirective &S, Address LB, Address UB)> CodeGenDispatchBoundsTy
This represents the body of a CapturedStmt, and serves as its DeclContext.
detail::InMemoryDirectory::const_iterator I
SmallVector< const Expr *, 4 > ReductionVars
static void EmitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst, const Expr *X, const Expr *E, SourceLocation Loc)
static llvm::Value * convertToScalarValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, QualType DestType, SourceLocation Loc)
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type...
static CodeGenFunction::ComplexPairTy convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, QualType DestType, SourceLocation Loc)
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
This represents '#pragma omp target parallel for simd' directive.
ArrayRef< Expr * > private_counters()
OpenMPDirectiveKind getCancelRegion() const
Get cancellation region for the current cancellation point.
llvm::Constant * getStaticLocalDeclAddress(const VarDecl *D)
CompoundStmt - This represents a group of statements like { stmt stmt }.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.
This represents '#pragma omp taskgroup' directive.
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
This represents clause 'aligned' in the '#pragma omp ...' directives.
SourceLocation getLocEnd() const LLVM_READONLY
bool addPrivate(const VarDecl *LocalVD, llvm::function_ref< Address()> PrivateGen)
Registers LocalVD variable as a private and apply PrivateGen function for it to generate correspondin...
Class intended to support codegen of all kind of the reduction clauses.
bool isPostfixUpdate() const
Return true if 'v' expression must be updated to original value of 'x', false if 'v' must be updated ...
SourceLocation getBodyRBrace() const
getBodyRBrace - Gets the right brace of the body, if a body exists.
void EmitOMPLoopBody(const OMPLoopDirective &D, JumpDest LoopExit)
Helper for the OpenMP loop directives.
Expr * getCombinedNextUpperBound() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
This represents '#pragma omp distribute' directive.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
virtual StringRef getHelperName() const
Get the name of the capture helper.
static TypeEvaluationKind getEvaluationKind(QualType T)
hasAggregateLLVMType - Return true if the specified AST type will map into an aggregate LLVM type or ...
llvm::Value * getPointer() const
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
Emit only debug info necessary for generating line number tables (-gline-tables-only).
void EmitAutoVarInit(const AutoVarEmission &emission)
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
This represents 'simdlen' clause in the '#pragma omp ...' directive.
Stmt * IgnoreContainers(bool IgnoreCaptured=false)
Skip no-op (attributed, compound) container stmts and skip captured stmt at the top, if IgnoreCaptured is true.
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type, where the destination type is an LLVM scalar type.
llvm::function_ref< void(CodeGenFunction &, SourceLocation, const unsigned, const bool)> CodeGenOrderedTy
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
void EmitOMPTeamsDirective(const OMPTeamsDirective &S)
void SetInternalFunctionAttributes(const Decl *D, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
Expr * getIterationVariable() const
static std::pair< llvm::Value *, llvm::Value * > emitDispatchForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S, Address LB, Address UB)
When dealing with dispatch schedules (e.g.
This represents '#pragma omp target teams distribute parallel for simd' combined directive.
Expr * getCombinedLowerBoundVariable() const
static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S, const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount)
OpenMPClauseKind
OpenMP clauses.
Expr * getPrevLowerBoundVariable() const
ASTContext & getContext() const
static void emitDistributeParallelForDistributeInnerBoundParams(CodeGenFunction &CGF, const OMPExecutableDirective &S, llvm::SmallVectorImpl< llvm::Value * > &CapturedVars)
void EmitOMPLinearClauseInit(const OMPLoopDirective &D)
Emit initial code for linear variables.
unsigned getContextParamPosition() const
This represents '#pragma omp target teams distribute simd' combined directive.
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, LValueBaseInfo BaseInfo=LValueBaseInfo(AlignmentSource::Type), llvm::MDNode *TBAAInfo=nullptr, bool isInit=false, QualType TBAABaseTy=QualType(), uint64_t TBAAOffset=0, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
This represents 'ordered' clause in the '#pragma omp ...' directive.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
std::pair< bool, RValue > EmitOMPAtomicSimpleUpdateExpr(LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart, llvm::AtomicOrdering AO, SourceLocation Loc, const llvm::function_ref< RValue(RValue)> &CommonGen)
Emit atomic update code for constructs: X = X BO E or X = E BO E.
This represents '#pragma omp for' directive.
static void emitTargetTeamsRegion(CodeGenFunction &CGF, PrePostActionTy &Action, const OMPTargetTeamsDirective &S)
SmallVector< const Expr *, 4 > FirstprivateVars
static void EmitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst, const Expr *X, const Expr *V, 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.
void setParallel(bool Enable=true)
Set the next pushed loop as parallel.
This represents '#pragma omp target teams' directive.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
Expr * getIsLastIterVariable() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
void EmitOMPBarrierDirective(const OMPBarrierDirective &S)
Expr * getNextUpperBound() const
This represents '#pragma omp cancel' directive.
This represents clause 'firstprivate' in the '#pragma omp ...' directives.
static void EmitOMPAtomicUpdateExpr(CodeGenFunction &CGF, bool IsSeqCst, const Expr *X, const Expr *E, const Expr *UE, bool IsXLHSInRHSPart, SourceLocation Loc)
static void emitCommonOMPTargetDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, const RegionCodeGenTy &CodeGen)
RValue EmitAtomicLoad(LValue LV, SourceLocation SL, AggValueSlot Slot=AggValueSlot::ignored())
static std::pair< LValue, LValue > emitForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S)
The following two functions generate expressions for the loop lower and upper bounds in case of stati...
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
GlobalDecl - represents a global declaration.
This represents '#pragma omp flush' directive.
This represents '#pragma omp parallel for simd' directive.
This represents 'seq_cst' clause in the '#pragma omp atomic' directive.
This represents 'untied' clause in the '#pragma omp ...' directive.
SourceLocation getLocStart() const
Returns starting location of directive kind.
static void emitAlignedClause(CodeGenFunction &CGF, const OMPExecutableDirective &D)
The l-value was considered opaque, so the alignment was determined from a type.
void EmitAlignmentAssumption(llvm::Value *PtrValue, unsigned Alignment, llvm::Value *OffsetValue=nullptr)
llvm::function_ref< void(CodeGenFunction &, const OMPLoopDirective &, JumpDest)> CodeGenLoopTy
This represents '#pragma omp target enter data' directive.
void EmitOMPFlushDirective(const OMPFlushDirective &S)
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
This represents 'num_teams' clause in the '#pragma omp ...' directive.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
This captures a statement into a function.
static void emitTargetParallelRegion(CodeGenFunction &CGF, const OMPTargetParallelDirective &S, PrePostActionTy &Action)
ASTContext & getContext() const
This represents '#pragma omp single' directive.
Encodes a location in the source.
CharUnits getPointerAlign() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
This represents 'hint' clause in the '#pragma omp ...' directive.
Pseudo declaration for capturing expressions.
llvm::PointerIntPair< llvm::Value *, 1, bool > Final
static void emitInnerParallelForWhenCombined(CodeGenFunction &CGF, const OMPLoopDirective &S, CodeGenFunction::JumpDest LoopExit)
This is a basic class for representing single OpenMP executable directive.
Expr * getLowerBoundVariable() const
This represents 'schedule' clause in the '#pragma omp ...' directive.
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
OpenMPDirectiveKind
OpenMP directives.
void EmitOMPLinearClauseFinal(const OMPLoopDirective &D, const llvm::function_ref< llvm::Value *(CodeGenFunction &)> &CondGen)
Emit final code for linear clauses.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
CanQualType getCanonicalParamType(QualType T) const
Return the canonical parameter type corresponding to the specific potentially non-canonical one...
param_iterator param_begin() const
Retrieve an iterator pointing to the first parameter decl.
This represents '#pragma omp taskwait' directive.
void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S)
This file defines OpenMP nodes for declarative directives.
This is a basic class for representing single OpenMP clause.
bool isTrivialInitializer(const Expr *Init)
Determine whether the given initializer is trivial in the sense that it requires no code to be genera...
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of the composite or combined directives that need loop ...
void emitAggregateType(CodeGenFunction &CGF, unsigned N)
Emits the code for the variable-modified type, if required.
const CodeGenOptions & getCodeGenOpts() const
virtual void Enter(CodeGenFunction &CGF)
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
const LangOptions & getLangOpts() const
void setAction(PrePostActionTy &Action) const
This represents '#pragma omp target' directive.
SourceLocation getBegin() const
const T * castAs() const
Member-template castAs<specific type>.
Expr * getUpperBoundVariable() const
static void EmitOMPAtomicCaptureExpr(CodeGenFunction &CGF, bool IsSeqCst, bool IsPostfixUpdate, const Expr *V, const Expr *X, const Expr *E, const Expr *UE, bool IsXLHSInRHSPart, SourceLocation Loc)
Expr * getV()
Get 'v' part of the associated expression/statement.
void EmitOMPAtomicDirective(const OMPAtomicDirective &S)
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
This represents '#pragma omp ordered' directive.
const SpecificClause * getSingleClause() const
Gets a single clause of the specified kind associated with the current directive iff there is only on...
This represents '#pragma omp target update' directive.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
void EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S)
Expr * getPrevEnsureUpperBound() const
void enterFullExpression(const ExprWithCleanups *E)
void EmitDecl(const Decl &D)
EmitDecl - Emit a declaration.
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
Expr * getPreCond() const
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
llvm::Constant * GetAddrOfGlobal(GlobalDecl GD, ForDefinition_t IsForDefinition=NotForDefinition)
JumpDest getOMPCancelDestination(OpenMPDirectiveKind Kind)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
FunctionArgList - Type for representing both the decl and type of parameters to a function...
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
void GenerateOpenMPCapturedVars(const CapturedStmt &S, SmallVectorImpl< llvm::Value * > &CapturedVars)
CGFunctionInfo - Class to encapsulate the information about a function definition.
CharUnits getAlignment() const
Return the alignment of this pointer.
This class organizes the cross-function state that is used while generating LLVM code.
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
Expr * getCombinedNextLowerBound() const
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
void EmitOMPTargetTeamsDirective(const OMPTargetTeamsDirective &S)
Class provides a way to call simple version of codegen for OpenMP region, or an advanced with possibl...
This represents 'device' clause in the '#pragma omp ...' directive.
void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S)
bool hasCancel() const
Return true if current directive has inner cancel directive.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
This represents '#pragma omp section' directive.
std::vector< llvm::Triple > OMPTargetTriples
Triples of the OpenMP targets that the host code codegen should take into account in order to generat...
OpenMPScheduleClauseModifier M1
This represents '#pragma omp teams distribute' directive.
void push(llvm::BasicBlock *Header, const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
Begin a new structured loop.
A basic class for pre|post-action for advanced codegen sequence for OpenMP region.
static void emitOMPLoopBodyWithStopPoint(CodeGenFunction &CGF, const OMPLoopDirective &S, CodeGenFunction::JumpDest LoopExit)
void EmitOMPPrivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
void EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S)
const Stmt * getBody() const
This represents '#pragma omp simd' directive.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::IntegerType * IntPtrTy
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
llvm::PointerIntPair< llvm::Value *, 1, bool > Priority
static RValue convertToType(CodeGenFunction &CGF, RValue Value, QualType SourceType, QualType ResType, SourceLocation Loc)
void EmitOMPLinearClause(const OMPLoopDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope)
Emit initial code for linear clauses.
This represents clause 'linear' in the '#pragma omp ...' directives.
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
Expr * getEnsureUpperBound() const
detail::InMemoryDirectory::const_iterator E
bool EmitOMPFirstprivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
void EmitOMPCancelDirective(const OMPCancelDirective &S)
Expr * getUpdateExpr()
Get helper expression of the form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 'OpaqueValueExp...
bool isLValueReferenceType() const
This represents '#pragma omp atomic' directive.
Expr * getCalcLastIteration() const
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
ArrayRef< Expr * > counters()
void emitInitialization(CodeGenFunction &CGF, unsigned N, Address PrivateAddr, LValue SharedLVal, llvm::function_ref< bool(CodeGenFunction &)> DefaultInit)
Performs initialization of the private copy for the reduction item.
JumpDest ReturnBlock
ReturnBlock - Unified return block.
void EmitOMPReductionClauseFinal(const OMPExecutableDirective &D, const OpenMPDirectiveKind ReductionKind)
Emit final update of reduction values to original variables at the end of the directive.
SwitchStmt - This represents a 'switch' stmt.
void EmitAutoVarCleanups(const AutoVarEmission &emission)
API for captured statement code generation.
llvm::PointerType * getType() const
Return the type of the pointer value.
Complex values, per C99 6.2.5p11.
static void emitSimpleAtomicStore(CodeGenFunction &CGF, bool IsSeqCst, LValue LVal, RValue RVal)
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location)
Converts Location to a DebugLoc, if debug information is enabled.
This file defines OpenMP AST classes for executable directives and clauses.
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
ArrayRef< Expr * > inits()
static void EmitOMPTargetTeamsDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDirective &S)
void EmitOMPTaskBasedDirective(const OMPExecutableDirective &S, const RegionCodeGenTy &BodyGen, const TaskGenTy &TaskGen, OMPTaskDataTy &Data)
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
Base for LValueReferenceType and RValueReferenceType.
StringRef getMangledName(GlobalDecl GD)
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S)
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
bool hasAssociatedStmt() const
Returns true if directive has associated statement.
void EmitStopPoint(const Stmt *S)
EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
param_iterator param_end() const
Retrieve an iterator one past the last parameter decl.
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Expr * getNextLowerBound() const
void EmitOMPReductionClauseInit(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)
Emit initial code for reduction variables.
This represents '#pragma omp target parallel' directive.
static QualType getCanonicalParamType(ASTContext &C, QualType T)
static llvm::iterator_range< specific_clause_iterator< SpecificClause > > getClausesOfKind(ArrayRef< OMPClause * > Clauses)
This represents 'nowait' clause in the '#pragma omp ...' directive.
llvm::PointerIntPair< llvm::Value *, 1, bool > Schedule
BoundNodesTreeBuilder *const Builder
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block, taking care to avoid creation of branches from dummy blocks.
static void emitPostUpdateForReductionClause(CodeGenFunction &CGF, const OMPExecutableDirective &D, const llvm::function_ref< llvm::Value *(CodeGenFunction &)> &CondGen)
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
Privates[]
Gets the list of initial values for linear variables.
LValue MakeAddrLValue(Address Addr, QualType T, LValueBaseInfo BaseInfo=LValueBaseInfo(AlignmentSource::Type))
void EmitOMPUseDevicePtrClause(const OMPClause &C, OMPPrivateScope &PrivateScope, const llvm::DenseMap< const ValueDecl *, Address > &CaptureDeviceAddrMap)
LValue EmitLValue(const Expr *E)
EmitLValue - Emit code to compute a designator that specifies the location of the expression...
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
This represents '#pragma omp taskloop simd' directive.
std::pair< llvm::Value *, QualType > getVLASize(const VariableArrayType *vla)
getVLASize - Returns an LLVM value that corresponds to the size, in non-variably-sized elements...
bool EmitOMPCopyinClause(const OMPExecutableDirective &D)
Emit code for copyin clause in D directive.
const VarDecl * getBaseDecl(unsigned N) const
Returns the base declaration of the reduction item.
This represents 'dist_schedule' clause in the '#pragma omp ...' directive.
CGCapturedStmtInfo * CapturedStmtInfo
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...
const llvm::function_ref< void(CodeGenFunction &, llvm::Value *, const OMPTaskDataTy &)> TaskGenTy
This represents '#pragma omp sections' directive.
This represents '#pragma omp target data' directive.
void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S)
void EmitOMPInnerLoop(const Stmt &S, bool RequiresCleanup, const Expr *LoopCond, const Expr *IncExpr, const llvm::function_ref< void(CodeGenFunction &)> &BodyGen, const llvm::function_ref< void(CodeGenFunction &)> &PostIncGen)
Emit inner loop of the worksharing/simd construct.
A reference to a declared variable, function, enum, etc.
static RValue get(llvm::Value *V)
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
Expr * getLastIteration() const
static void EmitOMPTargetDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetDirective &S)
Emit device code for the target directive.
void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S)
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
Expr * getCombinedCond() const
An l-value expression is a reference to an object with independent storage.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
A trivial tuple used to represent a source range.
SourceLocation getLocation() const
LValue - This represents an lvalue references.
This represents '#pragma omp taskyield' directive.
This represents '#pragma omp distribute parallel for simd' composite directive.
This represents '#pragma omp parallel sections' directive.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g., it is an signed integer type or a vector.
SourceLocation getLocEnd() const
Returns ending location of directive.
llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)
emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...
Expr *const * const_capture_init_iterator
Const iterator that walks over the capture initialization arguments.
Stmt * getAssociatedStmt() const
Returns statement associated with the directive.
Expr * getDistInc() const
SourceLocation getLocStart() const LLVM_READONLY
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument.
Address CreateMemTemp(QualType T, const Twine &Name="tmp", bool CastToDefaultAddrSpace=true)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignment...
virtual bool hasBody() const
Returns true if this Decl represents a declaration for a body of code, such as a function or method d...
A class which abstracts out some details necessary for making a call.
This represents '#pragma omp target parallel for' directive.
SmallVector< const Expr *, 4 > FirstprivateInits
This represents clause 'use_device_ptr' in the '#pragma omp ...' directives.
Expr * getStrideVariable() const
bool Privatize()
Privatizes local variables previously registered as private.
bool isPointerType() const
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
This represents '#pragma omp taskloop' directive.