23 #include "llvm/ADT/ArrayRef.h" 24 #include "llvm/Bitcode/BitcodeReader.h" 25 #include "llvm/IR/CallSite.h" 26 #include "llvm/IR/DerivedTypes.h" 27 #include "llvm/IR/GlobalValue.h" 28 #include "llvm/IR/Value.h" 29 #include "llvm/Support/Format.h" 30 #include "llvm/Support/raw_ostream.h" 33 using namespace clang;
34 using namespace CodeGen;
41 enum CGOpenMPRegionKind {
44 ParallelOutlinedRegion,
55 const CGOpenMPRegionKind RegionKind,
58 : CGCapturedStmtInfo(CS,
CR_OpenMP), RegionKind(RegionKind),
59 CodeGen(CodeGen), Kind(Kind), HasCancel(HasCancel) {}
61 CGOpenMPRegionInfo(
const CGOpenMPRegionKind RegionKind,
64 : CGCapturedStmtInfo(
CR_OpenMP), RegionKind(RegionKind), CodeGen(CodeGen),
65 Kind(Kind), HasCancel(HasCancel) {}
69 virtual const VarDecl *getThreadIDVariable()
const = 0;
80 CGOpenMPRegionKind getRegionKind()
const {
return RegionKind; }
84 bool hasCancel()
const {
return HasCancel; }
86 static bool classof(
const CGCapturedStmtInfo *Info) {
90 ~CGOpenMPRegionInfo()
override =
default;
93 CGOpenMPRegionKind RegionKind;
100 class CGOpenMPOutlinedRegionInfo final :
public CGOpenMPRegionInfo {
105 StringRef HelperName)
106 : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind,
108 ThreadIDVar(ThreadIDVar), HelperName(HelperName) {
109 assert(ThreadIDVar !=
nullptr &&
"No ThreadID in OpenMP region.");
114 const VarDecl *getThreadIDVariable()
const override {
return ThreadIDVar; }
117 StringRef getHelperName()
const override {
return HelperName; }
119 static bool classof(
const CGCapturedStmtInfo *Info) {
121 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
122 ParallelOutlinedRegion;
129 StringRef HelperName;
133 class CGOpenMPTaskOutlinedRegionInfo final :
public CGOpenMPRegionInfo {
139 llvm::SwitchInst *UntiedSwitch =
nullptr;
142 UntiedTaskActionTy(
bool Tied,
const VarDecl *PartIDVar,
144 : Untied(!Tied), PartIDVar(PartIDVar), UntiedCodeGen(UntiedCodeGen) {}
154 UntiedSwitch = CGF.
Builder.CreateSwitch(Res, DoneBB);
158 UntiedSwitch->addCase(CGF.
Builder.getInt32(0),
160 emitUntiedSwitch(CGF);
175 UntiedSwitch->addCase(CGF.
Builder.getInt32(UntiedSwitch->getNumCases()),
181 unsigned getNumberOfParts()
const {
return UntiedSwitch->getNumCases(); }
187 const UntiedTaskActionTy &Action)
188 : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen, Kind, HasCancel),
189 ThreadIDVar(ThreadIDVar), Action(Action) {
190 assert(ThreadIDVar !=
nullptr &&
"No ThreadID in OpenMP region.");
195 const VarDecl *getThreadIDVariable()
const override {
return ThreadIDVar; }
201 StringRef getHelperName()
const override {
return ".omp_outlined."; }
204 Action.emitUntiedSwitch(CGF);
207 static bool classof(
const CGCapturedStmtInfo *Info) {
209 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
218 const UntiedTaskActionTy &Action;
223 class CGOpenMPInlinedRegionInfo :
public CGOpenMPRegionInfo {
228 : CGOpenMPRegionInfo(InlinedRegion, CodeGen, Kind, HasCancel),
230 OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {}
235 return OuterRegionInfo->getContextValue();
236 llvm_unreachable(
"No context value for inlined OpenMP region");
240 if (OuterRegionInfo) {
241 OuterRegionInfo->setContextValue(V);
244 llvm_unreachable(
"No context value for inlined OpenMP region");
250 return OuterRegionInfo->lookup(VD);
256 FieldDecl *getThisFieldDecl()
const override {
258 return OuterRegionInfo->getThisFieldDecl();
264 const VarDecl *getThreadIDVariable()
const override {
266 return OuterRegionInfo->getThreadIDVariable();
273 return OuterRegionInfo->getThreadIDVariableLValue(CGF);
274 llvm_unreachable(
"No LValue for inlined OpenMP construct");
278 StringRef getHelperName()
const override {
279 if (
auto *OuterRegionInfo = getOldCSI())
280 return OuterRegionInfo->getHelperName();
281 llvm_unreachable(
"No helper name for inlined OpenMP construct");
286 OuterRegionInfo->emitUntiedSwitch(CGF);
291 static bool classof(
const CGCapturedStmtInfo *Info) {
293 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == InlinedRegion;
296 ~CGOpenMPInlinedRegionInfo()
override =
default;
301 CGOpenMPRegionInfo *OuterRegionInfo;
309 class CGOpenMPTargetRegionInfo final :
public CGOpenMPRegionInfo {
313 : CGOpenMPRegionInfo(CS, TargetRegion, CodeGen, OMPD_target,
315 HelperName(HelperName) {}
319 const VarDecl *getThreadIDVariable()
const override {
return nullptr; }
322 StringRef getHelperName()
const override {
return HelperName; }
324 static bool classof(
const CGCapturedStmtInfo *Info) {
326 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == TargetRegion;
330 StringRef HelperName;
334 llvm_unreachable(
"No codegen for expressions");
338 class CGOpenMPInnerExprInfo final :
public CGOpenMPInlinedRegionInfo {
341 : CGOpenMPInlinedRegionInfo(CGF.CapturedStmtInfo, EmptyCodeGen,
348 for (
const auto &C : CS.
captures()) {
349 if (!
C.capturesVariable() && !
C.capturesVariableByCopy())
352 const VarDecl *VD =
C.getCapturedVar();
360 PrivScope.addPrivate(
363 (void)PrivScope.Privatize();
368 if (
const FieldDecl *FD = CGOpenMPInlinedRegionInfo::lookup(VD))
375 llvm_unreachable(
"No body for expressions");
380 const VarDecl *getThreadIDVariable()
const override {
381 llvm_unreachable(
"No thread id for expressions");
385 StringRef getHelperName()
const override {
386 llvm_unreachable(
"No helper name for expressions");
389 static bool classof(
const CGCapturedStmtInfo *Info) {
return false; }
397 class InlinedOpenMPRegionRAII {
399 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
400 FieldDecl *LambdaThisCaptureField =
nullptr;
421 ~InlinedOpenMPRegionRAII() {
438 OMP_IDENT_IMD = 0x01,
440 OMP_IDENT_KMPC = 0x02,
442 OMP_ATOMIC_REDUCE = 0x10,
444 OMP_IDENT_BARRIER_EXPL = 0x20,
446 OMP_IDENT_BARRIER_IMPL = 0x40,
448 OMP_IDENT_BARRIER_IMPL_FOR = 0x40,
450 OMP_IDENT_BARRIER_IMPL_SECTIONS = 0xC0,
452 OMP_IDENT_BARRIER_IMPL_SINGLE = 0x140,
454 OMP_IDENT_WORK_LOOP = 0x200,
456 OMP_IDENT_WORK_SECTIONS = 0x400,
458 OMP_IDENT_WORK_DISTRIBUTE = 0x800,
459 LLVM_MARK_AS_BITMASK_ENUM(OMP_IDENT_WORK_DISTRIBUTE)
739 Callback(CodeGen, CGF, *PrePostAction);
742 Callback(CodeGen, CGF, Action);
750 if (
const auto *CE = dyn_cast<CallExpr>(ReductionOp))
751 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
752 if (
const auto *DRE =
753 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
754 if (
const auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl()))
765 std::pair<llvm::Function *, llvm::Function *> Reduction =
767 const auto *CE = cast<CallExpr>(InitOp);
768 const auto *OVE = cast<OpaqueValueExpr>(CE->getCallee());
772 cast<DeclRefExpr>(cast<UnaryOperator>(LHS)->getSubExpr());
774 cast<DeclRefExpr>(cast<UnaryOperator>(RHS)->getSubExpr());
776 PrivateScope.addPrivate(cast<VarDecl>(LHSDRE->getDecl()),
777 [=]() {
return Private; });
778 PrivateScope.addPrivate(cast<VarDecl>(RHSDRE->getDecl()),
779 [=]() {
return Original; });
780 (void)PrivateScope.Privatize();
787 auto *GV =
new llvm::GlobalVariable(
789 llvm::GlobalValue::PrivateLinkage, Init, Name);
835 SrcBegin = SrcAddr.getPointer();
843 CGF.
Builder.CreateICmpEQ(DestBegin, DestEnd,
"omp.arrayinit.isempty");
844 CGF.
Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
847 llvm::BasicBlock *EntryBB = CGF.
Builder.GetInsertBlock();
852 llvm::PHINode *SrcElementPHI =
nullptr;
855 SrcElementPHI = CGF.
Builder.CreatePHI(SrcBegin->getType(), 2,
856 "omp.arraycpy.srcElementPast");
857 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
860 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
862 llvm::PHINode *DestElementPHI = CGF.
Builder.CreatePHI(
863 DestBegin->getType(), 2,
"omp.arraycpy.destElementPast");
864 DestElementPHI->addIncoming(DestBegin, EntryBB);
872 if (EmitDeclareReductionInit) {
874 SrcElementCurrent, ElementTy);
883 SrcElementPHI, 1,
"omp.arraycpy.dest.element");
884 SrcElementPHI->addIncoming(SrcElementNext, CGF.
Builder.GetInsertBlock());
889 DestElementPHI, 1,
"omp.arraycpy.dest.element");
892 CGF.
Builder.CreateICmpEQ(DestElementNext, DestEnd,
"omp.arraycpy.done");
893 CGF.
Builder.CreateCondBr(Done, DoneBB, BodyBB);
894 DestElementPHI->addIncoming(DestElementNext, CGF.
Builder.GetInsertBlock());
906 if (
const auto *OASE = dyn_cast<OMPArraySectionExpr>(E))
911 void ReductionCodeGen::emitAggregateInitialization(
917 const auto *PrivateVD =
918 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
919 bool EmitDeclareReductionInit =
922 EmitDeclareReductionInit,
923 EmitDeclareReductionInit ? ClausesData[N].ReductionOp
924 : PrivateVD->getInit(),
931 ClausesData.reserve(Shareds.size());
932 SharedAddresses.reserve(Shareds.size());
933 Sizes.reserve(Shareds.size());
934 BaseDecls.reserve(Shareds.size());
935 auto IPriv = Privates.begin();
936 auto IRed = ReductionOps.begin();
937 for (
const Expr *Ref : Shareds) {
938 ClausesData.emplace_back(Ref, *IPriv, *IRed);
939 std::advance(IPriv, 1);
940 std::advance(IRed, 1);
945 assert(SharedAddresses.size() == N &&
946 "Number of generated lvalues must be exactly N.");
947 LValue First = emitSharedLValue(CGF, ClausesData[N].Ref);
948 LValue Second = emitSharedLValueUB(CGF, ClausesData[N].Ref);
949 SharedAddresses.emplace_back(First, Second);
953 const auto *PrivateVD =
954 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
955 QualType PrivateType = PrivateVD->getType();
956 bool AsArraySection = isa<OMPArraySectionExpr>(ClausesData[N].Ref);
957 if (!PrivateType->isVariablyModifiedType()) {
960 SharedAddresses[N].first.getType().getNonReferenceType()),
967 cast<llvm::PointerType>(SharedAddresses[N].first.getPointer()->getType())
969 auto *ElemSizeOf = llvm::ConstantExpr::getSizeOf(ElemType);
970 if (AsArraySection) {
971 Size = CGF.
Builder.CreatePtrDiff(SharedAddresses[N].second.getPointer(),
972 SharedAddresses[N].first.getPointer());
973 Size = CGF.
Builder.CreateNUWAdd(
974 Size, llvm::ConstantInt::get(Size->getType(), 1));
975 SizeInChars = CGF.
Builder.CreateNUWMul(Size, ElemSizeOf);
978 SharedAddresses[N].first.getType().getNonReferenceType());
979 Size = CGF.
Builder.CreateExactUDiv(SizeInChars, ElemSizeOf);
981 Sizes.emplace_back(SizeInChars, Size);
984 cast<OpaqueValueExpr>(
992 const auto *PrivateVD =
993 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
994 QualType PrivateType = PrivateVD->getType();
995 if (!PrivateType->isVariablyModifiedType()) {
996 assert(!Size && !Sizes[N].second &&
997 "Size should be nullptr for non-variably modified reduction " 1003 cast<OpaqueValueExpr>(
1012 assert(SharedAddresses.size() > N &&
"No variable was generated");
1013 const auto *PrivateVD =
1014 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1017 QualType PrivateType = PrivateVD->getType();
1020 QualType SharedType = SharedAddresses[N].first.getType();
1024 SharedType, SharedAddresses[N].first.getBaseInfo(),
1027 emitAggregateInitialization(CGF, N, PrivateAddr, SharedLVal, DRD);
1028 }
else if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
1032 }
else if (!DefaultInit(CGF) && PrivateVD->hasInit() &&
1035 PrivateVD->
getType().getQualifiers(),
1041 const auto *PrivateVD =
1042 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1043 QualType PrivateType = PrivateVD->getType();
1050 const auto *PrivateVD =
1051 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1052 QualType PrivateType = PrivateVD->getType();
1054 if (needCleanups(N)) {
1057 CGF.
pushDestroy(DTorKind, PrivateAddr, PrivateType);
1106 return Address(Addr, BaseLVAlignment);
1110 const VarDecl *OrigVD =
nullptr;
1111 if (
const auto *OASE = dyn_cast<OMPArraySectionExpr>(Ref)) {
1112 const Expr *
Base = OASE->getBase()->IgnoreParenImpCasts();
1113 while (
const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
1115 while (
const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
1117 DE = cast<DeclRefExpr>(
Base);
1118 OrigVD = cast<VarDecl>(DE->
getDecl());
1119 }
else if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(Ref)) {
1120 const Expr *
Base = ASE->getBase()->IgnoreParenImpCasts();
1121 while (
const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
1123 DE = cast<DeclRefExpr>(
Base);
1124 OrigVD = cast<VarDecl>(DE->
getDecl());
1133 BaseDecls.emplace_back(OrigVD);
1136 loadToBegin(CGF, OrigVD->getType(), SharedAddresses[N].first.getType(),
1137 OriginalBaseLValue);
1139 BaseLValue.
getPointer(), SharedAddresses[N].first.getPointer());
1143 SharedAddresses[N].first.getAddress().getType());
1146 SharedAddresses[N].first.getType(),
1150 BaseDecls.emplace_back(
1151 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Ref)->getDecl()));
1180 LValue CGOpenMPTaskOutlinedRegionInfo::getThreadIDVariableLValue(
1183 getThreadIDVariable()->
getType(),
1199 StringRef Separator)
1200 : CGM(CGM), FirstSeparator(FirstSeparator), Separator(Separator),
1219 KmpCriticalNameTy = llvm::ArrayType::get(CGM.
Int32Ty, 8);
1225 InternalVars.clear();
1230 llvm::raw_svector_ostream OS(Buffer);
1232 for (StringRef Part : Parts) {
1239 static llvm::Function *
1241 const Expr *CombinerInitializer,
const VarDecl *In,
1242 const VarDecl *Out,
bool IsCombiner) {
1251 Args.push_back(&OmpOutParm);
1252 Args.push_back(&OmpInParm);
1257 {IsCombiner ?
"omp_combiner" :
"omp_initializer",
""});
1261 Fn->removeFnAttr(llvm::Attribute::NoInline);
1262 Fn->removeFnAttr(llvm::Attribute::OptimizeNone);
1263 Fn->addFnAttr(llvm::Attribute::AlwaysInline);
1271 Scope.
addPrivate(In, [&CGF, AddrIn, PtrTy]() {
1276 Scope.
addPrivate(Out, [&CGF, AddrOut, PtrTy]() {
1281 if (!IsCombiner && Out->
hasInit() &&
1287 if (CombinerInitializer)
1296 if (UDRMap.count(D) > 0)
1307 llvm::Function *Initializer =
nullptr;
1309 if (!Priv || !Orig) {
1321 UDRMap.try_emplace(D, Combiner, Initializer);
1323 auto &Decls = FunctionUDRMap.FindAndConstruct(CGF->
CurFn);
1324 Decls.second.push_back(D);
1328 std::pair<llvm::Function *, llvm::Function *>
1330 auto I = UDRMap.find(D);
1331 if (I != UDRMap.end())
1334 return UDRMap.lookup(D);
1342 "thread id variable must be of type kmp_int32 *");
1344 bool HasCancel =
false;
1345 if (
const auto *OPD = dyn_cast<OMPParallelDirective>(&D))
1346 HasCancel = OPD->hasCancel();
1347 else if (
const auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&D))
1348 HasCancel = OPSD->hasCancel();
1349 else if (
const auto *OPFD = dyn_cast<OMPParallelForDirective>(&D))
1350 HasCancel = OPFD->hasCancel();
1351 else if (
const auto *OPFD = dyn_cast<OMPTargetParallelForDirective>(&D))
1352 HasCancel = OPFD->hasCancel();
1353 else if (
const auto *OPFD = dyn_cast<OMPDistributeParallelForDirective>(&D))
1354 HasCancel = OPFD->hasCancel();
1355 else if (
const auto *OPFD =
1356 dyn_cast<OMPTeamsDistributeParallelForDirective>(&D))
1357 HasCancel = OPFD->hasCancel();
1358 else if (
const auto *OPFD =
1359 dyn_cast<OMPTargetTeamsDistributeParallelForDirective>(&D))
1360 HasCancel = OPFD->hasCancel();
1361 CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind,
1362 HasCancel, OutlinedHelperName);
1364 return CGF.GenerateOpenMPCapturedStmtFunction(*CS);
1387 bool Tied,
unsigned &NumberOfParts) {
1394 CGF.EmitLoadOfPointerLValue(CGF.GetAddrOfLocalVar(TaskTVar),
1399 CGOpenMPTaskOutlinedRegionInfo::UntiedTaskActionTy Action(Tied, PartIDVar,
1403 "thread id variable must be of type kmp_int32 for tasks");
1410 CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen,
1412 TD ? TD->hasCancel() :
false, Action);
1414 llvm::Value *Res = CGF.GenerateCapturedStmtFunction(*CS);
1416 NumberOfParts = Action.getNumberOfParts();
1422 ArrayRef<llvm::Constant *> Data) {
1424 unsigned PrevIdx = 0;
1426 auto DI = Data.begin();
1430 for (
unsigned I = PrevIdx; I < Idx; ++I)
1431 Fields.add(llvm::Constant::getNullValue(StructTy->getElementType(I)));
1438 template <
class... As>
1439 static llvm::GlobalVariable *
1441 ArrayRef<llvm::Constant *> Data,
const Twine &Name,
1450 true, std::forward<As>(Args)...);
1453 template <
typename T>
1456 ArrayRef<llvm::Constant *> Data,
1465 Address CGOpenMPRuntime::getOrCreateDefaultLocation(
unsigned Flags) {
1467 llvm::Value *Entry = OpenMPDefaultLocMap.lookup(Flags);
1469 if (!DefaultOpenMPPSource) {
1474 DefaultOpenMPPSource =
1476 DefaultOpenMPPSource =
1477 llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource,
CGM.
Int8PtrTy);
1480 llvm::Constant *Data[] = {llvm::ConstantInt::getNullValue(
CGM.
Int32Ty),
1482 llvm::ConstantInt::getNullValue(
CGM.
Int32Ty),
1483 llvm::ConstantInt::getNullValue(
CGM.
Int32Ty),
1484 DefaultOpenMPPSource};
1486 CGM, IdentQTy, Data,
"", llvm::GlobalValue::PrivateLinkage);
1487 DefaultOpenMPLocation->setUnnamedAddr(
1488 llvm::GlobalValue::UnnamedAddr::Global);
1490 OpenMPDefaultLocMap[Flags] = Entry = DefaultOpenMPLocation;
1498 Flags |= OMP_IDENT_KMPC;
1502 return getOrCreateDefaultLocation(Flags).
getPointer();
1504 assert(CGF.
CurFn &&
"No function in current CodeGenFunction.");
1508 auto I = OpenMPLocThreadIDMap.find(CGF.
CurFn);
1509 if (I != OpenMPLocThreadIDMap.end())
1510 LocValue =
Address(I->second.DebugLoc, Align);
1517 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.
CurFn);
1521 CGBuilderTy::InsertPointGuard IPG(CGF.
Builder);
1529 auto Fields = cast<RecordDecl>(IdentQTy->
getAsTagDecl())->field_begin();
1534 if (OMPDebugLoc ==
nullptr) {
1536 llvm::raw_svector_ostream OS2(Buffer2);
1540 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(CGF.
CurFuncDecl))
1541 OS2 << FD->getQualifiedNameAsString();
1543 OMPDebugLoc = CGF.
Builder.CreateGlobalStringPtr(OS2.str());
1556 assert(CGF.
CurFn &&
"No function in current CodeGenFunction.");
1561 auto I = OpenMPLocThreadIDMap.find(CGF.
CurFn);
1562 if (I != OpenMPLocThreadIDMap.end()) {
1563 ThreadID = I->second.ThreadID;
1564 if (ThreadID !=
nullptr)
1571 if (
auto *OMPRegionInfo =
1573 if (OMPRegionInfo->getThreadIDVariable()) {
1575 LValue LVal = OMPRegionInfo->getThreadIDVariableLValue(CGF);
1580 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.
CurFn);
1581 Elem.second.ThreadID = ThreadID;
1592 CGBuilderTy::InsertPointGuard IPG(CGF.
Builder);
1594 llvm::CallInst *Call = CGF.
Builder.CreateCall(
1598 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.
CurFn);
1599 Elem.second.ThreadID = Call;
1604 assert(CGF.
CurFn &&
"No function in current CodeGenFunction.");
1605 if (OpenMPLocThreadIDMap.count(CGF.
CurFn))
1606 OpenMPLocThreadIDMap.erase(CGF.
CurFn);
1607 if (FunctionUDRMap.count(CGF.
CurFn) > 0) {
1608 for(
auto *D : FunctionUDRMap[CGF.
CurFn])
1610 FunctionUDRMap.erase(CGF.
CurFn);
1615 return IdentTy->getPointerTo();
1619 if (!Kmpc_MicroTy) {
1623 Kmpc_MicroTy = llvm::FunctionType::get(
CGM.
VoidTy, MicroParams,
true);
1625 return llvm::PointerType::getUnqual(Kmpc_MicroTy);
1630 llvm::Constant *RTLFn =
nullptr;
1631 switch (static_cast<OpenMPRTLFunction>(Function)) {
1638 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
true);
1646 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1657 llvm::FunctionType::get(
CGM.
VoidPtrTy, TypeParams,
false);
1666 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1668 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1676 llvm::PointerType::getUnqual(KmpCriticalNameTy),
1679 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1689 false)->getPointerTo();
1692 auto *KmpcCopyCtorTy =
1693 llvm::FunctionType::get(
CGM.
VoidPtrTy, KmpcCopyCtorTyArgs,
1701 KmpcCopyCtorTy, KmpcDtorTy};
1702 auto *FnTy = llvm::FunctionType::get(
CGM.
VoidTy, FnTyArgs,
1712 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1714 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1723 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1731 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1739 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1749 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1758 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1767 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1775 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1783 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1791 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1800 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1808 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1816 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1824 assert(KmpRoutineEntryPtrTy !=
nullptr &&
1825 "Type kmp_routine_entry_t must be created.");
1830 llvm::FunctionType::get(
CGM.
VoidPtrTy, TypeParams,
false);
1840 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1850 llvm::FunctionType::get(
CGM.
VoidTy, CpyTypeParams,
false);
1855 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1864 auto *ReduceFnTy = llvm::FunctionType::get(
CGM.
VoidTy, ReduceTypeParams,
1869 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1871 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1881 auto *ReduceFnTy = llvm::FunctionType::get(
CGM.
VoidTy, ReduceTypeParams,
1886 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1888 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1897 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1899 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1908 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1910 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1921 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1932 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1934 "__kmpc_omp_task_complete_if0");
1941 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1949 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1957 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1965 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1973 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1982 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1994 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2007 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2016 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2025 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2035 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2045 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
true);
2065 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2077 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2085 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2095 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2105 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2114 llvm::FunctionType::get(
CGM.
VoidPtrTy, TypeParams,
false);
2124 llvm::FunctionType::get(
CGM.
VoidPtrTy, TypeParams,
false);
2126 FnTy,
"__kmpc_task_reduction_get_th_data");
2141 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2157 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2175 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2193 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2203 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2213 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2227 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2242 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2256 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2271 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2285 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2300 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2305 assert(RTLFn &&
"Unable to find OpenMP runtime function");
2311 assert((IVSize == 32 || IVSize == 64) &&
2312 "IV size is not compatible with the omp runtime");
2313 StringRef Name = IVSize == 32 ? (IVSigned ?
"__kmpc_for_static_init_4" 2314 :
"__kmpc_for_static_init_4u")
2315 : (IVSigned ?
"__kmpc_for_static_init_8" 2316 :
"__kmpc_for_static_init_8u");
2318 auto *PtrTy = llvm::PointerType::getUnqual(ITy);
2331 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2337 assert((IVSize == 32 || IVSize == 64) &&
2338 "IV size is not compatible with the omp runtime");
2341 ? (IVSigned ?
"__kmpc_dispatch_init_4" :
"__kmpc_dispatch_init_4u")
2342 : (IVSigned ?
"__kmpc_dispatch_init_8" :
"__kmpc_dispatch_init_8u");
2353 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2359 assert((IVSize == 32 || IVSize == 64) &&
2360 "IV size is not compatible with the omp runtime");
2363 ? (IVSigned ?
"__kmpc_dispatch_fini_4" :
"__kmpc_dispatch_fini_4u")
2364 : (IVSigned ?
"__kmpc_dispatch_fini_8" :
"__kmpc_dispatch_fini_8u");
2370 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2376 assert((IVSize == 32 || IVSize == 64) &&
2377 "IV size is not compatible with the omp runtime");
2380 ? (IVSigned ?
"__kmpc_dispatch_next_4" :
"__kmpc_dispatch_next_4u")
2381 : (IVSigned ?
"__kmpc_dispatch_next_8" :
"__kmpc_dispatch_next_8u");
2383 auto *PtrTy = llvm::PointerType::getUnqual(ITy);
2393 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2401 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2402 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
2405 llvm::raw_svector_ostream OS(PtrName);
2414 auto *GV = cast<llvm::GlobalVariable>(Ptr);
2431 std::string Suffix =
getName({
"cache",
""});
2467 Ctor, CopyCtor, Dtor};
2484 llvm::Value *Ctor =
nullptr, *CopyCtor =
nullptr, *Dtor =
nullptr;
2494 Args.push_back(&Dst);
2499 std::string Name =
getName({
"__kmpc_global_ctor_",
""});
2500 llvm::Function *Fn =
2527 Args.push_back(&Dst);
2532 std::string Name =
getName({
"__kmpc_global_dtor_",
""});
2533 llvm::Function *Fn =
2554 auto *CopyCtorTy = llvm::FunctionType::get(
CGM.
VoidPtrTy, CopyCtorTyArgs,
2560 CopyCtor = llvm::Constant::getNullValue(CopyCtorTy);
2561 if (Ctor ==
nullptr) {
2565 Ctor = llvm::Constant::getNullValue(CtorTy);
2567 if (Dtor ==
nullptr) {
2571 Dtor = llvm::Constant::getNullValue(DtorTy);
2574 auto *InitFunctionTy =
2575 llvm::FunctionType::get(
CGM.
VoidTy,
false);
2576 std::string Name =
getName({
"__omp_threadprivate_init_",
""});
2586 return InitFunction;
2597 unsigned &DeviceID,
unsigned &
FileID,
2598 unsigned &LineNum) {
2604 assert(Loc.
isValid() &&
"Source location is expected to be always valid.");
2607 assert(PLoc.isValid() &&
"Source location is expected to be always valid.");
2609 llvm::sys::fs::UniqueID
ID;
2610 if (
auto EC = llvm::sys::fs::getUniqueID(PLoc.getFilename(),
ID))
2612 << PLoc.getFilename() << EC.message();
2614 DeviceID = ID.getDevice();
2615 FileID = ID.getFile();
2616 LineNum = PLoc.getLine();
2620 llvm::GlobalVariable *Addr,
2623 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2624 if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link)
2642 llvm::raw_svector_ostream OS(Buffer);
2643 OS <<
"__omp_offloading_" << llvm::format(
"_%x", DeviceID)
2644 << llvm::format(
"_%x_", FileID) << VD->
getName() <<
"_l" <<
Line;
2649 llvm::Constant *Ctor;
2659 FTy, Twine(Buffer,
"_ctor"), FI, Loc);
2670 ID = llvm::ConstantExpr::getBitCast(Fn,
CGM.
Int8PtrTy);
2673 Ctor =
new llvm::GlobalVariable(
2675 llvm::GlobalValue::PrivateLinkage,
2676 llvm::Constant::getNullValue(
CGM.
Int8Ty), Twine(Buffer,
"_ctor"));
2683 DeviceID, FileID, Twine(Buffer,
"_ctor").toStringRef(Out), Line, Ctor,
2687 llvm::Constant *Dtor;
2697 FTy, Twine(Buffer,
"_dtor"), FI, Loc);
2709 ID = llvm::ConstantExpr::getBitCast(Fn,
CGM.
Int8PtrTy);
2712 Dtor =
new llvm::GlobalVariable(
2714 llvm::GlobalValue::PrivateLinkage,
2715 llvm::Constant::getNullValue(
CGM.
Int8Ty), Twine(Buffer,
"_dtor"));
2721 DeviceID, FileID, Twine(Buffer,
"_dtor").toStringRef(Out), Line, Dtor,
2730 std::string Suffix =
getName({
"artificial",
""});
2731 std::string CacheSuffix =
getName({
"cache",
""});
2747 VarLVType->getPointerTo(0)),
2793 const Expr *IfCond) {
2797 auto &&ThenGen = [OutlinedFn, CapturedVars, RTLoc](
CodeGenFunction &CGF,
2803 CGF.Builder.getInt32(CapturedVars.size()),
2804 CGF.Builder.CreateBitCast(OutlinedFn, RT.getKmpc_MicroPointerTy())};
2806 RealArgs.append(std::begin(Args), std::end(Args));
2807 RealArgs.append(CapturedVars.begin(), CapturedVars.end());
2810 CGF.EmitRuntimeCall(RTLFn, RealArgs);
2812 auto &&ElseGen = [OutlinedFn, CapturedVars, RTLoc, Loc](
CodeGenFunction &CGF,
2819 CGF.EmitRuntimeCall(
2823 Address ZeroAddr = CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty,
2825 CGF.InitTempAlloca(ZeroAddr, CGF.Builder.getInt32( 0));
2828 OutlinedFnArgs.push_back(ZeroAddr.
getPointer());
2829 OutlinedFnArgs.push_back(ZeroAddr.
getPointer());
2830 OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
2831 RT.emitOutlinedFunctionCall(CGF, Loc, OutlinedFn, OutlinedFnArgs);
2835 CGF.EmitRuntimeCall(
2855 if (
auto *OMPRegionInfo =
2857 if (OMPRegionInfo->getThreadIDVariable())
2858 return OMPRegionInfo->getThreadIDVariableLValue(CGF).getAddress();
2867 return ThreadIDTemp;
2872 const llvm::Twine &Name) {
2874 llvm::raw_svector_ostream Out(Buffer);
2876 StringRef RuntimeName = Out.str();
2877 auto &Elem = *InternalVars.try_emplace(RuntimeName,
nullptr).first;
2879 assert(Elem.second->getType()->getPointerElementType() == Ty &&
2880 "OMP internal variable has different type than requested");
2881 return &*Elem.second;
2884 return Elem.second =
new llvm::GlobalVariable(
2886 llvm::GlobalValue::CommonLinkage, llvm::Constant::getNullValue(Ty),
2891 std::string Prefix = Twine(
"gomp_critical_user_", CriticalName).str();
2892 std::string Name =
getName({Prefix,
"var"});
2904 llvm::BasicBlock *ContBlock =
nullptr;
2909 bool Conditional =
false)
2910 : EnterCallee(EnterCallee), EnterArgs(EnterArgs), ExitCallee(ExitCallee),
2919 CGF.
Builder.CreateCondBr(CallBool, ThenBlock, ContBlock);
2935 StringRef CriticalName,
2949 EnterArgs.push_back(CGF.
Builder.CreateIntCast(
2952 CommonActionTy Action(
2986 llvm::ConstantInt::get(
CGM.
IntTy, 0,
true)};
2988 if (
auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.
CapturedStmtInfo))
2989 Region->emitUntiedSwitch(CGF);
3012 unsigned Index,
const VarDecl *Var) {
3026 ArrayRef<const Expr *> CopyprivateVars, ArrayRef<const Expr *> DestExprs,
3027 ArrayRef<const Expr *> SrcExprs, ArrayRef<const Expr *> AssignmentOps,
3036 Args.push_back(&LHSArg);
3037 Args.push_back(&RHSArg);
3046 Fn->setDoesNotRecurse();
3061 for (
unsigned I = 0, E = AssignmentOps.size(); I < E; ++I) {
3062 const auto *DestVar =
3063 cast<VarDecl>(cast<DeclRefExpr>(DestExprs[I])->getDecl());
3066 const auto *SrcVar =
3067 cast<VarDecl>(cast<DeclRefExpr>(SrcExprs[I])->getDecl());
3070 const auto *VD = cast<DeclRefExpr>(CopyprivateVars[I])->getDecl();
3072 CGF.
EmitOMPCopy(Type, DestAddr, SrcAddr, DestVar, SrcVar, AssignmentOps[I]);
3081 ArrayRef<const Expr *> CopyprivateVars,
3082 ArrayRef<const Expr *> SrcExprs,
3083 ArrayRef<const Expr *> DstExprs,
3084 ArrayRef<const Expr *> AssignmentOps) {
3087 assert(CopyprivateVars.size() == SrcExprs.size() &&
3088 CopyprivateVars.size() == DstExprs.size() &&
3089 CopyprivateVars.size() == AssignmentOps.size());
3101 if (!CopyprivateVars.empty()) {
3104 C.getIntTypeForBitwidth(32, 1);
3105 DidIt = CGF.
CreateMemTemp(KmpInt32Ty,
".omp.copyprivate.did_it");
3123 llvm::APInt ArraySize(32, CopyprivateVars.size());
3129 CGF.
CreateMemTemp(CopyprivateArrayTy,
".omp.copyprivate.cpr_list");
3130 for (
unsigned I = 0, E = CopyprivateVars.size(); I < E; ++I) {
3142 CopyprivateVars, SrcExprs, DstExprs, AssignmentOps, Loc);
3183 bool ForceSimpleCall) {
3189 if (Kind == OMPD_for)
3190 Flags = OMP_IDENT_BARRIER_IMPL_FOR;
3191 else if (Kind == OMPD_sections)
3192 Flags = OMP_IDENT_BARRIER_IMPL_SECTIONS;
3193 else if (Kind == OMPD_single)
3194 Flags = OMP_IDENT_BARRIER_IMPL_SINGLE;
3195 else if (Kind == OMPD_barrier)
3196 Flags = OMP_IDENT_BARRIER_EXPL;
3198 Flags = OMP_IDENT_BARRIER_IMPL;
3203 if (
auto *OMPRegionInfo =
3205 if (!ForceSimpleCall && OMPRegionInfo->hasCancel()) {
3215 CGF.
Builder.CreateCondBr(Cmp, ExitBB, ContBB);
3231 bool Chunked,
bool Ordered) {
3232 switch (ScheduleKind) {
3233 case OMPC_SCHEDULE_static:
3236 case OMPC_SCHEDULE_dynamic:
3238 case OMPC_SCHEDULE_guided:
3240 case OMPC_SCHEDULE_runtime:
3242 case OMPC_SCHEDULE_auto:
3245 assert(!Chunked &&
"chunk was specified but schedule kind not known");
3248 llvm_unreachable(
"Unexpected runtime schedule");
3259 bool Chunked)
const {
3284 case OMPC_SCHEDULE_MODIFIER_monotonic:
3287 case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
3290 case OMPC_SCHEDULE_MODIFIER_simd:
3299 case OMPC_SCHEDULE_MODIFIER_monotonic:
3302 case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
3305 case OMPC_SCHEDULE_MODIFIER_simd:
3323 ScheduleKind.
Schedule, DispatchValues.
Chunk !=
nullptr, Ordered);
3335 : CGF.
Builder.getIntN(IVSize, 1);
3339 Schedule, ScheduleKind.
M1, ScheduleKind.
M2)),
3342 CGF.
Builder.getIntN(IVSize, 1),
3352 const CGOpenMPRuntime::StaticRTInput &Values) {
3356 assert(!Values.Ordered);
3369 if (Chunk ==
nullptr) {
3372 "expected static non-chunked schedule");
3374 Chunk = CGF.
Builder.getIntN(Values.IVSize, 1);
3380 "expected static chunked schedule");
3387 Values.IL.getPointer(),
3388 Values.LB.getPointer(),
3389 Values.UB.getPointer(),
3390 Values.ST.getPointer(),
3391 CGF.
Builder.getIntN(Values.IVSize, 1),
3405 "Expected loop-based or sections-based directive.");
3408 ? OMP_IDENT_WORK_LOOP
3409 : OMP_IDENT_WORK_SECTIONS);
3411 llvm::Constant *StaticInitFunction =
3414 ScheduleNum, ScheduleKind.
M1, ScheduleKind.
M2, Values);
3420 const CGOpenMPRuntime::StaticRTInput &Values) {
3426 llvm::Constant *StaticInitFunction =
3442 ? OMP_IDENT_WORK_DISTRIBUTE
3444 ? OMP_IDENT_WORK_LOOP
3445 : OMP_IDENT_WORK_SECTIONS),
3515 case OMPC_PROC_BIND_master:
3516 RuntimeProcBind = ProcBindMaster;
3518 case OMPC_PROC_BIND_close:
3519 RuntimeProcBind = ProcBindClose;
3521 case OMPC_PROC_BIND_spread:
3522 RuntimeProcBind = ProcBindSpread;
3525 llvm_unreachable(
"Unsupported proc_bind value.");
3530 llvm::ConstantInt::get(
CGM.
IntTy, RuntimeProcBind,
true)};
3569 bool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::empty()
const {
3570 return OffloadEntriesTargetRegion.empty() &&
3571 OffloadEntriesDeviceGlobalVar.empty();
3575 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3576 initializeTargetRegionEntryInfo(
unsigned DeviceID,
unsigned FileID,
3577 StringRef ParentName,
unsigned LineNum,
3579 assert(
CGM.
getLangOpts().OpenMPIsDevice &&
"Initialization of entries is " 3580 "only required for the device " 3581 "code generation.");
3582 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] =
3583 OffloadEntryInfoTargetRegion(Order,
nullptr,
nullptr,
3584 OMPTargetRegionEntryTargetRegion);
3585 ++OffloadingEntriesNum;
3588 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3589 registerTargetRegionEntryInfo(
unsigned DeviceID,
unsigned FileID,
3590 StringRef ParentName,
unsigned LineNum,
3591 llvm::Constant *Addr, llvm::Constant *
ID,
3592 OMPTargetRegionEntryKind Flags) {
3596 if (!hasTargetRegionEntryInfo(DeviceID, FileID, ParentName, LineNum)) {
3599 "Unable to find target region on line '%0' in the device code.");
3604 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum];
3605 assert(Entry.isValid() &&
"Entry not initialized!");
3606 Entry.setAddress(Addr);
3608 Entry.setFlags(Flags);
3610 OffloadEntryInfoTargetRegion Entry(OffloadingEntriesNum, Addr, ID, Flags);
3611 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] = Entry;
3612 ++OffloadingEntriesNum;
3616 bool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::hasTargetRegionEntryInfo(
3617 unsigned DeviceID,
unsigned FileID, StringRef ParentName,
3618 unsigned LineNum)
const {
3619 auto PerDevice = OffloadEntriesTargetRegion.find(DeviceID);
3620 if (PerDevice == OffloadEntriesTargetRegion.end())
3622 auto PerFile = PerDevice->second.find(FileID);
3623 if (PerFile == PerDevice->second.end())
3625 auto PerParentName = PerFile->second.find(ParentName);
3626 if (PerParentName == PerFile->second.end())
3628 auto PerLine = PerParentName->second.find(LineNum);
3629 if (PerLine == PerParentName->second.end())
3632 if (PerLine->second.getAddress() || PerLine->second.getID())
3637 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::actOnTargetRegionEntriesInfo(
3638 const OffloadTargetRegionEntryInfoActTy &Action) {
3640 for (
const auto &D : OffloadEntriesTargetRegion)
3641 for (
const auto &F : D.second)
3642 for (
const auto &
P : F.second)
3643 for (
const auto &L :
P.second)
3644 Action(D.first, F.first,
P.first(), L.first, L.second);
3647 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3648 initializeDeviceGlobalVarEntryInfo(StringRef Name,
3649 OMPTargetGlobalVarEntryKind Flags,
3651 assert(
CGM.
getLangOpts().OpenMPIsDevice &&
"Initialization of entries is " 3652 "only required for the device " 3653 "code generation.");
3654 OffloadEntriesDeviceGlobalVar.try_emplace(Name, Order, Flags);
3655 ++OffloadingEntriesNum;
3658 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3659 registerDeviceGlobalVarEntryInfo(StringRef VarName, llvm::Constant *Addr,
3661 OMPTargetGlobalVarEntryKind Flags,
3662 llvm::GlobalValue::LinkageTypes
Linkage) {
3664 auto &Entry = OffloadEntriesDeviceGlobalVar[VarName];
3665 assert(Entry.isValid() && Entry.getFlags() == Flags &&
3666 "Entry not initialized!");
3667 assert((!Entry.getAddress() || Entry.getAddress() == Addr) &&
3668 "Resetting with the new address.");
3669 if (Entry.getAddress() && hasDeviceGlobalVarEntryInfo(VarName))
3671 Entry.setAddress(Addr);
3672 Entry.setVarSize(VarSize);
3673 Entry.setLinkage(Linkage);
3675 if (hasDeviceGlobalVarEntryInfo(VarName))
3677 OffloadEntriesDeviceGlobalVar.try_emplace(
3678 VarName, OffloadingEntriesNum, Addr, VarSize, Flags, Linkage);
3679 ++OffloadingEntriesNum;
3683 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3684 actOnDeviceGlobalVarEntriesInfo(
3685 const OffloadDeviceGlobalVarEntryInfoActTy &Action) {
3687 for (
const auto &E : OffloadEntriesDeviceGlobalVar)
3688 Action(E.getKey(), E.getValue());
3706 assert(!Devices.empty() &&
"No OpenMP offloading devices??");
3712 std::string EntriesBeginName =
getName({
"omp_offloading",
"entries_begin"});
3713 auto *HostEntriesBegin =
new llvm::GlobalVariable(
3714 M, OffloadEntryTy,
true,
3717 std::string EntriesEndName =
getName({
"omp_offloading",
"entries_end"});
3718 auto *HostEntriesEnd =
3719 new llvm::GlobalVariable(M, OffloadEntryTy,
true,
3721 nullptr, EntriesEndName);
3724 auto *DeviceImageTy = cast<llvm::StructType>(
3728 DeviceImagesBuilder.
beginArray(DeviceImageTy);
3730 for (
const llvm::Triple &Device : Devices) {
3731 StringRef T = Device.getTriple();
3732 std::string BeginName =
getName({
"omp_offloading",
"img_start",
""});
3733 auto *ImgBegin =
new llvm::GlobalVariable(
3735 llvm::GlobalValue::ExternalWeakLinkage,
3736 nullptr, Twine(BeginName).concat(T));
3737 std::string EndName =
getName({
"omp_offloading",
"img_end",
""});
3738 auto *ImgEnd =
new llvm::GlobalVariable(
3740 llvm::GlobalValue::ExternalWeakLinkage,
3741 nullptr, Twine(EndName).concat(T));
3743 llvm::Constant *Data[] = {ImgBegin, ImgEnd, HostEntriesBegin,
3746 DeviceImagesEntries);
3750 std::string ImagesName =
getName({
"omp_offloading",
"device_images"});
3751 llvm::GlobalVariable *DeviceImages =
3755 DeviceImages->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3758 llvm::Constant *Index[] = {llvm::Constant::getNullValue(
CGM.
Int32Ty),
3762 llvm::Constant *Data[] = {
3763 llvm::ConstantInt::get(
CGM.
Int32Ty, Devices.size()),
3764 llvm::ConstantExpr::getGetElementPtr(DeviceImages->getValueType(),
3765 DeviceImages, Index),
3766 HostEntriesBegin, HostEntriesEnd};
3767 std::string Descriptor =
getName({
"omp_offloading",
"descriptor"});
3774 llvm::Function *UnRegFn;
3778 Args.push_back(&DummyPtr);
3787 std::string UnregName =
getName({
"omp_offloading",
"descriptor_unreg"});
3794 llvm::Function *RegFn;
3802 std::string Descriptor =
getName({
"omp_offloading",
"descriptor_reg"});
3819 llvm::Comdat *ComdatKey = M.getOrInsertComdat(RegFn->getName());
3820 RegFn->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage);
3822 RegFn->setComdat(ComdatKey);
3823 UnRegFn->setComdat(ComdatKey);
3824 DeviceImages->setComdat(ComdatKey);
3825 Desc->setComdat(ComdatKey);
3831 llvm::Constant *ID, llvm::Constant *Addr, uint64_t Size, int32_t Flags,
3832 llvm::GlobalValue::LinkageTypes Linkage) {
3833 StringRef Name = Addr->getName();
3835 llvm::LLVMContext &C = M.getContext();
3838 llvm::Constant *StrPtrInit = llvm::ConstantDataArray::getString(C, Name);
3840 std::string StringName =
getName({
"omp_offloading",
"entry_name"});
3841 auto *Str =
new llvm::GlobalVariable(
3842 M, StrPtrInit->getType(),
true,
3844 Str->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3846 llvm::Constant *Data[] = {llvm::ConstantExpr::getBitCast(ID,
CGM.
VoidPtrTy),
3848 llvm::ConstantInt::get(
CGM.
SizeTy, Size),
3851 std::string EntryName =
getName({
"omp_offloading",
"entry",
""});
3854 llvm::GlobalValue::WeakAnyLinkage);
3857 std::string Section =
getName({
"omp_offloading",
"entries"});
3858 Entry->setSection(Section);
3876 llvm::LLVMContext &C = M.getContext();
3881 auto &&GetMDInt = [
this](
unsigned V) {
3882 return llvm::ConstantAsMetadata::get(
3886 auto &&GetMDString = [&C](StringRef V) {
return llvm::MDString::get(C, V); };
3889 llvm::NamedMDNode *MD = M.getOrInsertNamedMetadata(
"omp_offload.info");
3892 auto &&TargetRegionMetadataEmitter =
3893 [&C, MD, &OrderedEntries, &GetMDInt, &GetMDString](
3894 unsigned DeviceID,
unsigned FileID, StringRef ParentName,
3907 llvm::Metadata *Ops[] = {GetMDInt(E.getKind()), GetMDInt(DeviceID),
3908 GetMDInt(FileID), GetMDString(ParentName),
3909 GetMDInt(Line), GetMDInt(E.getOrder())};
3912 OrderedEntries[E.getOrder()] = &E;
3915 MD->addOperand(llvm::MDNode::get(C, Ops));
3919 TargetRegionMetadataEmitter);
3922 auto &&DeviceGlobalVarMetadataEmitter =
3923 [&C, &OrderedEntries, &GetMDInt, &GetMDString,
3924 MD](StringRef MangledName,
3934 llvm::Metadata *Ops[] = {
3935 GetMDInt(E.getKind()), GetMDString(MangledName),
3936 GetMDInt(E.getFlags()), GetMDInt(E.getOrder())};
3939 OrderedEntries[E.getOrder()] = &E;
3942 MD->addOperand(llvm::MDNode::get(C, Ops));
3946 DeviceGlobalVarMetadataEmitter);
3948 for (
const auto *E : OrderedEntries) {
3949 assert(E &&
"All ordered entries must exist!");
3950 if (
const auto *CE =
3951 dyn_cast<OffloadEntriesInfoManagerTy::OffloadEntryInfoTargetRegion>(
3953 if (!CE->getID() || !CE->getAddress()) {
3956 "Offloading entry for target region is incorrect: either the " 3957 "address or the ID is invalid.");
3962 CE->getFlags(), llvm::GlobalValue::WeakAnyLinkage);
3963 }
else if (
const auto *CE =
3965 OffloadEntryInfoDeviceGlobalVar>(E)) {
3971 if (!CE->getAddress()) {
3974 "Offloading entry for declare target variable is incorrect: the " 3975 "address is invalid.");
3982 assert(((
CGM.
getLangOpts().OpenMPIsDevice && !CE->getAddress()) ||
3984 "Declaret target link address is set.");
3987 if (!CE->getAddress()) {
3990 "Offloading entry for declare target variable is incorrect: the " 3991 "address is invalid.");
3998 CE->getVarSize().getQuantity(), Flags,
4001 llvm_unreachable(
"Unsupported entry kind.");
4019 if (
auto EC = Buf.getError()) {
4025 llvm::LLVMContext C;
4026 auto ME = expectedToErrorOrAndEmitErrors(
4027 C, llvm::parseBitcodeFile(Buf.get()->getMemBufferRef(), C));
4029 if (
auto EC = ME.getError()) {
4037 llvm::NamedMDNode *MD = ME.get()->getNamedMetadata(
"omp_offload.info");
4041 for (llvm::MDNode *MN : MD->operands()) {
4042 auto &&GetMDInt = [MN](
unsigned Idx) {
4043 auto *V = cast<llvm::ConstantAsMetadata>(MN->getOperand(Idx));
4044 return cast<llvm::ConstantInt>(V->getValue())->getZExtValue();
4047 auto &&GetMDString = [MN](
unsigned Idx) {
4048 auto *V = cast<llvm::MDString>(MN->getOperand(Idx));
4049 return V->getString();
4052 switch (GetMDInt(0)) {
4054 llvm_unreachable(
"Unexpected metadata!");
4059 GetMDInt(1), GetMDInt(2),
4060 GetMDString(3), GetMDInt(4),
4067 static_cast<OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind>(
4076 if (!KmpRoutineEntryPtrTy) {
4110 RD->
addAttr(PackedAttr::CreateImplicit(C));
4168 struct PrivateHelpersTy {
4169 PrivateHelpersTy(
const VarDecl *Original,
const VarDecl *PrivateCopy,
4170 const VarDecl *PrivateElemInit)
4171 : Original(Original), PrivateCopy(PrivateCopy),
4172 PrivateElemInit(PrivateElemInit) {}
4175 const VarDecl *PrivateElemInit;
4177 typedef std::pair<
CharUnits , PrivateHelpersTy> PrivateDataTy;
4182 if (!Privates.empty()) {
4189 for (
const auto &Pair : Privates) {
4190 const VarDecl *VD = Pair.second.Original;
4209 QualType KmpRoutineEntryPointerQTy) {
4254 ArrayRef<PrivateDataTy>
Privates) {
4283 QualType KmpTaskTWithPrivatesPtrQTy,
4294 Args.push_back(&GtidArg);
4295 Args.push_back(&TaskTypeArg);
4296 const auto &TaskEntryFnInfo =
4298 llvm::FunctionType *TaskEntryTy =
4304 TaskEntry->setDoesNotRecurse();
4319 const auto *KmpTaskTWithPrivatesQTyRD =
4320 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->
getAsTagDecl());
4323 const auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->
getAsTagDecl());
4324 auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
4326 llvm::Value *PartidParam = PartIdLVal.getPointer();
4328 auto SharedsFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTShareds);
4334 auto PrivatesFI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin(), 1);
4336 if (PrivatesFI != KmpTaskTWithPrivatesQTyRD->field_end()) {
4341 PrivatesParam = llvm::ConstantPointerNull::get(CGF.
VoidPtrTy);
4344 llvm::Value *CommonArgs[] = {GtidParam, PartidParam, PrivatesParam,
4351 std::end(CommonArgs));
4353 auto LBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound);
4356 auto UBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound);
4359 auto StFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTStride);
4362 auto LIFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLastIter);
4365 auto RFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTReductions);
4368 CallArgs.push_back(LBParam);
4369 CallArgs.push_back(UBParam);
4370 CallArgs.push_back(StParam);
4371 CallArgs.push_back(LIParam);
4372 CallArgs.push_back(RParam);
4374 CallArgs.push_back(SharedsParam);
4387 QualType KmpTaskTWithPrivatesPtrQTy,
4388 QualType KmpTaskTWithPrivatesQTy) {
4396 Args.push_back(&GtidArg);
4397 Args.push_back(&TaskTypeArg);
4398 const auto &DestructorFnInfo =
4400 llvm::FunctionType *DestructorFnTy =
4404 auto *DestructorFn =
4409 DestructorFn->setDoesNotRecurse();
4417 const auto *KmpTaskTWithPrivatesQTyRD =
4418 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->
getAsTagDecl());
4419 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
4421 for (
const auto *Field :
4422 cast<RecordDecl>(FI->getType()->getAsTagDecl())->fields()) {
4424 Field->getType().isDestructedType()) {
4430 return DestructorFn;
4445 ArrayRef<const Expr *> PrivateVars,
4446 ArrayRef<const Expr *> FirstprivateVars,
4447 ArrayRef<const Expr *> LastprivateVars,
4449 ArrayRef<PrivateDataTy>
Privates) {
4453 C,
nullptr, Loc,
nullptr,
4456 Args.push_back(&TaskPrivatesArg);
4457 llvm::DenseMap<const VarDecl *, unsigned> PrivateVarsPos;
4458 unsigned Counter = 1;
4459 for (
const Expr *E : PrivateVars) {
4461 C,
nullptr, Loc,
nullptr,
4466 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4467 PrivateVarsPos[VD] = Counter;
4470 for (
const Expr *E : FirstprivateVars) {
4472 C,
nullptr, Loc,
nullptr,
4477 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4478 PrivateVarsPos[VD] = Counter;
4481 for (
const Expr *E : LastprivateVars) {
4483 C,
nullptr, Loc,
nullptr,
4488 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4489 PrivateVarsPos[VD] = Counter;
4492 const auto &TaskPrivatesMapFnInfo =
4494 llvm::FunctionType *TaskPrivatesMapTy =
4502 TaskPrivatesMapFnInfo);
4503 TaskPrivatesMap->removeFnAttr(llvm::Attribute::NoInline);
4504 TaskPrivatesMap->removeFnAttr(llvm::Attribute::OptimizeNone);
4505 TaskPrivatesMap->addFnAttr(llvm::Attribute::AlwaysInline);
4508 TaskPrivatesMapFnInfo, Args, Loc, Loc);
4514 const auto *PrivatesQTyRD = cast<RecordDecl>(PrivatesQTy->
getAsTagDecl());
4516 for (
const FieldDecl *Field : PrivatesQTyRD->fields()) {
4518 const VarDecl *VD = Args[PrivateVarsPos[Privates[Counter].second.Original]];
4527 return TaskPrivatesMap;
4531 const PrivateDataTy P2) {
4532 return P1.first > P2.first;
4542 ArrayRef<PrivateDataTy>
Privates,
bool ForDup) {
4544 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->
field_begin());
4559 (IsTargetTask && KmpTaskSharedsPtr.
isValid())) {
4565 FI = cast<RecordDecl>(FI->getType()->getAsTagDecl())->field_begin();
4566 for (
const PrivateDataTy &Pair : Privates) {
4567 const VarDecl *VD = Pair.second.PrivateCopy;
4569 if (Init && (!ForDup || (isa<CXXConstructExpr>(Init) &&
4572 if (
const VarDecl *Elem = Pair.second.PrivateElemInit) {
4573 const VarDecl *OriginalVD = Pair.second.Original;
4579 if (IsTargetTask && !SharedField) {
4580 assert(isa<ImplicitParamDecl>(OriginalVD) &&
4583 ->getNumParams() == 0 &&
4584 isa<TranslationUnitDecl>(
4586 ->getDeclContext()) &&
4587 "Expected artificial target data variable.");
4607 [&CGF, Elem, Init, &CapturesInfo](
Address DestElement,
4612 Elem, [SrcElement]() ->
Address {
return SrcElement; });
4616 CGF, &CapturesInfo);
4617 CGF.EmitAnyExprToMem(Init, DestElement,
4618 Init->getType().getQualifiers(),
4642 ArrayRef<PrivateDataTy>
Privates) {
4643 bool InitRequired =
false;
4644 for (
const PrivateDataTy &Pair : Privates) {
4645 const VarDecl *VD = Pair.second.PrivateCopy;
4647 InitRequired = InitRequired || (Init && isa<CXXConstructExpr>(Init) &&
4652 return InitRequired;
4669 QualType KmpTaskTWithPrivatesPtrQTy,
4673 ArrayRef<PrivateDataTy>
Privates,
bool WithLastIter) {
4677 KmpTaskTWithPrivatesPtrQTy,
4680 KmpTaskTWithPrivatesPtrQTy,
4684 Args.push_back(&DstArg);
4685 Args.push_back(&SrcArg);
4686 Args.push_back(&LastprivArg);
4687 const auto &TaskDupFnInfo =
4694 TaskDup->setDoesNotRecurse();
4704 auto LIFI = std::next(KmpTaskTQTyRD->
field_begin(), KmpTaskTLastIter);
4706 TDBase, *KmpTaskTWithPrivatesQTyRD->
field_begin());
4714 assert(!Privates.empty());
4721 TDBase, *KmpTaskTWithPrivatesQTyRD->
field_begin());
4729 emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, TDBase, KmpTaskTWithPrivatesQTyRD,
4730 SharedsTy, SharedsPtrTy, Data, Privates,
true);
4739 bool NeedsCleanup =
false;
4740 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->
field_begin(), 1);
4741 const auto *PrivateRD = cast<RecordDecl>(FI->getType()->getAsTagDecl());
4742 for (
const FieldDecl *FD : PrivateRD->fields()) {
4743 NeedsCleanup = NeedsCleanup || FD->getType().isDestructedType();
4747 return NeedsCleanup;
4750 CGOpenMPRuntime::TaskResultTy
4760 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4761 Privates.emplace_back(
4763 PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
4770 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4771 Privates.emplace_back(
4774 VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
4775 cast<VarDecl>(cast<DeclRefExpr>(*IElemInitRef)->getDecl())));
4781 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4782 Privates.emplace_back(
4784 PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
4803 "Expected taskloop, task or target directive");
4812 const RecordDecl *KmpTaskTWithPrivatesQTyRD =
4815 QualType KmpTaskTWithPrivatesPtrQTy =
4819 KmpTaskTWithPrivatesTy->getPointerTo();
4827 std::next(cast<llvm::Function>(TaskFunction)->arg_begin(), 3)->getType();
4828 if (!Privates.empty()) {
4829 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
4834 TaskPrivatesMap, TaskPrivatesMapTy);
4836 TaskPrivatesMap = llvm::ConstantPointerNull::get(
4837 cast<llvm::PointerType>(TaskPrivatesMapTy));
4843 KmpTaskTWithPrivatesQTy,
KmpTaskTQTy, SharedsPtrTy, TaskFunction,
4855 DestructorsFlag = 0x8,
4858 unsigned Flags = Data.
Tied ? TiedFlag : 0;
4859 bool NeedsCleanup =
false;
4860 if (!Privates.empty()) {
4863 Flags = Flags | DestructorsFlag;
4866 Flags = Flags | PriorityFlag;
4868 Data.
Final.getPointer()
4870 CGF.
Builder.getInt32(FinalFlag),
4872 : CGF.
Builder.getInt32(Data.
Final.getInt() ? FinalFlag : 0);
4873 TaskFlags = CGF.
Builder.CreateOr(TaskFlags, CGF.
Builder.getInt32(Flags));
4877 KmpTaskTWithPrivatesTySize, SharedsSize,
4879 TaskEntry, KmpRoutineEntryPtrTy)};
4884 NewTask, KmpTaskTWithPrivatesPtrTy);
4886 KmpTaskTWithPrivatesQTy);
4896 TDBase, *std::next(KmpTaskTQTyRD->field_begin(),
4906 if (!Privates.empty()) {
4907 emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, Base, KmpTaskTWithPrivatesQTyRD,
4908 SharedsTy, SharedsPtrTy, Data, Privates,
4913 CGM, Loc, D, KmpTaskTWithPrivatesPtrQTy, KmpTaskTWithPrivatesQTyRD,
4914 KmpTaskTQTyRD, SharedsTy, SharedsPtrTy, Data, Privates,
4919 enum { Priority = 0, Destructors = 1 };
4921 auto FI = std::next(KmpTaskTQTyRD->field_begin(), Data1);
4923 (*FI)->getType()->getAsUnionType()->getDecl();
4926 CGM, Loc, KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy,
4927 KmpTaskTWithPrivatesQTy);
4930 Data1LV, *std::next(KmpCmplrdataUD->field_begin(), Destructors));
4932 DestructorFn, KmpRoutineEntryPtrTy),
4938 TDBase, *std::next(KmpTaskTQTyRD->field_begin(), Data2));
4940 Data2LV, *std::next(KmpCmplrdataUD->field_begin(), Priority));
4961 emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
4970 unsigned NumDependencies = Data.
Dependences.size();
4971 if (NumDependencies) {
4973 enum RTLDependenceKindTy { DepIn = 0x01, DepInOut = 0x3 };
4974 enum RTLDependInfoFieldsTy { BaseAddr, Len, Flags };
4998 for (
unsigned I = 0; I < NumDependencies; ++I) {
5003 if (
const auto *ASE =
5012 Size = CGF.
Builder.CreateNUWSub(UpIntPtr, LowIntPtr);
5021 Base, *std::next(KmpDependInfoRD->
field_begin(), BaseAddr));
5027 Base, *std::next(KmpDependInfoRD->
field_begin(), Len));
5030 RTLDependenceKindTy DepKind;
5032 case OMPC_DEPEND_in:
5036 case OMPC_DEPEND_out:
5037 case OMPC_DEPEND_inout:
5040 case OMPC_DEPEND_source:
5041 case OMPC_DEPEND_sink:
5043 llvm_unreachable(
"Unknown task dependence type");
5046 Base, *std::next(KmpDependInfoRD->
field_begin(), Flags));
5063 llvm::Value *TaskArgs[] = { UpLoc, ThreadID, NewTask };
5065 if (NumDependencies) {
5066 DepTaskArgs[0] = UpLoc;
5067 DepTaskArgs[1] = ThreadID;
5068 DepTaskArgs[2] = NewTask;
5069 DepTaskArgs[3] = CGF.
Builder.getInt32(NumDependencies);
5070 DepTaskArgs[4] = DependenciesArray.
getPointer();
5071 DepTaskArgs[5] = CGF.
Builder.getInt32(0);
5072 DepTaskArgs[6] = llvm::ConstantPointerNull::get(CGF.
VoidPtrTy);
5074 auto &&ThenCodeGen = [
this, &Data, TDBase, KmpTaskTQTyRD, NumDependencies,
5078 auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
5079 LValue PartIdLVal = CGF.EmitLValueForField(TDBase, *PartIdFI);
5080 CGF.EmitStoreOfScalar(CGF.Builder.getInt32(0), PartIdLVal);
5082 if (NumDependencies) {
5083 CGF.EmitRuntimeCall(
5091 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
5092 Region->emitUntiedSwitch(CGF);
5096 if (NumDependencies) {
5097 DepWaitTaskArgs[0] = UpLoc;
5098 DepWaitTaskArgs[1] = ThreadID;
5099 DepWaitTaskArgs[2] = CGF.Builder.getInt32(NumDependencies);
5100 DepWaitTaskArgs[3] = DependenciesArray.
getPointer();
5101 DepWaitTaskArgs[4] = CGF.Builder.getInt32(0);
5102 DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
5104 auto &&ElseCodeGen = [&TaskArgs, ThreadID, NewTaskNewTaskTTy, TaskEntry,
5105 NumDependencies, &DepWaitTaskArgs,
5113 if (NumDependencies)
5117 auto &&CodeGen = [TaskEntry, ThreadID, NewTaskNewTaskTTy,
5120 llvm::Value *OutlinedFnArgs[] = {ThreadID, NewTaskNewTaskTTy};
5121 CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, Loc, TaskEntry,
5130 CommonActionTy Action(
5154 emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
5167 IfVal = llvm::ConstantInt::getSigned(CGF.
IntTy, 1);
5201 enum { NoSchedule = 0, Grainsize = 1, NumTasks = 2 };
5210 llvm::ConstantInt::getNullValue(
5212 llvm::ConstantInt::getSigned(
5214 ? Data.
Schedule.getInt() ? NumTasks : Grainsize
5219 : llvm::ConstantInt::get(CGF.
Int64Ty, 0),
5222 : llvm::ConstantPointerNull::get(CGF.
VoidPtrTy)};
5239 const Expr *,
const Expr *)> &RedOpGen,
5240 const Expr *XExpr =
nullptr,
const Expr *EExpr =
nullptr,
5241 const Expr *UpExpr =
nullptr) {
5259 CGF.
Builder.CreateICmpEQ(LHSBegin, LHSEnd,
"omp.arraycpy.isempty");
5260 CGF.
Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
5263 llvm::BasicBlock *EntryBB = CGF.
Builder.GetInsertBlock();
5268 llvm::PHINode *RHSElementPHI = CGF.
Builder.CreatePHI(
5269 RHSBegin->getType(), 2,
"omp.arraycpy.srcElementPast");
5270 RHSElementPHI->addIncoming(RHSBegin, EntryBB);
5275 llvm::PHINode *LHSElementPHI = CGF.
Builder.CreatePHI(
5276 LHSBegin->getType(), 2,
"omp.arraycpy.destElementPast");
5277 LHSElementPHI->addIncoming(LHSBegin, EntryBB);
5284 Scope.addPrivate(LHSVar, [=]() {
return LHSElementCurrent; });
5285 Scope.addPrivate(RHSVar, [=]() {
return RHSElementCurrent; });
5287 RedOpGen(CGF, XExpr, EExpr, UpExpr);
5288 Scope.ForceCleanup();
5292 LHSElementPHI, 1,
"omp.arraycpy.dest.element");
5294 RHSElementPHI, 1,
"omp.arraycpy.src.element");
5297 CGF.
Builder.CreateICmpEQ(LHSElementNext, LHSEnd,
"omp.arraycpy.done");
5298 CGF.
Builder.CreateCondBr(Done, DoneBB, BodyBB);
5299 LHSElementPHI->addIncoming(LHSElementNext, CGF.
Builder.GetInsertBlock());
5300 RHSElementPHI->addIncoming(RHSElementNext, CGF.
Builder.GetInsertBlock());
5310 const Expr *ReductionOp) {
5311 if (
const auto *CE = dyn_cast<CallExpr>(ReductionOp))
5312 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
5313 if (
const auto *DRE =
5314 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
5315 if (
const auto *DRD =
5316 dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl())) {
5317 std::pair<llvm::Function *, llvm::Function *> Reduction =
5329 ArrayRef<const Expr *>
Privates, ArrayRef<const Expr *> LHSExprs,
5330 ArrayRef<const Expr *> RHSExprs, ArrayRef<const Expr *> ReductionOps) {
5339 Args.push_back(&LHSArg);
5340 Args.push_back(&RHSArg);
5343 std::string Name =
getName({
"omp",
"reduction",
"reduction_func"});
5348 Fn->setDoesNotRecurse();
5365 auto IPriv = Privates.begin();
5367 for (
unsigned I = 0, E = ReductionOps.size(); I < E; ++I, ++IPriv, ++Idx) {
5368 const auto *RHSVar =
5369 cast<VarDecl>(cast<DeclRefExpr>(RHSExprs[I])->getDecl());
5370 Scope.addPrivate(RHSVar, [&CGF, RHS, Idx, RHSVar]() {
5373 const auto *LHSVar =
5374 cast<VarDecl>(cast<DeclRefExpr>(LHSExprs[I])->getDecl());
5375 Scope.addPrivate(LHSVar, [&CGF, LHS, Idx, LHSVar]() {
5378 QualType PrivTy = (*IPriv)->getType();
5387 const auto *OVE = cast<OpaqueValueExpr>(VLA->
getSizeExpr());
5394 IPriv = Privates.begin();
5395 auto ILHS = LHSExprs.begin();
5396 auto IRHS = RHSExprs.begin();
5397 for (
const Expr *E : ReductionOps) {
5398 if ((*IPriv)->getType()->isArrayType()) {
5400 const auto *LHSVar = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5401 const auto *RHSVar = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
5403 CGF, (*IPriv)->getType(), LHSVar, RHSVar,
5415 Scope.ForceCleanup();
5421 const Expr *ReductionOp,
5422 const Expr *PrivateRef,
5427 const auto *LHSVar = cast<VarDecl>(LHS->
getDecl());
5428 const auto *RHSVar = cast<VarDecl>(RHS->
getDecl());
5430 CGF, PrivateRef->
getType(), LHSVar, RHSVar,
5489 if (SimpleReduction) {
5491 auto IPriv = Privates.begin();
5492 auto ILHS = LHSExprs.begin();
5493 auto IRHS = RHSExprs.begin();
5494 for (
const Expr *E : ReductionOps) {
5496 cast<DeclRefExpr>(*IRHS));
5506 auto Size = RHSExprs.size();
5507 for (
const Expr *E : Privates) {
5512 llvm::APInt ArraySize(32, Size);
5517 CGF.
CreateMemTemp(ReductionArrayTy,
".omp.reduction.red_list");
5518 auto IPriv = Privates.begin();
5520 for (
unsigned I = 0, E = RHSExprs.size(); I < E; ++I, ++IPriv, ++Idx) {
5527 if ((*IPriv)->getType()->isVariablyModifiedType()) {
5545 Privates, LHSExprs, RHSExprs, ReductionOps);
5548 std::string Name =
getName({
"reduction"});
5561 CGF.
Builder.getInt32(RHSExprs.size()),
5562 ReductionArrayTySize,
5573 llvm::BasicBlock *DefaultBB = CGF.
createBasicBlock(
".omp.reduction.default");
5574 llvm::SwitchInst *SwInst =
5575 CGF.
Builder.CreateSwitch(Res, DefaultBB, 2);
5584 SwInst->addCase(CGF.
Builder.getInt32(1), Case1BB);
5593 auto &&CodeGen = [
Privates, LHSExprs, RHSExprs, ReductionOps](
5596 auto IPriv = Privates.begin();
5597 auto ILHS = LHSExprs.begin();
5598 auto IRHS = RHSExprs.begin();
5599 for (
const Expr *E : ReductionOps) {
5600 RT.emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
5601 cast<DeclRefExpr>(*IRHS));
5608 CommonActionTy Action(
5616 CGF.EmitBranch(DefaultBB);
5623 llvm::BasicBlock *Case2BB = CGF.createBasicBlock(
".omp.reduction.case2");
5624 SwInst->addCase(CGF.Builder.getInt32(2), Case2BB);
5625 CGF.EmitBlock(Case2BB);
5627 auto &&AtomicCodeGen = [Loc,
Privates, LHSExprs, RHSExprs, ReductionOps](
5629 auto ILHS = LHSExprs.begin();
5630 auto IRHS = RHSExprs.begin();
5631 auto IPriv = Privates.begin();
5632 for (
const Expr *E : ReductionOps) {
5633 const Expr *XExpr =
nullptr;
5634 const Expr *EExpr =
nullptr;
5635 const Expr *UpExpr =
nullptr;
5637 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
5638 if (BO->getOpcode() == BO_Assign) {
5639 XExpr = BO->getLHS();
5640 UpExpr = BO->getRHS();
5644 const Expr *RHSExpr = UpExpr;
5647 if (
const auto *ACO = dyn_cast<AbstractConditionalOperator>(
5651 RHSExpr = ACO->getCond();
5653 if (
const auto *BORHS =
5655 EExpr = BORHS->getRHS();
5656 BO = BORHS->getOpcode();
5660 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5661 auto &&AtomicRedGen = [BO, VD,
5663 const Expr *EExpr,
const Expr *UpExpr) {
5664 LValue X = CGF.EmitLValue(XExpr);
5667 E = CGF.EmitAnyExpr(EExpr);
5668 CGF.EmitOMPAtomicSimpleUpdateExpr(
5670 llvm::AtomicOrdering::Monotonic, Loc,
5671 [&CGF, UpExpr, VD, Loc](
RValue XRValue) {
5674 VD, [&CGF, VD, XRValue, Loc]() {
5675 Address LHSTemp = CGF.CreateMemTemp(VD->getType());
5676 CGF.emitOMPSimpleStore(
5677 CGF.MakeAddrLValue(LHSTemp, VD->
getType()), XRValue,
5678 VD->getType().getNonReferenceType(), Loc);
5682 return CGF.EmitAnyExpr(UpExpr);
5685 if ((*IPriv)->getType()->isArrayType()) {
5687 const auto *RHSVar =
5688 cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
5690 AtomicRedGen, XExpr, EExpr, UpExpr);
5693 AtomicRedGen(CGF, XExpr, EExpr, UpExpr);
5698 const Expr *,
const Expr *) {
5700 std::string Name = RT.getName({
"atomic_reduction"});
5701 RT.emitCriticalRegion(
5709 if ((*IPriv)->getType()->isArrayType()) {
5710 const auto *LHSVar =
5711 cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5712 const auto *RHSVar =
5713 cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
5717 CritRedGen(CGF,
nullptr,
nullptr,
nullptr);
5742 CGF.EmitBranch(DefaultBB);
5743 CGF.EmitBlock(DefaultBB,
true);
5751 llvm::raw_svector_ostream Out(Buffer);
5755 D = cast<VarDecl>(cast<DeclRefExpr>(Ref)->getDecl());
5758 {D->isLocalVarDeclOrParm() ? D->getName() : CGM.
getMangledName(D)});
5759 Out << Prefix << Name <<
"_" 5760 << D->getCanonicalDecl()->getLocStart().getRawEncoding();
5779 Args.emplace_back(&Param);
5780 const auto &FnInfo =
5787 Fn->setDoesNotRecurse();
5819 llvm::ConstantPointerNull::get(CGM.
VoidPtrTy),
5844 const Expr *ReductionOp,
5846 const Expr *PrivateRef) {
5848 const auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(LHS)->getDecl());
5849 const auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(RHS)->getDecl());
5855 Args.emplace_back(&ParamInOut);
5856 Args.emplace_back(&ParamIn);
5857 const auto &FnInfo =
5864 Fn->setDoesNotRecurse();
5882 PrivateScope.
addPrivate(LHSVD, [&C, &CGF, &ParamInOut, LHSVD]() {
5890 PrivateScope.
addPrivate(RHSVD, [&C, &CGF, &ParamIn, RHSVD]() {
5903 CGF, ReductionOp, PrivateRef, cast<DeclRefExpr>(LHS),
5904 cast<DeclRefExpr>(RHS));
5926 Args.emplace_back(&Param);
5927 const auto &FnInfo =
5934 Fn->setDoesNotRecurse();
5960 ArrayRef<const Expr *> RHSExprs,
const OMPTaskDataTy &Data) {
5986 llvm::APInt ArraySize(64, Size);
5993 for (
unsigned Cnt = 0; Cnt < Size; ++Cnt) {
5996 llvm::ConstantInt::get(CGM.
SizeTy, Cnt)};
6004 RCG.emitSharedLValue(CGF, Cnt);
6011 std::tie(SizeValInChars, SizeVal) = RCG.
getSizes(Cnt);
6018 bool DelayedCreation = !!SizeVal;
6019 SizeValInChars = CGF.
Builder.CreateIntCast(SizeValInChars, CGM.
SizeTy,
6034 : llvm::ConstantPointerNull::get(CGM.
VoidPtrTy);
6039 CGM, Loc, RCG, Cnt, Data.
ReductionOps[Cnt], LHSExprs[Cnt],
6044 if (DelayedCreation) {
6046 llvm::ConstantInt::get(CGM.
Int32Ty, 1,
true),
6056 llvm::ConstantInt::get(CGM.
IntTy, Size,
true),
6117 if (
auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.
CapturedStmtInfo))
6118 Region->emitUntiedSwitch(CGF);
6127 InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind, HasCancel);
6143 if (CancelRegion == OMPD_parallel)
6144 CancelKind = CancelParallel;
6145 else if (CancelRegion == OMPD_for)
6146 CancelKind = CancelLoop;
6147 else if (CancelRegion == OMPD_sections)
6148 CancelKind = CancelSections;
6150 assert(CancelRegion == OMPD_taskgroup);
6151 CancelKind = CancelTaskgroup;
6163 if (
auto *OMPRegionInfo =
6167 if (CancelRegion == OMPD_taskgroup || OMPRegionInfo->hasCancel()) {
6180 CGF.
Builder.CreateCondBr(Cmp, ExitBB, ContBB);
6198 if (
auto *OMPRegionInfo =
6200 auto &&ThenGen = [Loc, CancelRegion, OMPRegionInfo](
CodeGenFunction &CGF,
6212 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(
".cancel.exit");
6213 llvm::BasicBlock *ContBB = CGF.createBasicBlock(
".cancel.continue");
6214 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Result);
6215 CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
6216 CGF.EmitBlock(ExitBB);
6219 CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
6220 CGF.EmitBranchThroughCleanup(CancelDest);
6221 CGF.EmitBlock(ContBB,
true);
6235 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
6237 assert(!ParentName.empty() &&
"Invalid target region parent name!");
6239 IsOffloadEntry, CodeGen);
6244 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
6262 llvm::raw_svector_ostream OS(EntryFnName);
6263 OS <<
"__omp_offloading" << llvm::format(
"_%x", DeviceID)
6264 << llvm::format(
"_%x_", FileID) << ParentName <<
"_l" <<
Line;
6270 CGOpenMPTargetRegionInfo CGInfo(CS, CodeGen, EntryFnName);
6277 if (!IsOffloadEntry)
6292 OutlinedFnID = llvm::ConstantExpr::getBitCast(OutlinedFn, CGM.
Int8PtrTy);
6293 OutlinedFn->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6294 OutlinedFn->setDSOLocal(
false);
6296 std::string Name =
getName({EntryFnName,
"region_id"});
6297 OutlinedFnID =
new llvm::GlobalVariable(
6299 llvm::GlobalValue::WeakAnyLinkage,
6300 llvm::Constant::getNullValue(CGM.
Int8Ty), Name);
6305 DeviceID, FileID, ParentName, Line, OutlinedFn, OutlinedFnID,
6311 while (
const auto *CS = dyn_cast_or_null<CompoundStmt>(Body))
6312 Body = CS->body_front();
6329 assert(!CGF.
getLangOpts().OpenMPIsDevice &&
"Clauses associated with the " 6330 "teams directive expected to be " 6331 "emitted only for the host!");
6343 return Bld.CreateIntCast(NumTeams, CGF.
Int32Ty,
6348 return Bld.getInt32(0);
6354 return Bld.getInt32(1);
6364 if (
const auto *TeamsDir = dyn_cast_or_null<OMPExecutableDirective>(
6368 CGOpenMPInnerExprInfo CGInfo(CGF, CS);
6371 return Bld.CreateIntCast(NumTeams, CGF.
Int32Ty,
6377 return Bld.getInt32(0);
6397 assert(!CGF.
getLangOpts().OpenMPIsDevice &&
"Clauses associated with the " 6398 "teams directive expected to be " 6399 "emitted only for the host!");
6419 llvm::Value *DefaultThreadLimitVal = Bld.getInt32(0);
6423 if (
const auto *ThreadLimitClause =
6429 ThreadLimitVal = Bld.CreateIntCast(ThreadLimit, CGF.
Int32Ty,
6433 if (
const auto *NumThreadsClause =
6440 Bld.CreateIntCast(NumThreads, CGF.
Int32Ty,
true);
6445 ThreadLimitVal = ThreadLimitVal
6446 ? Bld.CreateSelect(Bld.CreateICmpSLT(NumThreadsVal,
6448 NumThreadsVal, ThreadLimitVal)
6453 if (!ThreadLimitVal)
6454 ThreadLimitVal = DefaultThreadLimitVal;
6456 return ThreadLimitVal;
6467 if (
const auto *TeamsDir = dyn_cast_or_null<OMPExecutableDirective>(
6471 CGOpenMPInnerExprInfo CGInfo(CGF, CS);
6480 return CGF.
Builder.getInt32(0);
6495 class MappableExprsHandler {
6499 enum OpenMPOffloadMappingFlags : uint64_t {
6505 OMP_MAP_FROM = 0x02,
6508 OMP_MAP_ALWAYS = 0x04,
6511 OMP_MAP_DELETE = 0x08,
6514 OMP_MAP_PTR_AND_OBJ = 0x10,
6517 OMP_MAP_TARGET_PARAM = 0x20,
6521 OMP_MAP_RETURN_PARAM = 0x40,
6524 OMP_MAP_PRIVATE = 0x80,
6526 OMP_MAP_LITERAL = 0x100,
6528 OMP_MAP_IMPLICIT = 0x200,
6531 OMP_MAP_MEMBER_OF = 0xffff000000000000,
6532 LLVM_MARK_AS_BITMASK_ENUM( OMP_MAP_MEMBER_OF),
6537 class BasePointerInfo {
6546 : Ptr(Ptr), DevPtrDecl(DevPtrDecl) {}
6548 const ValueDecl *getDevicePtrDecl()
const {
return DevPtrDecl; }
6549 void setDevicePtrDecl(
const ValueDecl *D) { DevPtrDecl = D; }
6560 struct StructRangeInfoTy {
6561 std::pair<
unsigned ,
Address > LowestElem = {
6563 std::pair<
unsigned ,
Address > HighestElem = {
6574 bool ReturnDevicePointer =
false;
6575 bool IsImplicit =
false;
6577 MapInfo() =
default;
6581 bool ReturnDevicePointer,
bool IsImplicit)
6582 : Components(Components), MapType(MapType),
6583 MapTypeModifier(MapTypeModifier),
6584 ReturnDevicePointer(ReturnDevicePointer), IsImplicit(IsImplicit) {}
6590 struct DeferredDevicePtrEntryTy {
6591 const Expr *IE =
nullptr;
6594 DeferredDevicePtrEntryTy(
const Expr *IE,
const ValueDecl *VD)
6605 llvm::SmallPtrSet<const VarDecl *, 8> FirstPrivateDecls;
6624 if (
const auto *OAE = dyn_cast<OMPArraySectionExpr>(E)) {
6626 OAE->getBase()->IgnoreParenImpCasts())
6627 .getCanonicalType();
6631 if (!OAE->getLength() && OAE->getColonLoc().isValid())
6636 ElemSize = CGF.
getTypeSize(PTy->getPointeeType().getCanonicalType());
6638 const auto *ATy = cast<ArrayType>(BaseTy.
getTypePtr());
6639 assert(ATy &&
"Expecting array type if not a pointer type.");
6640 ElemSize = CGF.
getTypeSize(ATy->getElementType().getCanonicalType());
6645 if (!OAE->getLength())
6651 return CGF.
Builder.CreateNUWMul(LengthVal, ElemSize);
6662 bool IsImplicit,
bool AddPtrFlag,
6663 bool AddIsTargetParamFlag)
const {
6664 OpenMPOffloadMappingFlags Bits =
6665 IsImplicit ? OMP_MAP_IMPLICIT : OMP_MAP_NONE;
6667 case OMPC_MAP_alloc:
6668 case OMPC_MAP_release:
6678 Bits |= OMP_MAP_FROM;
6680 case OMPC_MAP_tofrom:
6681 Bits |= OMP_MAP_TO | OMP_MAP_FROM;
6683 case OMPC_MAP_delete:
6684 Bits |= OMP_MAP_DELETE;
6686 case OMPC_MAP_always:
6688 llvm_unreachable(
"Unexpected map type!");
6691 Bits |= OMP_MAP_PTR_AND_OBJ;
6692 if (AddIsTargetParamFlag)
6693 Bits |= OMP_MAP_TARGET_PARAM;
6694 if (MapTypeModifier == OMPC_MAP_always)
6695 Bits |= OMP_MAP_ALWAYS;
6701 bool isFinalArraySectionExpression(
const Expr *E)
const {
6709 if (OASE->getColonLoc().isInvalid())
6712 const Expr *Length = OASE->getLength();
6719 OASE->getBase()->IgnoreParenImpCasts())
6720 .getCanonicalType();
6721 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
6722 return ATy->getSize().getSExtValue() != 1;
6730 llvm::APSInt ConstLength;
6734 return ConstLength.getSExtValue() != 1;
6741 void generateInfoForComponentList(
6744 MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers,
6745 MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types,
6746 StructRangeInfoTy &PartialStruct,
bool IsFirstComponentList,
6747 bool IsImplicit)
const {
6905 bool IsCaptureFirstInfo = IsFirstComponentList;
6906 bool IsLink =
false;
6909 auto CI = Components.rbegin();
6910 auto CE = Components.rend();
6915 bool IsExpressionFirstInfo =
true;
6918 if (isa<MemberExpr>(I->getAssociatedExpression())) {
6926 if (
const auto *VD =
6927 dyn_cast_or_null<VarDecl>(I->getAssociatedDeclaration())) {
6929 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
6930 if (*Res == OMPDeclareTargetDeclAttr::MT_Link) {
6940 I->getAssociatedDeclaration()->getType().getNonReferenceType();
6964 bool ShouldBeMemberOf =
false;
6975 for (; I != CE; ++I) {
6977 if (!EncounteredME) {
6978 EncounteredME = dyn_cast<
MemberExpr>(I->getAssociatedExpression());
6982 ShouldBeMemberOf =
true;
6985 auto Next = std::next(I);
6993 bool IsFinalArraySection =
6994 isFinalArraySectionExpression(I->getAssociatedExpression());
7005 I->getAssociatedExpression()->getType()->isAnyPointerType();
7007 if (Next == CE || IsPointer || IsFinalArraySection) {
7010 assert((Next == CE ||
7011 isa<MemberExpr>(Next->getAssociatedExpression()) ||
7012 isa<ArraySubscriptExpr>(Next->getAssociatedExpression()) ||
7013 isa<OMPArraySectionExpr>(Next->getAssociatedExpression())) &&
7014 "Unexpected expression");
7018 llvm::Value *Size = getExprTypeSize(I->getAssociatedExpression());
7023 bool IsMemberPointer =
7024 IsPointer && EncounteredME &&
7025 (dyn_cast<
MemberExpr>(I->getAssociatedExpression()) ==
7027 if (!IsMemberPointer) {
7029 Pointers.push_back(LB.getPointer());
7030 Sizes.push_back(Size);
7036 OpenMPOffloadMappingFlags Flags = getMapTypeBits(
7037 MapType, MapTypeModifier, IsImplicit,
7038 !IsExpressionFirstInfo || IsLink, IsCaptureFirstInfo && !IsLink);
7040 if (!IsExpressionFirstInfo) {
7044 Flags &= ~(OMP_MAP_TO | OMP_MAP_FROM | OMP_MAP_ALWAYS |
7047 if (ShouldBeMemberOf) {
7050 Flags |= OMP_MAP_MEMBER_OF;
7053 ShouldBeMemberOf =
false;
7057 Types.push_back(Flags);
7063 if (EncounteredME) {
7064 const auto *FD = dyn_cast<
FieldDecl>(EncounteredME->getMemberDecl());
7068 if (!PartialStruct.Base.isValid()) {
7069 PartialStruct.LowestElem = {FieldIndex, LB};
7070 PartialStruct.HighestElem = {FieldIndex, LB};
7071 PartialStruct.Base = BP;
7072 }
else if (FieldIndex < PartialStruct.LowestElem.first) {
7073 PartialStruct.LowestElem = {FieldIndex, LB};
7074 }
else if (FieldIndex > PartialStruct.HighestElem.first) {
7075 PartialStruct.HighestElem = {FieldIndex, LB};
7080 if (IsFinalArraySection)
7087 IsExpressionFirstInfo =
false;
7088 IsCaptureFirstInfo =
false;
7096 MappableExprsHandler::OpenMPOffloadMappingFlags
7104 return MappableExprsHandler::OMP_MAP_PRIVATE |
7105 MappableExprsHandler::OMP_MAP_TO;
7106 return MappableExprsHandler::OMP_MAP_TO |
7107 MappableExprsHandler::OMP_MAP_FROM;
7110 static OpenMPOffloadMappingFlags getMemberOfFlag(
unsigned Position) {
7112 return static_cast<OpenMPOffloadMappingFlags
>(((uint64_t)Position + 1)
7116 static void setCorrectMemberOfFlag(OpenMPOffloadMappingFlags &Flags,
7117 OpenMPOffloadMappingFlags MemberOfFlag) {
7121 if ((Flags & OMP_MAP_PTR_AND_OBJ) &&
7122 ((Flags & OMP_MAP_MEMBER_OF) != OMP_MAP_MEMBER_OF))
7127 Flags &= ~OMP_MAP_MEMBER_OF;
7128 Flags |= MemberOfFlag;
7133 : CurDir(Dir), CGF(CGF) {
7136 for (
const auto *D : C->varlists())
7137 FirstPrivateDecls.insert(
7141 for (
auto L : C->component_lists())
7142 DevPointersMap[L.first].push_back(L.second);
7148 void emitCombinedEntry(MapBaseValuesArrayTy &BasePointers,
7149 MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
7150 MapFlagsArrayTy &Types, MapFlagsArrayTy &CurTypes,
7151 const StructRangeInfoTy &PartialStruct)
const {
7153 BasePointers.push_back(PartialStruct.Base.getPointer());
7155 llvm::Value *LB = PartialStruct.LowestElem.second.getPointer();
7156 Pointers.push_back(LB);
7158 llvm::Value *HB = PartialStruct.HighestElem.second.getPointer();
7165 Sizes.push_back(Size);
7167 Types.push_back(OMP_MAP_TARGET_PARAM);
7169 (*CurTypes.begin()) &= ~OMP_MAP_TARGET_PARAM;
7174 OpenMPOffloadMappingFlags MemberOfFlag =
7175 getMemberOfFlag(BasePointers.size() - 1);
7176 for (
auto &M : CurTypes)
7177 setCorrectMemberOfFlag(M, MemberOfFlag);
7184 void generateAllInfo(MapBaseValuesArrayTy &BasePointers,
7185 MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
7186 MapFlagsArrayTy &Types)
const {
7190 llvm::MapVector<const ValueDecl *, SmallVector<MapInfo, 8>> Info;
7194 auto &&InfoGen = [&Info](
7198 bool ReturnDevicePointer,
bool IsImplicit) {
7199 const ValueDecl *VD =
7201 Info[VD].emplace_back(L, MapType, MapModifier, ReturnDevicePointer,
7207 for (
const auto &L : C->component_lists()) {
7208 InfoGen(L.first, L.second, C->getMapType(), C->getMapTypeModifier(),
7209 false, C->isImplicit());
7212 for (
const auto &L : C->component_lists()) {
7214 false, C->isImplicit());
7217 for (
const auto &L : C->component_lists()) {
7219 false, C->isImplicit());
7228 llvm::MapVector<const ValueDecl *, SmallVector<DeferredDevicePtrEntryTy, 4>>
7232 for (
const auto *C :
7234 for (
const auto &L : C->component_lists()) {
7235 assert(!L.second.empty() &&
"Not expecting empty list of components!");
7236 const ValueDecl *VD = L.second.back().getAssociatedDeclaration();
7237 VD = cast<ValueDecl>(VD->getCanonicalDecl());
7238 const Expr *IE = L.second.back().getAssociatedExpression();
7242 auto It = Info.find(isa<MemberExpr>(IE) ?
nullptr : VD);
7246 if (It != Info.end()) {
7247 auto CI = std::find_if(
7248 It->second.begin(), It->second.end(), [VD](
const MapInfo &MI) {
7249 return MI.Components.back().getAssociatedDeclaration() == VD;
7253 if (CI != It->second.end()) {
7254 CI->ReturnDevicePointer =
true;
7263 if (isa<MemberExpr>(IE)) {
7272 false, C->isImplicit());
7273 DeferredInfo[
nullptr].emplace_back(IE, VD);
7277 BasePointers.emplace_back(Ptr, VD);
7278 Pointers.push_back(Ptr);
7279 Sizes.push_back(llvm::Constant::getNullValue(this->CGF.
SizeTy));
7280 Types.push_back(OMP_MAP_RETURN_PARAM | OMP_MAP_TARGET_PARAM);
7285 for (
const auto &M : Info) {
7288 bool IsFirstComponentList =
true;
7291 MapBaseValuesArrayTy CurBasePointers;
7292 MapValuesArrayTy CurPointers;
7293 MapValuesArrayTy CurSizes;
7294 MapFlagsArrayTy CurTypes;
7295 StructRangeInfoTy PartialStruct;
7297 for (
const MapInfo &L : M.second) {
7298 assert(!L.Components.empty() &&
7299 "Not expecting declaration with no component lists.");
7302 unsigned CurrentBasePointersIdx = CurBasePointers.size();
7304 this->generateInfoForComponentList(
7305 L.MapType, L.MapTypeModifier, L.Components, CurBasePointers,
7306 CurPointers, CurSizes, CurTypes, PartialStruct,
7307 IsFirstComponentList, L.IsImplicit);
7311 if (L.ReturnDevicePointer) {
7312 assert(CurBasePointers.size() > CurrentBasePointersIdx &&
7313 "Unexpected number of mapped base pointers.");
7315 const ValueDecl *RelevantVD =
7316 L.Components.back().getAssociatedDeclaration();
7317 assert(RelevantVD &&
7318 "No relevant declaration related with device pointer??");
7320 CurBasePointers[CurrentBasePointersIdx].setDevicePtrDecl(RelevantVD);
7321 CurTypes[CurrentBasePointersIdx] |= OMP_MAP_RETURN_PARAM;
7323 IsFirstComponentList =
false;
7328 auto CI = DeferredInfo.find(M.first);
7329 if (CI != DeferredInfo.end()) {
7330 for (
const DeferredDevicePtrEntryTy &L : CI->second) {
7333 this->CGF.
EmitLValue(L.IE), L.IE->getExprLoc());
7334 CurBasePointers.emplace_back(BasePtr, L.VD);
7335 CurPointers.push_back(Ptr);
7336 CurSizes.push_back(llvm::Constant::getNullValue(this->CGF.
SizeTy));
7340 CurTypes.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_RETURN_PARAM |
7347 if (PartialStruct.Base.isValid())
7348 emitCombinedEntry(BasePointers, Pointers, Sizes, Types, CurTypes,
7352 BasePointers.append(CurBasePointers.begin(), CurBasePointers.end());
7353 Pointers.append(CurPointers.begin(), CurPointers.end());
7354 Sizes.append(CurSizes.begin(), CurSizes.end());
7355 Types.append(CurTypes.begin(), CurTypes.end());
7363 MapBaseValuesArrayTy &BasePointers,
7364 MapValuesArrayTy &Pointers,
7365 MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types,
7366 StructRangeInfoTy &PartialStruct)
const {
7368 "Not expecting to generate map info for a variable array type!");
7372 bool IsFirstComponentList =
true;
7381 if (DevPointersMap.count(VD)) {
7382 BasePointers.emplace_back(Arg, VD);
7383 Pointers.push_back(Arg);
7385 Types.push_back(OMP_MAP_LITERAL | OMP_MAP_TARGET_PARAM);
7391 for (
const auto &L : C->decl_component_lists(VD)) {
7392 assert(L.first == VD &&
7393 "We got information for the wrong declaration??");
7394 assert(!L.second.empty() &&
7395 "Not expecting declaration with no component lists.");
7396 generateInfoForComponentList(C->getMapType(), C->getMapTypeModifier(),
7397 L.second, BasePointers, Pointers, Sizes,
7398 Types, PartialStruct, IsFirstComponentList,
7400 IsFirstComponentList =
false;
7406 void generateInfoForDeclareTargetLink(MapBaseValuesArrayTy &BasePointers,
7407 MapValuesArrayTy &Pointers,
7408 MapValuesArrayTy &Sizes,
7409 MapFlagsArrayTy &Types)
const {
7413 for (
const auto &L : C->component_lists()) {
7416 const auto *VD = dyn_cast<
VarDecl>(L.first);
7420 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
7421 if (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)
7423 StructRangeInfoTy PartialStruct;
7424 generateInfoForComponentList(
7425 C->getMapType(), C->getMapTypeModifier(), L.second, BasePointers,
7426 Pointers, Sizes, Types, PartialStruct,
7427 true, C->isImplicit());
7428 assert(!PartialStruct.Base.isValid() &&
7429 "No partial structs for declare target link expected.");
7438 MapBaseValuesArrayTy &CurBasePointers,
7439 MapValuesArrayTy &CurPointers,
7440 MapValuesArrayTy &CurSizes,
7441 MapFlagsArrayTy &CurMapTypes)
const {
7444 CurBasePointers.push_back(CV);
7445 CurPointers.push_back(CV);
7447 CurSizes.push_back(CGF.
getTypeSize(PtrTy->getPointeeType()));
7449 CurMapTypes.push_back(OMP_MAP_TO | OMP_MAP_FROM);
7451 CurBasePointers.push_back(CV);
7452 CurPointers.push_back(CV);
7456 CurMapTypes.push_back(OMP_MAP_LITERAL);
7461 CurMapTypes.push_back(OMP_MAP_NONE);
7462 CurSizes.push_back(llvm::Constant::getNullValue(CGF.
SizeTy));
7466 CurBasePointers.push_back(CV);
7467 CurPointers.push_back(CV);
7475 CurMapTypes.push_back(getMapModifiersForPrivateClauses(CI));
7478 CurMapTypes.back() |= OMP_MAP_TARGET_PARAM;
7481 CurMapTypes.back() |= OMP_MAP_IMPLICIT;
7488 OMP_DEVICEID_UNDEF = -1,
7498 MappableExprsHandler::MapValuesArrayTy &Pointers,
7499 MappableExprsHandler::MapValuesArrayTy &Sizes,
7501 CGOpenMPRuntime::TargetDataInfo &Info) {
7506 Info.clearArrayInfo();
7507 Info.NumberOfPtrs = BasePointers.size();
7509 if (Info.NumberOfPtrs) {
7512 bool hasRuntimeEvaluationCaptureSize =
false;
7514 if (!isa<llvm::Constant>(S)) {
7515 hasRuntimeEvaluationCaptureSize =
true;
7519 llvm::APInt PointerNumAP(32, Info.NumberOfPtrs,
true);
7524 Info.BasePointersArray =
7526 Info.PointersArray =
7532 if (hasRuntimeEvaluationCaptureSize) {
7543 ConstSizes.push_back(cast<llvm::Constant>(S));
7545 auto *SizesArrayInit = llvm::ConstantArray::get(
7546 llvm::ArrayType::get(CGM.
SizeTy, ConstSizes.size()), ConstSizes);
7548 auto *SizesArrayGbl =
new llvm::GlobalVariable(
7549 CGM.
getModule(), SizesArrayInit->getType(),
7550 true, llvm::GlobalValue::PrivateLinkage,
7551 SizesArrayInit, Name);
7552 SizesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
7553 Info.SizesArray = SizesArrayGbl;
7559 llvm::copy(MapTypes, Mapping.begin());
7560 llvm::Constant *MapTypesArrayInit =
7561 llvm::ConstantDataArray::get(CGF.
Builder.getContext(), Mapping);
7562 std::string MaptypesName =
7564 auto *MapTypesArrayGbl =
new llvm::GlobalVariable(
7565 CGM.
getModule(), MapTypesArrayInit->getType(),
7566 true, llvm::GlobalValue::PrivateLinkage,
7567 MapTypesArrayInit, MaptypesName);
7568 MapTypesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
7569 Info.MapTypesArray = MapTypesArrayGbl;
7571 for (
unsigned I = 0; I < Info.NumberOfPtrs; ++I) {
7574 llvm::ArrayType::get(CGM.
VoidPtrTy, Info.NumberOfPtrs),
7575 Info.BasePointersArray, 0, I);
7577 BP, BPVal->getType()->getPointerTo(0));
7581 if (Info.requiresDevicePointerInfo())
7582 if (
const ValueDecl *DevVD = BasePointers[I].getDevicePtrDecl())
7583 Info.CaptureDeviceAddrMap.try_emplace(DevVD, BPAddr);
7587 llvm::ArrayType::get(CGM.
VoidPtrTy, Info.NumberOfPtrs),
7588 Info.PointersArray, 0, I);
7590 P, PVal->getType()->getPointerTo(0));
7594 if (hasRuntimeEvaluationCaptureSize) {
7596 llvm::ArrayType::get(CGM.
SizeTy, Info.NumberOfPtrs),
7613 llvm::Value *&MapTypesArrayArg, CGOpenMPRuntime::TargetDataInfo &Info) {
7615 if (Info.NumberOfPtrs) {
7617 llvm::ArrayType::get(CGM.
VoidPtrTy, Info.NumberOfPtrs),
7618 Info.BasePointersArray,
7621 llvm::ArrayType::get(CGM.
VoidPtrTy, Info.NumberOfPtrs),
7626 llvm::ArrayType::get(CGM.
SizeTy, Info.NumberOfPtrs), Info.SizesArray,
7629 llvm::ArrayType::get(CGM.
Int64Ty, Info.NumberOfPtrs),
7634 BasePointersArrayArg = llvm::ConstantPointerNull::get(CGM.
VoidPtrPtrTy);
7635 PointersArrayArg = llvm::ConstantPointerNull::get(CGM.
VoidPtrPtrTy);
7636 SizesArrayArg = llvm::ConstantPointerNull::get(CGM.
SizeTy->getPointerTo());
7638 llvm::ConstantPointerNull::get(CGM.
Int64Ty->getPointerTo());
7646 const Expr *IfCond,
const Expr *Device) {
7650 assert(OutlinedFn &&
"Invalid outlined function!");
7657 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
7664 auto &&ThenGen = [
this, Device, OutlinedFn, OutlinedFnID, &D, &InputInfo,
7665 &MapTypesArray, &CS, RequiresOuterTask,
7677 assert(OutlinedFnID &&
"Invalid outlined function ID!");
7682 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
7685 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
7690 CGF.Builder.getInt32(InputInfo.NumberOfTargetItems);
7732 assert(NumThreads &&
"Thread limit expression should be available along " 7733 "with number of teams.");
7737 InputInfo.BasePointersArray.getPointer(),
7738 InputInfo.PointersArray.getPointer(),
7739 InputInfo.SizesArray.getPointer(),
7743 Return = CGF.EmitRuntimeCall(
7751 InputInfo.BasePointersArray.getPointer(),
7752 InputInfo.PointersArray.getPointer(),
7753 InputInfo.SizesArray.getPointer(),
7755 Return = CGF.EmitRuntimeCall(
7762 llvm::BasicBlock *OffloadFailedBlock =
7763 CGF.createBasicBlock(
"omp_offload.failed");
7764 llvm::BasicBlock *OffloadContBlock =
7765 CGF.createBasicBlock(
"omp_offload.cont");
7766 llvm::Value *Failed = CGF.Builder.CreateIsNotNull(Return);
7767 CGF.Builder.CreateCondBr(Failed, OffloadFailedBlock, OffloadContBlock);
7769 CGF.EmitBlock(OffloadFailedBlock);
7770 if (RequiresOuterTask) {
7771 CapturedVars.clear();
7772 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
7775 CGF.EmitBranch(OffloadContBlock);
7777 CGF.EmitBlock(OffloadContBlock,
true);
7781 auto &&ElseGen = [
this, &D, OutlinedFn, &CS, &CapturedVars,
7784 if (RequiresOuterTask) {
7785 CapturedVars.clear();
7786 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
7791 auto &&TargetThenGen = [
this, &ThenGen, &D, &InputInfo, &MapTypesArray,
7792 &CapturedVars, RequiresOuterTask,
7796 MappableExprsHandler::MapValuesArrayTy Pointers;
7797 MappableExprsHandler::MapValuesArrayTy Sizes;
7801 MappableExprsHandler MEHandler(D, CGF);
7803 auto RI = CS.getCapturedRecordDecl()->field_begin();
7804 auto CV = CapturedVars.begin();
7806 CE = CS.capture_end();
7807 CI != CE; ++CI, ++RI, ++CV) {
7809 MappableExprsHandler::MapValuesArrayTy CurPointers;
7810 MappableExprsHandler::MapValuesArrayTy CurSizes;
7812 MappableExprsHandler::StructRangeInfoTy PartialStruct;
7816 if (CI->capturesVariableArrayType()) {
7817 CurBasePointers.push_back(*CV);
7818 CurPointers.push_back(*CV);
7819 CurSizes.push_back(CGF.getTypeSize(RI->getType()));
7821 CurMapTypes.push_back(MappableExprsHandler::OMP_MAP_LITERAL |
7822 MappableExprsHandler::OMP_MAP_TARGET_PARAM);
7826 MEHandler.generateInfoForCapture(CI, *CV, CurBasePointers, CurPointers,
7827 CurSizes, CurMapTypes, PartialStruct);
7828 if (CurBasePointers.empty())
7829 MEHandler.generateDefaultMapInfo(*CI, **RI, *CV, CurBasePointers,
7830 CurPointers, CurSizes, CurMapTypes);
7833 assert(!CurBasePointers.empty() &&
7834 "Non-existing map pointer for capture!");
7835 assert(CurBasePointers.size() == CurPointers.size() &&
7836 CurBasePointers.size() == CurSizes.size() &&
7837 CurBasePointers.size() == CurMapTypes.size() &&
7838 "Inconsistent map information sizes!");
7842 if (PartialStruct.Base.isValid())
7843 MEHandler.emitCombinedEntry(BasePointers, Pointers, Sizes, MapTypes,
7844 CurMapTypes, PartialStruct);
7847 BasePointers.append(CurBasePointers.begin(), CurBasePointers.end());
7848 Pointers.append(CurPointers.begin(), CurPointers.end());
7849 Sizes.append(CurSizes.begin(), CurSizes.end());
7850 MapTypes.append(CurMapTypes.begin(), CurMapTypes.end());
7854 MEHandler.generateInfoForDeclareTargetLink(BasePointers, Pointers, Sizes,
7864 InputInfo.BasePointersArray =
7866 InputInfo.PointersArray =
7870 if (RequiresOuterTask)
7871 CGF.EmitOMPTargetTaskBasedDirective(D, ThenGen, InputInfo);
7876 auto &&TargetElseGen = [
this, &ElseGen, &D, RequiresOuterTask](
7878 if (RequiresOuterTask) {
7880 CGF.EmitOMPTargetTaskBasedDirective(D, ElseGen, InputInfo);
7904 StringRef ParentName) {
7909 bool RequiresDeviceCodegen =
7910 isa<OMPExecutableDirective>(S) &&
7912 cast<OMPExecutableDirective>(S)->getDirectiveKind());
7914 if (RequiresDeviceCodegen) {
7915 const auto &E = *cast<OMPExecutableDirective>(S);
7928 switch (E.getDirectiveKind()) {
7931 cast<OMPTargetDirective>(E));
7933 case OMPD_target_parallel:
7935 CGM, ParentName, cast<OMPTargetParallelDirective>(E));
7937 case OMPD_target_teams:
7939 CGM, ParentName, cast<OMPTargetTeamsDirective>(E));
7941 case OMPD_target_teams_distribute:
7943 CGM, ParentName, cast<OMPTargetTeamsDistributeDirective>(E));
7945 case OMPD_target_teams_distribute_simd:
7947 CGM, ParentName, cast<OMPTargetTeamsDistributeSimdDirective>(E));
7949 case OMPD_target_parallel_for:
7951 CGM, ParentName, cast<OMPTargetParallelForDirective>(E));
7953 case OMPD_target_parallel_for_simd:
7955 CGM, ParentName, cast<OMPTargetParallelForSimdDirective>(E));
7957 case OMPD_target_simd:
7959 CGM, ParentName, cast<OMPTargetSimdDirective>(E));
7961 case OMPD_target_teams_distribute_parallel_for:
7964 cast<OMPTargetTeamsDistributeParallelForDirective>(E));
7966 case OMPD_target_teams_distribute_parallel_for_simd:
7970 cast<OMPTargetTeamsDistributeParallelForSimdDirective>(E));
7974 case OMPD_parallel_for:
7975 case OMPD_parallel_sections:
7977 case OMPD_parallel_for_simd:
7979 case OMPD_cancellation_point:
7981 case OMPD_threadprivate:
7989 case OMPD_taskyield:
7992 case OMPD_taskgroup:
7996 case OMPD_target_data:
7997 case OMPD_target_exit_data:
7998 case OMPD_target_enter_data:
7999 case OMPD_distribute:
8000 case OMPD_distribute_simd:
8001 case OMPD_distribute_parallel_for:
8002 case OMPD_distribute_parallel_for_simd:
8003 case OMPD_teams_distribute:
8004 case OMPD_teams_distribute_simd:
8005 case OMPD_teams_distribute_parallel_for:
8006 case OMPD_teams_distribute_parallel_for_simd:
8007 case OMPD_target_update:
8008 case OMPD_declare_simd:
8009 case OMPD_declare_target:
8010 case OMPD_end_declare_target:
8011 case OMPD_declare_reduction:
8013 case OMPD_taskloop_simd:
8015 llvm_unreachable(
"Unknown target directive for OpenMP device codegen.");
8020 if (
const auto *E = dyn_cast<OMPExecutableDirective>(S)) {
8021 if (!E->hasAssociatedStmt() || !E->getAssociatedStmt())
8025 E->getInnermostCapturedStmt()->getCapturedStmt(), ParentName);
8030 if (
const auto *L = dyn_cast<LambdaExpr>(S))
8039 const auto *FD = cast<FunctionDecl>(GD.
getDecl());
8050 return !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD) &&
8064 StringRef ParentName =
8069 StringRef ParentName =
8077 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
8079 return !Res || *Res == OMPDeclareTargetDeclAttr::MT_Link;
8083 llvm::Constant *Addr) {
8085 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
8089 llvm::GlobalValue::LinkageTypes
Linkage;
8091 case OMPDeclareTargetDeclAttr::MT_To:
8098 std::string RefName =
getName({VarName,
"ref"});
8100 llvm::Constant *AddrRef =
8102 auto *GVAddrRef = cast<llvm::GlobalVariable>(AddrRef);
8103 GVAddrRef->setConstant(
true);
8105 GVAddrRef->setInitializer(Addr);
8110 case OMPDeclareTargetDeclAttr::MT_Link:
8113 VarName = Addr->getName();
8121 Linkage = llvm::GlobalValue::WeakAnyLinkage;
8125 VarName, Addr, VarSize, Flags, Linkage);
8130 if (isa<FunctionDecl>(GD.
getDecl()))
8154 const auto *D = cast<FunctionDecl>(GD.
getDecl());
8158 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(D)) {
8160 if (
auto *F = dyn_cast_or_null<llvm::Function>(
8162 return !F->isDeclaration();
8196 CGF.
Builder.getInt32(CapturedVars.size()),
8199 RealArgs.append(std::begin(Args), std::end(Args));
8200 RealArgs.append(CapturedVars.begin(), CapturedVars.end());
8207 const Expr *NumTeams,
8208 const Expr *ThreadLimit,
8247 auto &&BeginThenGen = [
this, &D, Device, &Info,
8251 MappableExprsHandler::MapValuesArrayTy Pointers;
8252 MappableExprsHandler::MapValuesArrayTy Sizes;
8256 MappableExprsHandler MCHandler(D, CGF);
8257 MCHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);
8267 SizesArrayArg, MapTypesArrayArg, Info);
8272 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
8275 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
8279 llvm::Value *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);
8282 DeviceID, PointerNum, BasePointersArrayArg,
8283 PointersArrayArg, SizesArrayArg, MapTypesArrayArg};
8289 if (!Info.CaptureDeviceAddrMap.empty())
8296 assert(Info.isValid() &&
"Invalid data environment closing arguments.");
8303 SizesArrayArg, MapTypesArrayArg, Info);
8308 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
8311 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
8315 llvm::Value *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);
8318 DeviceID, PointerNum, BasePointersArrayArg,
8319 PointersArrayArg, SizesArrayArg, MapTypesArrayArg};
8327 auto &&BeginElseGen = [&Info, &CodeGen, &NoPrivAction](
CodeGenFunction &CGF,
8329 if (!Info.CaptureDeviceAddrMap.empty()) {
8330 CodeGen.setAction(NoPrivAction);
8348 if (Info.CaptureDeviceAddrMap.empty()) {
8349 CodeGen.setAction(NoPrivAction);
8363 const Expr *Device) {
8367 assert((isa<OMPTargetEnterDataDirective>(D) ||
8368 isa<OMPTargetExitDataDirective>(D) ||
8369 isa<OMPTargetUpdateDirective>(D)) &&
8370 "Expecting either target enter, exit data, or update directives.");
8375 auto &&ThenGen = [
this, &D, Device, &InputInfo,
8380 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
8383 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
8387 llvm::Constant *PointerNum =
8388 CGF.Builder.getInt32(InputInfo.NumberOfTargetItems);
8392 InputInfo.BasePointersArray.getPointer(),
8393 InputInfo.PointersArray.getPointer(),
8394 InputInfo.SizesArray.getPointer(),
8402 case OMPD_target_enter_data:
8406 case OMPD_target_exit_data:
8410 case OMPD_target_update:
8416 case OMPD_parallel_for:
8417 case OMPD_parallel_sections:
8419 case OMPD_parallel_for_simd:
8421 case OMPD_cancellation_point:
8423 case OMPD_threadprivate:
8431 case OMPD_taskyield:
8434 case OMPD_taskgroup:
8438 case OMPD_target_data:
8439 case OMPD_distribute:
8440 case OMPD_distribute_simd:
8441 case OMPD_distribute_parallel_for:
8442 case OMPD_distribute_parallel_for_simd:
8443 case OMPD_teams_distribute:
8444 case OMPD_teams_distribute_simd:
8445 case OMPD_teams_distribute_parallel_for:
8446 case OMPD_teams_distribute_parallel_for_simd:
8447 case OMPD_declare_simd:
8448 case OMPD_declare_target:
8449 case OMPD_end_declare_target:
8450 case OMPD_declare_reduction:
8452 case OMPD_taskloop_simd:
8454 case OMPD_target_simd:
8455 case OMPD_target_teams_distribute:
8456 case OMPD_target_teams_distribute_simd:
8457 case OMPD_target_teams_distribute_parallel_for:
8458 case OMPD_target_teams_distribute_parallel_for_simd:
8459 case OMPD_target_teams:
8460 case OMPD_target_parallel:
8461 case OMPD_target_parallel_for:
8462 case OMPD_target_parallel_for_simd:
8464 llvm_unreachable(
"Unexpected standalone target data directive.");
8470 auto &&TargetThenGen = [
this, &ThenGen, &D, &InputInfo, &MapTypesArray](
8474 MappableExprsHandler::MapValuesArrayTy Pointers;
8475 MappableExprsHandler::MapValuesArrayTy Sizes;
8479 MappableExprsHandler MEHandler(D, CGF);
8480 MEHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);
8489 InputInfo.BasePointersArray =
8491 InputInfo.PointersArray =
8493 InputInfo.SizesArray =
8497 CGF.EmitOMPTargetTaskBasedDirective(D, ThenGen, InputInfo);
8515 struct ParamAttrTy {
8517 llvm::APSInt StrideOrArg;
8518 llvm::APSInt Alignment;
8523 ArrayRef<ParamAttrTy> ParamAttrs) {
8552 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
8553 if (ParamAttrs[Offset].Kind == Vector)
8558 for (
unsigned I = 0, E = FD->
getNumParams(); I < E; ++I) {
8559 if (ParamAttrs[I + Offset].Kind == Vector) {
8576 const llvm::APSInt &VLENVal,
8577 ArrayRef<ParamAttrTy> ParamAttrs,
8578 OMPDeclareSimdDeclAttr::BranchStateTy
State) {
8581 unsigned VecRegSize;
8583 ISADataTy ISAData[] = {
8599 case OMPDeclareSimdDeclAttr::BS_Undefined:
8600 Masked.push_back(
'N');
8601 Masked.push_back(
'M');
8603 case OMPDeclareSimdDeclAttr::BS_Notinbranch:
8604 Masked.push_back(
'N');
8606 case OMPDeclareSimdDeclAttr::BS_Inbranch:
8607 Masked.push_back(
'M');
8610 for (
char Mask : Masked) {
8611 for (
const ISADataTy &Data : ISAData) {
8613 llvm::raw_svector_ostream Out(Buffer);
8614 Out <<
"_ZGV" << Data.ISA << Mask;
8616 Out << llvm::APSInt::getUnsigned(Data.VecRegSize /
8621 for (
const ParamAttrTy &ParamAttr : ParamAttrs) {
8622 switch (ParamAttr.Kind){
8623 case LinearWithVarStride:
8624 Out <<
's' << ParamAttr.StrideOrArg;
8628 if (!!ParamAttr.StrideOrArg)
8629 Out << ParamAttr.StrideOrArg;
8638 if (!!ParamAttr.Alignment)
8639 Out <<
'a' << ParamAttr.Alignment;
8641 Out <<
'_' << Fn->getName();
8642 Fn->addFnAttr(Out.str());
8648 llvm::Function *Fn) {
8652 llvm::DenseMap<const Decl *, unsigned> ParamPositions;
8653 if (isa<CXXMethodDecl>(FD))
8654 ParamPositions.try_emplace(FD, 0);
8655 unsigned ParamPos = ParamPositions.size();
8657 ParamPositions.try_emplace(
P->getCanonicalDecl(), ParamPos);
8664 for (
const Expr *E :
Attr->uniforms()) {
8667 if (isa<CXXThisExpr>(E)) {
8668 Pos = ParamPositions[FD];
8670 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
8672 Pos = ParamPositions[PVD];
8674 ParamAttrs[Pos].Kind = Uniform;
8677 auto NI =
Attr->alignments_begin();
8678 for (
const Expr *E :
Attr->aligneds()) {
8682 if (isa<CXXThisExpr>(E)) {
8683 Pos = ParamPositions[FD];
8686 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
8688 Pos = ParamPositions[PVD];
8689 ParmTy = PVD->getType();
8691 ParamAttrs[Pos].Alignment =
8693 ? (*NI)->EvaluateKnownConstInt(C)
8694 : llvm::APSInt::getUnsigned(
8700 auto SI =
Attr->steps_begin();
8701 auto MI =
Attr->modifiers_begin();
8702 for (
const Expr *E :
Attr->linears()) {
8705 if (isa<CXXThisExpr>(E)) {
8706 Pos = ParamPositions[FD];
8708 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
8710 Pos = ParamPositions[PVD];
8712 ParamAttrTy &ParamAttr = ParamAttrs[Pos];
8713 ParamAttr.Kind = Linear;
8715 if (!(*SI)->EvaluateAsInt(ParamAttr.StrideOrArg, C,
8717 if (
const auto *DRE =
8718 cast<DeclRefExpr>((*SI)->IgnoreParenImpCasts())) {
8719 if (
const auto *StridePVD = cast<ParmVarDecl>(DRE->getDecl())) {
8720 ParamAttr.Kind = LinearWithVarStride;
8721 ParamAttr.StrideOrArg = llvm::APSInt::getUnsigned(
8722 ParamPositions[StridePVD->getCanonicalDecl()]);
8730 llvm::APSInt VLENVal;
8731 if (
const Expr *VLEN =
Attr->getSimdlen())
8732 VLENVal = VLEN->EvaluateKnownConstInt(C);
8733 OMPDeclareSimdDeclAttr::BranchStateTy
State =
Attr->getBranchState();
8734 if (CGM.
getTriple().getArch() == llvm::Triple::x86 ||
8735 CGM.
getTriple().getArch() == llvm::Triple::x86_64)
8746 static const int DoacrossFinArgs = 2;
8755 assert(CallArgs.size() == DoacrossFinArgs);
8756 std::copy(CallArgs.begin(), CallArgs.end(), std::begin(Args));
8791 llvm::APInt Size(32, NumIterations.size());
8797 enum { LowerFD = 0, UpperFD, StrideFD };
8799 for (
unsigned I = 0, E = NumIterations.size(); I < E; ++I) {
8806 DimsLVal, *std::next(RD->
field_begin(), UpperFD));
8814 DimsLVal, *std::next(RD->
field_begin(), StrideFD));
8824 llvm::ConstantInt::getSigned(CGM.
Int32Ty, NumIterations.size()),
8833 llvm::Value *FiniArgs[DoacrossCleanupTy::DoacrossFinArgs] = {
8837 llvm::makeArrayRef(FiniArgs));
8848 for (
unsigned I = 0, E = C->
getNumLoops(); I < E; ++I) {
8880 assert(Loc.
isValid() &&
"Outlined function call location must be valid.");
8883 if (
auto *Fn = dyn_cast<llvm::Function>(Callee)) {
8884 if (Fn->doesNotThrow()) {
8895 emitCall(CGF, Loc, OutlinedFn, Args);
8900 const VarDecl *TargetParam)
const {
8912 llvm_unreachable(
"Not supported in SIMD-only mode");
8918 llvm_unreachable(
"Not supported in SIMD-only mode");
8925 bool Tied,
unsigned &NumberOfParts) {
8926 llvm_unreachable(
"Not supported in SIMD-only mode");
8933 const Expr *IfCond) {
8934 llvm_unreachable(
"Not supported in SIMD-only mode");
8941 llvm_unreachable(
"Not supported in SIMD-only mode");
8947 llvm_unreachable(
"Not supported in SIMD-only mode");
8952 llvm_unreachable(
"Not supported in SIMD-only mode");
8958 llvm_unreachable(
"Not supported in SIMD-only mode");
8966 llvm_unreachable(
"Not supported in SIMD-only mode");
8973 llvm_unreachable(
"Not supported in SIMD-only mode");
8980 bool ForceSimpleCall) {
8981 llvm_unreachable(
"Not supported in SIMD-only mode");
8988 llvm_unreachable(
"Not supported in SIMD-only mode");
8994 llvm_unreachable(
"Not supported in SIMD-only mode");
9000 llvm_unreachable(
"Not supported in SIMD-only mode");
9007 llvm_unreachable(
"Not supported in SIMD-only mode");
9013 llvm_unreachable(
"Not supported in SIMD-only mode");
9018 unsigned IVSize,
bool IVSigned,
9021 llvm_unreachable(
"Not supported in SIMD-only mode");
9027 llvm_unreachable(
"Not supported in SIMD-only mode");
9033 llvm_unreachable(
"Not supported in SIMD-only mode");
9040 llvm_unreachable(
"Not supported in SIMD-only mode");
9046 llvm_unreachable(
"Not supported in SIMD-only mode");
9051 llvm_unreachable(
"Not supported in SIMD-only mode");
9057 llvm_unreachable(
"Not supported in SIMD-only mode");
9066 llvm_unreachable(
"Not supported in SIMD-only mode");
9073 llvm_unreachable(
"Not supported in SIMD-only mode");
9080 assert(Options.
SimpleReduction &&
"Only simple reduction is expected.");
9082 ReductionOps, Options);
9088 llvm_unreachable(
"Not supported in SIMD-only mode");
9095 llvm_unreachable(
"Not supported in SIMD-only mode");
9102 llvm_unreachable(
"Not supported in SIMD-only mode");
9107 llvm_unreachable(
"Not supported in SIMD-only mode");
9113 llvm_unreachable(
"Not supported in SIMD-only mode");
9119 llvm_unreachable(
"Not supported in SIMD-only mode");
9124 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
9126 llvm_unreachable(
"Not supported in SIMD-only mode");
9133 const Expr *IfCond,
const Expr *Device) {
9134 llvm_unreachable(
"Not supported in SIMD-only mode");
9138 llvm_unreachable(
"Not supported in SIMD-only mode");
9142 llvm_unreachable(
"Not supported in SIMD-only mode");
9158 llvm_unreachable(
"Not supported in SIMD-only mode");
9162 const Expr *NumTeams,
9163 const Expr *ThreadLimit,
9165 llvm_unreachable(
"Not supported in SIMD-only mode");
9171 llvm_unreachable(
"Not supported in SIMD-only mode");
9176 const Expr *Device) {
9177 llvm_unreachable(
"Not supported in SIMD-only mode");
9183 llvm_unreachable(
"Not supported in SIMD-only mode");
9188 llvm_unreachable(
"Not supported in SIMD-only mode");
9193 const VarDecl *NativeParam)
const {
9194 llvm_unreachable(
"Not supported in SIMD-only mode");
9200 const VarDecl *TargetParam)
const {
9201 llvm_unreachable(
"Not supported in SIMD-only mode");
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
llvm::PointerType * Int8PtrPtrTy
RecordDecl * buildImplicitRecord(StringRef Name, RecordDecl::TagKind TK=TTK_Struct) const
Create a new implicit TU-level CXXRecordDecl or RecordDecl declaration.
TBAAAccessInfo getTBAAInfoForSubobject(LValue Base, QualType AccessType)
getTBAAInfoForSubobject - Get TBAA information for an access with a given base lvalue.
void pushTerminate()
Push a terminate handler on the stack.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, llvm::Type *BaseLVType, CharUnits BaseLVAlignment, llvm::Value *Addr)
virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S)
Emit the captured statement body.
DisableAutoDeclareTargetRAII(CodeGenModule &CGM)
static llvm::Value * emitParallelOrTeamsOutlinedFunction(CodeGenModule &CGM, const OMPExecutableDirective &D, const CapturedStmt *CS, const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind, const StringRef OutlinedHelperName, const RegionCodeGenTy &CodeGen)
This represents '#pragma omp task' directive.
static const Decl * getCanonicalDecl(const Decl *D)
Represents a function declaration or definition.
llvm::IntegerType * IntTy
int
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
External linkage, which indicates that the entity can be referred to from other translation units...
virtual Address getAddressOfLocalVariable(CodeGenFunction &CGF, const VarDecl *VD)
Gets the OpenMP-specific address of the local variable.
Expr * getUpperBoundVariable() const
Other implicit parameter.
QualType TgtDeviceImageQTy
struct __tgt_device_image{ void *ImageStart; // Pointer to the target code start. ...
unsigned getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it...
PointerType - C99 6.7.5.1 - Pointer Declarators.
Scheduling data for loop-based OpenMP directives.
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
A (possibly-)qualified type.
CodeGenTypes & getTypes()
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.
const CodeGenOptions & getCodeGenOpts() const
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 Data Additional data for task generation like final list of privates etc *void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D, llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds, const Expr *IfCond, const OMPTaskDataTy &Data) override
Address CreateMemTemp(QualType T, const Twine &Name="tmp", Address *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
const RecordDecl * KmpTaskTQTyRD
static void EmitOMPTargetParallelForSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelForSimdDirective &S)
Emit device code for the target parallel for simd directive.
void emitSingleReductionCombiner(CodeGenFunction &CGF, const Expr *ReductionOp, const Expr *PrivateRef, const DeclRefExpr *LHS, const DeclRefExpr *RHS)
Emits single reduction combiner.
llvm::SmallPtrSet< const VarDecl *, 4 > ThreadPrivateWithDefinition
Set of threadprivate variables with the generated initializer.
void actOnDeviceGlobalVarEntriesInfo(const OffloadDeviceGlobalVarEntryInfoActTy &Action)
The standard implementation of ConstantInitBuilder used in Clang.
Stmt - This represents one statement.
Expr * getLowerBoundVariable() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
virtual void emitUserDefinedReduction(CodeGenFunction *CGF, const OMPDeclareReductionDecl *D)
Emit code for the specified user defined reduction construct.
Expr * getLoopData(unsigned NumLoop)
Get the loop data.
bool capturesThis() const
Determine whether this capture handles the C++ 'this' pointer.
VarDecl * getCapturedVar() const
Retrieve the declaration of the variable being captured.
bool emitTargetGlobal(GlobalDecl GD) override
Emit the global GD if it is meaningful for the target.
CharUnits getAlignOfGlobalVarInChars(QualType T) const
Return the alignment in characters that should be given to a global variable with type T...
QualType getTgtBinaryDescriptorQTy()
Returns __tgt_bin_desc type.
SmallVector< std::pair< OpenMPDependClauseKind, const Expr * >, 4 > Dependences
CGOpenMPRuntime(CodeGenModule &CGM, StringRef FirstSeparator, StringRef Separator)
Constructor allowing to redefine the name separator for the variables.
bool isRecordType() const
void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc, const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned, bool Ordered, const DispatchRTInput &DispatchValues) override
This is used for non static scheduled types and when the ordered clause is present on the loop constr...
Address getParameterAddress(CodeGenFunction &CGF, const VarDecl *NativeParam, const VarDecl *TargetParam) const override
Gets the address of the native argument basing on the address of the target-specific parameter...
SmallVector< const Expr *, 4 > LastprivateCopies
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
Entry is a target region.
CharUnits getPointerSize() const
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...
virtual llvm::Value * emitTaskReductionInit(CodeGenFunction &CGF, SourceLocation Loc, ArrayRef< const Expr *> LHSExprs, ArrayRef< const Expr *> RHSExprs, const OMPTaskDataTy &Data)
Emit a code for initialization of task reduction clause.
const RecordType * getAsStructureType() const
llvm::Value * getTypeSize(QualType Ty)
Returns calculated size of the specified type.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
static bool stable_sort_comparator(const PrivateDataTy P1, const PrivateDataTy P2)
static llvm::Value * emitTaskPrivateMappingFunction(CodeGenModule &CGM, SourceLocation Loc, ArrayRef< const Expr *> PrivateVars, ArrayRef< const Expr *> FirstprivateVars, ArrayRef< const Expr *> LastprivateVars, QualType PrivatesQTy, ArrayRef< PrivateDataTy > Privates)
Emit a privates mapping function for correct handling of private and firstprivate variables...
virtual Address getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF, QualType VarType, StringRef Name)
Creates artificial threadprivate variable with name Name and type VarType.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
Call to void __kmpc_threadprivate_register( ident_t *, void *data, kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
ReductionCodeGen(ArrayRef< const Expr *> Shareds, ArrayRef< const Expr *> Privates, ArrayRef< const Expr *> ReductionOps)
static RecordDecl * createPrivatesRecordDecl(CodeGenModule &CGM, ArrayRef< PrivateDataTy > Privates)
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target data offload directive.
The base class of the type hierarchy.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
void emitReduction(CodeGenFunction &CGF, SourceLocation Loc, ArrayRef< const Expr *> Privates, ArrayRef< const Expr *> LHSExprs, ArrayRef< const Expr *> RHSExprs, ArrayRef< const Expr *> ReductionOps, ReductionOptionsTy Options) override
Emit a code for reduction clause.
void emitTargetDataStandAloneCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond, const Expr *Device) override
Emit the data mapping/movement code associated with the directive D that should be of the form 'targe...
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
virtual const FieldDecl * lookup(const VarDecl *VD) const
Lookup the captured field decl for a variable.
llvm::Value * PointersArray
The array of section pointers passed to the runtime library.
virtual void completeDefinition()
Note that the definition of this type is now complete.
QualType withConst() const
bool markAsGlobalTarget(GlobalDecl GD)
Marks the declaration as alread emitted for the device code and returns true, if it was marked alread...
const TargetInfo & getTargetInfo() const
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to...
void scanForTargetRegionsFunctions(const Stmt *S, StringRef ParentName)
Start scanning from statement S and and emit all target regions found along the way.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Represents a C++ constructor within a class.
static void EmitOMPAggregateReduction(CodeGenFunction &CGF, QualType Type, const VarDecl *LHSVar, const VarDecl *RHSVar, const llvm::function_ref< void(CodeGenFunction &CGF, const Expr *, const Expr *, const Expr *)> &RedOpGen, const Expr *XExpr=nullptr, const Expr *EExpr=nullptr, const Expr *UpExpr=nullptr)
Emit reduction operation for each element of array (required for array sections) LHS op = RHS...
llvm::Value * getCriticalRegionLock(StringRef CriticalName)
Returns corresponding lock object for the specified critical region name.
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.
OpenMPSchedType
Schedule types for 'omp for' loops (these enumerators are taken from the enum sched_type in kmp...
SmallVector< const Expr *, 4 > ReductionCopies
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
llvm::Function * GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S)
Represents a variable declaration or definition.
Objects with "hidden" visibility are not seen by the dynamic linker.
llvm::Value * getThreadID(CodeGenFunction &CGF, SourceLocation Loc)
Gets thread id value for the current thread.
QualType getReturnType() const
This represents 'num_threads' clause in the '#pragma omp ...' directive.
virtual void emitOutlinedFunctionCall(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn, ArrayRef< llvm::Value *> Args=llvm::None) const
Emits call of the outlined function with the provided arguments, translating these arguments to corre...
const T * getAs() const
Member-template getAs<specific type>'.
Extra information about a function prototype.
bool supportsCOMDAT() const
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
virtual llvm::Value * emitForNext(CodeGenFunction &CGF, SourceLocation Loc, unsigned IVSize, bool IVSigned, Address IL, Address LB, Address UB, Address ST)
Call __kmpc_dispatch_next( ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter, kmp_int[32|64] *p_lowe...
DiagnosticsEngine & getDiags() const
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
llvm::Value * getPointer() const
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
Represents a parameter to a function.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
static std::string generateUniqueName(CodeGenModule &CGM, StringRef Prefix, const Expr *Ref)
Generates unique name for artificial threadprivate variables.
void createOffloadEntriesAndInfoMetadata()
Creates all the offload entries in the current compilation unit along with the associated metadata...
static unsigned evaluateCDTSize(const FunctionDecl *FD, ArrayRef< ParamAttrTy > ParamAttrs)
std::string getName(ArrayRef< StringRef > Parts) const
Get the platform-specific name separator.
static void EmitOMPTargetParallelDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelDirective &S)
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
Struct that keeps all the relevant information that should be kept throughout a 'target data' region...
QualType getTgtOffloadEntryQTy()
Returns __tgt_offload_entry type.
virtual void emitTargetDataStandAloneCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond, const Expr *Device)
Emit the data mapping/movement code associated with the directive D that should be of the form 'targe...
SmallVector< const Expr *, 4 > PrivateVars
Represents a struct/union/class.
llvm::DenseMap< const VarDecl *, FieldDecl * > LambdaCaptureFields
Source[4] in Fortran, do not use for C++.
static llvm::Value * emitDestructorsFunction(CodeGenModule &CGM, SourceLocation Loc, QualType KmpInt32Ty, QualType KmpTaskTWithPrivatesPtrQTy, QualType KmpTaskTWithPrivatesQTy)
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
emitDestroy - Immediately perform the destruction of the given object.
static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, LValue BaseLV)
Address getAddress() const
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
virtual void emitMasterRegion(CodeGenFunction &CGF, const RegionCodeGenTy &MasterOpGen, SourceLocation Loc)
Emits a master region.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
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...
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...
Call to void *__kmpc_threadprivate_cached(ident_t *loc, kmp_int32 global_tid, void *data...
llvm::IntegerType * Int64Ty
The scope used to remap some variables as private in the OpenMP loop body (or other captured region e...
field_range fields() const
SmallVector< const Expr *, 4 > LastprivateVars
virtual void emitDoacrossOrdered(CodeGenFunction &CGF, const OMPDependClause *C)
Emit code for doacross ordered directive with 'depend' clause.
Represents a member of a struct/union/class.
CharUnits getAlignment() const
llvm::IntegerType * SizeTy
const CapturedStmt * getCapturedStmt(OpenMPDirectiveKind RegionKind) const
Returns the captured statement associated with the component region within the (combined) directive...
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
std::pair< llvm::Value *, llvm::Value * > getSizes(unsigned N) const
Returns the size of the reduction item (in chars and total number of elements in the item)...
LValue EmitOMPArraySectionExpr(const OMPArraySectionExpr *E, bool IsLowerBound=true)
static void emitOffloadingArrays(CodeGenFunction &CGF, MappableExprsHandler::MapBaseValuesArrayTy &BasePointers, MappableExprsHandler::MapValuesArrayTy &Pointers, MappableExprsHandler::MapValuesArrayTy &Sizes, MappableExprsHandler::MapFlagsArrayTy &MapTypes, CGOpenMPRuntime::TargetDataInfo &Info)
Emit the arrays used to pass the captures and map information to the offloading runtime library...
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
void startDefinition()
Starts the definition of this tag declaration.
bool isReferenceType() const
This represents clause 'map' in the '#pragma omp ...' directives.
InitKind getInitializerKind() const
Get initializer kind.
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...
OMPTargetGlobalVarEntryKind
Kind of the global variable entry..
virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const
Check if the specified ScheduleKind is dynamic.
static Address emitAddrOfVarFromArray(CodeGenFunction &CGF, Address Array, unsigned Index, const VarDecl *Var)
Given an array of pointers to variables, project the address of a given variable. ...
This represents clause 'to' in the '#pragma omp ...' directives.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
clang::CharUnits operator*(clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU)
llvm::Type * getKmpc_MicroPointerTy()
Returns pointer to kmpc_micro type.
OpenMPDirectiveKind getDirectiveKind() const
This is a common base class for loop directives ('omp simd', 'omp for', 'omp for simd' etc...
void emitNumThreadsClause(CodeGenFunction &CGF, llvm::Value *NumThreads, SourceLocation Loc) override
Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid, kmp_int32 num_threads)...
virtual bool emitTargetFunctions(GlobalDecl GD)
Emit the target regions enclosed in GD function definition or the function itself in case it is a val...
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const
Return the store size, in character units, of the given LLVM type.
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
ArrayRef< ParmVarDecl * > parameters() const
Mark the entry as a to declare target.
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
void emitProcBindClause(CodeGenFunction &CGF, OpenMPProcBindClauseKind ProcBind, SourceLocation Loc) override
Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid, int proc_bind) to generat...
virtual void emitDoacrossInit(CodeGenFunction &CGF, const OMPLoopDirective &D, ArrayRef< Expr *> NumIterations)
Emit initialization for doacross loop nesting support.
virtual void emitTargetCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, llvm::Value *OutlinedFn, llvm::Value *OutlinedFnID, const Expr *IfCond, const Expr *Device)
Emit the target offloading code associated with D.
Expr * getInitializer()
Get initializer expression (if specified) of the declare reduction construct.
QualType TgtOffloadEntryQTy
Type struct __tgt_offload_entry{ void *addr; // Pointer to the offload entry info.
static void buildStructValue(ConstantStructBuilder &Fields, CodeGenModule &CGM, const RecordDecl *RD, const CGRecordLayout &RL, ArrayRef< llvm::Constant *> Data)
static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr, QualType Type, bool EmitDeclareReductionInit, const Expr *Init, const OMPDeclareReductionDecl *DRD, Address SrcAddr=Address::invalid())
Emit initialization of arrays of complex types.
llvm::Function * emitRegistrationFunction() override
Creates the offloading descriptor in the event any target region was emitted in the current module an...
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.
void emitForOrderedIterationEnd(CodeGenFunction &CGF, SourceLocation Loc, unsigned IVSize, bool IVSigned) override
Call the appropriate runtime routine to notify that we finished iteration of the ordered loop with th...
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
bool requiresLandingPad() const
virtual void emitTargetDataCalls(CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond, const Expr *Device, const RegionCodeGenTy &CodeGen, TargetDataInfo &Info)
Emit the target data mapping code associated with D.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type...
void emitCleanups(CodeGenFunction &CGF, unsigned N, Address PrivateAddr)
Emits cleanup code for the reduction item.
RAII for correct setting/restoring of CapturedStmtInfo.
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 Data Additional data for task generation like final list of privates etc *virtual void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D, llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds, const Expr *IfCond, const OMPTaskDataTy &Data)
CharUnits getAlignment() const
Return the alignment of this pointer.
void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc) override
Emits code for a taskyield directive.
llvm::PointerType * VoidPtrTy
bool empty() const
Return true if a there are no entries defined.
String describing the source location.
void emitMasterRegion(CodeGenFunction &CGF, const RegionCodeGenTy &MasterOpGen, SourceLocation Loc) override
Emits a master region.
virtual std::pair< llvm::Function *, llvm::Function * > getUserDefinedReduction(const OMPDeclareReductionDecl *D)
Get combiner/initializer for the specified user-defined reduction, if any.
void actOnTargetRegionEntriesInfo(const OffloadTargetRegionEntryInfoActTy &Action)
OpenMPScheduleClauseModifier M2
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind...
void emitTargetCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, llvm::Value *OutlinedFn, llvm::Value *OutlinedFnID, const Expr *IfCond, const Expr *Device) override
Emit the target offloading code associated with D.
SmallVector< const Expr *, 4 > PrivateCopies
SourceLocation getLocStart() const LLVM_READONLY
Returns starting location of directive kind.
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
unsigned NumberOfPtrs
The total number of pointers passed to the runtime library.
void operator()(CodeGenFunction &CGF) const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
Address adjustPrivateAddress(CodeGenFunction &CGF, unsigned N, Address PrivateAddr)
Adjusts PrivatedAddr for using instead of the original variable address in normal operations...
Expr * getSizeExpr() const
Scope - A scope is a transient data structure that is used while parsing the program.
llvm::PointerType * VoidPtrPtrTy
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
virtual void emitDeclareSimdFunction(const FunctionDecl *FD, llvm::Function *Fn)
Marks function Fn with properly mangled versions of vector functions.
field_iterator field_begin() const
bool usesReductionInitializer(unsigned N) const
Returns true if the initialization of the reduction item uses initializer from declare reduction cons...
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
virtual void emitTeamsCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, SourceLocation Loc, llvm::Value *OutlinedFn, ArrayRef< llvm::Value *> CapturedVars)
Emits code for teams call of the OutlinedFn with variables captured in a record which address is stor...
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.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
SmallVector< const Expr *, 4 > FirstprivateCopies
OpenMPDependClauseKind getDependencyKind() const
Get dependency type.
static void emitPrivatesInit(CodeGenFunction &CGF, const OMPExecutableDirective &D, Address KmpTaskSharedsPtr, LValue TDBase, const RecordDecl *KmpTaskTWithPrivatesQTyRD, QualType SharedsTy, QualType SharedsPtrTy, const OMPTaskDataTy &Data, ArrayRef< PrivateDataTy > Privates, bool ForDup)
Emit initialization for private variables in task-based directives.
static int addMonoNonMonoModifier(OpenMPSchedType Schedule, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2)
llvm::Value * emitReductionFunction(CodeGenModule &CGM, SourceLocation Loc, llvm::Type *ArgsType, ArrayRef< const Expr *> Privates, ArrayRef< const Expr *> LHSExprs, ArrayRef< const Expr *> RHSExprs, ArrayRef< const Expr *> ReductionOps)
Emits reduction function.
DiagnosticsEngine & getDiagnostics() const
static llvm::Function * emitCombinerOrInitializer(CodeGenModule &CGM, QualType Ty, const Expr *CombinerInitializer, const VarDecl *In, const VarDecl *Out, bool IsCombiner)
static void emitOffloadingArraysArgument(CodeGenFunction &CGF, llvm::Value *&BasePointersArrayArg, llvm::Value *&PointersArrayArg, llvm::Value *&SizesArrayArg, llvm::Value *&MapTypesArrayArg, CGOpenMPRuntime::TargetDataInfo &Info)
Emit the arguments to be passed to the runtime library based on the arrays of pointers, sizes and map types.
Support for OpenMP 4.5 monotonic and nonmonotonic schedule modifiers.
static const OMPDeclareReductionDecl * getReductionInit(const Expr *ReductionOp)
Check if the combiner is a call to UDR combiner and if it is so return the UDR decl used for reductio...
llvm::Value * emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc, unsigned Flags=0)
Emits object of ident_t type with info for source location.
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
virtual llvm::Value * emitTeamsOutlinedFunction(const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)
Emits outlined function for the specified OpenMP teams directive D.
CharUnits getPointerAlign() const
SmallVector< const Expr *, 4 > ReductionOps
This represents clause 'is_device_ptr' in the '#pragma omp ...' directives.
llvm::SmallDenseSet< const FunctionDecl * > AlreadyEmittedTargetFunctions
SmallVector< const Expr *, 4 > ReductionVars
virtual void emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind)
Call the appropriate runtime routine to notify that we finished all the work with current loop...
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
This represents clause 'from' in the '#pragma omp ...' directives.
LValue EmitLValueForField(LValue Base, const FieldDecl *Field)
const VarDecl * translateParameter(const FieldDecl *FD, const VarDecl *NativeParam) const override
Translates the native parameter of outlined function if this is required for target.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create a new runtime function with the specified type and name.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
OpenMP 4.0 [2.4, Array Sections].
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
ASTContext & getContext() const
void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName, const RegionCodeGenTy &CriticalOpGen, SourceLocation Loc, const Expr *Hint=nullptr) override
Emits a critical region.
virtual Address getAddrOfDeclareTargetLink(const VarDecl *VD)
Returns the address of the variable marked as declare target with link clause.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
Describes the capture of either a variable, or 'this', or variable-length array type.
const CodeGen::CGBlockInfo * BlockInfo
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
virtual Address getParameterAddress(CodeGenFunction &CGF, const VarDecl *NativeParam, const VarDecl *TargetParam) const
Gets the address of the native argument basing on the address of the target-specific parameter...
llvm::Constant * createForStaticInitFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_for_static_init_* runtime function for the specified size IVSize and sign IVSigned...
CGBlockInfo - Information to generate a block literal.
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...
OMP_IDENT_xxx flags; OMP_IDENT_KMPC identifies this union member.
LValueBaseInfo getBaseInfo() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
bool needCleanups(unsigned N)
Returns true if the private copy requires cleanups.
Class intended to support codegen of all kind of the reduction clauses.
llvm::Constant * createDispatchFiniFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_dispatch_fini_* runtime function for the specified size IVSize and sign IVSigned...
Expr * getCombiner()
Get combiner expression of the declare reduction construct.
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.
unsigned getNumLoops() const
Get number of loops associated with the clause.
virtual void createOffloadEntry(llvm::Constant *ID, llvm::Constant *Addr, uint64_t Size, int32_t Flags, llvm::GlobalValue::LinkageTypes Linkage)
Creates offloading entry for the provided entry ID ID, address Addr, size Size, and flags Flags...
static llvm::GlobalVariable * createConstantGlobalStruct(CodeGenModule &CGM, QualType Ty, ArrayRef< llvm::Constant *> Data, const Twine &Name, As &&... Args)
llvm::CallingConv::ID getRuntimeCC() const
QualType getTgtDeviceImageQTy()
Returns __tgt_device_image type.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
KmpTaskTFields
Indexes of fields for type kmp_task_t.
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
virtual void emitTaskReductionFixups(CodeGenFunction &CGF, SourceLocation Loc, ReductionCodeGen &RCG, unsigned N)
Required to resolve existing problems in the runtime.
virtual void emitFlush(CodeGenFunction &CGF, ArrayRef< const Expr *> Vars, SourceLocation Loc)
Emit flush of the variables specified in 'omp flush' directive.
static void createConstantGlobalStructAndAddToParent(CodeGenModule &CGM, QualType Ty, ArrayRef< llvm::Constant *> Data, T &Parent)
bool addPrivate(const VarDecl *LocalVD, const llvm::function_ref< Address()> PrivateGen)
Registers LocalVD variable as a private and apply PrivateGen function for it to generate correspondin...
void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc) override
Emit code for 'taskwait' directive.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Expr - This represents one expression.
Allow any unmodeled side effect.
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.
void loadOffloadInfoMetadata()
Loads all the offload entries information from the host IR metadata.
static void emitInitWithReductionInitializer(CodeGenFunction &CGF, const OMPDeclareReductionDecl *DRD, const Expr *InitOp, Address Private, Address Original, QualType Ty)
static llvm::Value * emitReduceCombFunction(CodeGenModule &CGM, SourceLocation Loc, ReductionCodeGen &RCG, unsigned N, const Expr *ReductionOp, const Expr *LHS, const Expr *RHS, const Expr *PrivateRef)
Emits reduction combiner function:
const AnnotatedLine * Line
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
static llvm::Value * emitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc, OpenMPDirectiveKind Kind, 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.
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
std::string OMPHostIRFile
Name of the IR file that contains the result of the OpenMP target host code generation.
void emitKmpRoutineEntryT(QualType KmpInt32Ty)
Build type kmp_routine_entry_t (if not built yet).
const T * castAs() const
Member-template castAs<specific type>.
llvm::BasicBlock * getBlock() const
unsigned getLine() const
Return the presumed line number of this location.
llvm::Value * emitForNext(CodeGenFunction &CGF, SourceLocation Loc, unsigned IVSize, bool IVSigned, Address IL, Address LB, Address UB, Address ST) override
Call __kmpc_dispatch_next( ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter, kmp_int[32|64] *p_lowe...
static bool checkDestructorsRequired(const RecordDecl *KmpTaskTWithPrivatesQTyRD)
Checks if destructor function is required to be generated.
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) override
Emits a single region.
Represents a C++ destructor within a class.
static RTCancelKind getCancellationKind(OpenMPDirectiveKind CancelRegion)
QualType SavedKmpTaskloopTQTy
Saved kmp_task_t for taskloop-based directive.
static RecordDecl * createKmpTaskTRecordDecl(CodeGenModule &CGM, OpenMPDirectiveKind Kind, QualType KmpInt32Ty, QualType KmpRoutineEntryPointerQTy)
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements, of a variable length array type, plus that largest non-variably-sized element type.
llvm::PointerType * getType() const
Return the type of the pointer value.
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
Address getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF, QualType VarType, StringRef Name) override
Creates artificial threadprivate variable with name Name and type VarType.
DeclContext * getDeclContext()
static llvm::iterator_range< specific_clause_iterator< SpecificClause > > getClausesOfKind(ArrayRef< OMPClause *> Clauses)
Mark the entry as a to declare target link.
void emitFlush(CodeGenFunction &CGF, ArrayRef< const Expr *> Vars, SourceLocation Loc) override
Emit flush of the variables specified in 'omp flush' directive.
virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, llvm::Constant *Dtor, llvm::Constant *Addr)=0
Emit code to force the execution of a destructor during global teardown.
static OpenMPSchedType getRuntimeSchedule(OpenMPScheduleClauseKind ScheduleKind, bool Chunked, bool Ordered)
Map the OpenMP loop schedule to the runtime enumeration.
llvm::IntegerType * Int32Ty
llvm::GlobalValue::LinkageTypes getLLVMLinkageVarDefinition(const VarDecl *VD, bool IsConstant)
Returns LLVM linkage for a declarator.
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
Provides LLVM's BitmaskEnum facility to enumeration types declared in namespace clang.
SmallVector< const Expr *, 4 > FirstprivateVars
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
TBAAAccessInfo getTBAAInfo() const
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
static llvm::Value * emitCopyprivateCopyFunction(CodeGenModule &CGM, llvm::Type *ArgsType, ArrayRef< const Expr *> CopyprivateVars, ArrayRef< const Expr *> DestExprs, ArrayRef< const Expr *> SrcExprs, ArrayRef< const Expr *> AssignmentOps, SourceLocation Loc)
virtual Address getAddrOfThreadPrivate(CodeGenFunction &CGF, const VarDecl *VD, Address VDAddr, SourceLocation Loc)
Returns address of the threadprivate variable for the current thread.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
QualType getRecordType(const RecordDecl *Decl) const
Represents an unpacked "presumed" location which can be presented to the user.
void Emit(CodeGenFunction &CGF, Flags) override
Emit the cleanup.
virtual void emitTargetOutlinedFunctionHelper(const OMPExecutableDirective &D, StringRef ParentName, llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID, bool IsOffloadEntry, const RegionCodeGenTy &CodeGen)
Helper to emit outlined function for 'target' directive.
void registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID, StringRef ParentName, unsigned LineNum, llvm::Constant *Addr, llvm::Constant *ID, OMPTargetRegionEntryKind Flags)
Register target region entry.
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
llvm::Function * emitThreadPrivateVarDefinition(const VarDecl *VD, Address VDAddr, SourceLocation Loc, bool PerformInit, CodeGenFunction *CGF=nullptr) override
Emit a code for initialization of threadprivate variable.
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
This represents clause 'firstprivate' in the '#pragma omp ...' directives.
void emitTaskgroupRegion(CodeGenFunction &CGF, const RegionCodeGenTy &TaskgroupOpGen, SourceLocation Loc) override
Emit a taskgroup region.
const Qualifiers & getQuals() const
Address getAddrOfThreadPrivate(CodeGenFunction &CGF, const VarDecl *VD, Address VDAddr, SourceLocation Loc) override
Returns address of the threadprivate variable for the current thread.
const LangOptions & getLangOpts() const
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()
ASTContext & getContext() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
OpenMPProcBindClauseKind
OpenMP attributes for 'proc_bind' clause.
llvm::Constant * createDispatchInitFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_dispatch_init_* runtime function for the specified size IVSize and sign IVSigned...
virtual void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName, const RegionCodeGenTy &CriticalOpGen, SourceLocation Loc, const Expr *Hint=nullptr)
Emits a critical region.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
GlobalDecl - represents a global declaration.
bool hasClausesOfKind() const
Returns true if the current directive has one or more clauses of a specific kind. ...
llvm::Value * emitParallelOutlinedFunction(const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) override
Emits outlined function for the specified OpenMP parallel directive D.
virtual bool emitTargetGlobalVariable(GlobalDecl GD)
Emit the global variable if it is a valid device global variable.
void finishAndAddTo(AggregateBuilderBase &parent)
Given that this builder was created by beginning an array or struct component on the given parent bui...
CanQualType getCanonicalTypeUnqualified() const
QualType KmpDependInfoTy
Type typedef struct kmp_depend_info { kmp_intptr_t base_addr; size_t len; struct { bool in:1; bool ou...
static llvm::Value * emitNumThreadsForTargetDirective(CGOpenMPRuntime &OMPRuntime, CodeGenFunction &CGF, const OMPExecutableDirective &D)
Emit the number of threads for a target directive.
LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy)
QualType TgtBinaryDescriptorQTy
struct __tgt_bin_desc{ int32_t NumDevices; // Number of devices supported.
The l-value was considered opaque, so the alignment was determined from a type.
RecordDecl * getDecl() const
const char * getFilename() const
Return the presumed filename of this location.
const SpecificClause * getSingleClause() const
Gets a single clause of the specified kind associated with the current directive iff there is only on...
static void emitReductionCombiner(CodeGenFunction &CGF, const Expr *ReductionOp)
Emit reduction combiner.
Expr * getStrideVariable() const
This represents 'num_teams' clause in the '#pragma omp ...' directive.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
virtual void registerTargetGlobalVariable(const VarDecl *VD, llvm::Constant *Addr)
Checks if the provided global decl GD is a declare target variable and registers it when emitting cod...
static llvm::Value * emitNumTeamsForTargetDirective(CGOpenMPRuntime &OMPRuntime, CodeGenFunction &CGF, const OMPExecutableDirective &D)
Emit the number of teams for a target directive.
CanProxy< U > castAs() const
This captures a statement into a function.
QualType getCanonicalType() const
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
unsigned getColumn() const
Return the presumed column number of this location.
static with chunk adjustment (e.g., simd)
void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
pushDestroy - Push the standard destructor for the given type as at least a normal cleanup...
void emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond, const RegionCodeGenTy &ThenGen, const RegionCodeGenTy &ElseGen)
Emits code for OpenMP 'if' clause using specified CodeGen function.
void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, const Expr *IfCond, OpenMPDirectiveKind CancelRegion) override
Emit code for 'cancel' construct.
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
llvm::Type * getIdentTyPointerTy()
Returns pointer to ident_t type.
llvm::Value * MapTypesArray
The array of map types passed to the runtime library.
This represents '#pragma omp declare reduction ...' directive.
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
llvm::PointerIntPair< llvm::Value *, 1, bool > Final
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
virtual void emitSingleRegion(CodeGenFunction &CGF, const RegionCodeGenTy &SingleOpGen, SourceLocation Loc, ArrayRef< const Expr *> CopyprivateVars, ArrayRef< const Expr *> DestExprs, ArrayRef< const Expr *> SrcExprs, ArrayRef< const Expr *> AssignmentOps)
Emits a single region.
virtual void emitNumTeamsClause(CodeGenFunction &CGF, const Expr *NumTeams, const Expr *ThreadLimit, SourceLocation Loc)
Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32 global_tid, kmp_int32 num_teams...
void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind Kind, bool EmitChecks=true, bool ForceSimpleCall=false) override
Emit an implicit/explicit barrier for OpenMP threads.
This is a basic class for representing single OpenMP executable directive.
bool emitTargetGlobalVariable(GlobalDecl GD) override
Emit the global variable if it is a valid device global variable.
llvm::Value * emitTeamsOutlinedFunction(const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) override
Emits outlined function for the specified OpenMP teams directive D.
Lower bound for 'ordered' versions.
ASTContext & getASTContext() const LLVM_READONLY
SourceLocation getLocStart() const LLVM_READONLY
const Decl * getDecl() const
virtual void emitCancellationPointCall(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind CancelRegion)
Emit code for 'cancellation point' construct.
OpenMPDirectiveKind
OpenMP directives.
bool capturesVariable() const
Determine whether this capture handles a variable (by reference).
void emitDoacrossInit(CodeGenFunction &CGF, const OMPLoopDirective &D, ArrayRef< Expr *> NumIterations) override
Emit initialization for doacross loop nesting support.
Set if the nonmonotonic schedule modifier was present.
virtual llvm::Function * emitThreadPrivateVarDefinition(const VarDecl *VD, Address VDAddr, SourceLocation Loc, bool PerformInit, CodeGenFunction *CGF=nullptr)
Emit a code for initialization of threadprivate variable.
OpenMPLinearClauseKind Modifier
Modifier of 'linear' clause.
Target region entries info.
const ParmVarDecl * getParamDecl(unsigned i) const
static void EmitOMPTargetSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetSimdDirective &S)
Emit device code for the target simd directive.
Device global variable entries info.
void emitDistributeStaticInit(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDistScheduleClauseKind SchedKind, const StaticRTInput &Values) override
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
bool isTrivialInitializer(const Expr *Init)
Determine whether the given initializer is trivial in the sense that it requires no code to be genera...
void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind, const OpenMPScheduleTy &ScheduleKind, const StaticRTInput &Values) override
Call the appropriate runtime routine to initialize it before start of loop.
virtual llvm::Value * emitTaskOutlinedFunction(const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, const VarDecl *PartIDVar, const VarDecl *TaskTVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, bool Tied, unsigned &NumberOfParts)
Emits outlined function for the OpenMP task directive D.
void emitAggregateType(CodeGenFunction &CGF, unsigned N)
Emits the code for the variable-modified type, if required.
static void EmitOMPTargetTeamsDistributeParallelForDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeParallelForDirective &S)
bool isAnyPointerType() const
unsigned size() const
Return number of entries defined so far.
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.
Stmt * getCapturedStmt()
Retrieve the statement being captured.
void emitTargetDataCalls(CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond, const Expr *Device, const RegionCodeGenTy &CodeGen, TargetDataInfo &Info) override
Emit the target data mapping code associated with D.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after...
virtual void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn, ArrayRef< llvm::Value *> CapturedVars, const Expr *IfCond)
Emits code for parallel or serial call of the OutlinedFn with variables captured in a record which ad...
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
void emitThreadPrivateVarInit(CodeGenFunction &CGF, Address VDAddr, llvm::Value *Ctor, llvm::Value *CopyCtor, llvm::Value *Dtor, SourceLocation Loc)
Emits initialization code for the threadprivate variables.
Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, const llvm::DataLayout &DL, const llvm::Twine &Name="")
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...
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...
virtual void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc)
Emits code for a taskyield directive.
void EmitAggregateAssign(LValue Dest, LValue Src, QualType EltTy)
Emit an aggregate assignment.
CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)
llvm::Value * NewTaskNewTaskTTy
bool hasTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID, StringRef ParentName, unsigned LineNum) const
Return true if a target region entry with the provided information exists.
virtual void functionFinished(CodeGenFunction &CGF)
Cleans up references to the objects in finished function.
const Expr * getRefExpr(unsigned N) const
Returns the base declaration of the reduction item.
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void emitTaskReductionFixups(CodeGenFunction &CGF, SourceLocation Loc, ReductionCodeGen &RCG, unsigned N) override
Required to resolve existing problems in the runtime.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
void registerDeviceGlobalVarEntryInfo(StringRef VarName, llvm::Constant *Addr, CharUnits VarSize, OMPTargetGlobalVarEntryKind Flags, llvm::GlobalValue::LinkageTypes Linkage)
Register device global variable entry.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character...
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 Data Additional data for task generation like final list of privates etc *TaskResultTy emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D, llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds, const OMPTaskDataTy &Data)
llvm::Constant * GetAddrOfGlobal(GlobalDecl GD, ForDefinition_t IsForDefinition=NotForDefinition)
static void EmitOMPTargetTeamsDistributeDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeDirective &S)
Emit device code for the target teams distribute directive.
A basic class for pre|post-action for advanced codegen sequence for OpenMP region.
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.
void emitOrderedRegion(CodeGenFunction &CGF, const RegionCodeGenTy &OrderedOpGen, SourceLocation Loc, bool IsThreads) override
Emit an ordered region.
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
FunctionArgList - Type for representing both the decl and type of parameters to a function...
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 Data Additional data for task generation like final list of privates etc *void emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D, llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds, const Expr *IfCond, const OMPTaskDataTy &Data) override
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
static void emitX86DeclareSimdFunction(const FunctionDecl *FD, llvm::Function *Fn, const llvm::APSInt &VLENVal, ArrayRef< ParamAttrTy > ParamAttrs, OMPDeclareSimdDeclAttr::BranchStateTy State)
void setAction(PrePostActionTy &Action) const
CGFunctionInfo - Class to encapsulate the information about a function definition.
This class organizes the cross-function state that is used while generating LLVM code.
QualType withRestrict() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
static const VarDecl * getBaseDecl(const Expr *Ref, const DeclRefExpr *&DE)
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
LValue EmitOMPSharedLValue(const Expr *E)
Emits the lvalue for the expression with possibly captured variable.
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
Dataflow Directional Tag Classes.
static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)
Apply TemporaryLocation if it is valid.
static void emitForStaticInitCall(CodeGenFunction &CGF, llvm::Value *UpdateLocation, llvm::Value *ThreadId, llvm::Constant *ForStaticInitFunction, OpenMPSchedType Schedule, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, const CGOpenMPRuntime::StaticRTInput &Values)
Class provides a way to call simple version of codegen for OpenMP region, or an advanced with possibl...
LValue EmitLoadOfReferenceLValue(LValue RefLVal)
static llvm::Value * emitReduceInitFunction(CodeGenModule &CGM, SourceLocation Loc, ReductionCodeGen &RCG, unsigned N)
Emits reduction initializer function:
bool isValid() const
Return true if this is a valid SourceLocation object.
bool emitTargetFunctions(GlobalDecl GD) override
Emit the target regions enclosed in GD function definition or the function itself in case it is a val...
llvm::Value * emitTaskOutlinedFunction(const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, const VarDecl *PartIDVar, const VarDecl *TaskTVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, bool Tied, unsigned &NumberOfParts) override
Emits outlined function for the OpenMP task directive D.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
virtual bool emitTargetGlobal(GlobalDecl GD)
Emit the global GD if it is meaningful for the target.
virtual void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, const Expr *IfCond, OpenMPDirectiveKind CancelRegion)
Emit code for 'cancel' construct.
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
A basic class for pre|post-action for advanced codegen sequence for OpenMP region.
LValue getSharedLValue(unsigned N) const
Returns LValue for the reduction item.
const Expr * getInit() const
llvm::Constant * getPointer() const
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 Data Additional data for task generation like final list of privates etc *virtual void emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D, llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds, const Expr *IfCond, const OMPTaskDataTy &Data)
void initializeTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID, StringRef ParentName, unsigned LineNum, unsigned Order)
Initialize target region entry.
llvm::Function * createOffloadingBinaryDescriptorRegistration()
Creates and registers offloading binary descriptor for the current compilation unit.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::IntegerType * IntPtrTy
llvm::PointerIntPair< llvm::Value *, 1, bool > Priority
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
SourceLocation getLocStart() const LLVM_READONLY
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Module & getModule() const
Call to void __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro microtask, ...
Not really used in Fortran any more.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
virtual void emitTargetOutlinedFunction(const OMPExecutableDirective &D, StringRef ParentName, llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID, bool IsOffloadEntry, const RegionCodeGenTy &CodeGen)
Emit outilined function for 'target' directive.
llvm::StructType * ConvertRecordDeclType(const RecordDecl *TD)
ConvertRecordDeclType - Lay out a tagged decl type like struct or union.
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
virtual Address emitThreadIDAddress(CodeGenFunction &CGF, SourceLocation Loc)
Emits address of the word in a memory where current thread id is stored.
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.
OffloadEntriesInfoManagerTy OffloadEntriesInfoManager
virtual bool isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind, bool Chunked) const
Check if the specified ScheduleKind is static non-chunked.
bool capturesVariableByCopy() const
Determine whether this capture handles a variable by copy.
API for captured statement code generation.
virtual bool emitDeclareTargetVarDefinition(const VarDecl *VD, llvm::GlobalVariable *Addr, bool PerformInit)
Emit a code for initialization of declare target variable.
virtual void emitDistributeStaticInit(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDistScheduleClauseKind SchedKind, const StaticRTInput &Values)
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
virtual StringRef getOutlinedHelperName() const
Get the function name of an outlined region.
static bool classof(const OMPClause *T)
virtual void emitOrderedRegion(CodeGenFunction &CGF, const RegionCodeGenTy &OrderedOpGen, SourceLocation Loc, bool IsThreads)
Emit an ordered region.
This file defines OpenMP AST classes for executable directives and clauses.
static FieldDecl * addFieldToRecordDecl(ASTContext &C, DeclContext *DC, QualType FieldTy)
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
Address CreateConstArrayGEP(Address Addr, uint64_t Index, CharUnits EltSize, const llvm::Twine &Name="")
Given addr = [n x T]* ...
static void EmitOMPTargetTeamsDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDirective &S)
Emit device code for the target teams directive.
CleanupTy(PrePostActionTy *Action)
llvm::Type * getElementType() const
Return the type of the values stored in this address.
void initializeDeviceGlobalVarEntryInfo(StringRef Name, OMPTargetGlobalVarEntryKind Flags, unsigned Order)
Initialize device global variable entry.
static bool checkInitIsRequired(CodeGenFunction &CGF, ArrayRef< PrivateDataTy > Privates)
Check if duplication function is required for taskloops.
llvm::Value * EmitCheckedInBoundsGEP(llvm::Value *Ptr, ArrayRef< llvm::Value *> IdxList, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, const Twine &Name="")
Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to detect undefined behavior whe...
static void getTargetEntryUniqueInfo(ASTContext &C, SourceLocation Loc, unsigned &DeviceID, unsigned &FileID, unsigned &LineNum)
Obtain information that uniquely identifies a target entry.
llvm::PointerType * Int8PtrTy
Address getTaskReductionItem(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *ReductionsPtr, LValue SharedLVal) override
Get the address of void * type of the privatue copy of the reduction item specified by the SharedLVal...
llvm::AssertingVH< llvm::Instruction > AllocaInsertPt
AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...
OpenMPLocationFlags
Values for bit flags used in the ident_t to describe the fields.
virtual void emitInlinedDirective(CodeGenFunction &CGF, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, bool HasCancel=false)
Emit code for the directive that does not require outlining.
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
Expr * getNumIterations() const
llvm::StringRef getName() const
Return the IR name of the pointer value.
llvm::StructType * getLLVMType() const
Return the "complete object" LLVM type associated with this record.
Base for LValueReferenceType and RValueReferenceType.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Entity that registers the offloading constants that were emitted so far.
void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
StringRef getMangledName(GlobalDecl GD)
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 addDecl(Decl *D)
Add the declaration D into this context.
FieldDecl * LambdaThisCaptureField
void emitCall(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *Callee, ArrayRef< llvm::Value *> Args=llvm::None) const
Emits Callee function call with arguments Args with location Loc.
llvm::Constant * createDispatchNextFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_dispatch_next_* runtime function for the specified size IVSize and sign IVSigned...
Mark the entry as target region.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
virtual void emitTaskgroupRegion(CodeGenFunction &CGF, const RegionCodeGenTy &TaskgroupOpGen, SourceLocation Loc)
Emit a taskgroup region.
SourceManager & getSourceManager()
virtual llvm::Function * emitRegistrationFunction()
Creates the offloading descriptor in the event any target region was emitted in the current module an...
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.
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
Mark the entry as a global destructor.
Address LoadCXXThisAddress()
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
Lower bound for default (unordered) versions.
void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn, ArrayRef< llvm::Value *> CapturedVars, const Expr *IfCond) override
Emits code for parallel or serial call of the OutlinedFn with variables captured in a record which ad...
void emitNumTeamsClause(CodeGenFunction &CGF, const Expr *NumTeams, const Expr *ThreadLimit, SourceLocation Loc) override
Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32 global_tid, kmp_int32 num_teams...
TranslationUnitDecl * getTranslationUnitDecl() const
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
virtual void emitReduction(CodeGenFunction &CGF, SourceLocation Loc, ArrayRef< const Expr *> Privates, ArrayRef< const Expr *> LHSExprs, ArrayRef< const Expr *> RHSExprs, ArrayRef< const Expr *> ReductionOps, ReductionOptionsTy Options)
Emit a code for reduction clause.
This represents 'nowait' clause in the '#pragma omp ...' directive.
llvm::PointerIntPair< llvm::Value *, 1, bool > Schedule
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.
llvm::Function * CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false)
llvm::Value * BasePointersArray
The array of base pointer passed to the runtime library.
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
static llvm::Value * emitReduceFiniFunction(CodeGenModule &CGM, SourceLocation Loc, ReductionCodeGen &RCG, unsigned N)
Emits reduction finalizer function:
~DisableAutoDeclareTargetRAII()
OpenMPOffloadingReservedDeviceIDs
llvm::Type * ConvertType(QualType T)
bool isTLSSupported() const
Whether the target supports thread-local storage.
void emitDoacrossOrdered(CodeGenFunction &CGF, const OMPDependClause *C) override
Emit code for doacross ordered directive with 'depend' clause.
Privates[]
Gets the list of initial values for linear variables.
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
static const Stmt * ignoreCompoundStmts(const Stmt *Body)
discard all CompoundStmts intervening between two constructs
LValue EmitLValue(const Expr *E)
EmitLValue - Emit code to compute a designator that specifies the location of the expression...
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
llvm::SmallPtrSet< const VarDecl *, 4 > DeclareTargetWithDefinition
Set of declare target variables with the generated initializer.
void popTerminate()
Pops a terminate handler off the stack.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
Entry is a declare target variable.
virtual void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind Kind, bool EmitChecks=true, bool ForceSimpleCall=false)
Emit an implicit/explicit barrier for OpenMP threads.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void emitTargetOutlinedFunction(const OMPExecutableDirective &D, StringRef ParentName, llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID, bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) override
Emit outilined function for 'target' directive.
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
static llvm::Value * emitTaskDupFunction(CodeGenModule &CGM, SourceLocation Loc, const OMPExecutableDirective &D, QualType KmpTaskTWithPrivatesPtrQTy, const RecordDecl *KmpTaskTWithPrivatesQTyRD, const RecordDecl *KmpTaskTQTyRD, QualType SharedsTy, QualType SharedsPtrTy, const OMPTaskDataTy &Data, ArrayRef< PrivateDataTy > Privates, bool WithLastIter)
Emit task_dup function (for initialization of private/firstprivate/lastprivate vars and last_iter fla...
virtual void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc, const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned, bool Ordered, const DispatchRTInput &DispatchValues)
Call the appropriate runtime routine to initialize it before start of loop.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
static RecordDecl * createKmpTaskTWithPrivatesRecordDecl(CodeGenModule &CGM, QualType KmpTaskTQTy, ArrayRef< PrivateDataTy > Privates)
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...
CGCXXABI & getCXXABI() const
const VariableArrayType * getAsVariableArrayType(QualType T) const
Mark the entry as a global constructor.
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
A reference to a declared variable, function, enum, etc.
QualType getIntPtrType() const
Return a type compatible with "intptr_t" (C99 7.18.1.4), as defined by the target.
static RValue get(llvm::Value *V)
virtual void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind, const OpenMPScheduleTy &ScheduleKind, const StaticRTInput &Values)
Call the appropriate runtime routine to initialize it before start of loop.
llvm::Value * emitTaskReductionInit(CodeGenFunction &CGF, SourceLocation Loc, ArrayRef< const Expr *> LHSExprs, ArrayRef< const Expr *> RHSExprs, const OMPTaskDataTy &Data) override
Emit a code for initialization of task reduction clause.
bool isPointerType() const
static void EmitOMPTargetDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetDirective &S)
Emit device code for the target directive.
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
ParamKindTy
Kind of parameter in a function with 'declare simd' directive.
static void EmitOMPTargetParallelForDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelForDirective &S)
Emit device code for the target parallel for directive.
QualType KmpDimTy
struct kmp_dim { // loop bounds info casted to kmp_int64 kmp_int64 lo; // lower kmp_int64 up; // uppe...
void emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind) override
Call the appropriate runtime routine to notify that we finished all the work with current loop...
An l-value expression is a reference to an object with independent storage.
static RValue getAggregate(Address addr, bool isVolatile=false)
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
SourceLocation getLocEnd() const LLVM_READONLY
Returns ending location of directive.
LValue - This represents an lvalue references.
Information for lazily generating a cleanup.
QualType SavedKmpTaskTQTy
Saved kmp_task_t for task directive.
virtual Address getTaskReductionItem(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *ReductionsPtr, LValue SharedLVal)
Get the address of void * type of the privatue copy of the reduction item specified by the SharedLVal...
Represents a C array with a specified size that is not an integer-constant-expression.
void emitTeamsCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, SourceLocation Loc, llvm::Value *OutlinedFn, ArrayRef< llvm::Value *> CapturedVars) override
Emits code for teams call of the OutlinedFn with variables captured in a record which address is stor...
const LangOptions & getLangOpts() const
llvm::Constant * createRuntimeFunction(unsigned Function)
Returns specified OpenMP runtime function.
static FieldDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle)
Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)
emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
llvm::Value * getPointer() const
This class handles loading and caching of source files into memory.
void emitCancellationPointCall(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind CancelRegion) override
Emit code for 'cancellation point' construct.
A helper class of ConstantInitBuilder, used for building constant array initializers.
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)...
bool capturesVariableArrayType() const
Determine whether this capture handles a variable-length array type.
bool isLocalVarDeclOrParm() const
Similar to isLocalVarDecl but also includes parameters.
Attr - This represents one attribute.
SmallVector< const Expr *, 4 > FirstprivateInits
SourceLocation getLocation() const
This represents clause 'use_device_ptr' in the '#pragma omp ...' directives.
static void EmitOMPTargetTeamsDistributeSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeSimdDirective &S)
Emit device code for the target teams distribute simd directive.
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
bool isExternallyVisible() const
llvm::Constant * getOrCreateThreadPrivateCache(const VarDecl *VD)
If the specified mangled name is not in the module, create and return threadprivate cache object...
llvm::Value * SizesArray
The array of sizes passed to the runtime library.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth, signed/unsigned.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
bool Privatize()
Privatizes local variables previously registered as private.
static void EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeParallelForSimdDirective &S)
Emit device code for the target teams distribute parallel for simd directive.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc)
Emit code for 'taskwait' directive.
unsigned getLLVMFieldNo(const FieldDecl *FD) const
Return llvm::StructType element number that corresponds to the field FD.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const llvm::Triple & getTriple() const