19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/IR/CallSite.h"
21 #include "llvm/IR/DerivedTypes.h"
22 #include "llvm/IR/GlobalValue.h"
23 #include "llvm/IR/Value.h"
24 #include "llvm/Support/raw_ostream.h"
27 using namespace clang;
28 using namespace CodeGen;
35 enum CGOpenMPRegionKind {
38 ParallelOutlinedRegion,
47 const CGOpenMPRegionKind RegionKind,
49 : CGCapturedStmtInfo(CS,
CR_OpenMP), RegionKind(RegionKind),
50 CodeGen(CodeGen), Kind(Kind) {}
52 CGOpenMPRegionInfo(
const CGOpenMPRegionKind RegionKind,
54 : CGCapturedStmtInfo(
CR_OpenMP), RegionKind(RegionKind), CodeGen(CodeGen),
59 virtual const VarDecl *getThreadIDVariable()
const = 0;
68 CGOpenMPRegionKind getRegionKind()
const {
return RegionKind; }
72 static bool classof(
const CGCapturedStmtInfo *Info) {
77 CGOpenMPRegionKind RegionKind;
83 class CGOpenMPOutlinedRegionInfo :
public CGOpenMPRegionInfo {
88 : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind),
89 ThreadIDVar(ThreadIDVar) {
90 assert(ThreadIDVar !=
nullptr &&
"No ThreadID in OpenMP region.");
94 const VarDecl *getThreadIDVariable()
const override {
return ThreadIDVar; }
97 StringRef getHelperName()
const override {
return ".omp_outlined."; }
99 static bool classof(
const CGCapturedStmtInfo *Info) {
101 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
102 ParallelOutlinedRegion;
112 class CGOpenMPTaskOutlinedRegionInfo :
public CGOpenMPRegionInfo {
118 : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen, Kind),
119 ThreadIDVar(ThreadIDVar) {
120 assert(ThreadIDVar !=
nullptr &&
"No ThreadID in OpenMP region.");
124 const VarDecl *getThreadIDVariable()
const override {
return ThreadIDVar; }
130 StringRef getHelperName()
const override {
return ".omp_outlined."; }
132 static bool classof(
const CGCapturedStmtInfo *Info) {
134 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
146 class CGOpenMPInlinedRegionInfo :
public CGOpenMPRegionInfo {
151 : CGOpenMPRegionInfo(InlinedRegion, CodeGen, Kind), OldCSI(OldCSI),
152 OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {}
156 return OuterRegionInfo->getContextValue();
157 llvm_unreachable(
"No context value for inlined OpenMP region");
159 virtual void setContextValue(
llvm::Value *V)
override {
160 if (OuterRegionInfo) {
161 OuterRegionInfo->setContextValue(V);
164 llvm_unreachable(
"No context value for inlined OpenMP region");
169 return OuterRegionInfo->lookup(VD);
174 FieldDecl *getThisFieldDecl()
const override {
176 return OuterRegionInfo->getThisFieldDecl();
181 const VarDecl *getThreadIDVariable()
const override {
183 return OuterRegionInfo->getThreadIDVariable();
188 StringRef getHelperName()
const override {
189 if (
auto *OuterRegionInfo = getOldCSI())
190 return OuterRegionInfo->getHelperName();
191 llvm_unreachable(
"No helper name for inlined OpenMP construct");
196 static bool classof(
const CGCapturedStmtInfo *Info) {
198 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == InlinedRegion;
204 CGOpenMPRegionInfo *OuterRegionInfo;
208 class InlinedOpenMPRegionRAII {
223 ~InlinedOpenMPRegionRAII() {
226 cast<CGOpenMPInlinedRegionInfo>(CGF.CapturedStmtInfo)->getOldCSI();
227 delete CGF.CapturedStmtInfo;
228 CGF.CapturedStmtInfo = OldCSI;
239 getThreadIDVariable()
259 LValue CGOpenMPTaskOutlinedRegionInfo::getThreadIDVariableLValue(
263 getThreadIDVariable()->getType());
273 llvm::Type *MicroParams[] = {llvm::PointerType::getUnqual(CGM.
Int32Ty),
274 llvm::PointerType::getUnqual(CGM.
Int32Ty)};
287 "thread id variable must be of type kmp_int32 *");
290 CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind);
299 "thread id variable must be of type kmp_int32 for tasks");
302 CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen,
309 CGOpenMPRuntime::getOrCreateDefaultLocation(OpenMPLocationFlags Flags) {
310 llvm::Value *Entry = OpenMPDefaultLocMap.lookup(Flags);
312 if (!DefaultOpenMPPSource) {
317 DefaultOpenMPPSource =
319 DefaultOpenMPPSource =
320 llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource, CGM.
Int8PtrTy);
322 auto DefaultOpenMPLocation =
new llvm::GlobalVariable(
324 llvm::GlobalValue::PrivateLinkage,
nullptr);
325 DefaultOpenMPLocation->setUnnamedAddr(
true);
327 llvm::Constant *Zero = llvm::ConstantInt::get(CGM.
Int32Ty, 0,
true);
328 llvm::Constant *Values[] = {Zero,
329 llvm::ConstantInt::get(CGM.
Int32Ty, Flags),
330 Zero, Zero, DefaultOpenMPPSource};
331 llvm::Constant *Init = llvm::ConstantStruct::get(
IdentTy, Values);
332 DefaultOpenMPLocation->setInitializer(Init);
333 OpenMPDefaultLocMap[Flags] = DefaultOpenMPLocation;
334 return DefaultOpenMPLocation;
341 OpenMPLocationFlags Flags) {
345 return getOrCreateDefaultLocation(Flags);
347 assert(CGF.
CurFn &&
"No function in current CodeGenFunction.");
352 LocValue = I->second.DebugLoc;
355 if (LocValue ==
nullptr) {
360 Elem.second.DebugLoc = AI;
363 CGBuilderTy::InsertPointGuard IPG(CGF.
Builder);
365 CGF.
Builder.CreateMemCpy(LocValue, getOrCreateDefaultLocation(Flags),
366 llvm::ConstantExpr::getSizeOf(
IdentTy),
371 auto *PSource = CGF.
Builder.CreateConstInBoundsGEP2_32(
IdentTy, LocValue, 0,
375 if (OMPDebugLoc ==
nullptr) {
377 llvm::raw_svector_ostream OS2(Buffer2);
383 OS2 << FD->getQualifiedNameAsString();
386 OMPDebugLoc = CGF.
Builder.CreateGlobalStringPtr(OS2.str());
390 CGF.
Builder.CreateStore(OMPDebugLoc, PSource);
397 assert(CGF.
CurFn &&
"No function in current CodeGenFunction.");
404 ThreadID = I->second.ThreadID;
405 if (ThreadID !=
nullptr)
408 if (
auto OMPRegionInfo =
410 if (OMPRegionInfo->getThreadIDVariable()) {
412 auto LVal = OMPRegionInfo->getThreadIDVariableLValue(CGF);
418 Elem.second.ThreadID = ThreadID;
428 CGBuilderTy::InsertPointGuard IPG(CGF.
Builder);
434 Elem.second.ThreadID = ThreadID;
439 assert(CGF.
CurFn &&
"No function in current CodeGenFunction.");
445 return llvm::PointerType::getUnqual(
IdentTy);
454 llvm::Constant *RTLFn =
nullptr;
456 case OMPRTL__kmpc_fork_call: {
461 llvm::FunctionType *FnTy =
462 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
true);
466 case OMPRTL__kmpc_global_thread_num: {
469 llvm::FunctionType *FnTy =
470 llvm::FunctionType::get(CGM.
Int32Ty, TypeParams,
false);
474 case OMPRTL__kmpc_threadprivate_cached: {
479 CGM.
VoidPtrTy->getPointerTo()->getPointerTo()};
480 llvm::FunctionType *FnTy =
481 llvm::FunctionType::get(CGM.
VoidPtrTy, TypeParams,
false);
485 case OMPRTL__kmpc_critical: {
488 llvm::Type *TypeParams[] = {
491 llvm::FunctionType *FnTy =
492 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
496 case OMPRTL__kmpc_threadprivate_register: {
502 false)->getPointerTo();
505 auto KmpcCopyCtorTy =
506 llvm::FunctionType::get(CGM.
VoidPtrTy, KmpcCopyCtorTyArgs,
507 false)->getPointerTo();
513 KmpcCopyCtorTy, KmpcDtorTy};
514 auto FnTy = llvm::FunctionType::get(CGM.
VoidTy, FnTyArgs,
519 case OMPRTL__kmpc_end_critical: {
522 llvm::Type *TypeParams[] = {
525 llvm::FunctionType *FnTy =
526 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
530 case OMPRTL__kmpc_cancel_barrier: {
534 llvm::FunctionType *FnTy =
535 llvm::FunctionType::get(CGM.
Int32Ty, TypeParams,
false);
539 case OMPRTL__kmpc_barrier: {
542 llvm::FunctionType *FnTy =
543 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
547 case OMPRTL__kmpc_for_static_fini: {
550 llvm::FunctionType *FnTy =
551 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
555 case OMPRTL__kmpc_push_num_threads: {
560 llvm::FunctionType *FnTy =
561 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
565 case OMPRTL__kmpc_serialized_parallel: {
569 llvm::FunctionType *FnTy =
570 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
574 case OMPRTL__kmpc_end_serialized_parallel: {
578 llvm::FunctionType *FnTy =
579 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
583 case OMPRTL__kmpc_flush: {
586 llvm::FunctionType *FnTy =
587 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
591 case OMPRTL__kmpc_master: {
594 llvm::FunctionType *FnTy =
595 llvm::FunctionType::get(CGM.
Int32Ty, TypeParams,
false);
599 case OMPRTL__kmpc_end_master: {
602 llvm::FunctionType *FnTy =
603 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
607 case OMPRTL__kmpc_omp_taskyield: {
611 llvm::FunctionType *FnTy =
612 llvm::FunctionType::get(CGM.
Int32Ty, TypeParams,
false);
616 case OMPRTL__kmpc_single: {
619 llvm::FunctionType *FnTy =
620 llvm::FunctionType::get(CGM.
Int32Ty, TypeParams,
false);
624 case OMPRTL__kmpc_end_single: {
627 llvm::FunctionType *FnTy =
628 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
632 case OMPRTL__kmpc_omp_task_alloc: {
637 "Type kmp_routine_entry_t must be created.");
641 llvm::FunctionType *FnTy =
642 llvm::FunctionType::get(CGM.
VoidPtrTy, TypeParams,
false);
646 case OMPRTL__kmpc_omp_task: {
651 llvm::FunctionType *FnTy =
652 llvm::FunctionType::get(CGM.
Int32Ty, TypeParams,
false);
656 case OMPRTL__kmpc_copyprivate: {
662 llvm::FunctionType::get(CGM.
VoidTy, CpyTypeParams,
false);
666 llvm::FunctionType *FnTy =
667 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
671 case OMPRTL__kmpc_reduce: {
676 auto *ReduceFnTy = llvm::FunctionType::get(CGM.
VoidTy, ReduceTypeParams,
678 llvm::Type *TypeParams[] = {
680 CGM.
VoidPtrTy, ReduceFnTy->getPointerTo(),
682 llvm::FunctionType *FnTy =
683 llvm::FunctionType::get(CGM.
Int32Ty, TypeParams,
false);
687 case OMPRTL__kmpc_reduce_nowait: {
693 auto *ReduceFnTy = llvm::FunctionType::get(CGM.
VoidTy, ReduceTypeParams,
695 llvm::Type *TypeParams[] = {
697 CGM.
VoidPtrTy, ReduceFnTy->getPointerTo(),
699 llvm::FunctionType *FnTy =
700 llvm::FunctionType::get(CGM.
Int32Ty, TypeParams,
false);
704 case OMPRTL__kmpc_end_reduce: {
707 llvm::Type *TypeParams[] = {
710 llvm::FunctionType *FnTy =
711 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
715 case OMPRTL__kmpc_end_reduce_nowait: {
718 llvm::Type *TypeParams[] = {
721 llvm::FunctionType *FnTy =
722 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
727 case OMPRTL__kmpc_omp_task_begin_if0: {
732 llvm::FunctionType *FnTy =
733 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
738 case OMPRTL__kmpc_omp_task_complete_if0: {
743 llvm::FunctionType *FnTy =
744 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
746 "__kmpc_omp_task_complete_if0");
749 case OMPRTL__kmpc_ordered: {
752 llvm::FunctionType *FnTy =
753 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
757 case OMPRTL__kmpc_end_ordered: {
760 llvm::FunctionType *FnTy =
761 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
765 case OMPRTL__kmpc_omp_taskwait: {
768 llvm::FunctionType *FnTy =
769 llvm::FunctionType::get(CGM.
Int32Ty, TypeParams,
false);
773 case OMPRTL__kmpc_taskgroup: {
776 llvm::FunctionType *FnTy =
777 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
781 case OMPRTL__kmpc_end_taskgroup: {
784 llvm::FunctionType *FnTy =
785 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
789 case OMPRTL__kmpc_push_proc_bind: {
793 llvm::FunctionType *FnTy =
794 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
798 case OMPRTL__kmpc_omp_task_with_deps: {
802 llvm::Type *TypeParams[] = {
805 llvm::FunctionType *FnTy =
806 llvm::FunctionType::get(CGM.
Int32Ty, TypeParams,
false);
811 case OMPRTL__kmpc_omp_wait_deps: {
818 llvm::FunctionType *FnTy =
819 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
823 case OMPRTL__kmpc_cancellationpoint: {
827 llvm::FunctionType *FnTy =
828 llvm::FunctionType::get(CGM.
Int32Ty, TypeParams,
false);
832 case OMPRTL__kmpc_cancel: {
836 llvm::FunctionType *FnTy =
837 llvm::FunctionType::get(CGM.
Int32Ty, TypeParams,
false);
847 assert((IVSize == 32 || IVSize == 64) &&
848 "IV size is not compatible with the omp runtime");
849 auto Name = IVSize == 32 ? (IVSigned ?
"__kmpc_for_static_init_4"
850 :
"__kmpc_for_static_init_4u")
851 : (IVSigned ?
"__kmpc_for_static_init_8"
852 :
"__kmpc_for_static_init_8u");
854 auto PtrTy = llvm::PointerType::getUnqual(ITy);
855 llvm::Type *TypeParams[] = {
859 llvm::PointerType::getUnqual(CGM.
Int32Ty),
866 llvm::FunctionType *FnTy =
867 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
873 assert((IVSize == 32 || IVSize == 64) &&
874 "IV size is not compatible with the omp runtime");
877 ? (IVSigned ?
"__kmpc_dispatch_init_4" :
"__kmpc_dispatch_init_4u")
878 : (IVSigned ?
"__kmpc_dispatch_init_8" :
"__kmpc_dispatch_init_8u");
888 llvm::FunctionType *FnTy =
889 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
895 assert((IVSize == 32 || IVSize == 64) &&
896 "IV size is not compatible with the omp runtime");
899 ? (IVSigned ?
"__kmpc_dispatch_fini_4" :
"__kmpc_dispatch_fini_4u")
900 : (IVSigned ?
"__kmpc_dispatch_fini_8" :
"__kmpc_dispatch_fini_8u");
901 llvm::Type *TypeParams[] = {
905 llvm::FunctionType *FnTy =
906 llvm::FunctionType::get(CGM.
VoidTy, TypeParams,
false);
912 assert((IVSize == 32 || IVSize == 64) &&
913 "IV size is not compatible with the omp runtime");
916 ? (IVSigned ?
"__kmpc_dispatch_next_4" :
"__kmpc_dispatch_next_4u")
917 : (IVSigned ?
"__kmpc_dispatch_next_8" :
"__kmpc_dispatch_next_8u");
919 auto PtrTy = llvm::PointerType::getUnqual(ITy);
920 llvm::Type *TypeParams[] = {
923 llvm::PointerType::getUnqual(CGM.
Int32Ty),
928 llvm::FunctionType *FnTy =
929 llvm::FunctionType::get(CGM.
Int32Ty, TypeParams,
false);
950 auto VarTy = VDAddr->getType()->getPointerElementType();
971 Ctor, CopyCtor, Dtor};
988 llvm::Value *Ctor =
nullptr, *CopyCtor =
nullptr, *Dtor =
nullptr;
997 Args.push_back(&Dst);
1004 FTy,
".__kmpc_global_ctor_.", Loc);
1007 auto ArgVal = CtorCGF.EmitLoadOfScalar(
1008 CtorCGF.GetAddrOfLocalVar(&Dst),
1011 auto Arg = CtorCGF.Builder.CreatePointerCast(
1014 CtorCGF.EmitAnyExprToMem(Init, Arg, Init->getType().getQualifiers(),
1016 ArgVal = CtorCGF.EmitLoadOfScalar(
1017 CtorCGF.GetAddrOfLocalVar(&Dst),
1020 CtorCGF.Builder.CreateStore(ArgVal, CtorCGF.ReturnValue);
1021 CtorCGF.FinishFunction();
1031 Args.push_back(&Dst);
1038 FTy,
".__kmpc_global_dtor_.", Loc);
1041 auto ArgVal = DtorCGF.EmitLoadOfScalar(
1042 DtorCGF.GetAddrOfLocalVar(&Dst),
1045 DtorCGF.emitDestroy(ArgVal, ASTTy,
1048 DtorCGF.FinishFunction();
1057 llvm::FunctionType::get(CGM.
VoidPtrTy, CopyCtorTyArgs,
1058 false)->getPointerTo();
1062 CopyCtor = llvm::Constant::getNullValue(CopyCtorTy);
1063 if (Ctor ==
nullptr) {
1065 false)->getPointerTo();
1066 Ctor = llvm::Constant::getNullValue(CtorTy);
1068 if (Dtor ==
nullptr) {
1070 false)->getPointerTo();
1071 Dtor = llvm::Constant::getNullValue(DtorTy);
1074 auto InitFunctionTy =
1075 llvm::FunctionType::get(CGM.
VoidTy,
false);
1077 InitFunctionTy,
".__omp_threadprivate_init_.");
1084 InitCGF.FinishFunction();
1085 return InitFunction;
1153 const Expr *IfCond) {
1169 auto &&ElseGen = [
this, OutlinedFn, CapturedStruct, RTLoc, Loc](
1184 llvm::Value *OutlinedFnArgs[] = {ThreadIDAddr, ZeroAddr, CapturedStruct};
1208 if (
auto OMPRegionInfo =
1210 if (OMPRegionInfo->getThreadIDVariable())
1211 return OMPRegionInfo->getThreadIDVariableLValue(CGF).getAddress();
1216 auto ThreadIDTemp = CGF.
CreateMemTemp(Int32Ty,
".threadid_temp.");
1220 return ThreadIDTemp;
1225 const llvm::Twine &Name) {
1227 llvm::raw_svector_ostream Out(Buffer);
1229 auto RuntimeName = Out.str();
1230 auto &Elem = *
InternalVars.insert(std::make_pair(RuntimeName,
nullptr)).first;
1232 assert(Elem.second->getType()->getPointerElementType() == Ty &&
1233 "OMP internal variable has different type than requested");
1234 return &*Elem.second;
1237 return Elem.second =
new llvm::GlobalVariable(
1239 llvm::GlobalValue::CommonLinkage, llvm::Constant::getNullValue(Ty),
1244 llvm::Twine Name(
".gomp_critical_user_", CriticalName);
1256 assert(CleanupArgs.size() == N);
1257 std::copy(CleanupArgs.begin(), CleanupArgs.end(), std::begin(Args));
1266 StringRef CriticalName,
1279 CGF.
EHStack.pushCleanup<CallEndCleanup<std::extent<decltype(Args)>::value>>(
1281 llvm::makeArrayRef(Args));
1297 CGF.
Builder.CreateCondBr(CallBool, ThenBlock, ContBlock);
1316 typedef CallEndCleanup<std::extent<decltype(Args)>::value>
1317 MasterCallEndCleanup;
1320 CGF.
EHStack.pushCleanup<MasterCallEndCleanup>(
1322 llvm::makeArrayRef(Args));
1332 llvm::ConstantInt::get(CGM.
IntTy, 0,
true)};
1348 CGF.
EHStack.pushCleanup<CallEndCleanup<std::extent<decltype(Args)>::value>>(
1350 llvm::makeArrayRef(Args));
1366 Args.push_back(&LHSArg);
1367 Args.push_back(&RHSArg);
1370 C.VoidTy, Args, EI,
false);
1373 ".omp.copyprivate.copy_func", &CGM.
getModule());
1379 auto *LHS = CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(
1383 auto *RHS = CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(
1391 for (
unsigned I = 0, E = AssignmentOps.size(); I < E; ++I) {
1392 auto *DestAddr = CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(
1393 CGF.
Builder.CreateAlignedLoad(
1394 CGF.
Builder.CreateStructGEP(
nullptr, LHS, I),
1397 auto *SrcAddr = CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(
1398 CGF.
Builder.CreateAlignedLoad(
1399 CGF.
Builder.CreateStructGEP(
nullptr, RHS, I),
1402 auto *VD = cast<DeclRefExpr>(CopyprivateVars[I])->getDecl();
1405 cast<VarDecl>(cast<DeclRefExpr>(DestExprs[I])->getDecl()),
1406 cast<VarDecl>(cast<DeclRefExpr>(SrcExprs[I])->getDecl()),
1420 assert(CopyprivateVars.size() == SrcExprs.size() &&
1421 CopyprivateVars.size() == DstExprs.size() &&
1422 CopyprivateVars.size() == AssignmentOps.size());
1433 llvm::AllocaInst *DidIt =
nullptr;
1434 if (!CopyprivateVars.empty()) {
1437 DidIt = CGF.
CreateMemTemp(KmpInt32Ty,
".omp.copyprivate.did_it");
1439 DidIt->getAlignment());
1445 typedef CallEndCleanup<std::extent<decltype(Args)>::value>
1446 SingleCallEndCleanup;
1449 CGF.
EHStack.pushCleanup<SingleCallEndCleanup>(
1451 llvm::makeArrayRef(Args));
1456 DidIt->getAlignment());
1462 llvm::APInt ArraySize(32, CopyprivateVars.size());
1463 auto CopyprivateArrayTy =
1467 auto *CopyprivateList =
1468 CGF.
CreateMemTemp(CopyprivateArrayTy,
".omp.copyprivate.cpr_list");
1469 for (
unsigned I = 0, E = CopyprivateVars.size(); I < E; ++I) {
1470 auto *Elem = CGF.
Builder.CreateStructGEP(
1471 CopyprivateList->getAllocatedType(), CopyprivateList, I);
1472 CGF.
Builder.CreateAlignedStore(
1473 CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(
1481 CopyprivateVars, SrcExprs, DstExprs, AssignmentOps);
1482 auto *BufSize = llvm::ConstantInt::get(
1483 CGM.
SizeTy, C.getTypeSizeInChars(CopyprivateArrayTy).getQuantity());
1484 auto *CL = CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(CopyprivateList,
1512 CGF.
EHStack.pushCleanup<CallEndCleanup<std::extent<decltype(Args)>::value>>(
1514 llvm::makeArrayRef(Args));
1521 bool CheckForCancel) {
1524 OpenMPLocationFlags Flags = OMP_IDENT_KMPC;
1525 if (Kind == OMPD_for) {
1527 static_cast<OpenMPLocationFlags
>(Flags | OMP_IDENT_BARRIER_IMPL_FOR);
1528 }
else if (Kind == OMPD_sections) {
1529 Flags =
static_cast<OpenMPLocationFlags
>(Flags |
1530 OMP_IDENT_BARRIER_IMPL_SECTIONS);
1531 }
else if (Kind == OMPD_single) {
1533 static_cast<OpenMPLocationFlags
>(Flags | OMP_IDENT_BARRIER_IMPL_SINGLE);
1534 }
else if (Kind == OMPD_barrier) {
1535 Flags =
static_cast<OpenMPLocationFlags
>(Flags | OMP_IDENT_BARRIER_EXPL);
1537 Flags =
static_cast<OpenMPLocationFlags
>(Flags | OMP_IDENT_BARRIER_IMPL);
1543 if (
auto *OMPRegionInfo =
1545 auto CancelDestination =
1547 if (CancelDestination.isValid()) {
1550 if (CheckForCancel) {
1556 auto *Cmp = CGF.
Builder.CreateIsNotNull(Result);
1557 CGF.
Builder.CreateCondBr(Cmp, ExitBB, ContBB);
1593 bool Chunked,
bool Ordered) {
1594 switch (ScheduleKind) {
1595 case OMPC_SCHEDULE_static:
1598 case OMPC_SCHEDULE_dynamic:
1600 case OMPC_SCHEDULE_guided:
1602 case OMPC_SCHEDULE_runtime:
1604 case OMPC_SCHEDULE_auto:
1607 assert(!Chunked &&
"chunk was specified but schedule kind not known");
1610 llvm_unreachable(
"Unexpected runtime schedule");
1614 bool Chunked)
const {
1628 unsigned IVSize,
bool IVSigned,
bool Ordered,
1643 if (Chunk ==
nullptr)
1644 Chunk = CGF.
Builder.getIntN(IVSize, 1);
1647 CGF.
Builder.getInt32(Schedule),
1648 CGF.
Builder.getIntN(IVSize, 0),
1650 CGF.
Builder.getIntN(IVSize, 1),
1660 if (Chunk ==
nullptr) {
1662 "expected static non-chunked schedule");
1664 Chunk = CGF.
Builder.getIntN(IVSize, 1);
1668 "expected static chunked schedule");
1671 CGF.
Builder.getInt32(Schedule),
1676 CGF.
Builder.getIntN(IVSize, 1),
1750 case OMPC_PROC_BIND_master:
1751 RuntimeProcBind = ProcBindMaster;
1753 case OMPC_PROC_BIND_close:
1754 RuntimeProcBind = ProcBindClose;
1756 case OMPC_PROC_BIND_spread:
1757 RuntimeProcBind = ProcBindSpread;
1760 llvm_unreachable(
"Unsupported proc_bind value.");
1765 llvm::ConstantInt::get(CGM.
IntTy, RuntimeProcBind,
true)};
1786 KmpTaskTDestructors,
1794 QualType KmpRoutineEntryTyArgs[] = {KmpInt32Ty, C.VoidPtrTy};
1797 C.getFunctionType(KmpInt32Ty, KmpRoutineEntryTyArgs, EPI));
1813 struct PrivateHelpersTy {
1814 PrivateHelpersTy(
const VarDecl *Original,
const VarDecl *PrivateCopy,
1815 const VarDecl *PrivateElemInit)
1816 : Original(Original), PrivateCopy(PrivateCopy),
1817 PrivateElemInit(PrivateElemInit) {}
1820 const VarDecl *PrivateElemInit;
1822 typedef std::pair<
CharUnits , PrivateHelpersTy> PrivateDataTy;
1828 if (!Privates.empty()) {
1835 for (
auto &&Pair : Privates) {
1836 auto Type = Pair.second.Original->getType();
1840 RD->completeDefinition();
1848 QualType KmpRoutineEntryPointerQTy) {
1862 RD->completeDefinition();
1880 RD->completeDefinition();
1903 nullptr, KmpTaskTWithPrivatesPtrQTy);
1904 Args.push_back(&GtidArg);
1905 Args.push_back(&TaskTypeArg);
1907 auto &TaskEntryFnInfo =
1923 C.getTypeAlignInChars(KmpInt32Ty).getQuantity(), KmpInt32Ty, Loc);
1924 auto *TaskTypeArgAddr = CGF.
Builder.CreateAlignedLoad(
1928 auto *KmpTaskTWithPrivatesQTyRD =
1929 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->
getAsTagDecl());
1932 auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->
getAsTagDecl());
1933 auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
1937 auto SharedsFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTShareds);
1939 auto *SharedsParam = CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(
1943 auto PrivatesFI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin(), 1);
1945 if (PrivatesFI != KmpTaskTWithPrivatesQTyRD->field_end()) {
1947 PrivatesParam = CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(
1948 PrivatesLVal.getAddress(), CGF.
VoidPtrTy);
1950 PrivatesParam = llvm::ConstantPointerNull::get(CGF.
VoidPtrTy);
1953 llvm::Value *CallArgs[] = {GtidParam, PartidParam, PrivatesParam,
1954 TaskPrivatesMap, SharedsParam};
1966 QualType KmpTaskTWithPrivatesPtrQTy,
1967 QualType KmpTaskTWithPrivatesQTy) {
1972 nullptr, KmpTaskTWithPrivatesPtrQTy);
1973 Args.push_back(&GtidArg);
1974 Args.push_back(&TaskTypeArg);
1976 auto &DestructorFnInfo =
1980 auto *DestructorFn =
1982 ".omp_task_destructor.", &CGM.
getModule());
1989 auto *TaskTypeArgAddr = CGF.
Builder.CreateAlignedLoad(
1993 auto *KmpTaskTWithPrivatesQTyRD =
1994 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->
getAsTagDecl());
1995 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
1998 cast<RecordDecl>(FI->getType()->getAsTagDecl())->fields()) {
1999 if (
auto DtorKind = Field->getType().isDestructedType()) {
2001 CGF.
pushDestroy(DtorKind, FieldLValue.getAddress(), Field->getType());
2005 return DestructorFn;
2027 C,
nullptr, Loc,
nullptr,
2028 C.getPointerType(PrivatesQTy).withConst().withRestrict());
2029 Args.push_back(&TaskPrivatesArg);
2030 llvm::DenseMap<const VarDecl *, unsigned> PrivateVarsPos;
2031 unsigned Counter = 1;
2032 for (
auto *E: PrivateVars) {
2035 nullptr, C.getPointerType(C.getPointerType(E->getType()))
2038 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
2039 PrivateVarsPos[VD] = Counter;
2042 for (
auto *E : FirstprivateVars) {
2045 nullptr, C.getPointerType(C.getPointerType(E->getType()))
2048 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
2049 PrivateVarsPos[VD] = Counter;
2053 auto &TaskPrivatesMapFnInfo =
2056 auto *TaskPrivatesMapTy =
2060 ".omp_task_privates_map.", &CGM.
getModule());
2063 TaskPrivatesMap->addFnAttr(llvm::Attribute::AlwaysInline);
2067 TaskPrivatesMapFnInfo, Args);
2070 auto *TaskPrivatesArgAddr = CGF.
Builder.CreateAlignedLoad(
2074 auto *PrivatesQTyRD = cast<RecordDecl>(PrivatesQTy->
getAsTagDecl());
2076 for (
auto *Field : PrivatesQTyRD->fields()) {
2078 auto *VD = Args[PrivateVarsPos[Privates[Counter].second.Original]];
2083 FieldLVal.getAddress(),
2085 RefLVal.getType()->getPointeeType()));
2089 return TaskPrivatesMap;
2093 const PrivateDataTy *P2) {
2094 return P1->first < P2->first ? 1 : (P2->first < P1->first ? -1 : 0);
2099 bool Tied, llvm::PointerIntPair<llvm::Value *, 1, bool> Final,
2106 ArrayRef<std::pair<OpenMPDependClauseKind, const Expr *>> Dependences) {
2110 auto I = PrivateCopies.begin();
2111 for (
auto *E : PrivateVars) {
2112 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
2113 Privates.push_back(std::make_pair(
2114 C.getTypeAlignInChars(VD->
getType()),
2115 PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
2119 I = FirstprivateCopies.begin();
2120 auto IElemInitRef = FirstprivateInits.begin();
2121 for (
auto *E : FirstprivateVars) {
2122 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
2123 Privates.push_back(std::make_pair(
2124 C.getTypeAlignInChars(VD->
getType()),
2126 VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
2127 cast<VarDecl>(cast<DeclRefExpr>(*IElemInitRef)->getDecl()))));
2128 ++I, ++IElemInitRef;
2130 llvm::array_pod_sort(Privates.begin(), Privates.end(),
2132 auto KmpInt32Ty = C.getIntTypeForBitwidth(32, 1);
2142 auto *KmpTaskTWithPrivatesQTyRD =
2144 auto KmpTaskTWithPrivatesQTy = C.getRecordType(KmpTaskTWithPrivatesQTyRD);
2145 QualType KmpTaskTWithPrivatesPtrQTy =
2146 C.getPointerType(KmpTaskTWithPrivatesQTy);
2147 auto *KmpTaskTWithPrivatesTy = CGF.
ConvertType(KmpTaskTWithPrivatesQTy);
2148 auto *KmpTaskTWithPrivatesPtrTy = KmpTaskTWithPrivatesTy->getPointerTo();
2149 auto KmpTaskTWithPrivatesTySize =
2150 CGM.
getSize(C.getTypeSizeInChars(KmpTaskTWithPrivatesQTy));
2151 QualType SharedsPtrTy = C.getPointerType(SharedsTy);
2155 auto *TaskPrivatesMapTy =
2156 std::next(cast<llvm::Function>(TaskFunction)->getArgumentList().begin(),
2159 if (!Privates.empty()) {
2160 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
2162 CGM, Loc, PrivateVars, FirstprivateVars, FI->getType(), Privates);
2163 TaskPrivatesMap = CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(
2164 TaskPrivatesMap, TaskPrivatesMapTy);
2166 TaskPrivatesMap = llvm::ConstantPointerNull::get(
2167 cast<llvm::PointerType>(TaskPrivatesMapTy));
2172 CGM, Loc, KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy, KmpTaskTWithPrivatesQTy,
2173 KmpTaskTQTy, SharedsPtrTy, TaskFunction, TaskPrivatesMap);
2181 const unsigned TiedFlag = 0x1;
2182 const unsigned FinalFlag = 0x2;
2183 unsigned Flags = Tied ? TiedFlag : 0;
2186 ? CGF.
Builder.CreateSelect(Final.getPointer(),
2187 CGF.
Builder.getInt32(FinalFlag),
2189 : CGF.
Builder.getInt32(Final.getInt() ? FinalFlag : 0);
2190 TaskFlags = CGF.
Builder.CreateOr(TaskFlags, CGF.
Builder.getInt32(Flags));
2191 auto SharedsSize = C.getTypeSizeInChars(SharedsTy);
2194 KmpTaskTWithPrivatesTySize, CGM.
getSize(SharedsSize),
2195 CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(TaskEntry,
2199 auto *NewTaskNewTaskTTy = CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(
2200 NewTask, KmpTaskTWithPrivatesPtrTy);
2202 KmpTaskTWithPrivatesQTy);
2211 TDBase, *std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTShareds)),
2216 bool NeedsCleanup =
false;
2217 if (!Privates.empty()) {
2218 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
2220 FI = cast<RecordDecl>(FI->getType()->getAsTagDecl())->field_begin();
2222 if (!FirstprivateVars.empty()) {
2224 CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(
2230 for (
auto &&Pair : Privates) {
2231 auto *VD = Pair.second.PrivateCopy;
2235 if (
auto *Elem = Pair.second.PrivateElemInit) {
2236 auto *OriginalVD = Pair.second.Original;
2237 auto *SharedField = CapturesInfo.lookup(OriginalVD);
2238 auto SharedRefLValue =
2243 if (!isa<CXXConstructExpr>(Init) ||
2247 SharedRefLValue.getAddress(), Type);
2252 PrivateLValue.
getAddress(), SharedRefLValue.getAddress(),
2253 Type, [&CGF, Elem, Init, &CapturesInfo](
2257 InitScope.addPrivate(Elem, [SrcElement]() ->
llvm::Value *{
2260 (void)InitScope.Privatize();
2263 CGF, &CapturesInfo);
2264 CGF.EmitAnyExprToMem(Init, DestElement,
2265 Init->getType().getQualifiers(),
2271 InitScope.addPrivate(Elem, [SharedRefLValue]() ->
llvm::Value *{
2272 return SharedRefLValue.getAddress();
2274 (void)InitScope.Privatize();
2276 CGF.EmitExprAsInit(Init, VD, PrivateLValue,
2280 CGF.EmitExprAsInit(Init, VD, PrivateLValue,
false);
2283 NeedsCleanup = NeedsCleanup || FI->getType().isDestructedType();
2290 KmpTaskTWithPrivatesPtrQTy,
2291 KmpTaskTWithPrivatesQTy)
2292 : llvm::ConstantPointerNull::get(
2294 LValue Destructor = CGF.EmitLValueForField(
2295 TDBase, *std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTDestructors));
2296 CGF.EmitStoreOfScalar(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2302 unsigned DependencesNumber = Dependences.size();
2303 if (!Dependences.empty()) {
2305 enum RTLDependenceKindTy { DepIn = 1, DepOut = 2, DepInOut = 3 };
2306 enum RTLDependInfoFieldsTy { BaseAddr, Len, Flags };
2308 QualType FlagsTy = C.getIntTypeForBitwidth(
2309 C.toBits(C.getTypeSizeInChars(C.BoolTy)),
false);
2310 llvm::Type *LLVMFlagsTy = CGF.ConvertTypeForMem(FlagsTy);
2312 KmpDependInfoRD = C.buildImplicitRecord(
"kmp_depend_info");
2323 QualType KmpDependInfoArrayTy = C.getConstantArrayType(
2327 DependInfo = CGF.CreateMemTemp(KmpDependInfoArrayTy);
2328 for (
unsigned i = 0; i < DependencesNumber; ++i) {
2329 auto Addr = CGF.EmitLValue(Dependences[i].second);
2330 auto *Size = llvm::ConstantInt::get(
2332 C.getTypeSizeInChars(Dependences[i].second->getType()).getQuantity());
2333 auto Base = CGF.MakeNaturalAlignAddrLValue(
2334 CGF.Builder.CreateStructGEP(
nullptr, DependInfo, i),
2337 auto BaseAddrLVal = CGF.EmitLValueForField(
2338 Base, *std::next(KmpDependInfoRD->
field_begin(), BaseAddr));
2339 CGF.EmitStoreOfScalar(
2340 CGF.Builder.CreatePtrToInt(Addr.getAddress(), CGF.IntPtrTy),
2343 auto LenLVal = CGF.EmitLValueForField(
2344 Base, *std::next(KmpDependInfoRD->
field_begin(), Len));
2345 CGF.EmitStoreOfScalar(Size, LenLVal);
2347 RTLDependenceKindTy DepKind;
2348 switch (Dependences[i].first) {
2349 case OMPC_DEPEND_in:
2352 case OMPC_DEPEND_out:
2355 case OMPC_DEPEND_inout:
2359 llvm_unreachable(
"Unknown task dependence type");
2361 auto FlagsLVal = CGF.EmitLValueForField(
2362 Base, *std::next(KmpDependInfoRD->
field_begin(), Flags));
2363 CGF.EmitStoreOfScalar(llvm::ConstantInt::get(LLVMFlagsTy, DepKind),
2366 DependInfo = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2367 CGF.Builder.CreateStructGEP(
nullptr, DependInfo, 0),
2381 llvm::Value *TaskArgs[] = {UpLoc, ThreadID, NewTask};
2386 DependInfo ? CGF.Builder.getInt32(DependencesNumber) :
nullptr,
2388 DependInfo ? CGF.Builder.getInt32(0) :
nullptr,
2389 DependInfo ? llvm::ConstantPointerNull::get(CGF.VoidPtrTy) : nullptr};
2390 auto &&ThenCodeGen = [
this, DependInfo, &TaskArgs,
2393 CGF.EmitRuntimeCall(
2395 : OMPRTL__kmpc_omp_task),
2396 DependInfo ? makeArrayRef(DepTaskArgs) : makeArrayRef(TaskArgs));
2398 typedef CallEndCleanup<std::extent<decltype(TaskArgs)>::value>
2403 DependInfo ? CGF.Builder.getInt32(DependencesNumber) :
nullptr,
2405 DependInfo ? CGF.Builder.getInt32(0) :
nullptr,
2406 DependInfo ? llvm::ConstantPointerNull::get(CGF.VoidPtrTy) : nullptr};
2407 auto &&ElseCodeGen = [
this, &TaskArgs, ThreadID, NewTaskNewTaskTTy, TaskEntry,
2423 CGF.EHStack.pushCleanup<IfCallEndCleanup>(
2426 llvm::makeArrayRef(TaskArgs));
2429 llvm::Value *OutlinedFnArgs[] = {ThreadID, NewTaskNewTaskTTy};
2430 CGF.EmitCallOrInvoke(TaskEntry, OutlinedFnArgs);
2441 llvm::Type *ArgsType,
2453 Args.push_back(&LHSArg);
2454 Args.push_back(&RHSArg);
2457 C.VoidTy, Args, EI,
false);
2460 ".omp.reduction.reduction_func", &CGM.
getModule());
2467 auto *LHS = CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(
2471 auto *RHS = CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(
2480 for (
unsigned I = 0, E = ReductionOps.size(); I < E; ++I) {
2482 cast<VarDecl>(cast<DeclRefExpr>(RHSExprs[I])->getDecl()),
2484 return CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(
2485 CGF.
Builder.CreateAlignedLoad(
2486 CGF.
Builder.CreateStructGEP(
nullptr, RHS, I),
2491 cast<VarDecl>(cast<DeclRefExpr>(LHSExprs[I])->getDecl()),
2493 return CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(
2494 CGF.
Builder.CreateAlignedLoad(
2495 CGF.
Builder.CreateStructGEP(
nullptr, LHS, I),
2501 for (
auto *E : ReductionOps) {
2513 bool WithNowait,
bool SimpleReduction) {
2551 if (SimpleReduction) {
2553 for (
auto *E : ReductionOps) {
2561 llvm::APInt ArraySize(32, RHSExprs.size());
2565 auto *ReductionList =
2566 CGF.
CreateMemTemp(ReductionArrayTy,
".omp.reduction.red_list");
2567 for (
unsigned I = 0, E = RHSExprs.size(); I < E; ++I) {
2568 auto *Elem = CGF.
Builder.CreateStructGEP(
nullptr, ReductionList, I);
2569 CGF.
Builder.CreateAlignedStore(
2570 CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(
2578 RHSExprs, ReductionOps);
2587 static_cast<OpenMPLocationFlags>(OMP_IDENT_KMPC | OMP_ATOMIC_REDUCE));
2589 auto *ReductionArrayTySize = llvm::ConstantInt::get(
2590 CGM.
SizeTy, C.getTypeSizeInChars(ReductionArrayTy).getQuantity());
2591 auto *RL = CGF.
Builder.CreatePointerBitCastOrAddrSpaceCast(ReductionList,
2596 CGF.
Builder.getInt32(RHSExprs.size()),
2597 ReductionArrayTySize,
2604 : OMPRTL__kmpc_reduce),
2609 auto *SwInst = CGF.
Builder.CreateSwitch(Res, DefaultBB, 2);
2618 SwInst->addCase(CGF.
Builder.getInt32(1), Case1BB);
2630 .pushCleanup<CallEndCleanup<std::extent<decltype(EndArgs)>::value>>(
2633 : OMPRTL__kmpc_end_reduce),
2634 llvm::makeArrayRef(EndArgs));
2635 for (
auto *E : ReductionOps) {
2648 SwInst->addCase(CGF.
Builder.getInt32(2), Case2BB);
2661 .pushCleanup<CallEndCleanup<std::extent<decltype(EndArgs)>::value>>(
2664 llvm::makeArrayRef(EndArgs));
2666 auto I = LHSExprs.begin();
2667 for (
auto *E : ReductionOps) {
2668 const Expr *XExpr =
nullptr;
2669 const Expr *EExpr =
nullptr;
2670 const Expr *UpExpr =
nullptr;
2672 if (
auto *BO = dyn_cast<BinaryOperator>(E)) {
2674 XExpr = BO->getLHS();
2675 UpExpr = BO->getRHS();
2679 auto *RHSExpr = UpExpr;
2682 if (
auto *ACO = dyn_cast<AbstractConditionalOperator>(
2683 RHSExpr->IgnoreParenImpCasts())) {
2686 RHSExpr = ACO->getCond();
2689 dyn_cast<BinaryOperator>(RHSExpr->IgnoreParenImpCasts())) {
2690 EExpr = BORHS->getRHS();
2691 BO = BORHS->getOpcode();
2695 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl());
2701 X, E, BO,
true, llvm::Monotonic, Loc,
2702 [&CGF, UpExpr, VD](
RValue XRValue) {
2704 PrivateScope.addPrivate(
2712 (void)PrivateScope.Privatize();
2741 InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind);
2757 if (CancelRegion == OMPD_parallel)
2758 CancelKind = CancelParallel;
2759 else if (CancelRegion == OMPD_for)
2760 CancelKind = CancelLoop;
2761 else if (CancelRegion == OMPD_sections)
2762 CancelKind = CancelSections;
2764 assert(CancelRegion == OMPD_taskgroup);
2765 CancelKind = CancelTaskgroup;
2775 if (
auto *OMPRegionInfo =
2779 if (CancelDest.isValid()) {
2792 auto *Cmp = CGF.
Builder.CreateIsNotNull(Result);
2793 CGF.
Builder.CreateCondBr(Cmp, ExitBB, ContBB);
2808 if (
auto *OMPRegionInfo =
2812 if (CancelDest.isValid()) {
2825 auto *Cmp = CGF.
Builder.CreateIsNotNull(Result);
2826 CGF.
Builder.CreateCondBr(Cmp, ExitBB, ContBB);
llvm::PointerType * Int8PtrPtrTy
void functionFinished(CodeGenFunction &CGF)
Cleans up references to the objects in finished function.
void pushTerminate()
Push a terminate handler on the stack.
virtual llvm::Value * emitThreadIDAddress(CodeGenFunction &CGF, SourceLocation Loc)
Emits address of the word in a memory where current thread id is stored.
virtual void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind Kind, bool CheckForCancel=true)
Emit an implicit/explicit barrier for OpenMP threads.
virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S)
Emit the captured statement body.
llvm::IntegerType * IntTy
int
CodeGenTypes & getTypes()
unsigned getColumn() const
Return the presumed column number of this location.
llvm::Type * ConvertTypeForMem(QualType T)
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount)
DestructionKind isDestructedType() const
llvm::Module & getModule() const
RecordDecl * buildImplicitRecord(StringRef Name, RecordDecl::TagKind TK=TTK_Struct) const
Create a new implicit TU-level CXXRecordDecl or RecordDecl declaration.
virtual void emitForOrderedIterationEnd(CodeGenFunction &CGF, SourceLocation Loc, unsigned IVSize, bool IVSigned)
Call the appropriate runtime routine to notify that we finished iteration of the ordered loop with th...
virtual llvm::Value * emitParallelOutlinedFunction(const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)
Emits outlined function for the specified OpenMP parallel directive D. This outlined function has typ...
llvm::Value * getThreadID(CodeGenFunction &CGF, SourceLocation Loc)
Gets thread id value for the current thread.
OpenMPLocThreadIDMapTy OpenMPLocThreadIDMap
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
void EmitOMPCopy(CodeGenFunction &CGF, QualType OriginalType, llvm::Value *DestAddr, llvm::Value *SrcAddr, const VarDecl *DestVD, const VarDecl *SrcVD, const Expr *Copy)
Emit proper copying of data from one variable to another.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
const llvm::DataLayout & getDataLayout() const
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
QualType KmpDependInfoTy
Type typedef struct kmp_depend_info { kmp_intptr_t base_addr; size_t len; struct { bool in:1; bool ou...
virtual void completeDefinition()
bool addPrivate(const VarDecl *LocalVD, const std::function< llvm::Value *()> &PrivateGen)
Registers LocalVD variable as a private and apply PrivateGen function for it to generate correspondin...
unsigned getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it...
const CGFunctionInfo & arrangeFreeFunctionDeclaration(QualType ResTy, const FunctionArgList &Args, const FunctionType::ExtInfo &Info, bool isVariadic)
void EmitOMPAggregateAssign(llvm::Value *DestAddr, llvm::Value *SrcAddr, QualType OriginalType, const llvm::function_ref< void(llvm::Value *, llvm::Value *)> &CopyGen)
Perform element by element copying of arrays with type OriginalType from SrcAddr to DestAddr using co...
llvm::Value * getAddress() const
OpenMPSchedType
Schedule types for 'omp for' loops (these enumerators are taken from the enum sched_type in kmp...
ExtProtoInfo - Extra information about a function prototype.
field_iterator field_begin() const
static llvm::Value * emitReductionFunction(CodeGenModule &CGM, llvm::Type *ArgsType, ArrayRef< const Expr * > LHSExprs, ArrayRef< const Expr * > RHSExprs, ArrayRef< const Expr * > ReductionOps)
llvm::StringMap< llvm::AssertingVH< llvm::Constant >, llvm::BumpPtrAllocator > InternalVars
An ordered map of auto-generated variables to their unique names. It stores variables with the follow...
CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const
Return the store size, in character units, of the given LLVM type.
llvm::Value * ReturnValue
virtual void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc)
Emits code for a taskyield directive.
virtual void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn, llvm::Value *CapturedStruct, const Expr *IfCond)
Emits code for parallel or serial call of the OutlinedFn with variables captured in a record which ad...
static llvm::Value * emitDestructorsFunction(CodeGenModule &CGM, SourceLocation Loc, QualType KmpInt32Ty, QualType KmpTaskTWithPrivatesPtrQTy, QualType KmpTaskTWithPrivatesQTy)
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
String describing the source location. The string is composed of semi-colon separated fields which de...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
llvm::IntegerType * Int64Ty
The scope used to remap some variables as private in the OpenMP loop body (or other captured region e...
virtual void emitMasterRegion(CodeGenFunction &CGF, const RegionCodeGenTy &MasterOpGen, SourceLocation Loc)
Emits a master region.
llvm::IntegerType * SizeTy
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
void startDefinition()
Starts the definition of this tag declaration.
llvm::CallSite EmitCallOrInvoke(llvm::Value *Callee, ArrayRef< llvm::Value * > Args, const Twine &Name="")
static void emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond, const RegionCodeGenTy &ThenGen, const RegionCodeGenTy &ElseGen)
Emits code for OpenMP 'if' clause using specified CodeGen function. Here is the logic: if (Cond) { Th...
QualType KmpRoutineEntryPtrQTy
void EmitAggregateAssign(llvm::Value *DestPtr, llvm::Value *SrcPtr, QualType EltTy)
virtual void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind CancelRegion)
Emit code for 'cancel' construct.
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy)
virtual void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName, const RegionCodeGenTy &CriticalOpGen, SourceLocation Loc)
Emits a critical region.
llvm::ArrayType * KmpCriticalNameTy
Type kmp_critical_name, originally defined as typedef kmp_int32 kmp_critical_name[8];.
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
CGOpenMPRuntime(CodeGenModule &CGM)
llvm::Constant * getOrCreateThreadPrivateCache(const VarDecl *VD)
If the specified mangled name is not in the module, create and return threadprivate cache object...
const TargetInfo & getTargetInfo() const
RAII for correct setting/restoring of CapturedStmtInfo.
llvm::GlobalVariable * GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr, unsigned Alignment=0)
llvm::PointerType * VoidPtrTy
virtual void emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc)
Call the appropriate runtime routine to notify that we finished all the work with current loop...
llvm::FunctionType * Kmpc_MicroTy
The type for a microtask which gets passed to __kmpc_fork_call(). Original representation is: typedef...
virtual void emitTaskgroupRegion(CodeGenFunction &CGF, const RegionCodeGenTy &TaskgroupOpGen, SourceLocation Loc)
Emit a taskgroup region.
RecordDecl * getDecl() const
void pushDestroy(QualType::DestructionKind dtorKind, llvm::Value *addr, QualType type)
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
virtual void emitProcBindClause(CodeGenFunction &CGF, OpenMPProcBindClauseKind ProcBind, SourceLocation Loc)
Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid, int proc_bind) to generat...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
llvm::Constant * createDispatchInitFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_dispatch_init_* runtime function for the specified size IVSize and sign IVSigned...
unsigned getLine() const
Return the presumed line number of this location.
LValue EmitLValueForField(LValue Base, const FieldDecl *Field)
virtual void emitForInit(CodeGenFunction &CGF, SourceLocation Loc, OpenMPScheduleClauseKind SchedKind, unsigned IVSize, bool IVSigned, bool Ordered, llvm::Value *IL, llvm::Value *LB, llvm::Value *UB, llvm::Value *ST, llvm::Value *Chunk=nullptr)
Call the appropriate runtime routine to initialize it before start of loop.
llvm::Value * emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc, OpenMPLocationFlags Flags=OMP_IDENT_KMPC)
Emits object of ident_t type with info for source location.
virtual void emitReduction(CodeGenFunction &CGF, SourceLocation Loc, ArrayRef< const Expr * > LHSExprs, ArrayRef< const Expr * > RHSExprs, ArrayRef< const Expr * > ReductionOps, bool WithNowait, bool SimpleReduction)
Emit a code for reduction clause. Next code should be emitted for reduction:
KmpTaskTFields
Indexes of fields for type kmp_task_t.
void SetLLVMFunctionAttributes(const Decl *D, const CGFunctionInfo &Info, llvm::Function *F)
Set the LLVM function attributes (sext, zext, etc).
void InitTempAlloca(llvm::AllocaInst *Alloca, llvm::Value *Value)
InitTempAlloca - Provide an initial value for the given alloca.
virtual void emitSingleRegion(CodeGenFunction &CGF, const RegionCodeGenTy &SingleOpGen, SourceLocation Loc, ArrayRef< const Expr * > CopyprivateVars, ArrayRef< const Expr * > DestExprs, ArrayRef< const Expr * > SrcExprs, ArrayRef< const Expr * > AssignmentOps)
Emits a single region.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
llvm::Constant * createRuntimeFunction(OpenMPRTLFunction Function)
Returns specified OpenMP runtime function.
llvm::Value * GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
const CGFunctionInfo & arrangeNullaryFunction()
virtual bool isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind, bool Chunked) const
Check if the specified ScheduleKind is static non-chunked. This kind of worksharing directive is emit...
static RTCancelKind getCancellationKind(OpenMPDirectiveKind CancelRegion)
ASTContext & getContext() const
static OpenMPSchedType getRuntimeSchedule(OpenMPScheduleClauseKind ScheduleKind, bool Chunked, bool Ordered)
Map the OpenMP loop schedule to the runtime enumeration.
llvm::IntegerType * Int32Ty
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.
llvm::Function * GenerateCapturedStmtFunction(const CapturedStmt &S)
Creates the outlined function for a CapturedStmt.
virtual llvm::Value * getAddrOfThreadPrivate(CodeGenFunction &CGF, const VarDecl *VD, llvm::Value *VDAddr, SourceLocation Loc)
Returns address of the threadprivate variable for the current thread.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
Represents an unpacked "presumed" location which can be presented to the user.
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
The result type of a method or function.
OpenMPProcBindClauseKind
OpenMP attributes for 'proc_bind' clause.
static RecordDecl * createPrivatesRecordDecl(CodeGenModule &CGM, const ArrayRef< PrivateDataTy > Privates)
const Expr * getAnyInitializer() const
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeSet ExtraAttrs=llvm::AttributeSet())
Create a new runtime function with the specified type and name.
static llvm::Value * emitCopyprivateCopyFunction(CodeGenModule &CGM, llvm::Type *ArgsType, ArrayRef< const Expr * > CopyprivateVars, ArrayRef< const Expr * > DestExprs, ArrayRef< const Expr * > SrcExprs, ArrayRef< const Expr * > AssignmentOps)
This captures a statement into a function. For example, the following pragma annotated compound state...
const char * getFilename() const
Return the presumed filename of this location.
ASTContext & getContext() const
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr, QualType EltTy, bool isVolatile=false, CharUnits Alignment=CharUnits::Zero(), bool isAssignment=false)
This is a basic class for representing single OpenMP executable directive.
Lower bound for 'ordered' versions.
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result)
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
OpenMPDirectiveKind
OpenMP directives.
llvm::Constant * createDispatchFiniFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_dispatch_fini_* runtime function for the specified size IVSize and sign IVSigned...
virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc)
Emit code for 'taskwait' directive.
llvm::Constant * createDispatchNextFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_dispatch_next_* runtime function for the specified size IVSize and sign IVSigned...
virtual llvm::Function * emitThreadPrivateVarDefinition(const VarDecl *VD, llvm::Value *VDAddr, SourceLocation Loc, bool PerformInit, CodeGenFunction *CGF=nullptr)
Emit a code for initialization of threadprivate variable. It emits a call to runtime library which ad...
bool isTrivialInitializer(const Expr *Init)
Determine whether the given initializer is trivial in the sense that it requires no code to be genera...
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param IfCond Not a nullptr if if clause was nullptr *otherwise *param PrivateVars List of references to private variables for the task *directive *param PrivateCopies List of private copies for each private variable in *p PrivateVars *param FirstprivateVars List of references to private variables for the *task directive *param FirstprivateCopies List of private copies for each private variable *in p FirstprivateVars *param FirstprivateInits List of references to auto generated variables *used for initialization of a single array element Used if firstprivate *variable is of array type *param Dependences List of dependences for the task including *original expression and dependency type *virtual void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D, bool Tied, llvm::PointerIntPair< llvm::Value *, 1, bool > Final, llvm::Value *TaskFunction, QualType SharedsTy, llvm::Value *Shareds, const Expr *IfCond, ArrayRef< const Expr * > PrivateVars, ArrayRef< const Expr * > PrivateCopies, ArrayRef< const Expr * > FirstprivateVars, ArrayRef< const Expr * > FirstprivateCopies, ArrayRef< const Expr * > FirstprivateInits, ArrayRef< std::pair< OpenMPDependClauseKind, const Expr * >> Dependences)
const CodeGenOptions & getCodeGenOpts() const
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
const LangOptions & getLangOpts() const
llvm::AllocaInst * CreateMemTemp(QualType T, const Twine &Name="tmp")
llvm::Value * getCriticalRegionLock(StringRef CriticalName)
Returns corresponding lock object for the specified critical region name. If the lock object does not...
llvm::function_ref< void(CodeGenFunction &)> RegionCodeGenTy
llvm::Type * getKmpc_MicroPointerTy()
Returns pointer to kmpc_micro type.
void FinishFunction(SourceLocation EndLoc=SourceLocation())
OpenMPDebugLocMapTy OpenMPDebugLocMap
JumpDest getOMPCancelDestination(OpenMPDirectiveKind Kind)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
virtual llvm::Value * emitForNext(CodeGenFunction &CGF, SourceLocation Loc, unsigned IVSize, bool IVSigned, llvm::Value *IL, llvm::Value *LB, llvm::Value *UB, llvm::Value *ST)
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
void emitKmpRoutineEntryT(QualType KmpInt32Ty)
Build type kmp_routine_entry_t (if not built yet).
virtual void emitCancellationPointCall(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind CancelRegion)
Emit code for 'cancellation point' construct.
unsigned char PointerAlignInBytes
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
llvm::Type * KmpRoutineEntryPtrTy
Type typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *);.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, llvm::MDNode *TBAAInfo=nullptr, bool isInit=false, QualType TBAABaseTy=QualType(), uint64_t TBAAOffset=0)
const RecordType * getAsStructureType() const
virtual void emitInlinedDirective(CodeGenFunction &CGF, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)
Emit code for the directive that does not require outlining.
static void addFieldToRecordDecl(ASTContext &C, DeclContext *DC, QualType FieldTy)
API for captured statement code generation.
static bool classof(const OMPClause *T)
virtual void emitOrderedRegion(CodeGenFunction &CGF, const RegionCodeGenTy &OrderedOpGen, SourceLocation Loc)
Emit an ordered region.
This file defines OpenMP AST classes for executable directives and clauses.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T)
llvm::Constant * getOrCreateInternalVariable(llvm::Type *Ty, const llvm::Twine &Name)
Gets (if variable with the given name already exist) or creates internal global variable with the spe...
llvm::PointerType * Int8PtrTy
llvm::AssertingVH< llvm::Instruction > AllocaInsertPt
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
virtual llvm::Value * emitTaskOutlinedFunction(const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)
Emits outlined function for the OpenMP task directive D. This outlined function has type void(*)(kmp_...
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)
void addDecl(Decl *D)
Add the declaration D into this context.
SourceManager & getSourceManager()
bool isTLSSupported() const
Whether the target supports thread-local storage.
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
llvm::DenseSet< const VarDecl * > ThreadPrivateWithDefinition
Set of threadprivate variables with the generated initializer.
Lower bound for default (unordered) versions.
void EmitBranch(llvm::BasicBlock *Block)
llvm::Type * ConvertType(QualType T)
static void emitIfStmt(CodeGenFunction &CGF, llvm::Value *IfCond, OpenMPDirectiveKind Kind, const RegionCodeGenTy &BodyOpGen)
static RecordDecl * createKmpTaskTRecordDecl(CodeGenModule &CGM, QualType KmpInt32Ty, QualType KmpRoutineEntryPointerQTy)
LValue EmitLValue(const Expr *E)
void popTerminate()
Pops a terminate handler off the stack.
llvm::Type * getIdentTyPointerTy()
Returns pointer to ident_t type.
virtual void emitFlush(CodeGenFunction &CGF, ArrayRef< const Expr * > Vars, SourceLocation Loc)
Emit flush of the variables specified in 'omp flush' directive.
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
CGCapturedStmtInfo * CapturedStmtInfo
llvm::Function * CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty, const Twine &name, SourceLocation Loc=SourceLocation(), bool TLS=false)
static RValue get(llvm::Value *V)
static llvm::Value * emitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc, QualType KmpInt32Ty, QualType KmpTaskTWithPrivatesPtrQTy, QualType KmpTaskTWithPrivatesQTy, QualType KmpTaskTQTy, QualType SharedsPtrTy, llvm::Value *TaskFunction, llvm::Value *TaskPrivatesMap)
Emit a proxy function which accepts kmp_task_t as the second argument.
llvm::Value * EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, SourceLocation Loc, llvm::MDNode *TBAAInfo=nullptr, QualType TBAABaseTy=QualType(), uint64_t TBAAOffset=0)
virtual void emitNumThreadsClause(CodeGenFunction &CGF, llvm::Value *NumThreads, SourceLocation Loc)
Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid, kmp_int32 num_threads)...
void EmitBranchThroughCleanup(JumpDest Dest)
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
static RecordDecl * createKmpTaskTWithPrivatesRecordDecl(CodeGenModule &CGM, QualType KmpTaskTQTy, const ArrayRef< PrivateDataTy > Privates)
static int array_pod_sort_comparator(const PrivateDataTy *P1, const PrivateDataTy *P2)
void emitThreadPrivateVarInit(CodeGenFunction &CGF, llvm::Value *VDAddr, llvm::Value *Ctor, llvm::Value *CopyCtor, llvm::Value *Dtor, SourceLocation Loc)
Emits initialization code for the threadprivate variables.
virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const
Check if the specified ScheduleKind is dynamic. This kind of worksharing directive is emitted without...
llvm::Constant * createForStaticInitFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_for_static_init_* runtime function for the specified size IVSize and sign IVSigned...
void setAccess(AccessSpecifier AS)
bool isNull() const
isNull - Return true if this QualType doesn't point to a type yet.
static llvm::Value * emitTaskPrivateMappingFunction(CodeGenModule &CGM, SourceLocation Loc, const ArrayRef< const Expr * > PrivateVars, const ArrayRef< const Expr * > FirstprivateVars, QualType PrivatesQTy, const ArrayRef< PrivateDataTy > Privates)
Emit a privates mapping function for correct handling of private and firstprivate variables...
static FieldDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle)
Stmt * getAssociatedStmt() const
Returns statement associated with the directive.
llvm::StructType * IdentTy
bool Privatize()
Privatizes local variables previously registered as private. Registration is separate from the actual...
bool isPointerType() const
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.