21 #include "llvm/ADT/ArrayRef.h" 22 #include "llvm/ADT/BitmaskEnum.h" 23 #include "llvm/Bitcode/BitcodeReader.h" 24 #include "llvm/IR/CallSite.h" 25 #include "llvm/IR/DerivedTypes.h" 26 #include "llvm/IR/GlobalValue.h" 27 #include "llvm/IR/Value.h" 28 #include "llvm/Support/Format.h" 29 #include "llvm/Support/raw_ostream.h" 32 using namespace clang;
33 using namespace CodeGen;
40 enum CGOpenMPRegionKind {
43 ParallelOutlinedRegion,
54 const CGOpenMPRegionKind RegionKind,
57 : CGCapturedStmtInfo(CS,
CR_OpenMP), RegionKind(RegionKind),
58 CodeGen(CodeGen), Kind(Kind), HasCancel(HasCancel) {}
60 CGOpenMPRegionInfo(
const CGOpenMPRegionKind RegionKind,
63 : CGCapturedStmtInfo(
CR_OpenMP), RegionKind(RegionKind), CodeGen(CodeGen),
64 Kind(Kind), HasCancel(HasCancel) {}
68 virtual const VarDecl *getThreadIDVariable()
const = 0;
79 CGOpenMPRegionKind getRegionKind()
const {
return RegionKind; }
83 bool hasCancel()
const {
return HasCancel; }
85 static bool classof(
const CGCapturedStmtInfo *Info) {
89 ~CGOpenMPRegionInfo()
override =
default;
92 CGOpenMPRegionKind RegionKind;
99 class CGOpenMPOutlinedRegionInfo final :
public CGOpenMPRegionInfo {
104 StringRef HelperName)
105 : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind,
107 ThreadIDVar(ThreadIDVar), HelperName(HelperName) {
108 assert(ThreadIDVar !=
nullptr &&
"No ThreadID in OpenMP region.");
113 const VarDecl *getThreadIDVariable()
const override {
return ThreadIDVar; }
116 StringRef getHelperName()
const override {
return HelperName; }
118 static bool classof(
const CGCapturedStmtInfo *Info) {
120 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
121 ParallelOutlinedRegion;
128 StringRef HelperName;
132 class CGOpenMPTaskOutlinedRegionInfo final :
public CGOpenMPRegionInfo {
138 llvm::SwitchInst *UntiedSwitch =
nullptr;
141 UntiedTaskActionTy(
bool Tied,
const VarDecl *PartIDVar,
143 : Untied(!Tied), PartIDVar(PartIDVar), UntiedCodeGen(UntiedCodeGen) {}
152 UntiedSwitch = CGF.
Builder.CreateSwitch(Res, DoneBB);
156 UntiedSwitch->addCase(CGF.
Builder.getInt32(0),
158 emitUntiedSwitch(CGF);
173 UntiedSwitch->addCase(CGF.
Builder.getInt32(UntiedSwitch->getNumCases()),
179 unsigned getNumberOfParts()
const {
return UntiedSwitch->getNumCases(); }
185 const UntiedTaskActionTy &Action)
186 : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen, Kind, HasCancel),
187 ThreadIDVar(ThreadIDVar), Action(Action) {
188 assert(ThreadIDVar !=
nullptr &&
"No ThreadID in OpenMP region.");
193 const VarDecl *getThreadIDVariable()
const override {
return ThreadIDVar; }
199 StringRef getHelperName()
const override {
return ".omp_outlined."; }
202 Action.emitUntiedSwitch(CGF);
205 static bool classof(
const CGCapturedStmtInfo *Info) {
207 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
216 const UntiedTaskActionTy &Action;
221 class CGOpenMPInlinedRegionInfo :
public CGOpenMPRegionInfo {
226 : CGOpenMPRegionInfo(InlinedRegion, CodeGen, Kind, HasCancel),
228 OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {}
233 return OuterRegionInfo->getContextValue();
234 llvm_unreachable(
"No context value for inlined OpenMP region");
238 if (OuterRegionInfo) {
239 OuterRegionInfo->setContextValue(V);
242 llvm_unreachable(
"No context value for inlined OpenMP region");
248 return OuterRegionInfo->lookup(VD);
254 FieldDecl *getThisFieldDecl()
const override {
256 return OuterRegionInfo->getThisFieldDecl();
262 const VarDecl *getThreadIDVariable()
const override {
264 return OuterRegionInfo->getThreadIDVariable();
271 return OuterRegionInfo->getThreadIDVariableLValue(CGF);
272 llvm_unreachable(
"No LValue for inlined OpenMP construct");
276 StringRef getHelperName()
const override {
277 if (
auto *OuterRegionInfo = getOldCSI())
278 return OuterRegionInfo->getHelperName();
279 llvm_unreachable(
"No helper name for inlined OpenMP construct");
284 OuterRegionInfo->emitUntiedSwitch(CGF);
289 static bool classof(
const CGCapturedStmtInfo *Info) {
291 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == InlinedRegion;
294 ~CGOpenMPInlinedRegionInfo()
override =
default;
299 CGOpenMPRegionInfo *OuterRegionInfo;
307 class CGOpenMPTargetRegionInfo final :
public CGOpenMPRegionInfo {
311 : CGOpenMPRegionInfo(CS, TargetRegion, CodeGen, OMPD_target,
313 HelperName(HelperName) {}
317 const VarDecl *getThreadIDVariable()
const override {
return nullptr; }
320 StringRef getHelperName()
const override {
return HelperName; }
322 static bool classof(
const CGCapturedStmtInfo *Info) {
324 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == TargetRegion;
328 StringRef HelperName;
332 llvm_unreachable(
"No codegen for expressions");
336 class CGOpenMPInnerExprInfo final :
public CGOpenMPInlinedRegionInfo {
339 : CGOpenMPInlinedRegionInfo(CGF.CapturedStmtInfo, EmptyCodeGen,
347 if (!
C.capturesVariable() && !
C.capturesVariableByCopy())
350 const VarDecl *VD =
C.getCapturedVar();
358 PrivScope.addPrivate(VD, [&CGF, &DRE]() ->
Address {
362 (void)PrivScope.Privatize();
367 if (
auto *FD = CGOpenMPInlinedRegionInfo::lookup(VD))
374 llvm_unreachable(
"No body for expressions");
379 const VarDecl *getThreadIDVariable()
const override {
380 llvm_unreachable(
"No thread id for expressions");
384 StringRef getHelperName()
const override {
385 llvm_unreachable(
"No helper name for expressions");
388 static bool classof(
const CGCapturedStmtInfo *Info) {
return false; }
396 class InlinedOpenMPRegionRAII {
398 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
399 FieldDecl *LambdaThisCaptureField =
nullptr;
420 ~InlinedOpenMPRegionRAII() {
437 OMP_IDENT_IMD = 0x01,
439 OMP_IDENT_KMPC = 0x02,
441 OMP_ATOMIC_REDUCE = 0x10,
443 OMP_IDENT_BARRIER_EXPL = 0x20,
445 OMP_IDENT_BARRIER_IMPL = 0x40,
447 OMP_IDENT_BARRIER_IMPL_FOR = 0x40,
449 OMP_IDENT_BARRIER_IMPL_SECTIONS = 0xC0,
451 OMP_IDENT_BARRIER_IMPL_SINGLE = 0x140,
453 OMP_IDENT_WORK_LOOP = 0x200,
455 OMP_IDENT_WORK_SECTIONS = 0x400,
457 OMP_IDENT_WORK_DISTRIBUTE = 0x800,
458 LLVM_MARK_AS_BITMASK_ENUM(OMP_IDENT_WORK_DISTRIBUTE)
738 Callback(CodeGen, CGF, *PrePostAction);
741 Callback(CodeGen, CGF, Action);
749 if (
auto *CE = dyn_cast<CallExpr>(ReductionOp))
750 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
752 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
753 if (
auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl()))
764 std::pair<llvm::Function *, llvm::Function *> Reduction =
766 auto *CE = cast<CallExpr>(InitOp);
767 auto *OVE = cast<OpaqueValueExpr>(CE->getCallee());
770 auto *LHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(LHS)->getSubExpr());
771 auto *RHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(RHS)->getSubExpr());
773 PrivateScope.addPrivate(cast<VarDecl>(LHSDRE->getDecl()),
774 [=]() ->
Address {
return Private; });
775 PrivateScope.addPrivate(cast<VarDecl>(RHSDRE->getDecl()),
776 [=]() ->
Address {
return Original; });
777 (void)PrivateScope.Privatize();
783 auto *GV =
new llvm::GlobalVariable(
785 llvm::GlobalValue::PrivateLinkage, Init,
".init");
831 SrcBegin = SrcAddr.getPointer();
834 auto DestEnd = CGF.
Builder.CreateGEP(DestBegin, NumElements);
839 CGF.
Builder.CreateICmpEQ(DestBegin, DestEnd,
"omp.arrayinit.isempty");
840 CGF.
Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
843 auto EntryBB = CGF.
Builder.GetInsertBlock();
848 llvm::PHINode *SrcElementPHI =
nullptr;
851 SrcElementPHI = CGF.
Builder.CreatePHI(SrcBegin->getType(), 2,
852 "omp.arraycpy.srcElementPast");
853 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
856 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
858 llvm::PHINode *DestElementPHI = CGF.
Builder.CreatePHI(
859 DestBegin->getType(), 2,
"omp.arraycpy.destElementPast");
860 DestElementPHI->addIncoming(DestBegin, EntryBB);
868 if (EmitDeclareReductionInit) {
870 SrcElementCurrent, ElementTy);
878 auto SrcElementNext = CGF.
Builder.CreateConstGEP1_32(
879 SrcElementPHI, 1,
"omp.arraycpy.dest.element");
880 SrcElementPHI->addIncoming(SrcElementNext, CGF.
Builder.GetInsertBlock());
884 auto DestElementNext = CGF.
Builder.CreateConstGEP1_32(
885 DestElementPHI, 1,
"omp.arraycpy.dest.element");
888 CGF.
Builder.CreateICmpEQ(DestElementNext, DestEnd,
"omp.arraycpy.done");
889 CGF.
Builder.CreateCondBr(Done, DoneBB, BodyBB);
890 DestElementPHI->addIncoming(DestElementNext, CGF.
Builder.GetInsertBlock());
902 if (
const auto *OASE = dyn_cast<OMPArraySectionExpr>(E))
907 void ReductionCodeGen::emitAggregateInitialization(
914 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
915 bool EmitDeclareReductionInit =
918 EmitDeclareReductionInit,
919 EmitDeclareReductionInit ? ClausesData[N].ReductionOp
920 : PrivateVD->getInit(),
927 ClausesData.reserve(Shareds.size());
928 SharedAddresses.reserve(Shareds.size());
929 Sizes.reserve(Shareds.size());
930 BaseDecls.reserve(Shareds.size());
931 auto IPriv = Privates.begin();
932 auto IRed = ReductionOps.begin();
933 for (
const auto *Ref : Shareds) {
934 ClausesData.emplace_back(Ref, *IPriv, *IRed);
935 std::advance(IPriv, 1);
936 std::advance(IRed, 1);
941 assert(SharedAddresses.size() == N &&
942 "Number of generated lvalues must be exactly N.");
943 LValue First = emitSharedLValue(CGF, ClausesData[N].Ref);
944 LValue Second = emitSharedLValueUB(CGF, ClausesData[N].Ref);
945 SharedAddresses.emplace_back(First, Second);
950 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
951 QualType PrivateType = PrivateVD->getType();
952 bool AsArraySection = isa<OMPArraySectionExpr>(ClausesData[N].Ref);
953 if (!PrivateType->isVariablyModifiedType()) {
956 SharedAddresses[N].first.getType().getNonReferenceType()),
963 cast<llvm::PointerType>(SharedAddresses[N].first.getPointer()->getType())
965 auto *ElemSizeOf = llvm::ConstantExpr::getSizeOf(ElemType);
966 if (AsArraySection) {
967 Size = CGF.
Builder.CreatePtrDiff(SharedAddresses[N].second.getPointer(),
968 SharedAddresses[N].first.getPointer());
969 Size = CGF.
Builder.CreateNUWAdd(
970 Size, llvm::ConstantInt::get(Size->getType(), 1));
971 SizeInChars = CGF.
Builder.CreateNUWMul(Size, ElemSizeOf);
974 SharedAddresses[N].first.getType().getNonReferenceType());
975 Size = CGF.
Builder.CreateExactUDiv(SizeInChars, ElemSizeOf);
977 Sizes.emplace_back(SizeInChars, Size);
980 cast<OpaqueValueExpr>(
989 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
990 QualType PrivateType = PrivateVD->getType();
991 if (!PrivateType->isVariablyModifiedType()) {
992 assert(!Size && !Sizes[N].second &&
993 "Size should be nullptr for non-variably modified reduction " 999 cast<OpaqueValueExpr>(
1008 assert(SharedAddresses.size() > N &&
"No variable was generated");
1010 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1012 QualType PrivateType = PrivateVD->getType();
1015 QualType SharedType = SharedAddresses[N].first.getType();
1019 SharedType, SharedAddresses[N].first.getBaseInfo(),
1022 emitAggregateInitialization(CGF, N, PrivateAddr, SharedLVal, DRD);
1023 }
else if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
1027 }
else if (!DefaultInit(CGF) && PrivateVD->hasInit() &&
1030 PrivateVD->
getType().getQualifiers(),
1037 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1038 QualType PrivateType = PrivateVD->getType();
1046 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1047 QualType PrivateType = PrivateVD->getType();
1049 if (needCleanups(N)) {
1052 CGF.
pushDestroy(DTorKind, PrivateAddr, PrivateType);
1101 return Address(Addr, BaseLVAlignment);
1107 const VarDecl *OrigVD =
nullptr;
1108 if (
auto *OASE = dyn_cast<OMPArraySectionExpr>(ClausesData[N].Ref)) {
1109 auto *
Base = OASE->getBase()->IgnoreParenImpCasts();
1110 while (
auto *TempOASE = dyn_cast<OMPArraySectionExpr>(
Base))
1111 Base = TempOASE->getBase()->IgnoreParenImpCasts();
1112 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
1113 Base = TempASE->getBase()->IgnoreParenImpCasts();
1114 DE = cast<DeclRefExpr>(
Base);
1115 OrigVD = cast<VarDecl>(DE->
getDecl());
1116 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(ClausesData[N].Ref)) {
1117 auto *
Base = ASE->getBase()->IgnoreParenImpCasts();
1118 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
1119 Base = TempASE->getBase()->IgnoreParenImpCasts();
1120 DE = cast<DeclRefExpr>(
Base);
1121 OrigVD = cast<VarDecl>(DE->
getDecl());
1124 BaseDecls.emplace_back(OrigVD);
1125 auto OriginalBaseLValue = CGF.
EmitLValue(DE);
1128 OriginalBaseLValue);
1130 BaseLValue.
getPointer(), SharedAddresses[N].first.getPointer());
1134 SharedAddresses[N].first.getAddress().getType());
1137 SharedAddresses[N].first.getType(),
1138 OriginalBaseLValue.getAddress().getType(),
1139 OriginalBaseLValue.getAlignment(), Ptr);
1141 BaseDecls.emplace_back(
1142 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Ref)->getDecl()));
1170 LValue CGOpenMPTaskOutlinedRegionInfo::getThreadIDVariableLValue(
1173 getThreadIDVariable()->
getType(),
1183 KmpCriticalNameTy = llvm::ArrayType::get(CGM.
Int32Ty, 8);
1189 InternalVars.clear();
1192 static llvm::Function *
1194 const Expr *CombinerInitializer,
const VarDecl *In,
1195 const VarDecl *Out,
bool IsCombiner) {
1198 QualType PtrTy = C.getPointerType(Ty).withRestrict();
1204 Args.push_back(&OmpOutParm);
1205 Args.push_back(&OmpInParm);
1211 IsCombiner ?
".omp_combiner." :
".omp_initializer.", &CGM.
getModule());
1213 Fn->removeFnAttr(llvm::Attribute::NoInline);
1214 Fn->removeFnAttr(llvm::Attribute::OptimizeNone);
1215 Fn->addFnAttr(llvm::Attribute::AlwaysInline);
1232 if (!IsCombiner && Out->
hasInit() &&
1238 if (CombinerInitializer)
1247 if (UDRMap.count(D) > 0)
1251 In = &C.Idents.get(
"omp_in");
1252 Out = &C.Idents.get(
"omp_out");
1258 llvm::Function *Initializer =
nullptr;
1260 if (!Priv || !Orig) {
1261 Priv = &C.Idents.get(
"omp_priv");
1262 Orig = &C.Idents.get(
"omp_orig");
1272 UDRMap.insert(std::make_pair(D, std::make_pair(Combiner, Initializer)));
1274 auto &Decls = FunctionUDRMap.FindAndConstruct(CGF->
CurFn);
1275 Decls.second.push_back(D);
1279 std::pair<llvm::Function *, llvm::Function *>
1281 auto I = UDRMap.find(D);
1282 if (I != UDRMap.end())
1285 return UDRMap.lookup(D);
1302 const llvm::Twine &Name =
"") {
1312 "thread id variable must be of type kmp_int32 *");
1314 bool HasCancel =
false;
1315 if (
auto *OPD = dyn_cast<OMPParallelDirective>(&D))
1316 HasCancel = OPD->hasCancel();
1317 else if (
auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&D))
1318 HasCancel = OPSD->hasCancel();
1319 else if (
auto *OPFD = dyn_cast<OMPParallelForDirective>(&D))
1320 HasCancel = OPFD->hasCancel();
1321 else if (
auto *OPFD = dyn_cast<OMPTargetParallelForDirective>(&D))
1322 HasCancel = OPFD->hasCancel();
1323 else if (
auto *OPFD = dyn_cast<OMPDistributeParallelForDirective>(&D))
1324 HasCancel = OPFD->hasCancel();
1325 else if (
auto *OPFD = dyn_cast<OMPTeamsDistributeParallelForDirective>(&D))
1326 HasCancel = OPFD->hasCancel();
1327 else if (
auto *OPFD =
1328 dyn_cast<OMPTargetTeamsDistributeParallelForDirective>(&D))
1329 HasCancel = OPFD->hasCancel();
1330 CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind,
1331 HasCancel, OutlinedHelperName);
1333 return CGF.GenerateOpenMPCapturedStmtFunction(*CS);
1356 bool Tied,
unsigned &NumberOfParts) {
1363 CGF.EmitLoadOfPointerLValue(CGF.GetAddrOfLocalVar(TaskTVar),
1368 CGOpenMPTaskOutlinedRegionInfo::UntiedTaskActionTy Action(Tied, PartIDVar,
1372 "thread id variable must be of type kmp_int32 for tasks");
1376 CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen,
1378 TD ? TD->hasCancel() :
false, Action);
1380 auto *Res = CGF.GenerateCapturedStmtFunction(*CS);
1382 NumberOfParts = Action.getNumberOfParts();
1386 Address CGOpenMPRuntime::getOrCreateDefaultLocation(
unsigned Flags) {
1388 llvm::Value *Entry = OpenMPDefaultLocMap.lookup(Flags);
1390 if (!DefaultOpenMPPSource) {
1395 DefaultOpenMPPSource =
1397 DefaultOpenMPPSource =
1398 llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource,
CGM.
Int8PtrTy);
1407 fields.add(DefaultOpenMPPSource);
1408 auto DefaultOpenMPLocation =
1409 fields.finishAndCreateGlobal(
"", Align,
true,
1410 llvm::GlobalValue::PrivateLinkage);
1411 DefaultOpenMPLocation->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1413 OpenMPDefaultLocMap[Flags] = Entry = DefaultOpenMPLocation;
1421 Flags |= OMP_IDENT_KMPC;
1425 return getOrCreateDefaultLocation(Flags).
getPointer();
1427 assert(CGF.
CurFn &&
"No function in current CodeGenFunction.");
1430 auto I = OpenMPLocThreadIDMap.find(CGF.
CurFn);
1431 if (I != OpenMPLocThreadIDMap.end())
1440 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.
CurFn);
1444 CGBuilderTy::InsertPointGuard IPG(CGF.
Builder);
1453 auto OMPDebugLoc = OpenMPDebugLocMap.lookup(Loc.
getRawEncoding());
1454 if (OMPDebugLoc ==
nullptr) {
1456 llvm::raw_svector_ostream OS2(Buffer2);
1461 dyn_cast_or_null<FunctionDecl>(CGF.
CurFuncDecl)) {
1462 OS2 << FD->getQualifiedNameAsString();
1465 OMPDebugLoc = CGF.
Builder.CreateGlobalStringPtr(OS2.str());
1478 assert(CGF.
CurFn &&
"No function in current CodeGenFunction.");
1483 auto I = OpenMPLocThreadIDMap.find(CGF.
CurFn);
1484 if (I != OpenMPLocThreadIDMap.end()) {
1485 ThreadID = I->second.ThreadID;
1486 if (ThreadID !=
nullptr)
1493 if (
auto *OMPRegionInfo =
1495 if (OMPRegionInfo->getThreadIDVariable()) {
1497 auto LVal = OMPRegionInfo->getThreadIDVariableLValue(CGF);
1502 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.
CurFn);
1503 Elem.second.ThreadID = ThreadID;
1514 CGBuilderTy::InsertPointGuard IPG(CGF.
Builder);
1516 auto *Call = CGF.
Builder.CreateCall(
1520 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.
CurFn);
1521 Elem.second.ThreadID = Call;
1526 assert(CGF.
CurFn &&
"No function in current CodeGenFunction.");
1527 if (OpenMPLocThreadIDMap.count(CGF.
CurFn))
1528 OpenMPLocThreadIDMap.erase(CGF.
CurFn);
1529 if (FunctionUDRMap.count(CGF.
CurFn) > 0) {
1530 for(
auto *D : FunctionUDRMap[CGF.
CurFn]) {
1533 FunctionUDRMap.erase(CGF.
CurFn);
1540 return llvm::PointerType::getUnqual(IdentTy);
1544 if (!Kmpc_MicroTy) {
1548 Kmpc_MicroTy = llvm::FunctionType::get(
CGM.
VoidTy, MicroParams,
true);
1550 return llvm::PointerType::getUnqual(Kmpc_MicroTy);
1555 llvm::Constant *RTLFn =
nullptr;
1556 switch (static_cast<OpenMPRTLFunction>(Function)) {
1562 llvm::FunctionType *FnTy =
1563 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
true);
1570 llvm::FunctionType *FnTy =
1571 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1581 llvm::FunctionType *FnTy =
1582 llvm::FunctionType::get(
CGM.
VoidPtrTy, TypeParams,
false);
1591 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1592 llvm::FunctionType *FnTy =
1593 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1601 llvm::PointerType::getUnqual(KmpCriticalNameTy),
1603 llvm::FunctionType *FnTy =
1604 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1614 false)->getPointerTo();
1617 auto KmpcCopyCtorTy =
1618 llvm::FunctionType::get(
CGM.
VoidPtrTy, KmpcCopyCtorTyArgs,
1619 false)->getPointerTo();
1625 KmpcCopyCtorTy, KmpcDtorTy};
1626 auto FnTy = llvm::FunctionType::get(
CGM.
VoidTy, FnTyArgs,
1636 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1637 llvm::FunctionType *FnTy =
1638 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1646 llvm::FunctionType *FnTy =
1647 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1654 llvm::FunctionType *FnTy =
1655 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1662 llvm::FunctionType *FnTy =
1663 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1672 llvm::FunctionType *FnTy =
1673 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1681 llvm::FunctionType *FnTy =
1682 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1690 llvm::FunctionType *FnTy =
1691 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1698 llvm::FunctionType *FnTy =
1699 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1706 llvm::FunctionType *FnTy =
1707 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1714 llvm::FunctionType *FnTy =
1715 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1723 llvm::FunctionType *FnTy =
1724 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1731 llvm::FunctionType *FnTy =
1732 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1739 llvm::FunctionType *FnTy =
1740 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1748 assert(KmpRoutineEntryPtrTy !=
nullptr &&
1749 "Type kmp_routine_entry_t must be created.");
1753 llvm::FunctionType *FnTy =
1754 llvm::FunctionType::get(
CGM.
VoidPtrTy, TypeParams,
false);
1763 llvm::FunctionType *FnTy =
1764 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1774 llvm::FunctionType::get(
CGM.
VoidTy, CpyTypeParams,
false);
1778 llvm::FunctionType *FnTy =
1779 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1788 auto *ReduceFnTy = llvm::FunctionType::get(
CGM.
VoidTy, ReduceTypeParams,
1793 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1794 llvm::FunctionType *FnTy =
1795 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1805 auto *ReduceFnTy = llvm::FunctionType::get(
CGM.
VoidTy, ReduceTypeParams,
1810 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1811 llvm::FunctionType *FnTy =
1812 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1821 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1822 llvm::FunctionType *FnTy =
1823 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1832 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1833 llvm::FunctionType *FnTy =
1834 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1844 llvm::FunctionType *FnTy =
1845 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1855 llvm::FunctionType *FnTy =
1856 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1858 "__kmpc_omp_task_complete_if0");
1864 llvm::FunctionType *FnTy =
1865 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1872 llvm::FunctionType *FnTy =
1873 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1880 llvm::FunctionType *FnTy =
1881 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1888 llvm::FunctionType *FnTy =
1889 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1896 llvm::FunctionType *FnTy =
1897 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1905 llvm::FunctionType *FnTy =
1906 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1917 llvm::FunctionType *FnTy =
1918 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1930 llvm::FunctionType *FnTy =
1931 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1939 llvm::FunctionType *FnTy =
1940 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1948 llvm::FunctionType *FnTy =
1949 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1958 llvm::FunctionType *FnTy =
1959 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1968 llvm::FunctionType *FnTy =
1969 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
true);
1988 llvm::FunctionType *FnTy =
1989 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2000 llvm::FunctionType *FnTy =
2001 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2008 llvm::FunctionType *FnTy =
2009 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2018 llvm::FunctionType *FnTy =
2019 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2028 llvm::FunctionType *FnTy =
2029 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2037 llvm::FunctionType *FnTy =
2038 llvm::FunctionType::get(
CGM.
VoidPtrTy, TypeParams,
false);
2047 llvm::FunctionType *FnTy =
2048 llvm::FunctionType::get(
CGM.
VoidPtrTy, TypeParams,
false);
2050 FnTy,
"__kmpc_task_reduction_get_th_data");
2064 llvm::FunctionType *FnTy =
2065 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2080 llvm::FunctionType *FnTy =
2081 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2098 llvm::FunctionType *FnTy =
2099 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2116 llvm::FunctionType *FnTy =
2117 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2126 llvm::FunctionType *FnTy =
2127 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2136 llvm::FunctionType *FnTy =
2137 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2150 llvm::FunctionType *FnTy =
2151 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2166 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2179 llvm::FunctionType *FnTy =
2180 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2195 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2208 llvm::FunctionType *FnTy =
2209 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2224 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2229 assert(RTLFn &&
"Unable to find OpenMP runtime function");
2235 assert((IVSize == 32 || IVSize == 64) &&
2236 "IV size is not compatible with the omp runtime");
2237 auto Name = IVSize == 32 ? (IVSigned ?
"__kmpc_for_static_init_4" 2238 :
"__kmpc_for_static_init_4u")
2239 : (IVSigned ?
"__kmpc_for_static_init_8" 2240 :
"__kmpc_for_static_init_8u");
2242 auto PtrTy = llvm::PointerType::getUnqual(ITy);
2254 llvm::FunctionType *FnTy =
2255 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2261 assert((IVSize == 32 || IVSize == 64) &&
2262 "IV size is not compatible with the omp runtime");
2265 ? (IVSigned ?
"__kmpc_dispatch_init_4" :
"__kmpc_dispatch_init_4u")
2266 : (IVSigned ?
"__kmpc_dispatch_init_8" :
"__kmpc_dispatch_init_8u");
2276 llvm::FunctionType *FnTy =
2277 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2283 assert((IVSize == 32 || IVSize == 64) &&
2284 "IV size is not compatible with the omp runtime");
2287 ? (IVSigned ?
"__kmpc_dispatch_fini_4" :
"__kmpc_dispatch_fini_4u")
2288 : (IVSigned ?
"__kmpc_dispatch_fini_8" :
"__kmpc_dispatch_fini_8u");
2293 llvm::FunctionType *FnTy =
2294 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2300 assert((IVSize == 32 || IVSize == 64) &&
2301 "IV size is not compatible with the omp runtime");
2304 ? (IVSigned ?
"__kmpc_dispatch_next_4" :
"__kmpc_dispatch_next_4u")
2305 : (IVSigned ?
"__kmpc_dispatch_next_8" :
"__kmpc_dispatch_next_8u");
2307 auto PtrTy = llvm::PointerType::getUnqual(ITy);
2316 llvm::FunctionType *FnTy =
2317 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2362 Ctor, CopyCtor, Dtor};
2379 llvm::Value *Ctor =
nullptr, *CopyCtor =
nullptr, *Dtor =
nullptr;
2388 Args.push_back(&Dst);
2394 FTy,
".__kmpc_global_ctor_.", FI, Loc);
2419 Args.push_back(&Dst);
2425 FTy,
".__kmpc_global_dtor_.", FI, Loc);
2447 false)->getPointerTo();
2451 CopyCtor = llvm::Constant::getNullValue(CopyCtorTy);
2452 if (Ctor ==
nullptr) {
2454 false)->getPointerTo();
2455 Ctor = llvm::Constant::getNullValue(CtorTy);
2457 if (Dtor ==
nullptr) {
2459 false)->getPointerTo();
2460 Dtor = llvm::Constant::getNullValue(DtorTy);
2463 auto InitFunctionTy =
2464 llvm::FunctionType::get(
CGM.
VoidTy,
false);
2466 InitFunctionTy,
".__omp_threadprivate_init_.",
2475 return InitFunction;
2485 llvm::Twine VarName(Name,
".artificial.");
2499 VarLVType->getPointerTo(0)),
2552 const Expr *IfCond) {
2556 auto &&ThenGen = [OutlinedFn, CapturedVars, RTLoc](
CodeGenFunction &CGF,
2559 auto &RT = CGF.CGM.getOpenMPRuntime();
2562 CGF.Builder.getInt32(CapturedVars.size()),
2563 CGF.Builder.CreateBitCast(OutlinedFn, RT.getKmpc_MicroPointerTy())};
2565 RealArgs.append(std::begin(Args), std::end(Args));
2566 RealArgs.append(CapturedVars.begin(), CapturedVars.end());
2569 CGF.EmitRuntimeCall(RTLFn, RealArgs);
2571 auto &&ElseGen = [OutlinedFn, CapturedVars, RTLoc, Loc](
CodeGenFunction &CGF,
2573 auto &RT = CGF.CGM.getOpenMPRuntime();
2574 auto ThreadID = RT.getThreadID(CGF, Loc);
2578 CGF.EmitRuntimeCall(
2582 auto ThreadIDAddr = RT.emitThreadIDAddress(CGF, Loc);
2586 CGF.InitTempAlloca(ZeroAddr, CGF.Builder.getInt32( 0));
2588 OutlinedFnArgs.push_back(ThreadIDAddr.getPointer());
2589 OutlinedFnArgs.push_back(ZeroAddr.
getPointer());
2590 OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
2591 RT.emitOutlinedFunctionCall(CGF, Loc, OutlinedFn, OutlinedFnArgs);
2594 llvm::Value *EndArgs[] = {RT.emitUpdateLocation(CGF, Loc), ThreadID};
2595 CGF.EmitRuntimeCall(
2615 if (
auto *OMPRegionInfo =
2617 if (OMPRegionInfo->getThreadIDVariable())
2618 return OMPRegionInfo->getThreadIDVariableLValue(CGF).getAddress();
2623 auto ThreadIDTemp = CGF.
CreateMemTemp(Int32Ty,
".threadid_temp.");
2627 return ThreadIDTemp;
2632 const llvm::Twine &Name) {
2634 llvm::raw_svector_ostream Out(Buffer);
2636 auto RuntimeName = Out.str();
2637 auto &Elem = *InternalVars.insert(std::make_pair(RuntimeName,
nullptr)).first;
2639 assert(Elem.second->getType()->getPointerElementType() == Ty &&
2640 "OMP internal variable has different type than requested");
2641 return &*Elem.second;
2644 return Elem.second =
new llvm::GlobalVariable(
2646 llvm::GlobalValue::CommonLinkage, llvm::Constant::getNullValue(Ty),
2651 llvm::Twine Name(
".gomp_critical_user_", CriticalName);
2663 llvm::BasicBlock *ContBlock =
nullptr;
2668 bool Conditional =
false)
2669 : EnterCallee(EnterCallee), EnterArgs(EnterArgs), ExitCallee(ExitCallee),
2678 CGF.
Builder.CreateCondBr(CallBool, ThenBlock, ContBlock);
2694 StringRef CriticalName,
2708 EnterArgs.push_back(CGF.
Builder.CreateIntCast(
2711 CommonActionTy Action(
2745 llvm::ConstantInt::get(
CGM.
IntTy, 0,
true)};
2747 if (
auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.
CapturedStmtInfo))
2748 Region->emitUntiedSwitch(CGF);
2771 unsigned Index,
const VarDecl *Var) {
2785 ArrayRef<const Expr *> CopyprivateVars, ArrayRef<const Expr *> DestExprs,
2786 ArrayRef<const Expr *> SrcExprs, ArrayRef<const Expr *> AssignmentOps) {
2792 Args.push_back(&LHSArg);
2793 Args.push_back(&RHSArg);
2797 ".omp.copyprivate.copy_func", &CGM.
getModule());
2813 for (
unsigned I = 0, E = AssignmentOps.size(); I < E; ++I) {
2814 auto DestVar = cast<VarDecl>(cast<DeclRefExpr>(DestExprs[I])->getDecl());
2817 auto SrcVar = cast<VarDecl>(cast<DeclRefExpr>(SrcExprs[I])->getDecl());
2820 auto *VD = cast<DeclRefExpr>(CopyprivateVars[I])->getDecl();
2822 CGF.
EmitOMPCopy(Type, DestAddr, SrcAddr, DestVar, SrcVar, AssignmentOps[I]);
2831 ArrayRef<const Expr *> CopyprivateVars,
2832 ArrayRef<const Expr *> SrcExprs,
2833 ArrayRef<const Expr *> DstExprs,
2834 ArrayRef<const Expr *> AssignmentOps) {
2837 assert(CopyprivateVars.size() == SrcExprs.size() &&
2838 CopyprivateVars.size() == DstExprs.size() &&
2839 CopyprivateVars.size() == AssignmentOps.size());
2851 if (!CopyprivateVars.empty()) {
2853 auto KmpInt32Ty = C.getIntTypeForBitwidth(32, 1);
2854 DidIt = CGF.
CreateMemTemp(KmpInt32Ty,
".omp.copyprivate.did_it");
2872 llvm::APInt ArraySize(32, CopyprivateVars.size());
2873 auto CopyprivateArrayTy =
2878 CGF.
CreateMemTemp(CopyprivateArrayTy,
".omp.copyprivate.cpr_list");
2879 for (
unsigned I = 0, E = CopyprivateVars.size(); I < E; ++I) {
2891 CopyprivateVars, SrcExprs, DstExprs, AssignmentOps);
2892 auto *BufSize = CGF.
getTypeSize(CopyprivateArrayTy);
2932 bool ForceSimpleCall) {
2938 if (Kind == OMPD_for)
2939 Flags = OMP_IDENT_BARRIER_IMPL_FOR;
2940 else if (Kind == OMPD_sections)
2941 Flags = OMP_IDENT_BARRIER_IMPL_SECTIONS;
2942 else if (Kind == OMPD_single)
2943 Flags = OMP_IDENT_BARRIER_IMPL_SINGLE;
2944 else if (Kind == OMPD_barrier)
2945 Flags = OMP_IDENT_BARRIER_EXPL;
2947 Flags = OMP_IDENT_BARRIER_IMPL;
2952 if (
auto *OMPRegionInfo =
2954 if (!ForceSimpleCall && OMPRegionInfo->hasCancel()) {
2963 auto *Cmp = CGF.
Builder.CreateIsNotNull(Result);
2964 CGF.
Builder.CreateCondBr(Cmp, ExitBB, ContBB);
2967 auto CancelDestination =
2980 bool Chunked,
bool Ordered) {
2981 switch (ScheduleKind) {
2982 case OMPC_SCHEDULE_static:
2985 case OMPC_SCHEDULE_dynamic:
2987 case OMPC_SCHEDULE_guided:
2989 case OMPC_SCHEDULE_runtime:
2991 case OMPC_SCHEDULE_auto:
2994 assert(!Chunked &&
"chunk was specified but schedule kind not known");
2997 llvm_unreachable(
"Unexpected runtime schedule");
3008 bool Chunked)
const {
3032 case OMPC_SCHEDULE_MODIFIER_monotonic:
3035 case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
3038 case OMPC_SCHEDULE_MODIFIER_simd:
3047 case OMPC_SCHEDULE_MODIFIER_monotonic:
3050 case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
3053 case OMPC_SCHEDULE_MODIFIER_simd:
3071 ScheduleKind.
Schedule, DispatchValues.
Chunk !=
nullptr, Ordered);
3083 : CGF.
Builder.getIntN(IVSize, 1);
3087 Schedule, ScheduleKind.
M1, ScheduleKind.
M2)),
3090 CGF.
Builder.getIntN(IVSize, 1),
3100 const CGOpenMPRuntime::StaticRTInput &Values) {
3104 assert(!Values.Ordered);
3117 if (Chunk ==
nullptr) {
3120 "expected static non-chunked schedule");
3122 Chunk = CGF.
Builder.getIntN(Values.IVSize, 1);
3128 "expected static chunked schedule");
3135 Values.IL.getPointer(),
3136 Values.LB.getPointer(),
3137 Values.UB.getPointer(),
3138 Values.ST.getPointer(),
3139 CGF.
Builder.getIntN(Values.IVSize, 1),
3153 "Expected loop-based or sections-based directive.");
3156 ? OMP_IDENT_WORK_LOOP
3157 : OMP_IDENT_WORK_SECTIONS);
3159 auto *StaticInitFunction =
3162 ScheduleNum, ScheduleKind.
M1, ScheduleKind.
M2, Values);
3168 const CGOpenMPRuntime::StaticRTInput &Values) {
3171 auto *UpdatedLocation =
3174 auto *StaticInitFunction =
3190 ? OMP_IDENT_WORK_DISTRIBUTE
3192 ? OMP_IDENT_WORK_LOOP
3193 : OMP_IDENT_WORK_SECTIONS),
3263 case OMPC_PROC_BIND_master:
3264 RuntimeProcBind = ProcBindMaster;
3266 case OMPC_PROC_BIND_close:
3267 RuntimeProcBind = ProcBindClose;
3269 case OMPC_PROC_BIND_spread:
3270 RuntimeProcBind = ProcBindSpread;
3273 llvm_unreachable(
"Unsupported proc_bind value.");
3278 llvm::ConstantInt::get(
CGM.
IntTy, RuntimeProcBind,
true)};
3317 bool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::empty()
const {
3319 return OffloadEntriesTargetRegion.empty();
3323 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3324 initializeTargetRegionEntryInfo(
unsigned DeviceID,
unsigned FileID,
3325 StringRef ParentName,
unsigned LineNum,
3327 assert(
CGM.
getLangOpts().OpenMPIsDevice &&
"Initialization of entries is " 3328 "only required for the device " 3329 "code generation.");
3330 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] =
3331 OffloadEntryInfoTargetRegion(Order,
nullptr,
nullptr,
3333 ++OffloadingEntriesNum;
3336 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3337 registerTargetRegionEntryInfo(
unsigned DeviceID,
unsigned FileID,
3338 StringRef ParentName,
unsigned LineNum,
3339 llvm::Constant *Addr, llvm::Constant *
ID,
3344 assert(hasTargetRegionEntryInfo(DeviceID, FileID, ParentName, LineNum) &&
3345 "Entry must exist.");
3347 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum];
3348 assert(Entry.isValid() &&
"Entry not initialized!");
3349 Entry.setAddress(Addr);
3351 Entry.setFlags(Flags);
3354 OffloadEntryInfoTargetRegion Entry(OffloadingEntriesNum++, Addr, ID, Flags);
3355 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] = Entry;
3359 bool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::hasTargetRegionEntryInfo(
3360 unsigned DeviceID,
unsigned FileID, StringRef ParentName,
3361 unsigned LineNum)
const {
3362 auto PerDevice = OffloadEntriesTargetRegion.find(DeviceID);
3363 if (PerDevice == OffloadEntriesTargetRegion.end())
3365 auto PerFile = PerDevice->second.find(FileID);
3366 if (PerFile == PerDevice->second.end())
3368 auto PerParentName = PerFile->second.find(ParentName);
3369 if (PerParentName == PerFile->second.end())
3371 auto PerLine = PerParentName->second.find(LineNum);
3372 if (PerLine == PerParentName->second.end())
3375 if (PerLine->second.getAddress() || PerLine->second.getID())
3380 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::actOnTargetRegionEntriesInfo(
3381 const OffloadTargetRegionEntryInfoActTy &Action) {
3383 for (
auto &D : OffloadEntriesTargetRegion)
3384 for (
auto &F : D.second)
3385 for (
auto &
P : F.second)
3386 for (
auto &L :
P.second)
3387 Action(D.first, F.first,
P.first(), L.first, L.second);
3393 static llvm::Function *
3399 Args.push_back(&DummyPtr);
3428 assert(!Devices.empty() &&
"No OpenMP offloading devices??");
3432 auto *OffloadEntryTy =
3434 llvm::GlobalVariable *HostEntriesBegin =
new llvm::GlobalVariable(
3435 M, OffloadEntryTy,
true,
3437 ".omp_offloading.entries_begin");
3438 llvm::GlobalVariable *HostEntriesEnd =
new llvm::GlobalVariable(
3439 M, OffloadEntryTy,
true,
3441 ".omp_offloading.entries_end");
3444 auto *DeviceImageTy = cast<llvm::StructType>(
3447 auto DeviceImagesEntries = DeviceImagesBuilder.beginArray(DeviceImageTy);
3449 for (
unsigned i = 0; i < Devices.size(); ++i) {
3450 StringRef
T = Devices[i].getTriple();
3451 auto *ImgBegin =
new llvm::GlobalVariable(
3454 Twine(
".omp_offloading.img_start.") + Twine(T));
3455 auto *ImgEnd =
new llvm::GlobalVariable(
3457 nullptr, Twine(
".omp_offloading.img_end.") + Twine(T));
3459 auto Dev = DeviceImagesEntries.beginStruct(DeviceImageTy);
3462 Dev.add(HostEntriesBegin);
3463 Dev.add(HostEntriesEnd);
3464 Dev.finishAndAddTo(DeviceImagesEntries);
3468 llvm::GlobalVariable *DeviceImages =
3469 DeviceImagesEntries.finishAndCreateGlobal(
".omp_offloading.device_images",
3472 DeviceImages->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3475 llvm::Constant *Index[] = {llvm::Constant::getNullValue(
CGM.
Int32Ty),
3479 auto *BinaryDescriptorTy = cast<llvm::StructType>(
3482 auto DescInit = DescBuilder.beginStruct(BinaryDescriptorTy);
3483 DescInit.addInt(
CGM.
Int32Ty, Devices.size());
3484 DescInit.add(llvm::ConstantExpr::getGetElementPtr(DeviceImages->getValueType(),
3487 DescInit.add(HostEntriesBegin);
3488 DescInit.add(HostEntriesEnd);
3490 auto *Desc = DescInit.finishAndCreateGlobal(
".omp_offloading.descriptor",
3499 auto *IdentInfo = &C.Idents.get(
".omp_offloading.reg_unreg_var");
3504 CGM,
".omp_offloading.descriptor_unreg",
3510 CGM,
".omp_offloading.descriptor_reg",
3521 auto ComdatKey = M.getOrInsertComdat(RegFn->getName());
3522 RegFn->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage);
3524 RegFn->setComdat(ComdatKey);
3525 UnRegFn->setComdat(ComdatKey);
3526 DeviceImages->setComdat(ComdatKey);
3527 Desc->setComdat(ComdatKey);
3533 llvm::Constant *Addr, uint64_t Size,
3535 StringRef Name = Addr->getName();
3536 auto *TgtOffloadEntryType = cast<llvm::StructType>(
3542 llvm::Constant *AddrPtr = llvm::ConstantExpr::getBitCast(ID,
CGM.
VoidPtrTy);
3545 llvm::Constant *StrPtrInit = llvm::ConstantDataArray::getString(C, Name);
3547 llvm::GlobalVariable *Str =
3548 new llvm::GlobalVariable(M, StrPtrInit->getType(),
true,
3550 ".omp_offloading.entry_name");
3551 Str->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3552 llvm::Constant *StrPtr = llvm::ConstantExpr::getBitCast(Str,
CGM.
Int8PtrTy);
3560 auto EntryInit = EntryBuilder.
beginStruct(TgtOffloadEntryType);
3561 EntryInit.add(AddrPtr);
3562 EntryInit.add(StrPtr);
3566 llvm::GlobalVariable *Entry =
3567 EntryInit.finishAndCreateGlobal(
".omp_offloading.entry",
3573 Entry->setSection(
".omp_offloading.entries");
3591 llvm::LLVMContext &C = M.getContext();
3596 llvm::NamedMDNode *MD = M.getOrInsertNamedMetadata(
"omp_offload.info");
3599 auto getMDInt = [&](
unsigned v) {
3600 return llvm::ConstantAsMetadata::get(
3601 llvm::ConstantInt::get(llvm::Type::getInt32Ty(C),
v));
3604 auto getMDString = [&](StringRef
v) {
return llvm::MDString::get(C,
v); };
3607 auto &&TargetRegionMetadataEmitter = [&](
3608 unsigned DeviceID,
unsigned FileID, StringRef ParentName,
unsigned Line,
3620 Ops.push_back(getMDInt(E.getKind()));
3621 Ops.push_back(getMDInt(DeviceID));
3622 Ops.push_back(getMDInt(FileID));
3623 Ops.push_back(getMDString(ParentName));
3624 Ops.push_back(getMDInt(Line));
3625 Ops.push_back(getMDInt(E.getOrder()));
3628 OrderedEntries[E.getOrder()] = &E;
3631 MD->addOperand(llvm::MDNode::get(C, Ops));
3635 TargetRegionMetadataEmitter);
3637 for (
auto *E : OrderedEntries) {
3638 assert(E &&
"All ordered entries must exist!");
3640 dyn_cast<OffloadEntriesInfoManagerTy::OffloadEntryInfoTargetRegion>(
3642 assert(CE->getID() && CE->getAddress() &&
3643 "Entry ID and Addr are invalid!");
3646 llvm_unreachable(
"Unsupported entry kind.");
3666 llvm::LLVMContext C;
3667 auto ME = expectedToErrorOrAndEmitErrors(
3668 C, llvm::parseBitcodeFile(Buf.get()->getMemBufferRef(), C));
3673 llvm::NamedMDNode *MD = ME.get()->getNamedMetadata(
"omp_offload.info");
3677 for (
auto I : MD->operands()) {
3678 llvm::MDNode *MN = cast<llvm::MDNode>(I);
3680 auto getMDInt = [&](
unsigned Idx) {
3681 llvm::ConstantAsMetadata *V =
3682 cast<llvm::ConstantAsMetadata>(MN->getOperand(Idx));
3683 return cast<llvm::ConstantInt>(V->getValue())->getZExtValue();
3686 auto getMDString = [&](
unsigned Idx) {
3687 llvm::MDString *V = cast<llvm::MDString>(MN->getOperand(Idx));
3688 return V->getString();
3691 switch (getMDInt(0)) {
3693 llvm_unreachable(
"Unexpected metadata!");
3698 getMDInt(1), getMDInt(2),
3699 getMDString(3), getMDInt(4),
3707 if (!KmpRoutineEntryPtrTy) {
3710 QualType KmpRoutineEntryTyArgs[] = {KmpInt32Ty, C.VoidPtrTy};
3712 KmpRoutineEntryPtrQTy = C.getPointerType(
3713 C.getFunctionType(KmpInt32Ty, KmpRoutineEntryTyArgs, EPI));
3752 RD->completeDefinition();
3778 RD->completeDefinition();
3803 RD->completeDefinition();
3810 struct PrivateHelpersTy {
3811 PrivateHelpersTy(
const VarDecl *Original,
const VarDecl *PrivateCopy,
3812 const VarDecl *PrivateElemInit)
3813 : Original(Original), PrivateCopy(PrivateCopy),
3814 PrivateElemInit(PrivateElemInit) {}
3817 const VarDecl *PrivateElemInit;
3819 typedef std::pair<
CharUnits , PrivateHelpersTy> PrivateDataTy;
3824 if (!Privates.empty()) {
3829 auto *RD = C.buildImplicitRecord(
".kmp_privates.t");
3830 RD->startDefinition();
3831 for (
auto &&Pair : Privates) {
3832 auto *VD = Pair.second.Original;
3843 RD->completeDefinition();
3852 QualType KmpRoutineEntryPointerQTy) {
3867 auto *UD = C.buildImplicitRecord(
"kmp_cmplrdata_t",
TTK_Union);
3868 UD->startDefinition();
3871 UD->completeDefinition();
3872 QualType KmpCmplrdataTy = C.getRecordType(UD);
3873 auto *RD = C.buildImplicitRecord(
"kmp_task_t");
3874 RD->startDefinition();
3891 RD->completeDefinition();
3897 ArrayRef<PrivateDataTy>
Privates) {
3903 auto *RD = C.buildImplicitRecord(
"kmp_task_t_with_privates");
3904 RD->startDefinition();
3909 RD->completeDefinition();
3927 QualType KmpTaskTWithPrivatesPtrQTy,
3938 Args.push_back(&GtidArg);
3939 Args.push_back(&TaskTypeArg);
3940 auto &TaskEntryFnInfo =
3960 auto *KmpTaskTWithPrivatesQTyRD =
3961 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->
getAsTagDecl());
3964 auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->
getAsTagDecl());
3965 auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
3969 auto SharedsFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTShareds);
3975 auto PrivatesFI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin(), 1);
3977 if (PrivatesFI != KmpTaskTWithPrivatesQTyRD->field_end()) {
3980 PrivatesLVal.getPointer(), CGF.
VoidPtrTy);
3982 PrivatesParam = llvm::ConstantPointerNull::get(CGF.
VoidPtrTy);
3984 llvm::Value *CommonArgs[] = {GtidParam, PartidParam, PrivatesParam,
3991 std::end(CommonArgs));
3993 auto LBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound);
3996 auto UBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound);
3999 auto StFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTStride);
4002 auto LIFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLastIter);
4005 auto RFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTReductions);
4008 CallArgs.push_back(LBParam);
4009 CallArgs.push_back(UBParam);
4010 CallArgs.push_back(StParam);
4011 CallArgs.push_back(LIParam);
4012 CallArgs.push_back(RParam);
4014 CallArgs.push_back(SharedsParam);
4028 QualType KmpTaskTWithPrivatesPtrQTy,
4029 QualType KmpTaskTWithPrivatesQTy) {
4037 Args.push_back(&GtidArg);
4038 Args.push_back(&TaskTypeArg);
4039 auto &DestructorFnInfo =
4042 auto *DestructorFn =
4044 ".omp_task_destructor.", &CGM.
getModule());
4055 auto *KmpTaskTWithPrivatesQTyRD =
4056 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->
getAsTagDecl());
4057 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
4060 cast<RecordDecl>(FI->getType()->getAsTagDecl())->fields()) {
4061 if (
auto DtorKind = Field->getType().isDestructedType()) {
4063 CGF.
pushDestroy(DtorKind, FieldLValue.getAddress(), Field->getType());
4067 return DestructorFn;
4082 ArrayRef<const Expr *> PrivateVars,
4083 ArrayRef<const Expr *> FirstprivateVars,
4084 ArrayRef<const Expr *> LastprivateVars,
4086 ArrayRef<PrivateDataTy>
Privates) {
4090 C,
nullptr, Loc,
nullptr,
4091 C.getPointerType(PrivatesQTy).withConst().withRestrict(),
4093 Args.push_back(&TaskPrivatesArg);
4094 llvm::DenseMap<const VarDecl *, unsigned> PrivateVarsPos;
4095 unsigned Counter = 1;
4096 for (
auto *E: PrivateVars) {
4098 C,
nullptr, Loc,
nullptr,
4099 C.getPointerType(C.getPointerType(E->
getType()))
4103 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4104 PrivateVarsPos[VD] = Counter;
4107 for (
auto *E : FirstprivateVars) {
4109 C,
nullptr, Loc,
nullptr,
4110 C.getPointerType(C.getPointerType(E->
getType()))
4114 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4115 PrivateVarsPos[VD] = Counter;
4118 for (
auto *E: LastprivateVars) {
4120 C,
nullptr, Loc,
nullptr,
4121 C.getPointerType(C.getPointerType(E->
getType()))
4125 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4126 PrivateVarsPos[VD] = Counter;
4129 auto &TaskPrivatesMapFnInfo =
4131 auto *TaskPrivatesMapTy =
4135 ".omp_task_privates_map.", &CGM.
getModule());
4137 TaskPrivatesMapFnInfo);
4138 TaskPrivatesMap->removeFnAttr(llvm::Attribute::NoInline);
4139 TaskPrivatesMap->removeFnAttr(llvm::Attribute::OptimizeNone);
4140 TaskPrivatesMap->addFnAttr(llvm::Attribute::AlwaysInline);
4144 TaskPrivatesMapFnInfo, Args);
4150 auto *PrivatesQTyRD = cast<RecordDecl>(PrivatesQTy->
getAsTagDecl());
4152 for (
auto *Field : PrivatesQTyRD->fields()) {
4154 auto *VD = Args[PrivateVarsPos[Privates[Counter].second.Original]];
4157 RefLVal.getAddress(), RefLVal.getType()->castAs<
PointerType>());
4162 return TaskPrivatesMap;
4166 const PrivateDataTy P2) {
4167 return P1.first > P2.first;
4177 ArrayRef<PrivateDataTy>
Privates,
bool ForDup) {
4179 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->
field_begin());
4199 FI = cast<RecordDecl>(FI->getType()->getAsTagDecl())->field_begin();
4200 for (
auto &&Pair : Privates) {
4201 auto *VD = Pair.second.PrivateCopy;
4203 if (Init && (!ForDup || (isa<CXXConstructExpr>(Init) &&
4206 if (
auto *Elem = Pair.second.PrivateElemInit) {
4207 auto *OriginalVD = Pair.second.Original;
4211 QualType Type = OriginalVD->getType();
4212 if (IsTargetTask && isa<ImplicitParamDecl>(OriginalVD) &&
4213 isa<CapturedDecl>(OriginalVD->getDeclContext()) &&
4214 cast<CapturedDecl>(OriginalVD->getDeclContext())->getNumParams() ==
4216 isa<TranslationUnitDecl>(
4217 cast<CapturedDecl>(OriginalVD->getDeclContext())
4218 ->getDeclContext())) {
4222 auto *SharedField = CapturesInfo.lookup(OriginalVD);
4240 [&CGF, Elem, Init, &CapturesInfo](
Address DestElement,
4245 Elem, [SrcElement]() ->
Address {
return SrcElement; });
4249 CGF, &CapturesInfo);
4250 CGF.EmitAnyExprToMem(Init, DestElement,
4251 Init->getType().getQualifiers(),
4274 ArrayRef<PrivateDataTy>
Privates) {
4275 bool InitRequired =
false;
4276 for (
auto &&Pair : Privates) {
4277 auto *VD = Pair.second.PrivateCopy;
4279 InitRequired = InitRequired || (Init && isa<CXXConstructExpr>(Init) &&
4282 return InitRequired;
4299 QualType KmpTaskTWithPrivatesPtrQTy,
4303 ArrayRef<PrivateDataTy>
Privates,
bool WithLastIter) {
4307 KmpTaskTWithPrivatesPtrQTy,
4310 KmpTaskTWithPrivatesPtrQTy,
4314 Args.push_back(&DstArg);
4315 Args.push_back(&SrcArg);
4316 Args.push_back(&LastprivArg);
4317 auto &TaskDupFnInfo =
4333 auto LIFI = std::next(KmpTaskTQTyRD->
field_begin(), KmpTaskTLastIter);
4335 TDBase, *KmpTaskTWithPrivatesQTyRD->
field_begin());
4343 assert(!Privates.empty());
4350 TDBase, *KmpTaskTWithPrivatesQTyRD->
field_begin());
4358 emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, TDBase, KmpTaskTWithPrivatesQTyRD,
4359 SharedsTy, SharedsPtrTy, Data, Privates,
true);
4368 bool NeedsCleanup =
false;
4369 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->
field_begin());
4370 auto *PrivateRD = cast<RecordDecl>(FI->getType()->getAsTagDecl());
4371 for (
auto *FD : PrivateRD->fields()) {
4372 NeedsCleanup = NeedsCleanup || FD->getType().isDestructedType();
4376 return NeedsCleanup;
4379 CGOpenMPRuntime::TaskResultTy
4389 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4390 Privates.push_back(std::make_pair(
4392 PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
4399 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4400 Privates.push_back(std::make_pair(
4403 VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
4404 cast<VarDecl>(cast<DeclRefExpr>(*IElemInitRef)->getDecl()))));
4410 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4411 Privates.push_back(std::make_pair(
4413 PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
4418 auto KmpInt32Ty = C.getIntTypeForBitwidth(32, 1);
4432 "Expected taskloop, task or target directive");
4441 auto *KmpTaskTWithPrivatesQTyRD =
4443 auto KmpTaskTWithPrivatesQTy = C.getRecordType(KmpTaskTWithPrivatesQTyRD);
4444 QualType KmpTaskTWithPrivatesPtrQTy =
4445 C.getPointerType(KmpTaskTWithPrivatesQTy);
4446 auto *KmpTaskTWithPrivatesTy = CGF.
ConvertType(KmpTaskTWithPrivatesQTy);
4447 auto *KmpTaskTWithPrivatesPtrTy = KmpTaskTWithPrivatesTy->getPointerTo();
4448 auto *KmpTaskTWithPrivatesTySize = CGF.
getTypeSize(KmpTaskTWithPrivatesQTy);
4449 QualType SharedsPtrTy = C.getPointerType(SharedsTy);
4453 auto *TaskPrivatesMapTy =
4454 std::next(cast<llvm::Function>(TaskFunction)->arg_begin(), 3)->getType();
4455 if (!Privates.empty()) {
4456 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
4461 TaskPrivatesMap, TaskPrivatesMapTy);
4463 TaskPrivatesMap = llvm::ConstantPointerNull::get(
4464 cast<llvm::PointerType>(TaskPrivatesMapTy));
4470 KmpTaskTWithPrivatesQTy,
KmpTaskTQTy, SharedsPtrTy, TaskFunction,
4482 DestructorsFlag = 0x8,
4485 unsigned Flags = Data.
Tied ? TiedFlag : 0;
4486 bool NeedsCleanup =
false;
4487 if (!Privates.empty()) {
4490 Flags = Flags | DestructorsFlag;
4493 Flags = Flags | PriorityFlag;
4495 Data.
Final.getPointer()
4497 CGF.
Builder.getInt32(FinalFlag),
4499 : CGF.
Builder.getInt32(Data.
Final.getInt() ? FinalFlag : 0);
4500 TaskFlags = CGF.
Builder.CreateOr(TaskFlags, CGF.
Builder.getInt32(Flags));
4501 auto *SharedsSize =
CGM.
getSize(C.getTypeSizeInChars(SharedsTy));
4504 KmpTaskTWithPrivatesTySize, SharedsSize,
4506 TaskEntry, KmpRoutineEntryPtrTy)};
4510 NewTask, KmpTaskTWithPrivatesPtrTy);
4512 KmpTaskTWithPrivatesQTy);
4522 TDBase, *std::next(KmpTaskTQTyRD->field_begin(),
4530 if (!Privates.empty()) {
4531 emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, Base, KmpTaskTWithPrivatesQTyRD,
4532 SharedsTy, SharedsPtrTy, Data, Privates,
4537 CGM, Loc, D, KmpTaskTWithPrivatesPtrQTy, KmpTaskTWithPrivatesQTyRD,
4538 KmpTaskTQTyRD, SharedsTy, SharedsPtrTy, Data, Privates,
4543 enum { Priority = 0, Destructors = 1 };
4545 auto FI = std::next(KmpTaskTQTyRD->field_begin(), Data1);
4546 auto *KmpCmplrdataUD = (*FI)->getType()->getAsUnionType()->getDecl();
4549 CGM, Loc, KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy,
4550 KmpTaskTWithPrivatesQTy);
4553 Data1LV, *std::next(KmpCmplrdataUD->field_begin(), Destructors));
4555 DestructorFn, KmpRoutineEntryPtrTy),
4561 TDBase, *std::next(KmpTaskTQTyRD->field_begin(), Data2));
4563 Data2LV, *std::next(KmpCmplrdataUD->field_begin(), Priority));
4584 emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
4593 unsigned NumDependencies = Data.
Dependences.size();
4594 if (NumDependencies) {
4596 enum RTLDependenceKindTy { DepIn = 0x01, DepInOut = 0x3 };
4597 enum RTLDependInfoFieldsTy { BaseAddr, Len, Flags };
4600 C.getIntTypeForBitwidth(C.getTypeSize(C.BoolTy),
false);
4603 KmpDependInfoRD = C.buildImplicitRecord(
"kmp_depend_info");
4614 QualType KmpDependInfoArrayTy = C.getConstantArrayType(
4620 for (
unsigned i = 0; i < NumDependencies; ++i) {
4633 Size = CGF.
Builder.CreateNUWSub(UpIntPtr, LowIntPtr);
4650 RTLDependenceKindTy DepKind;
4652 case OMPC_DEPEND_in:
4656 case OMPC_DEPEND_out:
4657 case OMPC_DEPEND_inout:
4660 case OMPC_DEPEND_source:
4661 case OMPC_DEPEND_sink:
4663 llvm_unreachable(
"Unknown task dependence type");
4683 llvm::Value *TaskArgs[] = { UpLoc, ThreadID, NewTask };
4685 if (NumDependencies) {
4686 DepTaskArgs[0] = UpLoc;
4687 DepTaskArgs[1] = ThreadID;
4688 DepTaskArgs[2] = NewTask;
4689 DepTaskArgs[3] = CGF.
Builder.getInt32(NumDependencies);
4690 DepTaskArgs[4] = DependenciesArray.
getPointer();
4691 DepTaskArgs[5] = CGF.
Builder.getInt32(0);
4692 DepTaskArgs[6] = llvm::ConstantPointerNull::get(CGF.
VoidPtrTy);
4694 auto &&ThenCodeGen = [
this, &Data, TDBase, KmpTaskTQTyRD, NumDependencies,
4698 auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
4699 auto PartIdLVal = CGF.EmitLValueForField(TDBase, *PartIdFI);
4700 CGF.EmitStoreOfScalar(CGF.Builder.getInt32(0), PartIdLVal);
4702 if (NumDependencies) {
4703 CGF.EmitRuntimeCall(
4711 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
4712 Region->emitUntiedSwitch(CGF);
4716 if (NumDependencies) {
4717 DepWaitTaskArgs[0] = UpLoc;
4718 DepWaitTaskArgs[1] = ThreadID;
4719 DepWaitTaskArgs[2] = CGF.Builder.getInt32(NumDependencies);
4720 DepWaitTaskArgs[3] = DependenciesArray.
getPointer();
4721 DepWaitTaskArgs[4] = CGF.Builder.getInt32(0);
4722 DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
4724 auto &&ElseCodeGen = [&TaskArgs, ThreadID, NewTaskNewTaskTTy, TaskEntry,
4725 NumDependencies, &DepWaitTaskArgs,
4727 auto &RT = CGF.CGM.getOpenMPRuntime();
4733 if (NumDependencies)
4737 auto &&CodeGen = [TaskEntry, ThreadID, NewTaskNewTaskTTy,
4740 llvm::Value *OutlinedFnArgs[] = {ThreadID, NewTaskNewTaskTTy};
4741 CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, Loc, TaskEntry,
4750 CommonActionTy Action(
4774 emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
4787 IfVal = llvm::ConstantInt::getSigned(CGF.
IntTy, 1);
4820 enum { NoSchedule = 0, Grainsize = 1, NumTasks = 2 };
4829 llvm::ConstantInt::getNullValue(
4831 llvm::ConstantInt::getSigned(
4833 ? Data.
Schedule.getInt() ? NumTasks : Grainsize
4838 : llvm::ConstantInt::get(CGF.
Int64Ty, 0),
4841 : llvm::ConstantPointerNull::get(CGF.
VoidPtrTy)};
4858 const Expr *,
const Expr *)> &RedOpGen,
4859 const Expr *XExpr =
nullptr,
const Expr *EExpr =
nullptr,
4860 const Expr *UpExpr =
nullptr) {
4873 auto LHSEnd = CGF.
Builder.CreateGEP(LHSBegin, NumElements);
4878 CGF.
Builder.CreateICmpEQ(LHSBegin, LHSEnd,
"omp.arraycpy.isempty");
4879 CGF.
Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
4882 auto EntryBB = CGF.
Builder.GetInsertBlock();
4887 llvm::PHINode *RHSElementPHI = CGF.
Builder.CreatePHI(
4888 RHSBegin->getType(), 2,
"omp.arraycpy.srcElementPast");
4889 RHSElementPHI->addIncoming(RHSBegin, EntryBB);
4894 llvm::PHINode *LHSElementPHI = CGF.
Builder.CreatePHI(
4895 LHSBegin->getType(), 2,
"omp.arraycpy.destElementPast");
4896 LHSElementPHI->addIncoming(LHSBegin, EntryBB);
4903 Scope.addPrivate(LHSVar, [=]() ->
Address {
return LHSElementCurrent; });
4904 Scope.addPrivate(RHSVar, [=]() ->
Address {
return RHSElementCurrent; });
4906 RedOpGen(CGF, XExpr, EExpr, UpExpr);
4907 Scope.ForceCleanup();
4910 auto LHSElementNext = CGF.
Builder.CreateConstGEP1_32(
4911 LHSElementPHI, 1,
"omp.arraycpy.dest.element");
4912 auto RHSElementNext = CGF.
Builder.CreateConstGEP1_32(
4913 RHSElementPHI, 1,
"omp.arraycpy.src.element");
4916 CGF.
Builder.CreateICmpEQ(LHSElementNext, LHSEnd,
"omp.arraycpy.done");
4917 CGF.
Builder.CreateCondBr(Done, DoneBB, BodyBB);
4918 LHSElementPHI->addIncoming(LHSElementNext, CGF.
Builder.GetInsertBlock());
4919 RHSElementPHI->addIncoming(RHSElementNext, CGF.
Builder.GetInsertBlock());
4929 const Expr *ReductionOp) {
4930 if (
auto *CE = dyn_cast<CallExpr>(ReductionOp))
4931 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
4933 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
4934 if (
auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl())) {
4935 std::pair<llvm::Function *, llvm::Function *> Reduction =
4947 ArrayRef<const Expr *> LHSExprs, ArrayRef<const Expr *> RHSExprs,
4948 ArrayRef<const Expr *> ReductionOps) {
4955 Args.push_back(&LHSArg);
4956 Args.push_back(&RHSArg);
4960 ".omp.reduction.reduction_func", &CGM.
getModule());
4978 auto IPriv = Privates.begin();
4980 for (
unsigned I = 0, E = ReductionOps.size(); I < E; ++I, ++IPriv, ++Idx) {
4981 auto RHSVar = cast<VarDecl>(cast<DeclRefExpr>(RHSExprs[I])->getDecl());
4982 Scope.addPrivate(RHSVar, [&]() ->
Address {
4985 auto LHSVar = cast<VarDecl>(cast<DeclRefExpr>(LHSExprs[I])->getDecl());
4986 Scope.addPrivate(LHSVar, [&]() ->
Address {
4989 QualType PrivTy = (*IPriv)->getType();
4997 auto *OVE = cast<OpaqueValueExpr>(VLA->getSizeExpr());
5004 IPriv = Privates.begin();
5005 auto ILHS = LHSExprs.begin();
5006 auto IRHS = RHSExprs.begin();
5007 for (
auto *E : ReductionOps) {
5008 if ((*IPriv)->getType()->isArrayType()) {
5010 auto *LHSVar = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5011 auto *RHSVar = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
5013 CGF, (*IPriv)->getType(), LHSVar, RHSVar,
5024 Scope.ForceCleanup();
5030 const Expr *ReductionOp,
5031 const Expr *PrivateRef,
5036 auto *LHSVar = cast<VarDecl>(LHS->
getDecl());
5037 auto *RHSVar = cast<VarDecl>(RHS->
getDecl());
5039 CGF, PrivateRef->
getType(), LHSVar, RHSVar,
5097 if (SimpleReduction) {
5099 auto IPriv = Privates.begin();
5100 auto ILHS = LHSExprs.begin();
5101 auto IRHS = RHSExprs.begin();
5102 for (
auto *E : ReductionOps) {
5104 cast<DeclRefExpr>(*IRHS));
5114 auto Size = RHSExprs.size();
5115 for (
auto *E : Privates) {
5120 llvm::APInt ArraySize(32, Size);
5125 CGF.
CreateMemTemp(ReductionArrayTy,
".omp.reduction.red_list");
5126 auto IPriv = Privates.begin();
5128 for (
unsigned I = 0, E = RHSExprs.size(); I < E; ++I, ++IPriv, ++Idx) {
5135 if ((*IPriv)->getType()->isVariablyModifiedType()) {
5153 LHSExprs, RHSExprs, ReductionOps);
5162 auto *ReductionArrayTySize = CGF.
getTypeSize(ReductionArrayTy);
5168 CGF.
Builder.getInt32(RHSExprs.size()),
5169 ReductionArrayTySize,
5181 auto *SwInst = CGF.
Builder.CreateSwitch(Res, DefaultBB, 2);
5190 SwInst->addCase(CGF.
Builder.getInt32(1), Case1BB);
5199 auto &&CodeGen = [&
Privates, &LHSExprs, &RHSExprs, &ReductionOps](
5201 auto &RT = CGF.CGM.getOpenMPRuntime();
5202 auto IPriv = Privates.begin();
5203 auto ILHS = LHSExprs.begin();
5204 auto IRHS = RHSExprs.begin();
5205 for (
auto *E : ReductionOps) {
5206 RT.emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
5207 cast<DeclRefExpr>(*IRHS));
5214 CommonActionTy Action(
5222 CGF.EmitBranch(DefaultBB);
5229 auto *Case2BB = CGF.createBasicBlock(
".omp.reduction.case2");
5230 SwInst->addCase(CGF.Builder.getInt32(2), Case2BB);
5231 CGF.EmitBlock(Case2BB);
5233 auto &&AtomicCodeGen = [Loc, &
Privates, &LHSExprs, &RHSExprs, &ReductionOps](
5235 auto ILHS = LHSExprs.begin();
5236 auto IRHS = RHSExprs.begin();
5237 auto IPriv = Privates.begin();
5238 for (
auto *E : ReductionOps) {
5239 const Expr *XExpr =
nullptr;
5240 const Expr *EExpr =
nullptr;
5241 const Expr *UpExpr =
nullptr;
5243 if (
auto *BO = dyn_cast<BinaryOperator>(E)) {
5244 if (BO->getOpcode() == BO_Assign) {
5245 XExpr = BO->getLHS();
5246 UpExpr = BO->getRHS();
5250 auto *RHSExpr = UpExpr;
5253 if (
auto *ACO = dyn_cast<AbstractConditionalOperator>(
5254 RHSExpr->IgnoreParenImpCasts())) {
5257 RHSExpr = ACO->getCond();
5260 dyn_cast<BinaryOperator>(RHSExpr->IgnoreParenImpCasts())) {
5261 EExpr = BORHS->getRHS();
5262 BO = BORHS->getOpcode();
5266 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5267 auto &&AtomicRedGen = [BO, VD,
5269 const Expr *EExpr,
const Expr *UpExpr) {
5270 LValue X = CGF.EmitLValue(XExpr);
5273 E = CGF.EmitAnyExpr(EExpr);
5274 CGF.EmitOMPAtomicSimpleUpdateExpr(
5276 llvm::AtomicOrdering::Monotonic, Loc,
5277 [&CGF, UpExpr, VD, Loc](
RValue XRValue) {
5280 VD, [&CGF, VD, XRValue, Loc]() ->
Address {
5281 Address LHSTemp = CGF.CreateMemTemp(VD->getType());
5282 CGF.emitOMPSimpleStore(
5283 CGF.MakeAddrLValue(LHSTemp, VD->
getType()), XRValue,
5284 VD->getType().getNonReferenceType(), Loc);
5288 return CGF.EmitAnyExpr(UpExpr);
5291 if ((*IPriv)->getType()->isArrayType()) {
5293 auto *RHSVar = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
5295 AtomicRedGen, XExpr, EExpr, UpExpr);
5298 AtomicRedGen(CGF, XExpr, EExpr, UpExpr);
5302 const Expr *,
const Expr *) {
5303 auto &RT = CGF.CGM.getOpenMPRuntime();
5304 RT.emitCriticalRegion(
5305 CGF,
".atomic_reduction",
5312 if ((*IPriv)->getType()->isArrayType()) {
5313 auto *LHSVar = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5314 auto *RHSVar = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
5318 CritRedGen(CGF,
nullptr,
nullptr,
nullptr);
5341 CGF.EmitBranch(DefaultBB);
5342 CGF.EmitBlock(DefaultBB,
true);
5350 llvm::raw_svector_ostream Out(Buffer);
5369 Args.emplace_back(&Param);
5381 C.getPointerType(C.VoidPtrTy).castAs<
PointerType>());
5406 llvm::ConstantPointerNull::get(CGM.
VoidPtrTy),
5431 const Expr *ReductionOp,
5433 const Expr *PrivateRef) {
5435 auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(LHS)->getDecl());
5436 auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(RHS)->getDecl());
5440 Args.emplace_back(&ParamInOut);
5441 Args.emplace_back(&ParamIn);
5471 C.getPointerType(C.VoidPtrTy).castAs<
PointerType>());
5479 C.getPointerType(C.VoidPtrTy).castAs<
PointerType>());
5488 CGF, ReductionOp, PrivateRef, cast<DeclRefExpr>(LHS),
5489 cast<DeclRefExpr>(RHS));
5510 Args.emplace_back(&Param);
5522 C.getPointerType(C.VoidPtrTy).castAs<
PointerType>());
5544 ArrayRef<const Expr *> RHSExprs,
const OMPTaskDataTy &Data) {
5567 RD->completeDefinition();
5570 llvm::APInt ArraySize(64, Size);
5577 for (
unsigned Cnt = 0; Cnt < Size; ++Cnt) {
5580 llvm::ConstantInt::get(CGM.
SizeTy, Cnt)};
5588 RCG.emitSharedLValue(CGF, Cnt);
5595 std::tie(SizeValInChars, SizeVal) = RCG.
getSizes(Cnt);
5602 bool DelayedCreation = !!SizeVal;
5603 SizeValInChars = CGF.
Builder.CreateIntCast(SizeValInChars, CGM.
SizeTy,
5618 : llvm::ConstantPointerNull::get(CGM.
VoidPtrTy);
5623 CGM, Loc, RCG, Cnt, Data.
ReductionOps[Cnt], LHSExprs[Cnt],
5628 if (DelayedCreation) {
5630 llvm::ConstantInt::get(CGM.
Int32Ty, 1,
true),
5640 llvm::ConstantInt::get(CGM.
IntTy, Size,
true),
5701 if (
auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.
CapturedStmtInfo))
5702 Region->emitUntiedSwitch(CGF);
5711 InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind, HasCancel);
5727 if (CancelRegion == OMPD_parallel)
5728 CancelKind = CancelParallel;
5729 else if (CancelRegion == OMPD_for)
5730 CancelKind = CancelLoop;
5731 else if (CancelRegion == OMPD_sections)
5732 CancelKind = CancelSections;
5734 assert(CancelRegion == OMPD_taskgroup);
5735 CancelKind = CancelTaskgroup;
5747 if (
auto *OMPRegionInfo =
5751 if (CancelRegion == OMPD_taskgroup || OMPRegionInfo->hasCancel()) {
5763 auto *Cmp = CGF.
Builder.CreateIsNotNull(Result);
5764 CGF.
Builder.CreateCondBr(Cmp, ExitBB, ContBB);
5782 if (
auto *OMPRegionInfo =
5784 auto &&ThenGen = [Loc, CancelRegion, OMPRegionInfo](
CodeGenFunction &CGF,
5786 auto &RT = CGF.CGM.getOpenMPRuntime();
5788 RT.emitUpdateLocation(CGF, Loc), RT.getThreadID(CGF, Loc),
5791 auto *Result = CGF.EmitRuntimeCall(
5796 auto *ExitBB = CGF.createBasicBlock(
".cancel.exit");
5797 auto *ContBB = CGF.createBasicBlock(
".cancel.continue");
5798 auto *Cmp = CGF.Builder.CreateIsNotNull(Result);
5799 CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
5800 CGF.EmitBlock(ExitBB);
5803 CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
5804 CGF.EmitBranchThroughCleanup(CancelDest);
5805 CGF.EmitBlock(ContBB,
true);
5821 unsigned &DeviceID,
unsigned &FileID,
5822 unsigned &LineNum) {
5829 assert(Loc.
isValid() &&
"Source location is expected to be always valid.");
5830 assert(Loc.
isFileID() &&
"Source location is expected to refer to a file.");
5833 assert(PLoc.isValid() &&
"Source location is expected to be always valid.");
5835 llvm::sys::fs::UniqueID
ID;
5836 if (llvm::sys::fs::getUniqueID(PLoc.getFilename(),
ID))
5837 llvm_unreachable(
"Source file with target region no longer exists!");
5839 DeviceID = ID.getDevice();
5840 FileID = ID.getFile();
5841 LineNum = PLoc.getLine();
5846 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
5848 assert(!ParentName.empty() &&
"Invalid target region parent name!");
5851 IsOffloadEntry, CodeGen);
5856 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
5874 llvm::raw_svector_ostream OS(EntryFnName);
5875 OS <<
"__omp_offloading" << llvm::format(
"_%x", DeviceID)
5876 << llvm::format(
"_%x_", FileID) << ParentName <<
"_l" <<
Line;
5882 CGOpenMPTargetRegionInfo CGInfo(CS, CodeGen, EntryFnName);
5885 OutlinedFn = CGF.GenerateOpenMPCapturedStmtFunction(CS);
5889 if (!IsOffloadEntry)
5904 OutlinedFnID = llvm::ConstantExpr::getBitCast(OutlinedFn, CGM.
Int8PtrTy);
5907 OutlinedFnID =
new llvm::GlobalVariable(
5909 llvm::GlobalValue::PrivateLinkage,
5910 llvm::Constant::getNullValue(CGM.
Int8Ty),
".omp_offload.region_id");
5914 DeviceID, FileID, ParentName, Line, OutlinedFn, OutlinedFnID,
5920 while (
auto *CS = dyn_cast_or_null<CompoundStmt>(Body))
5921 Body = CS->body_front();
5939 assert(!CGF.
getLangOpts().OpenMPIsDevice &&
"Clauses associated with the " 5940 "teams directive expected to be " 5941 "emitted only for the host!");
5951 auto NumTeams = CGF.
EmitScalarExpr(NumTeamsClause->getNumTeams(),
5953 return Bld.CreateIntCast(NumTeams, CGF.
Int32Ty,
5958 return Bld.getInt32(0);
5964 return Bld.getInt32(1);
5974 if (
auto *TeamsDir = dyn_cast_or_null<OMPExecutableDirective>(
5978 CGOpenMPInnerExprInfo CGInfo(CGF, CS);
5981 return Bld.CreateIntCast(NumTeams, CGF.
Int32Ty,
5987 return Bld.getInt32(0);
6008 assert(!CGF.
getLangOpts().OpenMPIsDevice &&
"Clauses associated with the " 6009 "teams directive expected to be " 6010 "emitted only for the host!");
6030 llvm::Value *DefaultThreadLimitVal = Bld.getInt32(0);
6034 if (
const auto *ThreadLimitClause =
6037 auto ThreadLimit = CGF.
EmitScalarExpr(ThreadLimitClause->getThreadLimit(),
6039 ThreadLimitVal = Bld.CreateIntCast(ThreadLimit, CGF.
Int32Ty,
6043 if (
const auto *NumThreadsClause =
6050 Bld.CreateIntCast(NumThreads, CGF.
Int32Ty,
true);
6055 ThreadLimitVal = ThreadLimitVal
6056 ? Bld.CreateSelect(Bld.CreateICmpSLT(NumThreadsVal,
6058 NumThreadsVal, ThreadLimitVal)
6063 if (!ThreadLimitVal)
6064 ThreadLimitVal = DefaultThreadLimitVal;
6066 return ThreadLimitVal;
6077 if (
auto *TeamsDir = dyn_cast_or_null<OMPExecutableDirective>(
6081 CGOpenMPInnerExprInfo CGInfo(CGF, CS);
6090 return CGF.
Builder.getInt32(0);
6103 class MappableExprsHandler {
6107 enum OpenMPOffloadMappingFlags {
6111 OMP_MAP_FROM = 0x02,
6114 OMP_MAP_ALWAYS = 0x04,
6117 OMP_MAP_DELETE = 0x08,
6120 OMP_MAP_PTR_AND_OBJ = 0x10,
6123 OMP_MAP_TARGET_PARAM = 0x20,
6127 OMP_MAP_RETURN_PARAM = 0x40,
6130 OMP_MAP_PRIVATE = 0x80,
6132 OMP_MAP_LITERAL = 0x100,
6134 OMP_MAP_IMPLICIT = 0x200,
6139 class BasePointerInfo {
6148 : Ptr(Ptr), DevPtrDecl(DevPtrDecl) {}
6150 const ValueDecl *getDevicePtrDecl()
const {
return DevPtrDecl; }
6151 void setDevicePtrDecl(
const ValueDecl *D) { DevPtrDecl = D; }
6166 llvm::SmallPtrSet<const VarDecl *, 8> FirstPrivateDecls;
6168 llvm::SmallPtrSet<const VarDecl *, 8> ReductionDecls;
6187 if (
const auto *OAE = dyn_cast<OMPArraySectionExpr>(E)) {
6189 OAE->getBase()->IgnoreParenImpCasts())
6190 .getCanonicalType();
6194 if (!OAE->getLength() && OAE->getColonLoc().isValid())
6199 ElemSize = CGF.
getTypeSize(PTy->getPointeeType().getCanonicalType());
6201 auto *ATy = cast<ArrayType>(BaseTy.
getTypePtr());
6202 assert(ATy &&
"Expecting array type if not a pointer type.");
6203 ElemSize = CGF.
getTypeSize(ATy->getElementType().getCanonicalType());
6208 if (!OAE->getLength())
6214 return CGF.
Builder.CreateNUWMul(LengthVal, ElemSize);
6225 bool AddIsTargetParamFlag)
const {
6228 case OMPC_MAP_alloc:
6229 case OMPC_MAP_release:
6239 Bits = OMP_MAP_FROM;
6241 case OMPC_MAP_tofrom:
6242 Bits = OMP_MAP_TO | OMP_MAP_FROM;
6244 case OMPC_MAP_delete:
6245 Bits = OMP_MAP_DELETE;
6248 llvm_unreachable(
"Unexpected map type!");
6252 Bits |= OMP_MAP_PTR_AND_OBJ;
6253 if (AddIsTargetParamFlag)
6254 Bits |= OMP_MAP_TARGET_PARAM;
6255 if (MapTypeModifier == OMPC_MAP_always)
6256 Bits |= OMP_MAP_ALWAYS;
6262 bool isFinalArraySectionExpression(
const Expr *E)
const {
6270 if (OASE->getColonLoc().isInvalid())
6273 auto *Length = OASE->getLength();
6280 OASE->getBase()->IgnoreParenImpCasts())
6281 .getCanonicalType();
6282 if (
auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
6283 return ATy->getSize().getSExtValue() != 1;
6291 llvm::APSInt ConstLength;
6292 if (!Length->EvaluateAsInt(ConstLength, CGF.
getContext()))
6295 return ConstLength.getSExtValue() != 1;
6302 void generateInfoForComponentList(
6305 MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers,
6306 MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types,
6307 bool IsFirstComponentList,
bool IsImplicit)
const {
6422 bool IsCaptureFirstInfo = IsFirstComponentList;
6425 auto CI = Components.rbegin();
6426 auto CE = Components.rend();
6431 bool IsExpressionFirstInfo =
true;
6434 if (
auto *ME = dyn_cast<MemberExpr>(I->getAssociatedExpression())) {
6447 I->getAssociatedDeclaration()->getType().getNonReferenceType();
6460 uint64_t DefaultFlags = IsImplicit ? OMP_MAP_IMPLICIT : 0;
6461 for (; I != CE; ++I) {
6462 auto Next = std::next(I);
6470 bool IsFinalArraySection =
6471 isFinalArraySectionExpression(I->getAssociatedExpression());
6483 I->getAssociatedExpression()->getType()->isAnyPointerType();
6485 if (Next == CE || IsPointer || IsFinalArraySection) {
6489 assert((Next == CE ||
6490 isa<MemberExpr>(Next->getAssociatedExpression()) ||
6491 isa<ArraySubscriptExpr>(Next->getAssociatedExpression()) ||
6492 isa<OMPArraySectionExpr>(Next->getAssociatedExpression())) &&
6493 "Unexpected expression");
6497 auto *Size = getExprTypeSize(I->getAssociatedExpression());
6503 if (isa<MemberExpr>(I->getAssociatedExpression()) &&
6504 I->getAssociatedDeclaration()->getType()->isReferenceType()) {
6505 auto *LI = cast<llvm::LoadInst>(LB);
6506 auto *RefAddr = LI->getPointerOperand();
6508 BasePointers.push_back(BP);
6509 Pointers.push_back(RefAddr);
6511 Types.push_back(DefaultFlags |
6515 !IsExpressionFirstInfo, IsCaptureFirstInfo));
6516 IsExpressionFirstInfo =
false;
6517 IsCaptureFirstInfo =
false;
6522 BasePointers.push_back(BP);
6523 Pointers.push_back(LB);
6524 Sizes.push_back(Size);
6530 Types.push_back(DefaultFlags | getMapTypeBits(MapType, MapTypeModifier,
6531 !IsExpressionFirstInfo,
6532 IsCaptureFirstInfo));
6535 if (IsFinalArraySection)
6542 IsExpressionFirstInfo =
false;
6543 IsCaptureFirstInfo =
false;
6552 unsigned CurrentModifiers) {
6559 return MappableExprsHandler::OMP_MAP_PRIVATE |
6560 MappableExprsHandler::OMP_MAP_TO;
6564 return MappableExprsHandler::OMP_MAP_TO |
6565 MappableExprsHandler::OMP_MAP_FROM;
6569 return CurrentModifiers;
6574 : CurDir(Dir), CGF(CGF) {
6577 for (
const auto *D : C->varlists())
6578 FirstPrivateDecls.insert(
6581 for (
const auto *D : C->varlists()) {
6582 ReductionDecls.insert(
6588 for (
auto L : C->component_lists())
6589 DevPointersMap[L.first].push_back(L.second);
6596 void generateAllInfo(MapBaseValuesArrayTy &BasePointers,
6597 MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
6598 MapFlagsArrayTy &Types)
const {
6599 BasePointers.clear();
6606 enum ReturnPointerKind {
6614 RPK_MemberReference,
6619 ReturnPointerKind ReturnDevicePointer = RPK_None;
6620 bool IsImplicit =
false;
6622 MapInfo() =
default;
6626 ReturnPointerKind ReturnDevicePointer,
bool IsImplicit)
6627 : Components(Components), MapType(MapType),
6628 MapTypeModifier(MapTypeModifier),
6629 ReturnDevicePointer(ReturnDevicePointer), IsImplicit(IsImplicit) {}
6635 llvm::MapVector<const ValueDecl *, SmallVector<MapInfo, 8>> Info;
6639 auto &&InfoGen = [&Info](
6643 MapInfo::ReturnPointerKind ReturnDevicePointer,
bool IsImplicit) {
6644 const ValueDecl *VD =
6646 Info[VD].emplace_back(L, MapType, MapModifier, ReturnDevicePointer,
6652 for (
auto L : C->component_lists()) {
6653 InfoGen(L.first, L.second, C->getMapType(), C->getMapTypeModifier(),
6654 MapInfo::RPK_None, C->isImplicit());
6657 for (
auto L : C->component_lists()) {
6659 MapInfo::RPK_None, C->isImplicit());
6662 for (
auto L : C->component_lists()) {
6664 MapInfo::RPK_None, C->isImplicit());
6673 for (
auto L : C->component_lists()) {
6674 assert(!L.second.empty() &&
"Not expecting empty list of components!");
6675 const ValueDecl *VD = L.second.back().getAssociatedDeclaration();
6676 VD = cast<ValueDecl>(VD->getCanonicalDecl());
6677 auto *IE = L.second.back().getAssociatedExpression();
6681 auto It = Info.find(isa<MemberExpr>(IE) ?
nullptr : VD);
6685 if (It != Info.end()) {
6686 auto CI = std::find_if(
6687 It->second.begin(), It->second.end(), [VD](
const MapInfo &MI) {
6688 return MI.Components.back().getAssociatedDeclaration() == VD;
6692 if (CI != It->second.end()) {
6693 CI->ReturnDevicePointer = isa<MemberExpr>(IE)
6694 ? (VD->getType()->isReferenceType()
6695 ? MapInfo::RPK_MemberReference
6696 : MapInfo::RPK_Member)
6697 : MapInfo::RPK_Base;
6709 BasePointers.push_back({Ptr, VD});
6710 Pointers.push_back(Ptr);
6711 Sizes.push_back(llvm::Constant::getNullValue(this->CGF.
SizeTy));
6712 Types.push_back(OMP_MAP_RETURN_PARAM | OMP_MAP_TARGET_PARAM);
6715 for (
auto &M : Info) {
6718 bool IsFirstComponentList =
true;
6719 for (MapInfo &L : M.second) {
6720 assert(!L.Components.empty() &&
6721 "Not expecting declaration with no component lists.");
6724 unsigned CurrentBasePointersIdx = BasePointers.size();
6726 this->generateInfoForComponentList(
6727 L.MapType, L.MapTypeModifier, L.Components, BasePointers, Pointers,
6728 Sizes, Types, IsFirstComponentList, L.IsImplicit);
6732 if (IsFirstComponentList &&
6733 L.ReturnDevicePointer != MapInfo::RPK_None) {
6737 if (L.ReturnDevicePointer != MapInfo::RPK_Base) {
6738 ++CurrentBasePointersIdx;
6739 if (L.ReturnDevicePointer == MapInfo::RPK_MemberReference)
6740 ++CurrentBasePointersIdx;
6742 assert(BasePointers.size() > CurrentBasePointersIdx &&
6743 "Unexpected number of mapped base pointers.");
6745 auto *RelevantVD = L.Components.back().getAssociatedDeclaration();
6746 assert(RelevantVD &&
6747 "No relevant declaration related with device pointer??");
6749 BasePointers[CurrentBasePointersIdx].setDevicePtrDecl(RelevantVD);
6750 Types[CurrentBasePointersIdx] |= OMP_MAP_RETURN_PARAM;
6752 IsFirstComponentList =
false;
6761 MapBaseValuesArrayTy &BasePointers,
6762 MapValuesArrayTy &Pointers,
6763 MapValuesArrayTy &Sizes,
6764 MapFlagsArrayTy &Types)
const {
6766 "Not expecting to generate map info for a variable array type!");
6768 BasePointers.clear();
6775 bool IsFirstComponentList =
true;
6777 const ValueDecl *VD =
6787 auto It = DevPointersMap.find(VD);
6788 if (It != DevPointersMap.end()) {
6789 for (
auto L : It->second) {
6790 generateInfoForComponentList(
6792 BasePointers, Pointers, Sizes, Types, IsFirstComponentList,
6794 IsFirstComponentList =
false;
6798 }
else if (DevPointersMap.count(VD)) {
6799 BasePointers.push_back({Arg, VD});
6800 Pointers.push_back(Arg);
6802 Types.push_back(OMP_MAP_LITERAL | OMP_MAP_TARGET_PARAM);
6808 for (
auto L : C->decl_component_lists(VD)) {
6809 assert(L.first == VD &&
6810 "We got information for the wrong declaration??");
6811 assert(!L.second.empty() &&
6812 "Not expecting declaration with no component lists.");
6813 generateInfoForComponentList(
6814 C->getMapType(), C->getMapTypeModifier(), L.second, BasePointers,
6815 Pointers, Sizes, Types, IsFirstComponentList, C->isImplicit());
6816 IsFirstComponentList =
false;
6826 MapBaseValuesArrayTy &CurBasePointers,
6827 MapValuesArrayTy &CurPointers,
6828 MapValuesArrayTy &CurSizes,
6829 MapFlagsArrayTy &CurMapTypes) {
6833 CurBasePointers.push_back(CV);
6834 CurPointers.push_back(CV);
6838 CurMapTypes.push_back(OMP_MAP_TO | OMP_MAP_FROM);
6840 CurBasePointers.push_back(CV);
6841 CurPointers.push_back(CV);
6845 CurMapTypes.push_back(OMP_MAP_LITERAL);
6850 CurMapTypes.push_back(0u);
6851 CurSizes.push_back(llvm::Constant::getNullValue(CGF.
SizeTy));
6855 CurBasePointers.push_back(CV);
6856 CurPointers.push_back(CV);
6865 CurMapTypes.emplace_back(adjustMapModifiersForPrivateClauses(
6866 CI, ElementType->isAggregateType() ? (OMP_MAP_TO | OMP_MAP_FROM)
6870 CurMapTypes.back() |= OMP_MAP_TARGET_PARAM;
6877 OMP_DEVICEID_UNDEF = -1,
6890 CGOpenMPRuntime::TargetDataInfo &Info) {
6891 auto &CGM = CGF.
CGM;
6895 Info.clearArrayInfo();
6896 Info.NumberOfPtrs = BasePointers.size();
6898 if (Info.NumberOfPtrs) {
6901 bool hasRuntimeEvaluationCaptureSize =
false;
6902 for (
auto *S : Sizes)
6903 if (!isa<llvm::Constant>(S)) {
6904 hasRuntimeEvaluationCaptureSize =
true;
6908 llvm::APInt PointerNumAP(32, Info.NumberOfPtrs,
true);
6913 Info.BasePointersArray =
6915 Info.PointersArray =
6921 if (hasRuntimeEvaluationCaptureSize) {
6922 QualType SizeArrayType = Ctx.getConstantArrayType(
6931 for (
auto S : Sizes)
6932 ConstSizes.push_back(cast<llvm::Constant>(S));
6934 auto *SizesArrayInit = llvm::ConstantArray::get(
6935 llvm::ArrayType::get(CGM.
SizeTy, ConstSizes.size()), ConstSizes);
6936 auto *SizesArrayGbl =
new llvm::GlobalVariable(
6937 CGM.
getModule(), SizesArrayInit->getType(),
6938 true, llvm::GlobalValue::PrivateLinkage,
6939 SizesArrayInit,
".offload_sizes");
6940 SizesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
6941 Info.SizesArray = SizesArrayGbl;
6946 llvm::Constant *MapTypesArrayInit =
6947 llvm::ConstantDataArray::get(CGF.
Builder.getContext(), MapTypes);
6948 auto *MapTypesArrayGbl =
new llvm::GlobalVariable(
6949 CGM.
getModule(), MapTypesArrayInit->getType(),
6950 true, llvm::GlobalValue::PrivateLinkage,
6951 MapTypesArrayInit,
".offload_maptypes");
6952 MapTypesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
6953 Info.MapTypesArray = MapTypesArrayGbl;
6955 for (
unsigned i = 0; i < Info.NumberOfPtrs; ++i) {
6958 llvm::ArrayType::get(CGM.
VoidPtrTy, Info.NumberOfPtrs),
6959 Info.BasePointersArray, 0, i);
6961 BP, BPVal->getType()->getPointerTo(0));
6962 Address BPAddr(BP, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));
6965 if (Info.requiresDevicePointerInfo())
6966 if (
auto *DevVD = BasePointers[i].getDevicePtrDecl())
6967 Info.CaptureDeviceAddrMap.insert(std::make_pair(DevVD, BPAddr));
6971 llvm::ArrayType::get(CGM.
VoidPtrTy, Info.NumberOfPtrs),
6972 Info.PointersArray, 0, i);
6974 P, PVal->getType()->getPointerTo(0));
6975 Address PAddr(P, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));
6978 if (hasRuntimeEvaluationCaptureSize) {
6980 llvm::ArrayType::get(CGM.
SizeTy, Info.NumberOfPtrs),
6984 Address SAddr(S, Ctx.getTypeAlignInChars(Ctx.getSizeType()));
6997 llvm::Value *&MapTypesArrayArg, CGOpenMPRuntime::TargetDataInfo &Info) {
6998 auto &CGM = CGF.
CGM;
6999 if (Info.NumberOfPtrs) {
7000 BasePointersArrayArg = CGF.
Builder.CreateConstInBoundsGEP2_32(
7001 llvm::ArrayType::get(CGM.
VoidPtrTy, Info.NumberOfPtrs),
7002 Info.BasePointersArray,
7004 PointersArrayArg = CGF.
Builder.CreateConstInBoundsGEP2_32(
7005 llvm::ArrayType::get(CGM.
VoidPtrTy, Info.NumberOfPtrs),
7009 SizesArrayArg = CGF.
Builder.CreateConstInBoundsGEP2_32(
7010 llvm::ArrayType::get(CGM.
SizeTy, Info.NumberOfPtrs), Info.SizesArray,
7012 MapTypesArrayArg = CGF.
Builder.CreateConstInBoundsGEP2_32(
7013 llvm::ArrayType::get(CGM.
Int64Ty, Info.NumberOfPtrs),
7018 BasePointersArrayArg = llvm::ConstantPointerNull::get(CGM.
VoidPtrPtrTy);
7019 PointersArrayArg = llvm::ConstantPointerNull::get(CGM.
VoidPtrPtrTy);
7020 SizesArrayArg = llvm::ConstantPointerNull::get(CGM.
SizeTy->getPointerTo());
7022 llvm::ConstantPointerNull::get(CGM.
Int64Ty->getPointerTo());
7030 const Expr *IfCond,
const Expr *Device,
7031 ArrayRef<llvm::Value *> CapturedVars) {
7035 assert(OutlinedFn &&
"Invalid outlined function!");
7050 MappableExprsHandler MEHandler(D, CGF);
7054 auto CV = CapturedVars.begin();
7057 CI != CE; ++CI, ++RI, ++CV) {
7058 CurBasePointers.clear();
7059 CurPointers.clear();
7061 CurMapTypes.clear();
7065 if (CI->capturesVariableArrayType()) {
7066 CurBasePointers.push_back(*CV);
7067 CurPointers.push_back(*CV);
7068 CurSizes.push_back(CGF.
getTypeSize(RI->getType()));
7070 CurMapTypes.push_back(MappableExprsHandler::OMP_MAP_LITERAL |
7071 MappableExprsHandler::OMP_MAP_TARGET_PARAM);
7075 MEHandler.generateInfoForCapture(CI, *CV, CurBasePointers, CurPointers,
7076 CurSizes, CurMapTypes);
7077 if (CurBasePointers.empty())
7078 MEHandler.generateDefaultMapInfo(*CI, **RI, *CV, CurBasePointers,
7079 CurPointers, CurSizes, CurMapTypes);
7082 assert(!CurBasePointers.empty() &&
"Non-existing map pointer for capture!");
7083 assert(CurBasePointers.size() == CurPointers.size() &&
7084 CurBasePointers.size() == CurSizes.size() &&
7085 CurBasePointers.size() == CurMapTypes.size() &&
7086 "Inconsistent map information sizes!");
7090 KernelArgs.push_back(*CurBasePointers.front());
7092 BasePointers.append(CurBasePointers.begin(), CurBasePointers.end());
7093 Pointers.append(CurPointers.begin(), CurPointers.end());
7094 Sizes.append(CurSizes.begin(), CurSizes.end());
7095 MapTypes.append(CurMapTypes.begin(), CurMapTypes.end());
7099 auto &&ThenGen = [
this, &BasePointers, &Pointers, &Sizes, &MapTypes, Device,
7100 OutlinedFn, OutlinedFnID, &D,
7102 auto &RT = CGF.CGM.getOpenMPRuntime();
7120 assert(OutlinedFnID &&
"Invalid outlined function ID!");
7125 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
7128 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
7132 llvm::Value *PointerNum = CGF.Builder.getInt32(BasePointers.size());
7174 assert(NumThreads &&
"Thread limit expression should be available along " 7175 "with number of teams.");
7177 DeviceID, OutlinedFnID,
7182 Return = CGF.EmitRuntimeCall(
7188 DeviceID, OutlinedFnID,
7192 Return = CGF.EmitRuntimeCall(
7199 llvm::BasicBlock *OffloadFailedBlock =
7200 CGF.createBasicBlock(
"omp_offload.failed");
7201 llvm::BasicBlock *OffloadContBlock =
7202 CGF.createBasicBlock(
"omp_offload.cont");
7203 llvm::Value *Failed = CGF.Builder.CreateIsNotNull(Return);
7204 CGF.Builder.CreateCondBr(Failed, OffloadFailedBlock, OffloadContBlock);
7206 CGF.EmitBlock(OffloadFailedBlock);
7208 CGF.EmitBranch(OffloadContBlock);
7210 CGF.EmitBlock(OffloadContBlock,
true);
7214 auto &&ElseGen = [
this, &D, OutlinedFn, &KernelArgs](
CodeGenFunction &CGF,
7238 StringRef ParentName) {
7243 bool requiresDeviceCodegen =
7244 isa<OMPExecutableDirective>(S) &&
7246 cast<OMPExecutableDirective>(S)->getDirectiveKind());
7248 if (requiresDeviceCodegen) {
7249 auto &E = *cast<OMPExecutableDirective>(S);
7263 case Stmt::OMPTargetDirectiveClass:
7265 CGM, ParentName, cast<OMPTargetDirective>(*S));
7267 case Stmt::OMPTargetParallelDirectiveClass:
7269 CGM, ParentName, cast<OMPTargetParallelDirective>(*S));
7271 case Stmt::OMPTargetTeamsDirectiveClass:
7273 CGM, ParentName, cast<OMPTargetTeamsDirective>(*S));
7275 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
7277 CGM, ParentName, cast<OMPTargetTeamsDistributeDirective>(*S));
7279 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
7281 CGM, ParentName, cast<OMPTargetTeamsDistributeSimdDirective>(*S));
7283 case Stmt::OMPTargetParallelForDirectiveClass:
7285 CGM, ParentName, cast<OMPTargetParallelForDirective>(*S));
7287 case Stmt::OMPTargetParallelForSimdDirectiveClass:
7289 CGM, ParentName, cast<OMPTargetParallelForSimdDirective>(*S));
7291 case Stmt::OMPTargetSimdDirectiveClass:
7293 CGM, ParentName, cast<OMPTargetSimdDirective>(*S));
7296 llvm_unreachable(
"Unknown target directive for OpenMP device codegen.");
7302 if (!E->hasAssociatedStmt())
7306 cast<CapturedStmt>(E->getAssociatedStmt())->getCapturedStmt(),
7312 if (
auto *L = dyn_cast<LambdaExpr>(S))
7321 auto &FD = *cast<FunctionDecl>(GD.
getDecl());
7346 for (
auto *Ctor : RD->ctors()) {
7347 StringRef ParentName =
7351 auto *Dtor = RD->getDestructor();
7353 StringRef ParentName =
7366 if (isa<FunctionDecl>(VD))
7397 CGF.
Builder.getInt32(CapturedVars.size()),
7400 RealArgs.append(std::begin(Args), std::end(Args));
7401 RealArgs.append(CapturedVars.begin(), CapturedVars.end());
7408 const Expr *NumTeams,
7409 const Expr *ThreadLimit,
7448 auto &&BeginThenGen = [
this, &D, Device, &Info,
7457 MappableExprsHandler MCHandler(D, CGF);
7458 MCHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);
7468 SizesArrayArg, MapTypesArrayArg, Info);
7473 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
7476 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
7480 auto *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);
7483 DeviceID, PointerNum, BasePointersArrayArg,
7484 PointersArrayArg, SizesArrayArg, MapTypesArrayArg};
7490 if (!Info.CaptureDeviceAddrMap.empty())
7497 assert(Info.isValid() &&
"Invalid data environment closing arguments.");
7504 SizesArrayArg, MapTypesArrayArg, Info);
7509 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
7512 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
7516 auto *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);
7519 DeviceID, PointerNum, BasePointersArrayArg,
7520 PointersArrayArg, SizesArrayArg, MapTypesArrayArg};
7528 auto &&BeginElseGen = [&Info, &CodeGen, &NoPrivAction](
CodeGenFunction &CGF,
7530 if (!Info.CaptureDeviceAddrMap.empty()) {
7531 CodeGen.setAction(NoPrivAction);
7549 if (Info.CaptureDeviceAddrMap.empty()) {
7550 CodeGen.setAction(NoPrivAction);
7564 const Expr *Device) {
7568 assert((isa<OMPTargetEnterDataDirective>(D) ||
7569 isa<OMPTargetExitDataDirective>(D) ||
7570 isa<OMPTargetUpdateDirective>(D)) &&
7571 "Expecting either target enter, exit data, or update directives.");
7576 auto &&ThenGen = [
this, &D, Device, &InputInfo,
7581 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
7584 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
7588 llvm::Constant *PointerNum =
7589 CGF.Builder.getInt32(InputInfo.NumberOfTargetItems);
7593 InputInfo.BasePointersArray.getPointer(),
7594 InputInfo.PointersArray.getPointer(),
7595 InputInfo.SizesArray.getPointer(),
7604 llvm_unreachable(
"Unexpected standalone target data directive.");
7606 case OMPD_target_enter_data:
7610 case OMPD_target_exit_data:
7614 case OMPD_target_update:
7622 auto &&TargetThenGen = [
this, &ThenGen, &D, &InputInfo, &MapTypesArray](
7631 MappableExprsHandler MEHandler(D, CGF);
7632 MEHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);
7641 InputInfo.BasePointersArray =
7643 InputInfo.PointersArray =
7645 InputInfo.SizesArray =
7649 CGF.EmitOMPTargetTaskBasedDirective(D, ThenGen, InputInfo);
7667 struct ParamAttrTy {
7669 llvm::APSInt StrideOrArg;
7670 llvm::APSInt Alignment;
7675 ArrayRef<ParamAttrTy> ParamAttrs) {
7704 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
7705 if (ParamAttrs[Offset].Kind == Vector)
7710 for (
unsigned I = 0, E = FD->
getNumParams(); I < E; ++I) {
7711 if (ParamAttrs[I + Offset].Kind == Vector) {
7728 const llvm::APSInt &VLENVal,
7729 ArrayRef<ParamAttrTy> ParamAttrs,
7730 OMPDeclareSimdDeclAttr::BranchStateTy
State) {
7733 unsigned VecRegSize;
7735 ISADataTy ISAData[] = {
7751 case OMPDeclareSimdDeclAttr::BS_Undefined:
7752 Masked.push_back(
'N');
7753 Masked.push_back(
'M');
7755 case OMPDeclareSimdDeclAttr::BS_Notinbranch:
7756 Masked.push_back(
'N');
7758 case OMPDeclareSimdDeclAttr::BS_Inbranch:
7759 Masked.push_back(
'M');
7762 for (
auto Mask : Masked) {
7763 for (
auto &Data : ISAData) {
7765 llvm::raw_svector_ostream Out(Buffer);
7766 Out <<
"_ZGV" << Data.ISA << Mask;
7768 Out << llvm::APSInt::getUnsigned(Data.VecRegSize /
7772 for (
auto &ParamAttr : ParamAttrs) {
7773 switch (ParamAttr.Kind){
7774 case LinearWithVarStride:
7775 Out <<
's' << ParamAttr.StrideOrArg;
7779 if (!!ParamAttr.StrideOrArg)
7780 Out << ParamAttr.StrideOrArg;
7789 if (!!ParamAttr.Alignment)
7790 Out <<
'a' << ParamAttr.Alignment;
7792 Out <<
'_' << Fn->getName();
7793 Fn->addFnAttr(Out.str());
7799 llvm::Function *Fn) {
7803 llvm::DenseMap<const Decl *, unsigned> ParamPositions;
7804 if (isa<CXXMethodDecl>(FD))
7805 ParamPositions.insert({FD, 0});
7806 unsigned ParamPos = ParamPositions.size();
7808 ParamPositions.insert({
P->getCanonicalDecl(), ParamPos});
7814 for (
auto *E :
Attr->uniforms()) {
7817 if (isa<CXXThisExpr>(E))
7818 Pos = ParamPositions[FD];
7820 auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
7822 Pos = ParamPositions[PVD];
7824 ParamAttrs[Pos].Kind = Uniform;
7827 auto NI =
Attr->alignments_begin();
7828 for (
auto *E :
Attr->aligneds()) {
7832 if (isa<CXXThisExpr>(E)) {
7833 Pos = ParamPositions[FD];
7836 auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
7838 Pos = ParamPositions[PVD];
7839 ParmTy = PVD->getType();
7841 ParamAttrs[Pos].Alignment =
7842 (*NI) ? (*NI)->EvaluateKnownConstInt(C)
7843 : llvm::APSInt::getUnsigned(
7849 auto SI =
Attr->steps_begin();
7850 auto MI =
Attr->modifiers_begin();
7851 for (
auto *E :
Attr->linears()) {
7854 if (isa<CXXThisExpr>(E))
7855 Pos = ParamPositions[FD];
7857 auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
7859 Pos = ParamPositions[PVD];
7861 auto &ParamAttr = ParamAttrs[Pos];
7862 ParamAttr.Kind = Linear;
7864 if (!(*SI)->EvaluateAsInt(ParamAttr.StrideOrArg, C,
7866 if (
auto *DRE = cast<DeclRefExpr>((*SI)->IgnoreParenImpCasts())) {
7867 if (
auto *StridePVD = cast<ParmVarDecl>(DRE->getDecl())) {
7868 ParamAttr.Kind = LinearWithVarStride;
7869 ParamAttr.StrideOrArg = llvm::APSInt::getUnsigned(
7870 ParamPositions[StridePVD->getCanonicalDecl()]);
7878 llvm::APSInt VLENVal;
7879 if (
const Expr *VLEN =
Attr->getSimdlen())
7880 VLENVal = VLEN->EvaluateKnownConstInt(C);
7881 OMPDeclareSimdDeclAttr::BranchStateTy
State =
Attr->getBranchState();
7882 if (CGM.
getTriple().getArch() == llvm::Triple::x86 ||
7883 CGM.
getTriple().getArch() == llvm::Triple::x86_64)
7892 static const int DoacrossFinArgs = 2;
7901 assert(CallArgs.size() == DoacrossFinArgs);
7902 std::copy(CallArgs.begin(), CallArgs.end(), std::begin(Args));
7938 enum { LowerFD = 0, UpperFD, StrideFD };
7958 llvm::ConstantInt::getSigned(CGM.
Int32Ty, 1),
7964 llvm::Value *FiniArgs[DoacrossCleanupTy::DoacrossFinArgs] = {
7968 llvm::makeArrayRef(FiniArgs));
7978 CounterVal->
getType(), Int64Ty,
8000 if (
auto *Fn = dyn_cast<llvm::Function>(Callee)) {
8001 if (Fn->doesNotThrow()) {
8012 assert(Loc.
isValid() &&
"Outlined function call location must be valid.");
8013 emitCall(CGF, OutlinedFn, Args, Loc);
8018 const VarDecl *TargetParam)
const {
8025 llvm_unreachable(
"Not supported in SIMD-only mode");
8031 llvm_unreachable(
"Not supported in SIMD-only mode");
8038 bool Tied,
unsigned &NumberOfParts) {
8039 llvm_unreachable(
"Not supported in SIMD-only mode");
8046 const Expr *IfCond) {
8047 llvm_unreachable(
"Not supported in SIMD-only mode");
8054 llvm_unreachable(
"Not supported in SIMD-only mode");
8060 llvm_unreachable(
"Not supported in SIMD-only mode");
8065 llvm_unreachable(
"Not supported in SIMD-only mode");
8071 llvm_unreachable(
"Not supported in SIMD-only mode");
8079 llvm_unreachable(
"Not supported in SIMD-only mode");
8086 llvm_unreachable(
"Not supported in SIMD-only mode");
8093 bool ForceSimpleCall) {
8094 llvm_unreachable(
"Not supported in SIMD-only mode");
8101 llvm_unreachable(
"Not supported in SIMD-only mode");
8107 llvm_unreachable(
"Not supported in SIMD-only mode");
8113 llvm_unreachable(
"Not supported in SIMD-only mode");
8120 llvm_unreachable(
"Not supported in SIMD-only mode");
8126 llvm_unreachable(
"Not supported in SIMD-only mode");
8131 unsigned IVSize,
bool IVSigned,
8134 llvm_unreachable(
"Not supported in SIMD-only mode");
8140 llvm_unreachable(
"Not supported in SIMD-only mode");
8146 llvm_unreachable(
"Not supported in SIMD-only mode");
8153 llvm_unreachable(
"Not supported in SIMD-only mode");
8159 llvm_unreachable(
"Not supported in SIMD-only mode");
8164 llvm_unreachable(
"Not supported in SIMD-only mode");
8170 llvm_unreachable(
"Not supported in SIMD-only mode");
8179 llvm_unreachable(
"Not supported in SIMD-only mode");
8186 llvm_unreachable(
"Not supported in SIMD-only mode");
8193 assert(Options.
SimpleReduction &&
"Only simple reduction is expected.");
8195 ReductionOps, Options);
8201 llvm_unreachable(
"Not supported in SIMD-only mode");
8208 llvm_unreachable(
"Not supported in SIMD-only mode");
8215 llvm_unreachable(
"Not supported in SIMD-only mode");
8220 llvm_unreachable(
"Not supported in SIMD-only mode");
8226 llvm_unreachable(
"Not supported in SIMD-only mode");
8232 llvm_unreachable(
"Not supported in SIMD-only mode");
8237 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
8239 llvm_unreachable(
"Not supported in SIMD-only mode");
8246 const Expr *IfCond,
const Expr *Device,
8248 llvm_unreachable(
"Not supported in SIMD-only mode");
8252 llvm_unreachable(
"Not supported in SIMD-only mode");
8256 llvm_unreachable(
"Not supported in SIMD-only mode");
8272 llvm_unreachable(
"Not supported in SIMD-only mode");
8276 const Expr *NumTeams,
8277 const Expr *ThreadLimit,
8279 llvm_unreachable(
"Not supported in SIMD-only mode");
8285 llvm_unreachable(
"Not supported in SIMD-only mode");
8290 const Expr *Device) {
8291 llvm_unreachable(
"Not supported in SIMD-only mode");
8296 llvm_unreachable(
"Not supported in SIMD-only mode");
8301 llvm_unreachable(
"Not supported in SIMD-only mode");
8306 const VarDecl *NativeParam)
const {
8307 llvm_unreachable(
"Not supported in SIMD-only mode");
8313 const VarDecl *TargetParam)
const {
8314 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.
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)
An instance of this class is created to represent 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...
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.
QualType getPointeeType() const
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
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
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 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...
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.
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.
QualType getTgtBinaryDescriptorQTy()
Returns __tgt_bin_desc type.
SmallVector< std::pair< OpenMPDependClauseKind, const Expr * >, 4 > Dependences
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...
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
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)
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.
static Address createIdentFieldGEP(CodeGenFunction &CGF, Address Addr, IdentFieldIndex Field, const llvm::Twine &Name="")
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)
RecordDecl * KmpTaskTQTyRD
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...
const RecordDecl * getCapturedRecordDecl() const
Retrieve the record declaration for captured variables.
llvm::Value * PointersArray
The array of section pointers passed to the runtime library.
virtual void completeDefinition()
completeDefinition - Notes that the definition of this type is now complete.
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)
llvm::Value * emitReductionFunction(CodeGenModule &CGM, llvm::Type *ArgsType, ArrayRef< const Expr *> Privates, ArrayRef< const Expr *> LHSExprs, ArrayRef< const Expr *> RHSExprs, ArrayRef< const Expr *> ReductionOps)
Emits reduction function.
const Expr * getAnyInitializer() const
getAnyInitializer - Get the initializer for this variable, no matter which declaration it is attached...
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
static CharUnits getOffsetOfIdentField(IdentFieldIndex Field)
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
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
VarDecl - An instance of this class is created to represent 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
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...
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
capture_iterator capture_begin()
Retrieve an iterator pointing to the first capture.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
virtual void createOffloadEntry(llvm::Constant *ID, llvm::Constant *Addr, uint64_t Size, int32_t Flags=0)
Creates offloading entry for the provided entry ID ID, address Addr, size Size, and flags Flags...
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)
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...
void emitTargetCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, llvm::Value *OutlinedFn, llvm::Value *OutlinedFnID, const Expr *IfCond, const Expr *Device, ArrayRef< llvm::Value *> CapturedVars) override
Emit the target offloading code associated with D.
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
RecordDecl - 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...
SmallVector< const Expr *, 4 > LastprivateVars
virtual void emitDoacrossOrdered(CodeGenFunction &CGF, const OMPDependClause *C)
Emit code for doacross ordered directive with 'depend' clause.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
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.
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
Expr * getCounterValue()
Get the loop counter value.
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
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...
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.
SourceLocation getLocEnd() const
Returns ending location of directive.
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...
static CharUnits getIdentAlign(CodeGenModule &CGM)
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...
SmallVector< const Expr *, 4 > PrivateCopies
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.
void EmitAggregateAssign(Address DestPtr, Address SrcPtr, QualType EltTy)
EmitAggregateCopy - Emit an aggregate assignment.
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.
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)
static llvm::Function * emitCombinerOrInitializer(CodeGenModule &CGM, QualType Ty, const Expr *CombinerInitializer, const VarDecl *In, const VarDecl *Out, bool IsCombiner)
This represents clause 'reduction' in the '#pragma omp ...' directives.
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::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
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.
SourceLocation getLocStart() const
Returns starting location of directive kind.
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.
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
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 addPrivate(const VarDecl *LocalVD, llvm::function_ref< Address()> PrivateGen)
Registers LocalVD variable as a private and apply PrivateGen function for it to generate correspondin...
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.
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.
const Stmt * getAssociatedStmt() const
Returns statement associated with the directive.
virtual void emitFlush(CodeGenFunction &CGF, ArrayRef< const Expr *> Vars, SourceLocation Loc)
Emit flush of the variables specified in 'omp flush' directive.
void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc) override
Emit code for 'taskwait' directive.
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
QualType getPointeeType() const
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...
const FunctionProtoType * T
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.
static llvm::Function * createOffloadingBinaryDescriptorFunction(CodeGenModule &CGM, StringRef Name, const RegionCodeGenTy &Codegen)
Create a Ctor/Dtor-like function whose body is emitted through Codegen.
void emitKmpRoutineEntryT(QualType KmpInt32Ty)
Build type kmp_routine_entry_t (if not built yet).
const T * castAs() const
Member-template castAs<specific type>.
void SetInternalFunctionAttributes(const Decl *D, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
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.
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)
llvm::PointerType * getType() const
Return the type of the pointer value.
Address getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF, QualType VarType, StringRef Name) override
Creates artificial threadprivate variable with name Name and type VarType.
static llvm::iterator_range< specific_clause_iterator< SpecificClause > > getClausesOfKind(ArrayRef< OMPClause *> Clauses)
void registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID, StringRef ParentName, unsigned LineNum, llvm::Constant *Addr, llvm::Constant *ID, int32_t Flags)
Register target region entry.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
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
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
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...
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.
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
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.
CGOpenMPRuntime(CodeGenModule &CGM)
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
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.
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="")
static llvm::Value * emitNumTeamsForTargetDirective(CGOpenMPRuntime &OMPRuntime, CodeGenFunction &CGF, const OMPExecutableDirective &D)
Emit the number of teams for a target directive.
This captures a statement into a function.
QualType getCanonicalType() const
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 functionFinished(CodeGenFunction &CGF)
Cleans up references to the objects in finished function.
void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, const Expr *IfCond, OpenMPDirectiveKind CancelRegion) override
Emit code for 'cancel' construct.
Encodes a location in the source.
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
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).
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.
virtual void emitTargetCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, llvm::Value *OutlinedFn, llvm::Value *OutlinedFnID, const Expr *IfCond, const Expr *Device, ArrayRef< llvm::Value *> CapturedVars)
Emit the target offloading code associated with D.
OpenMPLinearClauseKind Modifier
Modifier of 'linear' clause.
Target region entries related.
const ParmVarDecl * getParamDecl(unsigned i) const
static void EmitOMPTargetSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetSimdDirective &S)
Emit device code for the target simd directive.
void emitDoacrossInit(CodeGenFunction &CGF, const OMPLoopDirective &D) override
Emit initialization for doacross loop nesting support.
void emitDistributeStaticInit(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDistScheduleClauseKind SchedKind, const StaticRTInput &Values) override
virtual void emitDoacrossInit(CodeGenFunction &CGF, const OMPLoopDirective &D)
Emit initialization for doacross loop nesting support.
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.
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...
void emitThreadPrivateVarInit(CodeGenFunction &CGF, Address VDAddr, llvm::Value *Ctor, llvm::Value *CopyCtor, llvm::Value *Dtor, SourceLocation Loc)
Emits initialization code for the threadprivate variables.
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.
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.
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...
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)
void emitCall(CodeGenFunction &CGF, llvm::Value *Callee, ArrayRef< llvm::Value *> Args=llvm::None, SourceLocation Loc=SourceLocation()) const
Emits Callee function call with arguments Args with location Loc.
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.
virtual Address emitThreadIDAddress(CodeGenFunction &CGF, SourceLocation Loc)
Emits address of the word in a memory where current thread id is stored.
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.
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
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
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
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.
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
LValue EmitOMPSharedLValue(const Expr *E)
Emits the lvalue for the expression with possibly captured variable.
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.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
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
StmtClass getStmtClass() const
llvm::PointerIntPair< llvm::Value *, 1, bool > Priority
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
void EmitAggregateCopy(Address DestPtr, Address SrcPtr, QualType EltTy, bool isVolatile=false, bool isAssignment=false)
EmitAggregateCopy - Emit an aggregate copy.
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.
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
static CharUnits getIdentSize(CodeGenModule &CGM)
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 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.
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
Base for LValueReferenceType and RValueReferenceType.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
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
llvm::Constant * createDispatchNextFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_dispatch_next_* runtime function for the specified size IVSize and sign IVSigned...
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
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...
static std::string generateUniqueName(StringRef Prefix, SourceLocation Loc, unsigned N)
Generates unique name for artificial threadprivate variables.
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...
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:
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.
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.
capture_iterator capture_end() const
Retrieve an iterator pointing past the end of the sequence of captures.
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...
std::pair< llvm::Value *, QualType > getVLASize(const VariableArrayType *vla)
getVLASize - Returns an LLVM value that corresponds to the size, in non-variably-sized elements...
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.
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
A reference to a declared variable, function, enum, etc.
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.
LValue - This represents an lvalue references.
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
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...
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.
SourceLocation getLocStart() const LLVM_READONLY
Address CreateMemTemp(QualType T, const Twine &Name="tmp", bool CastToDefaultAddrSpace=true)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignment...
llvm::Value * getPointer() const
void emitCancellationPointCall(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind CancelRegion) override
Emit code for 'cancellation point' construct.
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...
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.
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.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const llvm::Triple & getTriple() const