23 #include "llvm/ADT/ArrayRef.h" 24 #include "llvm/Bitcode/BitcodeReader.h" 25 #include "llvm/IR/CallSite.h" 26 #include "llvm/IR/DerivedTypes.h" 27 #include "llvm/IR/GlobalValue.h" 28 #include "llvm/IR/Value.h" 29 #include "llvm/Support/Format.h" 30 #include "llvm/Support/raw_ostream.h" 33 using namespace clang;
34 using namespace CodeGen;
41 enum CGOpenMPRegionKind {
44 ParallelOutlinedRegion,
55 const CGOpenMPRegionKind RegionKind,
58 : CGCapturedStmtInfo(CS,
CR_OpenMP), RegionKind(RegionKind),
59 CodeGen(CodeGen), Kind(Kind), HasCancel(HasCancel) {}
61 CGOpenMPRegionInfo(
const CGOpenMPRegionKind RegionKind,
64 : CGCapturedStmtInfo(
CR_OpenMP), RegionKind(RegionKind), CodeGen(CodeGen),
65 Kind(Kind), HasCancel(HasCancel) {}
69 virtual const VarDecl *getThreadIDVariable()
const = 0;
80 CGOpenMPRegionKind getRegionKind()
const {
return RegionKind; }
84 bool hasCancel()
const {
return HasCancel; }
86 static bool classof(
const CGCapturedStmtInfo *Info) {
90 ~CGOpenMPRegionInfo()
override =
default;
93 CGOpenMPRegionKind RegionKind;
100 class CGOpenMPOutlinedRegionInfo final :
public CGOpenMPRegionInfo {
105 StringRef HelperName)
106 : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind,
108 ThreadIDVar(ThreadIDVar), HelperName(HelperName) {
109 assert(ThreadIDVar !=
nullptr &&
"No ThreadID in OpenMP region.");
114 const VarDecl *getThreadIDVariable()
const override {
return ThreadIDVar; }
117 StringRef getHelperName()
const override {
return HelperName; }
119 static bool classof(
const CGCapturedStmtInfo *Info) {
121 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
122 ParallelOutlinedRegion;
129 StringRef HelperName;
133 class CGOpenMPTaskOutlinedRegionInfo final :
public CGOpenMPRegionInfo {
139 llvm::SwitchInst *UntiedSwitch =
nullptr;
142 UntiedTaskActionTy(
bool Tied,
const VarDecl *PartIDVar,
144 : Untied(!Tied), PartIDVar(PartIDVar), UntiedCodeGen(UntiedCodeGen) {}
154 UntiedSwitch = CGF.
Builder.CreateSwitch(Res, DoneBB);
158 UntiedSwitch->addCase(CGF.
Builder.getInt32(0),
160 emitUntiedSwitch(CGF);
175 UntiedSwitch->addCase(CGF.
Builder.getInt32(UntiedSwitch->getNumCases()),
181 unsigned getNumberOfParts()
const {
return UntiedSwitch->getNumCases(); }
187 const UntiedTaskActionTy &Action)
188 : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen, Kind, HasCancel),
189 ThreadIDVar(ThreadIDVar), Action(Action) {
190 assert(ThreadIDVar !=
nullptr &&
"No ThreadID in OpenMP region.");
195 const VarDecl *getThreadIDVariable()
const override {
return ThreadIDVar; }
201 StringRef getHelperName()
const override {
return ".omp_outlined."; }
204 Action.emitUntiedSwitch(CGF);
207 static bool classof(
const CGCapturedStmtInfo *Info) {
209 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
218 const UntiedTaskActionTy &Action;
223 class CGOpenMPInlinedRegionInfo :
public CGOpenMPRegionInfo {
228 : CGOpenMPRegionInfo(InlinedRegion, CodeGen, Kind, HasCancel),
230 OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {}
235 return OuterRegionInfo->getContextValue();
236 llvm_unreachable(
"No context value for inlined OpenMP region");
240 if (OuterRegionInfo) {
241 OuterRegionInfo->setContextValue(V);
244 llvm_unreachable(
"No context value for inlined OpenMP region");
250 return OuterRegionInfo->lookup(VD);
256 FieldDecl *getThisFieldDecl()
const override {
258 return OuterRegionInfo->getThisFieldDecl();
264 const VarDecl *getThreadIDVariable()
const override {
266 return OuterRegionInfo->getThreadIDVariable();
273 return OuterRegionInfo->getThreadIDVariableLValue(CGF);
274 llvm_unreachable(
"No LValue for inlined OpenMP construct");
278 StringRef getHelperName()
const override {
279 if (
auto *OuterRegionInfo = getOldCSI())
280 return OuterRegionInfo->getHelperName();
281 llvm_unreachable(
"No helper name for inlined OpenMP construct");
286 OuterRegionInfo->emitUntiedSwitch(CGF);
291 static bool classof(
const CGCapturedStmtInfo *Info) {
293 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == InlinedRegion;
296 ~CGOpenMPInlinedRegionInfo()
override =
default;
301 CGOpenMPRegionInfo *OuterRegionInfo;
309 class CGOpenMPTargetRegionInfo final :
public CGOpenMPRegionInfo {
313 : CGOpenMPRegionInfo(CS, TargetRegion, CodeGen, OMPD_target,
315 HelperName(HelperName) {}
319 const VarDecl *getThreadIDVariable()
const override {
return nullptr; }
322 StringRef getHelperName()
const override {
return HelperName; }
324 static bool classof(
const CGCapturedStmtInfo *Info) {
326 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == TargetRegion;
330 StringRef HelperName;
334 llvm_unreachable(
"No codegen for expressions");
338 class CGOpenMPInnerExprInfo final :
public CGOpenMPInlinedRegionInfo {
341 : CGOpenMPInlinedRegionInfo(CGF.CapturedStmtInfo, EmptyCodeGen,
348 for (
const auto &C : CS.
captures()) {
349 if (!
C.capturesVariable() && !
C.capturesVariableByCopy())
352 const VarDecl *VD =
C.getCapturedVar();
360 PrivScope.addPrivate(
363 (void)PrivScope.Privatize();
368 if (
const FieldDecl *FD = CGOpenMPInlinedRegionInfo::lookup(VD))
375 llvm_unreachable(
"No body for expressions");
380 const VarDecl *getThreadIDVariable()
const override {
381 llvm_unreachable(
"No thread id for expressions");
385 StringRef getHelperName()
const override {
386 llvm_unreachable(
"No helper name for expressions");
389 static bool classof(
const CGCapturedStmtInfo *Info) {
return false; }
397 class InlinedOpenMPRegionRAII {
399 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
400 FieldDecl *LambdaThisCaptureField =
nullptr;
421 ~InlinedOpenMPRegionRAII() {
438 OMP_IDENT_IMD = 0x01,
440 OMP_IDENT_KMPC = 0x02,
442 OMP_ATOMIC_REDUCE = 0x10,
444 OMP_IDENT_BARRIER_EXPL = 0x20,
446 OMP_IDENT_BARRIER_IMPL = 0x40,
448 OMP_IDENT_BARRIER_IMPL_FOR = 0x40,
450 OMP_IDENT_BARRIER_IMPL_SECTIONS = 0xC0,
452 OMP_IDENT_BARRIER_IMPL_SINGLE = 0x140,
454 OMP_IDENT_WORK_LOOP = 0x200,
456 OMP_IDENT_WORK_SECTIONS = 0x400,
458 OMP_IDENT_WORK_DISTRIBUTE = 0x800,
459 LLVM_MARK_AS_BITMASK_ENUM(OMP_IDENT_WORK_DISTRIBUTE)
742 Callback(CodeGen, CGF, *PrePostAction);
745 Callback(CodeGen, CGF, Action);
753 if (
const auto *CE = dyn_cast<CallExpr>(ReductionOp))
754 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
755 if (
const auto *DRE =
756 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
757 if (
const auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl()))
768 std::pair<llvm::Function *, llvm::Function *> Reduction =
770 const auto *CE = cast<CallExpr>(InitOp);
771 const auto *OVE = cast<OpaqueValueExpr>(CE->getCallee());
775 cast<DeclRefExpr>(cast<UnaryOperator>(LHS)->getSubExpr());
777 cast<DeclRefExpr>(cast<UnaryOperator>(RHS)->getSubExpr());
779 PrivateScope.addPrivate(cast<VarDecl>(LHSDRE->getDecl()),
780 [=]() {
return Private; });
781 PrivateScope.addPrivate(cast<VarDecl>(RHSDRE->getDecl()),
782 [=]() {
return Original; });
783 (void)PrivateScope.Privatize();
790 auto *GV =
new llvm::GlobalVariable(
792 llvm::GlobalValue::PrivateLinkage, Init, Name);
838 SrcBegin = SrcAddr.getPointer();
846 CGF.
Builder.CreateICmpEQ(DestBegin, DestEnd,
"omp.arrayinit.isempty");
847 CGF.
Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
850 llvm::BasicBlock *EntryBB = CGF.
Builder.GetInsertBlock();
855 llvm::PHINode *SrcElementPHI =
nullptr;
858 SrcElementPHI = CGF.
Builder.CreatePHI(SrcBegin->getType(), 2,
859 "omp.arraycpy.srcElementPast");
860 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
863 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
865 llvm::PHINode *DestElementPHI = CGF.
Builder.CreatePHI(
866 DestBegin->getType(), 2,
"omp.arraycpy.destElementPast");
867 DestElementPHI->addIncoming(DestBegin, EntryBB);
875 if (EmitDeclareReductionInit) {
877 SrcElementCurrent, ElementTy);
886 SrcElementPHI, 1,
"omp.arraycpy.dest.element");
887 SrcElementPHI->addIncoming(SrcElementNext, CGF.
Builder.GetInsertBlock());
892 DestElementPHI, 1,
"omp.arraycpy.dest.element");
895 CGF.
Builder.CreateICmpEQ(DestElementNext, DestEnd,
"omp.arraycpy.done");
896 CGF.
Builder.CreateCondBr(Done, DoneBB, BodyBB);
897 DestElementPHI->addIncoming(DestElementNext, CGF.
Builder.GetInsertBlock());
909 if (
const auto *OASE = dyn_cast<OMPArraySectionExpr>(E))
914 void ReductionCodeGen::emitAggregateInitialization(
920 const auto *PrivateVD =
921 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
922 bool EmitDeclareReductionInit =
925 EmitDeclareReductionInit,
926 EmitDeclareReductionInit ? ClausesData[N].ReductionOp
927 : PrivateVD->getInit(),
934 ClausesData.reserve(Shareds.size());
935 SharedAddresses.reserve(Shareds.size());
936 Sizes.reserve(Shareds.size());
937 BaseDecls.reserve(Shareds.size());
938 auto IPriv = Privates.begin();
939 auto IRed = ReductionOps.begin();
940 for (
const Expr *Ref : Shareds) {
941 ClausesData.emplace_back(Ref, *IPriv, *IRed);
942 std::advance(IPriv, 1);
943 std::advance(IRed, 1);
948 assert(SharedAddresses.size() == N &&
949 "Number of generated lvalues must be exactly N.");
950 LValue First = emitSharedLValue(CGF, ClausesData[N].Ref);
951 LValue Second = emitSharedLValueUB(CGF, ClausesData[N].Ref);
952 SharedAddresses.emplace_back(First, Second);
956 const auto *PrivateVD =
957 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
958 QualType PrivateType = PrivateVD->getType();
959 bool AsArraySection = isa<OMPArraySectionExpr>(ClausesData[N].Ref);
960 if (!PrivateType->isVariablyModifiedType()) {
963 SharedAddresses[N].first.getType().getNonReferenceType()),
970 cast<llvm::PointerType>(SharedAddresses[N].first.getPointer()->getType())
972 auto *ElemSizeOf = llvm::ConstantExpr::getSizeOf(ElemType);
973 if (AsArraySection) {
974 Size = CGF.
Builder.CreatePtrDiff(SharedAddresses[N].second.getPointer(),
975 SharedAddresses[N].first.getPointer());
976 Size = CGF.
Builder.CreateNUWAdd(
977 Size, llvm::ConstantInt::get(Size->getType(), 1));
978 SizeInChars = CGF.
Builder.CreateNUWMul(Size, ElemSizeOf);
981 SharedAddresses[N].first.getType().getNonReferenceType());
982 Size = CGF.
Builder.CreateExactUDiv(SizeInChars, ElemSizeOf);
984 Sizes.emplace_back(SizeInChars, Size);
987 cast<OpaqueValueExpr>(
995 const auto *PrivateVD =
996 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
997 QualType PrivateType = PrivateVD->getType();
998 if (!PrivateType->isVariablyModifiedType()) {
999 assert(!Size && !Sizes[N].second &&
1000 "Size should be nullptr for non-variably modified reduction " 1006 cast<OpaqueValueExpr>(
1015 assert(SharedAddresses.size() > N &&
"No variable was generated");
1016 const auto *PrivateVD =
1017 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1020 QualType PrivateType = PrivateVD->getType();
1023 QualType SharedType = SharedAddresses[N].first.getType();
1027 SharedType, SharedAddresses[N].first.getBaseInfo(),
1030 emitAggregateInitialization(CGF, N, PrivateAddr, SharedLVal, DRD);
1031 }
else if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
1035 }
else if (!DefaultInit(CGF) && PrivateVD->hasInit() &&
1038 PrivateVD->
getType().getQualifiers(),
1044 const auto *PrivateVD =
1045 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1046 QualType PrivateType = PrivateVD->getType();
1053 const auto *PrivateVD =
1054 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1055 QualType PrivateType = PrivateVD->getType();
1057 if (needCleanups(N)) {
1060 CGF.
pushDestroy(DTorKind, PrivateAddr, PrivateType);
1109 return Address(Addr, BaseLVAlignment);
1113 const VarDecl *OrigVD =
nullptr;
1114 if (
const auto *OASE = dyn_cast<OMPArraySectionExpr>(Ref)) {
1115 const Expr *
Base = OASE->getBase()->IgnoreParenImpCasts();
1116 while (
const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
1118 while (
const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
1120 DE = cast<DeclRefExpr>(
Base);
1121 OrigVD = cast<VarDecl>(DE->
getDecl());
1122 }
else if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(Ref)) {
1123 const Expr *
Base = ASE->getBase()->IgnoreParenImpCasts();
1124 while (
const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
1126 DE = cast<DeclRefExpr>(
Base);
1127 OrigVD = cast<VarDecl>(DE->
getDecl());
1136 BaseDecls.emplace_back(OrigVD);
1139 loadToBegin(CGF, OrigVD->getType(), SharedAddresses[N].first.getType(),
1140 OriginalBaseLValue);
1142 BaseLValue.
getPointer(), SharedAddresses[N].first.getPointer());
1146 SharedAddresses[N].first.getAddress().getType());
1149 SharedAddresses[N].first.getType(),
1153 BaseDecls.emplace_back(
1154 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Ref)->getDecl()));
1183 LValue CGOpenMPTaskOutlinedRegionInfo::getThreadIDVariableLValue(
1186 getThreadIDVariable()->
getType(),
1202 StringRef Separator)
1203 : CGM(CGM), FirstSeparator(FirstSeparator), Separator(Separator),
1222 KmpCriticalNameTy = llvm::ArrayType::get(CGM.
Int32Ty, 8);
1228 InternalVars.clear();
1231 if (!Data.getValue().pointsToAliveValue())
1233 auto *GV = dyn_cast<llvm::GlobalVariable>(Data.getValue());
1236 if (!GV->isDeclaration() || GV->getNumUses() > 0)
1238 GV->eraseFromParent();
1244 llvm::raw_svector_ostream OS(Buffer);
1246 for (StringRef Part : Parts) {
1253 static llvm::Function *
1255 const Expr *CombinerInitializer,
const VarDecl *In,
1256 const VarDecl *Out,
bool IsCombiner) {
1265 Args.push_back(&OmpOutParm);
1266 Args.push_back(&OmpInParm);
1271 {IsCombiner ?
"omp_combiner" :
"omp_initializer",
""});
1275 Fn->removeFnAttr(llvm::Attribute::NoInline);
1276 Fn->removeFnAttr(llvm::Attribute::OptimizeNone);
1277 Fn->addFnAttr(llvm::Attribute::AlwaysInline);
1285 Scope.
addPrivate(In, [&CGF, AddrIn, PtrTy]() {
1290 Scope.
addPrivate(Out, [&CGF, AddrOut, PtrTy]() {
1295 if (!IsCombiner && Out->
hasInit() &&
1301 if (CombinerInitializer)
1310 if (UDRMap.count(D) > 0)
1314 cast<VarDecl>(cast<DeclRefExpr>(D->
getCombinerIn())->getDecl()),
1315 cast<VarDecl>(cast<DeclRefExpr>(D->
getCombinerOut())->getDecl()),
1317 llvm::Function *Initializer =
nullptr;
1323 cast<VarDecl>(cast<DeclRefExpr>(D->
getInitOrig())->getDecl()),
1324 cast<VarDecl>(cast<DeclRefExpr>(D->
getInitPriv())->getDecl()),
1327 UDRMap.try_emplace(D, Combiner, Initializer);
1329 auto &Decls = FunctionUDRMap.FindAndConstruct(CGF->
CurFn);
1330 Decls.second.push_back(D);
1334 std::pair<llvm::Function *, llvm::Function *>
1336 auto I = UDRMap.find(D);
1337 if (I != UDRMap.end())
1340 return UDRMap.lookup(D);
1348 "thread id variable must be of type kmp_int32 *");
1350 bool HasCancel =
false;
1351 if (
const auto *OPD = dyn_cast<OMPParallelDirective>(&D))
1352 HasCancel = OPD->hasCancel();
1353 else if (
const auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&D))
1354 HasCancel = OPSD->hasCancel();
1355 else if (
const auto *OPFD = dyn_cast<OMPParallelForDirective>(&D))
1356 HasCancel = OPFD->hasCancel();
1357 else if (
const auto *OPFD = dyn_cast<OMPTargetParallelForDirective>(&D))
1358 HasCancel = OPFD->hasCancel();
1359 else if (
const auto *OPFD = dyn_cast<OMPDistributeParallelForDirective>(&D))
1360 HasCancel = OPFD->hasCancel();
1361 else if (
const auto *OPFD =
1362 dyn_cast<OMPTeamsDistributeParallelForDirective>(&D))
1363 HasCancel = OPFD->hasCancel();
1364 else if (
const auto *OPFD =
1365 dyn_cast<OMPTargetTeamsDistributeParallelForDirective>(&D))
1366 HasCancel = OPFD->hasCancel();
1367 CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind,
1368 HasCancel, OutlinedHelperName);
1370 return CGF.GenerateOpenMPCapturedStmtFunction(*CS);
1393 bool Tied,
unsigned &NumberOfParts) {
1400 CGF.EmitLoadOfPointerLValue(CGF.GetAddrOfLocalVar(TaskTVar),
1405 CGOpenMPTaskOutlinedRegionInfo::UntiedTaskActionTy Action(Tied, PartIDVar,
1409 "thread id variable must be of type kmp_int32 for tasks");
1416 CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen,
1418 TD ? TD->hasCancel() :
false, Action);
1420 llvm::Value *Res = CGF.GenerateCapturedStmtFunction(*CS);
1422 NumberOfParts = Action.getNumberOfParts();
1428 ArrayRef<llvm::Constant *> Data) {
1430 unsigned PrevIdx = 0;
1432 auto DI = Data.begin();
1436 for (
unsigned I = PrevIdx; I < Idx; ++I)
1437 Fields.add(llvm::Constant::getNullValue(StructTy->getElementType(I)));
1444 template <
class... As>
1445 static llvm::GlobalVariable *
1447 ArrayRef<llvm::Constant *> Data,
const Twine &Name,
1456 std::forward<As>(Args)...);
1459 template <
typename T>
1462 ArrayRef<llvm::Constant *> Data,
1471 Address CGOpenMPRuntime::getOrCreateDefaultLocation(
unsigned Flags) {
1474 FlagsTy FlagsKey(Flags, Reserved2Flags);
1475 llvm::Value *Entry = OpenMPDefaultLocMap.lookup(FlagsKey);
1477 if (!DefaultOpenMPPSource) {
1482 DefaultOpenMPPSource =
1484 DefaultOpenMPPSource =
1485 llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource,
CGM.
Int8PtrTy);
1488 llvm::Constant *Data[] = {
1489 llvm::ConstantInt::getNullValue(
CGM.
Int32Ty),
1491 llvm::ConstantInt::get(
CGM.
Int32Ty, Reserved2Flags),
1492 llvm::ConstantInt::getNullValue(
CGM.
Int32Ty), DefaultOpenMPPSource};
1493 llvm::GlobalValue *DefaultOpenMPLocation =
1495 llvm::GlobalValue::PrivateLinkage);
1496 DefaultOpenMPLocation->setUnnamedAddr(
1497 llvm::GlobalValue::UnnamedAddr::Global);
1499 OpenMPDefaultLocMap[FlagsKey] = Entry = DefaultOpenMPLocation;
1505 bool AtCurrentPoint) {
1506 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.
CurFn);
1507 assert(!Elem.second.ServiceInsertPt &&
"Insert point is set already.");
1510 if (AtCurrentPoint) {
1511 Elem.second.ServiceInsertPt =
new llvm::BitCastInst(
1514 Elem.second.ServiceInsertPt =
1515 new llvm::BitCastInst(Undef, CGF.
Int32Ty,
"svcpt");
1521 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.
CurFn);
1522 if (Elem.second.ServiceInsertPt) {
1523 llvm::Instruction *Ptr = Elem.second.ServiceInsertPt;
1524 Elem.second.ServiceInsertPt =
nullptr;
1525 Ptr->eraseFromParent();
1532 Flags |= OMP_IDENT_KMPC;
1536 return getOrCreateDefaultLocation(Flags).
getPointer();
1538 assert(CGF.
CurFn &&
"No function in current CodeGenFunction.");
1542 auto I = OpenMPLocThreadIDMap.find(CGF.
CurFn);
1543 if (I != OpenMPLocThreadIDMap.end())
1544 LocValue =
Address(I->second.DebugLoc, Align);
1551 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.
CurFn);
1555 if (!Elem.second.ServiceInsertPt)
1557 CGBuilderTy::InsertPointGuard IPG(CGF.
Builder);
1558 CGF.
Builder.SetInsertPoint(Elem.second.ServiceInsertPt);
1565 auto Fields = cast<RecordDecl>(IdentQTy->
getAsTagDecl())->field_begin();
1570 if (OMPDebugLoc ==
nullptr) {
1572 llvm::raw_svector_ostream OS2(Buffer2);
1576 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(CGF.
CurFuncDecl))
1577 OS2 << FD->getQualifiedNameAsString();
1579 OMPDebugLoc = CGF.
Builder.CreateGlobalStringPtr(OS2.str());
1592 assert(CGF.
CurFn &&
"No function in current CodeGenFunction.");
1597 auto I = OpenMPLocThreadIDMap.find(CGF.
CurFn);
1598 if (I != OpenMPLocThreadIDMap.end()) {
1599 ThreadID = I->second.ThreadID;
1600 if (ThreadID !=
nullptr)
1607 if (
auto *OMPRegionInfo =
1609 if (OMPRegionInfo->getThreadIDVariable()) {
1611 LValue LVal = OMPRegionInfo->getThreadIDVariableLValue(CGF);
1616 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.
CurFn);
1617 Elem.second.ThreadID = ThreadID;
1628 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.
CurFn);
1629 if (!Elem.second.ServiceInsertPt)
1631 CGBuilderTy::InsertPointGuard IPG(CGF.
Builder);
1632 CGF.
Builder.SetInsertPoint(Elem.second.ServiceInsertPt);
1633 llvm::CallInst *Call = CGF.
Builder.CreateCall(
1637 Elem.second.ThreadID = Call;
1642 assert(CGF.
CurFn &&
"No function in current CodeGenFunction.");
1643 if (OpenMPLocThreadIDMap.count(CGF.
CurFn)) {
1645 OpenMPLocThreadIDMap.erase(CGF.
CurFn);
1647 if (FunctionUDRMap.count(CGF.
CurFn) > 0) {
1648 for(
auto *D : FunctionUDRMap[CGF.
CurFn])
1650 FunctionUDRMap.erase(CGF.
CurFn);
1655 return IdentTy->getPointerTo();
1659 if (!Kmpc_MicroTy) {
1663 Kmpc_MicroTy = llvm::FunctionType::get(
CGM.
VoidTy, MicroParams,
true);
1665 return llvm::PointerType::getUnqual(Kmpc_MicroTy);
1670 llvm::Constant *RTLFn =
nullptr;
1671 switch (static_cast<OpenMPRTLFunction>(Function)) {
1678 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
true);
1686 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1697 llvm::FunctionType::get(
CGM.
VoidPtrTy, TypeParams,
false);
1706 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1708 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1716 llvm::PointerType::getUnqual(KmpCriticalNameTy),
1719 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1729 false)->getPointerTo();
1732 auto *KmpcCopyCtorTy =
1733 llvm::FunctionType::get(
CGM.
VoidPtrTy, KmpcCopyCtorTyArgs,
1741 KmpcCopyCtorTy, KmpcDtorTy};
1742 auto *FnTy = llvm::FunctionType::get(
CGM.
VoidTy, FnTyArgs,
1752 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1754 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1763 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1771 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1779 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1789 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1798 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1807 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1815 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1823 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1831 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1840 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1848 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1856 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1864 assert(KmpRoutineEntryPtrTy !=
nullptr &&
1865 "Type kmp_routine_entry_t must be created.");
1870 llvm::FunctionType::get(
CGM.
VoidPtrTy, TypeParams,
false);
1880 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1890 llvm::FunctionType::get(
CGM.
VoidTy, CpyTypeParams,
false);
1895 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1904 auto *ReduceFnTy = llvm::FunctionType::get(
CGM.
VoidTy, ReduceTypeParams,
1909 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1911 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1921 auto *ReduceFnTy = llvm::FunctionType::get(
CGM.
VoidTy, ReduceTypeParams,
1926 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1928 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
1937 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1939 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1948 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1950 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1961 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1972 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1974 "__kmpc_omp_task_complete_if0");
1981 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1989 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
1997 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2005 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2013 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2022 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2034 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2047 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2056 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2065 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2075 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2085 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
true);
2105 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2117 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2125 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2135 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2145 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2154 llvm::FunctionType::get(
CGM.
VoidPtrTy, TypeParams,
false);
2164 llvm::FunctionType::get(
CGM.
VoidPtrTy, TypeParams,
false);
2166 FnTy,
"__kmpc_task_reduction_get_th_data");
2173 llvm::FunctionType *FnTy =
2174 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2190 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2206 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2224 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2242 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2252 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2262 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2276 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2291 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2305 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2320 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2334 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2349 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2354 assert(RTLFn &&
"Unable to find OpenMP runtime function");
2360 assert((IVSize == 32 || IVSize == 64) &&
2361 "IV size is not compatible with the omp runtime");
2362 StringRef Name = IVSize == 32 ? (IVSigned ?
"__kmpc_for_static_init_4" 2363 :
"__kmpc_for_static_init_4u")
2364 : (IVSigned ?
"__kmpc_for_static_init_8" 2365 :
"__kmpc_for_static_init_8u");
2367 auto *PtrTy = llvm::PointerType::getUnqual(ITy);
2380 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2386 assert((IVSize == 32 || IVSize == 64) &&
2387 "IV size is not compatible with the omp runtime");
2390 ? (IVSigned ?
"__kmpc_dispatch_init_4" :
"__kmpc_dispatch_init_4u")
2391 : (IVSigned ?
"__kmpc_dispatch_init_8" :
"__kmpc_dispatch_init_8u");
2402 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2408 assert((IVSize == 32 || IVSize == 64) &&
2409 "IV size is not compatible with the omp runtime");
2412 ? (IVSigned ?
"__kmpc_dispatch_fini_4" :
"__kmpc_dispatch_fini_4u")
2413 : (IVSigned ?
"__kmpc_dispatch_fini_8" :
"__kmpc_dispatch_fini_8u");
2419 llvm::FunctionType::get(
CGM.
VoidTy, TypeParams,
false);
2425 assert((IVSize == 32 || IVSize == 64) &&
2426 "IV size is not compatible with the omp runtime");
2429 ? (IVSigned ?
"__kmpc_dispatch_next_4" :
"__kmpc_dispatch_next_4u")
2430 : (IVSigned ?
"__kmpc_dispatch_next_8" :
"__kmpc_dispatch_next_8u");
2432 auto *PtrTy = llvm::PointerType::getUnqual(ITy);
2442 llvm::FunctionType::get(
CGM.
Int32Ty, TypeParams,
false);
2450 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2451 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
2454 llvm::raw_svector_ostream OS(PtrName);
2463 auto *GV = cast<llvm::GlobalVariable>(Ptr);
2480 std::string Suffix =
getName({
"cache",
""});
2516 Ctor, CopyCtor, Dtor};
2532 llvm::Value *Ctor =
nullptr, *CopyCtor =
nullptr, *Dtor =
nullptr;
2542 Args.push_back(&Dst);
2547 std::string Name =
getName({
"__kmpc_global_ctor_",
""});
2548 llvm::Function *Fn =
2575 Args.push_back(&Dst);
2580 std::string Name =
getName({
"__kmpc_global_dtor_",
""});
2581 llvm::Function *Fn =
2602 auto *CopyCtorTy = llvm::FunctionType::get(
CGM.
VoidPtrTy, CopyCtorTyArgs,
2608 CopyCtor = llvm::Constant::getNullValue(CopyCtorTy);
2609 if (Ctor ==
nullptr) {
2613 Ctor = llvm::Constant::getNullValue(CtorTy);
2615 if (Dtor ==
nullptr) {
2619 Dtor = llvm::Constant::getNullValue(DtorTy);
2622 auto *InitFunctionTy =
2623 llvm::FunctionType::get(
CGM.
VoidTy,
false);
2624 std::string Name =
getName({
"__omp_threadprivate_init_",
""});
2634 return InitFunction;
2645 unsigned &DeviceID,
unsigned &
FileID,
2646 unsigned &LineNum) {
2652 assert(Loc.
isValid() &&
"Source location is expected to be always valid.");
2655 assert(PLoc.isValid() &&
"Source location is expected to be always valid.");
2657 llvm::sys::fs::UniqueID
ID;
2658 if (
auto EC = llvm::sys::fs::getUniqueID(PLoc.getFilename(),
ID))
2660 << PLoc.getFilename() << EC.message();
2662 DeviceID = ID.getDevice();
2663 FileID = ID.getFile();
2664 LineNum = PLoc.getLine();
2668 llvm::GlobalVariable *Addr,
2671 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2672 if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link)
2690 llvm::raw_svector_ostream OS(Buffer);
2691 OS <<
"__omp_offloading_" << llvm::format(
"_%x", DeviceID)
2692 << llvm::format(
"_%x_", FileID) << VD->
getName() <<
"_l" <<
Line;
2697 llvm::Constant *Ctor;
2707 FTy, Twine(Buffer,
"_ctor"), FI, Loc);
2718 ID = llvm::ConstantExpr::getBitCast(Fn,
CGM.
Int8PtrTy);
2721 Ctor =
new llvm::GlobalVariable(
2723 llvm::GlobalValue::PrivateLinkage,
2724 llvm::Constant::getNullValue(
CGM.
Int8Ty), Twine(Buffer,
"_ctor"));
2731 DeviceID, FileID, Twine(Buffer,
"_ctor").toStringRef(Out), Line, Ctor,
2735 llvm::Constant *Dtor;
2745 FTy, Twine(Buffer,
"_dtor"), FI, Loc);
2757 ID = llvm::ConstantExpr::getBitCast(Fn,
CGM.
Int8PtrTy);
2760 Dtor =
new llvm::GlobalVariable(
2762 llvm::GlobalValue::PrivateLinkage,
2763 llvm::Constant::getNullValue(
CGM.
Int8Ty), Twine(Buffer,
"_dtor"));
2769 DeviceID, FileID, Twine(Buffer,
"_dtor").toStringRef(Out), Line, Dtor,
2778 std::string Suffix =
getName({
"artificial",
""});
2779 std::string CacheSuffix =
getName({
"cache",
""});
2795 VarLVType->getPointerTo(0)),
2841 const Expr *IfCond) {
2845 auto &&ThenGen = [OutlinedFn, CapturedVars, RTLoc](
CodeGenFunction &CGF,
2851 CGF.Builder.getInt32(CapturedVars.size()),
2852 CGF.Builder.CreateBitCast(OutlinedFn, RT.getKmpc_MicroPointerTy())};
2854 RealArgs.append(std::begin(Args), std::end(Args));
2855 RealArgs.append(CapturedVars.begin(), CapturedVars.end());
2858 CGF.EmitRuntimeCall(RTLFn, RealArgs);
2860 auto &&ElseGen = [OutlinedFn, CapturedVars, RTLoc, Loc](
CodeGenFunction &CGF,
2867 CGF.EmitRuntimeCall(
2871 Address ZeroAddr = CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty,
2873 CGF.InitTempAlloca(ZeroAddr, CGF.Builder.getInt32( 0));
2876 OutlinedFnArgs.push_back(ZeroAddr.
getPointer());
2877 OutlinedFnArgs.push_back(ZeroAddr.
getPointer());
2878 OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
2879 RT.emitOutlinedFunctionCall(CGF, Loc, OutlinedFn, OutlinedFnArgs);
2883 CGF.EmitRuntimeCall(
2903 if (
auto *OMPRegionInfo =
2905 if (OMPRegionInfo->getThreadIDVariable())
2906 return OMPRegionInfo->getThreadIDVariableLValue(CGF).getAddress();
2915 return ThreadIDTemp;
2920 const llvm::Twine &Name) {
2922 llvm::raw_svector_ostream Out(Buffer);
2924 StringRef RuntimeName = Out.str();
2925 auto &Elem = *InternalVars.try_emplace(RuntimeName,
nullptr).first;
2927 assert(Elem.second->getType()->getPointerElementType() == Ty &&
2928 "OMP internal variable has different type than requested");
2929 return &*Elem.second;
2932 return Elem.second =
new llvm::GlobalVariable(
2934 llvm::GlobalValue::CommonLinkage, llvm::Constant::getNullValue(Ty),
2939 std::string Prefix = Twine(
"gomp_critical_user_", CriticalName).str();
2940 std::string Name =
getName({Prefix,
"var"});
2952 llvm::BasicBlock *ContBlock =
nullptr;
2957 bool Conditional =
false)
2958 : EnterCallee(EnterCallee), EnterArgs(EnterArgs), ExitCallee(ExitCallee),
2967 CGF.
Builder.CreateCondBr(CallBool, ThenBlock, ContBlock);
2983 StringRef CriticalName,
2997 EnterArgs.push_back(CGF.
Builder.CreateIntCast(
3000 CommonActionTy Action(
3034 llvm::ConstantInt::get(
CGM.
IntTy, 0,
true)};
3036 if (
auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.
CapturedStmtInfo))
3037 Region->emitUntiedSwitch(CGF);
3060 unsigned Index,
const VarDecl *Var) {
3074 ArrayRef<const Expr *> CopyprivateVars, ArrayRef<const Expr *> DestExprs,
3075 ArrayRef<const Expr *> SrcExprs, ArrayRef<const Expr *> AssignmentOps,
3084 Args.push_back(&LHSArg);
3085 Args.push_back(&RHSArg);
3094 Fn->setDoesNotRecurse();
3109 for (
unsigned I = 0, E = AssignmentOps.size(); I < E; ++I) {
3110 const auto *DestVar =
3111 cast<VarDecl>(cast<DeclRefExpr>(DestExprs[I])->getDecl());
3114 const auto *SrcVar =
3115 cast<VarDecl>(cast<DeclRefExpr>(SrcExprs[I])->getDecl());
3118 const auto *VD = cast<DeclRefExpr>(CopyprivateVars[I])->getDecl();
3120 CGF.
EmitOMPCopy(Type, DestAddr, SrcAddr, DestVar, SrcVar, AssignmentOps[I]);
3129 ArrayRef<const Expr *> CopyprivateVars,
3130 ArrayRef<const Expr *> SrcExprs,
3131 ArrayRef<const Expr *> DstExprs,
3132 ArrayRef<const Expr *> AssignmentOps) {
3135 assert(CopyprivateVars.size() == SrcExprs.size() &&
3136 CopyprivateVars.size() == DstExprs.size() &&
3137 CopyprivateVars.size() == AssignmentOps.size());
3149 if (!CopyprivateVars.empty()) {
3152 C.getIntTypeForBitwidth(32, 1);
3153 DidIt = CGF.
CreateMemTemp(KmpInt32Ty,
".omp.copyprivate.did_it");
3171 llvm::APInt ArraySize(32, CopyprivateVars.size());
3177 CGF.
CreateMemTemp(CopyprivateArrayTy,
".omp.copyprivate.cpr_list");
3178 for (
unsigned I = 0, E = CopyprivateVars.size(); I < E; ++I) {
3190 CopyprivateVars, SrcExprs, DstExprs, AssignmentOps, Loc);
3231 if (Kind == OMPD_for)
3232 Flags = OMP_IDENT_BARRIER_IMPL_FOR;
3233 else if (Kind == OMPD_sections)
3234 Flags = OMP_IDENT_BARRIER_IMPL_SECTIONS;
3235 else if (Kind == OMPD_single)
3236 Flags = OMP_IDENT_BARRIER_IMPL_SINGLE;
3237 else if (Kind == OMPD_barrier)
3238 Flags = OMP_IDENT_BARRIER_EXPL;
3240 Flags = OMP_IDENT_BARRIER_IMPL;
3246 bool ForceSimpleCall) {
3256 if (
auto *OMPRegionInfo =
3258 if (!ForceSimpleCall && OMPRegionInfo->hasCancel()) {
3268 CGF.
Builder.CreateCondBr(Cmp, ExitBB, ContBB);
3284 bool Chunked,
bool Ordered) {
3285 switch (ScheduleKind) {
3286 case OMPC_SCHEDULE_static:
3289 case OMPC_SCHEDULE_dynamic:
3291 case OMPC_SCHEDULE_guided:
3293 case OMPC_SCHEDULE_runtime:
3295 case OMPC_SCHEDULE_auto:
3298 assert(!Chunked &&
"chunk was specified but schedule kind not known");
3301 llvm_unreachable(
"Unexpected runtime schedule");
3312 bool Chunked)
const {
3325 bool Chunked)
const {
3349 case OMPC_SCHEDULE_MODIFIER_monotonic:
3352 case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
3355 case OMPC_SCHEDULE_MODIFIER_simd:
3364 case OMPC_SCHEDULE_MODIFIER_monotonic:
3367 case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
3370 case OMPC_SCHEDULE_MODIFIER_simd:
3388 ScheduleKind.
Schedule, DispatchValues.
Chunk !=
nullptr, Ordered);
3400 : CGF.
Builder.getIntN(IVSize, 1);
3404 Schedule, ScheduleKind.
M1, ScheduleKind.
M2)),
3407 CGF.
Builder.getIntN(IVSize, 1),
3417 const CGOpenMPRuntime::StaticRTInput &Values) {
3421 assert(!Values.Ordered);
3434 if (Chunk ==
nullptr) {
3437 "expected static non-chunked schedule");
3439 Chunk = CGF.
Builder.getIntN(Values.IVSize, 1);
3445 "expected static chunked schedule");
3452 Values.IL.getPointer(),
3453 Values.LB.getPointer(),
3454 Values.UB.getPointer(),
3455 Values.ST.getPointer(),
3456 CGF.
Builder.getIntN(Values.IVSize, 1),
3470 "Expected loop-based or sections-based directive.");
3473 ? OMP_IDENT_WORK_LOOP
3474 : OMP_IDENT_WORK_SECTIONS);
3476 llvm::Constant *StaticInitFunction =
3479 ScheduleNum, ScheduleKind.
M1, ScheduleKind.
M2, Values);
3485 const CGOpenMPRuntime::StaticRTInput &Values) {
3491 llvm::Constant *StaticInitFunction =
3507 ? OMP_IDENT_WORK_DISTRIBUTE
3509 ? OMP_IDENT_WORK_LOOP
3510 : OMP_IDENT_WORK_SECTIONS),
3580 case OMPC_PROC_BIND_master:
3581 RuntimeProcBind = ProcBindMaster;
3583 case OMPC_PROC_BIND_close:
3584 RuntimeProcBind = ProcBindClose;
3586 case OMPC_PROC_BIND_spread:
3587 RuntimeProcBind = ProcBindSpread;
3590 llvm_unreachable(
"Unsupported proc_bind value.");
3595 llvm::ConstantInt::get(
CGM.
IntTy, RuntimeProcBind,
true)};
3634 bool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::empty()
const {
3635 return OffloadEntriesTargetRegion.empty() &&
3636 OffloadEntriesDeviceGlobalVar.empty();
3640 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3641 initializeTargetRegionEntryInfo(
unsigned DeviceID,
unsigned FileID,
3642 StringRef ParentName,
unsigned LineNum,
3644 assert(
CGM.
getLangOpts().OpenMPIsDevice &&
"Initialization of entries is " 3645 "only required for the device " 3646 "code generation.");
3647 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] =
3648 OffloadEntryInfoTargetRegion(Order,
nullptr,
nullptr,
3649 OMPTargetRegionEntryTargetRegion);
3650 ++OffloadingEntriesNum;
3653 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3654 registerTargetRegionEntryInfo(
unsigned DeviceID,
unsigned FileID,
3655 StringRef ParentName,
unsigned LineNum,
3656 llvm::Constant *Addr, llvm::Constant *
ID,
3657 OMPTargetRegionEntryKind Flags) {
3661 if (!hasTargetRegionEntryInfo(DeviceID, FileID, ParentName, LineNum)) {
3664 "Unable to find target region on line '%0' in the device code.");
3669 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum];
3670 assert(Entry.isValid() &&
"Entry not initialized!");
3671 Entry.setAddress(Addr);
3673 Entry.setFlags(Flags);
3675 OffloadEntryInfoTargetRegion Entry(OffloadingEntriesNum, Addr, ID, Flags);
3676 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] = Entry;
3677 ++OffloadingEntriesNum;
3681 bool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::hasTargetRegionEntryInfo(
3682 unsigned DeviceID,
unsigned FileID, StringRef ParentName,
3683 unsigned LineNum)
const {
3684 auto PerDevice = OffloadEntriesTargetRegion.find(DeviceID);
3685 if (PerDevice == OffloadEntriesTargetRegion.end())
3687 auto PerFile = PerDevice->second.find(FileID);
3688 if (PerFile == PerDevice->second.end())
3690 auto PerParentName = PerFile->second.find(ParentName);
3691 if (PerParentName == PerFile->second.end())
3693 auto PerLine = PerParentName->second.find(LineNum);
3694 if (PerLine == PerParentName->second.end())
3697 if (PerLine->second.getAddress() || PerLine->second.getID())
3702 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::actOnTargetRegionEntriesInfo(
3703 const OffloadTargetRegionEntryInfoActTy &Action) {
3705 for (
const auto &D : OffloadEntriesTargetRegion)
3706 for (
const auto &F : D.second)
3707 for (
const auto &
P : F.second)
3708 for (
const auto &L :
P.second)
3709 Action(D.first, F.first,
P.first(), L.first, L.second);
3712 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3713 initializeDeviceGlobalVarEntryInfo(StringRef Name,
3714 OMPTargetGlobalVarEntryKind Flags,
3716 assert(
CGM.
getLangOpts().OpenMPIsDevice &&
"Initialization of entries is " 3717 "only required for the device " 3718 "code generation.");
3719 OffloadEntriesDeviceGlobalVar.try_emplace(Name, Order, Flags);
3720 ++OffloadingEntriesNum;
3723 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3724 registerDeviceGlobalVarEntryInfo(StringRef VarName, llvm::Constant *Addr,
3726 OMPTargetGlobalVarEntryKind Flags,
3727 llvm::GlobalValue::LinkageTypes
Linkage) {
3729 auto &Entry = OffloadEntriesDeviceGlobalVar[VarName];
3730 assert(Entry.isValid() && Entry.getFlags() == Flags &&
3731 "Entry not initialized!");
3732 assert((!Entry.getAddress() || Entry.getAddress() == Addr) &&
3733 "Resetting with the new address.");
3734 if (Entry.getAddress() && hasDeviceGlobalVarEntryInfo(VarName))
3736 Entry.setAddress(Addr);
3737 Entry.setVarSize(VarSize);
3738 Entry.setLinkage(Linkage);
3740 if (hasDeviceGlobalVarEntryInfo(VarName))
3742 OffloadEntriesDeviceGlobalVar.try_emplace(
3743 VarName, OffloadingEntriesNum, Addr, VarSize, Flags, Linkage);
3744 ++OffloadingEntriesNum;
3748 void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3749 actOnDeviceGlobalVarEntriesInfo(
3750 const OffloadDeviceGlobalVarEntryInfoActTy &Action) {
3752 for (
const auto &E : OffloadEntriesDeviceGlobalVar)
3753 Action(E.getKey(), E.getValue());
3771 assert(!Devices.empty() &&
"No OpenMP offloading devices??");
3777 std::string EntriesBeginName =
getName({
"omp_offloading",
"entries_begin"});
3778 auto *HostEntriesBegin =
new llvm::GlobalVariable(
3779 M, OffloadEntryTy,
true,
3782 std::string EntriesEndName =
getName({
"omp_offloading",
"entries_end"});
3783 auto *HostEntriesEnd =
3784 new llvm::GlobalVariable(M, OffloadEntryTy,
true,
3786 nullptr, EntriesEndName);
3789 auto *DeviceImageTy = cast<llvm::StructType>(
3793 DeviceImagesBuilder.
beginArray(DeviceImageTy);
3795 for (
const llvm::Triple &Device : Devices) {
3796 StringRef T = Device.getTriple();
3797 std::string BeginName =
getName({
"omp_offloading",
"img_start",
""});
3798 auto *ImgBegin =
new llvm::GlobalVariable(
3800 llvm::GlobalValue::ExternalWeakLinkage,
3801 nullptr, Twine(BeginName).concat(T));
3802 std::string EndName =
getName({
"omp_offloading",
"img_end",
""});
3803 auto *ImgEnd =
new llvm::GlobalVariable(
3805 llvm::GlobalValue::ExternalWeakLinkage,
3806 nullptr, Twine(EndName).concat(T));
3808 llvm::Constant *Data[] = {ImgBegin, ImgEnd, HostEntriesBegin,
3811 DeviceImagesEntries);
3815 std::string ImagesName =
getName({
"omp_offloading",
"device_images"});
3816 llvm::GlobalVariable *DeviceImages =
3820 DeviceImages->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3823 llvm::Constant *Index[] = {llvm::Constant::getNullValue(
CGM.
Int32Ty),
3827 llvm::Constant *Data[] = {
3828 llvm::ConstantInt::get(
CGM.
Int32Ty, Devices.size()),
3829 llvm::ConstantExpr::getGetElementPtr(DeviceImages->getValueType(),
3830 DeviceImages, Index),
3831 HostEntriesBegin, HostEntriesEnd};
3832 std::string Descriptor =
getName({
"omp_offloading",
"descriptor"});
3839 llvm::Function *UnRegFn;
3843 Args.push_back(&DummyPtr);
3852 std::string UnregName =
getName({
"omp_offloading",
"descriptor_unreg"});
3859 llvm::Function *RegFn;
3872 RegFnNameParts[0] =
"omp_offloading";
3873 RegFnNameParts[1] =
"descriptor_reg";
3874 llvm::transform(Devices, std::next(RegFnNameParts.begin(), 2),
3875 [](
const llvm::Triple &T) ->
const std::string& {
3876 return T.getTriple();
3878 llvm::sort(std::next(RegFnNameParts.begin(), 2), RegFnNameParts.end());
3879 std::string Descriptor =
getName(RegFnNameParts);
3896 llvm::Comdat *ComdatKey = M.getOrInsertComdat(RegFn->getName());
3897 RegFn->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage);
3899 RegFn->setComdat(ComdatKey);
3900 UnRegFn->setComdat(ComdatKey);
3901 DeviceImages->setComdat(ComdatKey);
3902 Desc->setComdat(ComdatKey);
3908 llvm::Constant *ID, llvm::Constant *Addr, uint64_t Size, int32_t Flags,
3909 llvm::GlobalValue::LinkageTypes Linkage) {
3910 StringRef Name = Addr->getName();
3912 llvm::LLVMContext &C = M.getContext();
3915 llvm::Constant *StrPtrInit = llvm::ConstantDataArray::getString(C, Name);
3917 std::string StringName =
getName({
"omp_offloading",
"entry_name"});
3918 auto *Str =
new llvm::GlobalVariable(
3919 M, StrPtrInit->getType(),
true,
3921 Str->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3923 llvm::Constant *Data[] = {llvm::ConstantExpr::getBitCast(ID,
CGM.
VoidPtrTy),
3925 llvm::ConstantInt::get(
CGM.
SizeTy, Size),
3928 std::string EntryName =
getName({
"omp_offloading",
"entry",
""});
3931 Twine(EntryName).concat(Name), llvm::GlobalValue::WeakAnyLinkage);
3934 std::string Section =
getName({
"omp_offloading",
"entries"});
3935 Entry->setSection(Section);
3953 llvm::LLVMContext &C = M.getContext();
3960 auto &&GetMDInt = [
this](
unsigned V) {
3961 return llvm::ConstantAsMetadata::get(
3965 auto &&GetMDString = [&C](StringRef V) {
return llvm::MDString::get(C, V); };
3968 llvm::NamedMDNode *MD = M.getOrInsertNamedMetadata(
"omp_offload.info");
3971 auto &&TargetRegionMetadataEmitter =
3972 [&C, MD, &OrderedEntries, &ParentFunctions, &GetMDInt, &GetMDString](
3973 unsigned DeviceID,
unsigned FileID, StringRef ParentName,
3986 llvm::Metadata *Ops[] = {GetMDInt(E.getKind()), GetMDInt(DeviceID),
3987 GetMDInt(FileID), GetMDString(ParentName),
3988 GetMDInt(Line), GetMDInt(E.getOrder())};
3991 OrderedEntries[E.getOrder()] = &E;
3992 ParentFunctions[E.getOrder()] = ParentName;
3995 MD->addOperand(llvm::MDNode::get(C, Ops));
3999 TargetRegionMetadataEmitter);
4002 auto &&DeviceGlobalVarMetadataEmitter =
4003 [&C, &OrderedEntries, &GetMDInt, &GetMDString,
4004 MD](StringRef MangledName,
4014 llvm::Metadata *Ops[] = {
4015 GetMDInt(E.getKind()), GetMDString(MangledName),
4016 GetMDInt(E.getFlags()), GetMDInt(E.getOrder())};
4019 OrderedEntries[E.getOrder()] = &E;
4022 MD->addOperand(llvm::MDNode::get(C, Ops));
4026 DeviceGlobalVarMetadataEmitter);
4028 for (
const auto *E : OrderedEntries) {
4029 assert(E &&
"All ordered entries must exist!");
4030 if (
const auto *CE =
4031 dyn_cast<OffloadEntriesInfoManagerTy::OffloadEntryInfoTargetRegion>(
4033 if (!CE->getID() || !CE->getAddress()) {
4035 StringRef FnName = ParentFunctions[CE->getOrder()];
4040 "Offloading entry for target region is incorrect: either the " 4041 "address or the ID is invalid.");
4046 CE->getFlags(), llvm::GlobalValue::WeakAnyLinkage);
4047 }
else if (
const auto *CE =
4049 OffloadEntryInfoDeviceGlobalVar>(E)) {
4055 if (!CE->getAddress()) {
4058 "Offloading entry for declare target variable is incorrect: the " 4059 "address is invalid.");
4064 if (CE->getVarSize().isZero())
4069 assert(((
CGM.
getLangOpts().OpenMPIsDevice && !CE->getAddress()) ||
4071 "Declaret target link address is set.");
4074 if (!CE->getAddress()) {
4077 "Offloading entry for declare target variable is incorrect: the " 4078 "address is invalid.");
4085 CE->getVarSize().getQuantity(), Flags,
4088 llvm_unreachable(
"Unsupported entry kind.");
4106 if (
auto EC = Buf.getError()) {
4112 llvm::LLVMContext C;
4113 auto ME = expectedToErrorOrAndEmitErrors(
4114 C, llvm::parseBitcodeFile(Buf.get()->getMemBufferRef(), C));
4116 if (
auto EC = ME.getError()) {
4124 llvm::NamedMDNode *MD = ME.get()->getNamedMetadata(
"omp_offload.info");
4128 for (llvm::MDNode *MN : MD->operands()) {
4129 auto &&GetMDInt = [MN](
unsigned Idx) {
4130 auto *V = cast<llvm::ConstantAsMetadata>(MN->getOperand(Idx));
4131 return cast<llvm::ConstantInt>(V->getValue())->getZExtValue();
4134 auto &&GetMDString = [MN](
unsigned Idx) {
4135 auto *V = cast<llvm::MDString>(MN->getOperand(Idx));
4136 return V->getString();
4139 switch (GetMDInt(0)) {
4141 llvm_unreachable(
"Unexpected metadata!");
4146 GetMDInt(1), GetMDInt(2),
4147 GetMDString(3), GetMDInt(4),
4154 static_cast<OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind>(
4163 if (!KmpRoutineEntryPtrTy) {
4197 RD->
addAttr(PackedAttr::CreateImplicit(C));
4255 struct PrivateHelpersTy {
4256 PrivateHelpersTy(
const VarDecl *Original,
const VarDecl *PrivateCopy,
4257 const VarDecl *PrivateElemInit)
4258 : Original(Original), PrivateCopy(PrivateCopy),
4259 PrivateElemInit(PrivateElemInit) {}
4262 const VarDecl *PrivateElemInit;
4264 typedef std::pair<
CharUnits , PrivateHelpersTy> PrivateDataTy;
4269 if (!Privates.empty()) {
4276 for (
const auto &Pair : Privates) {
4277 const VarDecl *VD = Pair.second.Original;
4296 QualType KmpRoutineEntryPointerQTy) {
4341 ArrayRef<PrivateDataTy>
Privates) {
4370 QualType KmpTaskTWithPrivatesPtrQTy,
4381 Args.push_back(&GtidArg);
4382 Args.push_back(&TaskTypeArg);
4383 const auto &TaskEntryFnInfo =
4385 llvm::FunctionType *TaskEntryTy =
4391 TaskEntry->setDoesNotRecurse();
4406 const auto *KmpTaskTWithPrivatesQTyRD =
4407 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->
getAsTagDecl());
4410 const auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->
getAsTagDecl());
4411 auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
4413 llvm::Value *PartidParam = PartIdLVal.getPointer();
4415 auto SharedsFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTShareds);
4421 auto PrivatesFI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin(), 1);
4423 if (PrivatesFI != KmpTaskTWithPrivatesQTyRD->field_end()) {
4428 PrivatesParam = llvm::ConstantPointerNull::get(CGF.
VoidPtrTy);
4431 llvm::Value *CommonArgs[] = {GtidParam, PartidParam, PrivatesParam,
4438 std::end(CommonArgs));
4440 auto LBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound);
4443 auto UBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound);
4446 auto StFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTStride);
4449 auto LIFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLastIter);
4452 auto RFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTReductions);
4455 CallArgs.push_back(LBParam);
4456 CallArgs.push_back(UBParam);
4457 CallArgs.push_back(StParam);
4458 CallArgs.push_back(LIParam);
4459 CallArgs.push_back(RParam);
4461 CallArgs.push_back(SharedsParam);
4474 QualType KmpTaskTWithPrivatesPtrQTy,
4475 QualType KmpTaskTWithPrivatesQTy) {
4483 Args.push_back(&GtidArg);
4484 Args.push_back(&TaskTypeArg);
4485 const auto &DestructorFnInfo =
4487 llvm::FunctionType *DestructorFnTy =
4491 auto *DestructorFn =
4496 DestructorFn->setDoesNotRecurse();
4504 const auto *KmpTaskTWithPrivatesQTyRD =
4505 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->
getAsTagDecl());
4506 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
4508 for (
const auto *Field :
4509 cast<RecordDecl>(FI->getType()->getAsTagDecl())->fields()) {
4511 Field->getType().isDestructedType()) {
4517 return DestructorFn;
4532 ArrayRef<const Expr *> PrivateVars,
4533 ArrayRef<const Expr *> FirstprivateVars,
4534 ArrayRef<const Expr *> LastprivateVars,
4536 ArrayRef<PrivateDataTy>
Privates) {
4540 C,
nullptr, Loc,
nullptr,
4543 Args.push_back(&TaskPrivatesArg);
4544 llvm::DenseMap<const VarDecl *, unsigned> PrivateVarsPos;
4545 unsigned Counter = 1;
4546 for (
const Expr *E : PrivateVars) {
4548 C,
nullptr, Loc,
nullptr,
4553 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4554 PrivateVarsPos[VD] = Counter;
4557 for (
const Expr *E : FirstprivateVars) {
4559 C,
nullptr, Loc,
nullptr,
4564 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4565 PrivateVarsPos[VD] = Counter;
4568 for (
const Expr *E : LastprivateVars) {
4570 C,
nullptr, Loc,
nullptr,
4575 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4576 PrivateVarsPos[VD] = Counter;
4579 const auto &TaskPrivatesMapFnInfo =
4581 llvm::FunctionType *TaskPrivatesMapTy =
4589 TaskPrivatesMapFnInfo);
4590 TaskPrivatesMap->removeFnAttr(llvm::Attribute::NoInline);
4591 TaskPrivatesMap->removeFnAttr(llvm::Attribute::OptimizeNone);
4592 TaskPrivatesMap->addFnAttr(llvm::Attribute::AlwaysInline);
4595 TaskPrivatesMapFnInfo, Args, Loc, Loc);
4601 const auto *PrivatesQTyRD = cast<RecordDecl>(PrivatesQTy->
getAsTagDecl());
4603 for (
const FieldDecl *Field : PrivatesQTyRD->fields()) {
4605 const VarDecl *VD = Args[PrivateVarsPos[Privates[Counter].second.Original]];
4614 return TaskPrivatesMap;
4618 const PrivateDataTy P2) {
4619 return P1.first > P2.first;
4629 ArrayRef<PrivateDataTy>
Privates,
bool ForDup) {
4631 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->
field_begin());
4646 (IsTargetTask && KmpTaskSharedsPtr.
isValid())) {
4652 FI = cast<RecordDecl>(FI->getType()->getAsTagDecl())->field_begin();
4653 for (
const PrivateDataTy &Pair : Privates) {
4654 const VarDecl *VD = Pair.second.PrivateCopy;
4656 if (Init && (!ForDup || (isa<CXXConstructExpr>(Init) &&
4659 if (
const VarDecl *Elem = Pair.second.PrivateElemInit) {
4660 const VarDecl *OriginalVD = Pair.second.Original;
4666 if (IsTargetTask && !SharedField) {
4667 assert(isa<ImplicitParamDecl>(OriginalVD) &&
4670 ->getNumParams() == 0 &&
4671 isa<TranslationUnitDecl>(
4673 ->getDeclContext()) &&
4674 "Expected artificial target data variable.");
4694 [&CGF, Elem, Init, &CapturesInfo](
Address DestElement,
4699 Elem, [SrcElement]() ->
Address {
return SrcElement; });
4703 CGF, &CapturesInfo);
4704 CGF.EmitAnyExprToMem(Init, DestElement,
4705 Init->getType().getQualifiers(),
4729 ArrayRef<PrivateDataTy>
Privates) {
4730 bool InitRequired =
false;
4731 for (
const PrivateDataTy &Pair : Privates) {
4732 const VarDecl *VD = Pair.second.PrivateCopy;
4734 InitRequired = InitRequired || (Init && isa<CXXConstructExpr>(Init) &&
4739 return InitRequired;
4756 QualType KmpTaskTWithPrivatesPtrQTy,
4760 ArrayRef<PrivateDataTy>
Privates,
bool WithLastIter) {
4764 KmpTaskTWithPrivatesPtrQTy,
4767 KmpTaskTWithPrivatesPtrQTy,
4771 Args.push_back(&DstArg);
4772 Args.push_back(&SrcArg);
4773 Args.push_back(&LastprivArg);
4774 const auto &TaskDupFnInfo =
4781 TaskDup->setDoesNotRecurse();
4791 auto LIFI = std::next(KmpTaskTQTyRD->
field_begin(), KmpTaskTLastIter);
4793 TDBase, *KmpTaskTWithPrivatesQTyRD->
field_begin());
4801 assert(!Privates.empty());
4808 TDBase, *KmpTaskTWithPrivatesQTyRD->
field_begin());
4816 emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, TDBase, KmpTaskTWithPrivatesQTyRD,
4817 SharedsTy, SharedsPtrTy, Data, Privates,
true);
4826 bool NeedsCleanup =
false;
4827 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->
field_begin(), 1);
4828 const auto *PrivateRD = cast<RecordDecl>(FI->getType()->getAsTagDecl());
4829 for (
const FieldDecl *FD : PrivateRD->fields()) {
4830 NeedsCleanup = NeedsCleanup || FD->getType().isDestructedType();
4834 return NeedsCleanup;
4837 CGOpenMPRuntime::TaskResultTy
4847 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4848 Privates.emplace_back(
4850 PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
4857 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4858 Privates.emplace_back(
4861 VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
4862 cast<VarDecl>(cast<DeclRefExpr>(*IElemInitRef)->getDecl())));
4868 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4869 Privates.emplace_back(
4871 PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
4890 "Expected taskloop, task or target directive");
4899 const RecordDecl *KmpTaskTWithPrivatesQTyRD =
4902 QualType KmpTaskTWithPrivatesPtrQTy =
4906 KmpTaskTWithPrivatesTy->getPointerTo();
4914 std::next(cast<llvm::Function>(TaskFunction)->arg_begin(), 3)->getType();
4915 if (!Privates.empty()) {
4916 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
4921 TaskPrivatesMap, TaskPrivatesMapTy);
4923 TaskPrivatesMap = llvm::ConstantPointerNull::get(
4924 cast<llvm::PointerType>(TaskPrivatesMapTy));
4930 KmpTaskTWithPrivatesQTy,
KmpTaskTQTy, SharedsPtrTy, TaskFunction,
4942 DestructorsFlag = 0x8,
4945 unsigned Flags = Data.
Tied ? TiedFlag : 0;
4946 bool NeedsCleanup =
false;
4947 if (!Privates.empty()) {
4950 Flags = Flags | DestructorsFlag;
4953 Flags = Flags | PriorityFlag;
4955 Data.
Final.getPointer()
4957 CGF.
Builder.getInt32(FinalFlag),
4959 : CGF.
Builder.getInt32(Data.
Final.getInt() ? FinalFlag : 0);
4960 TaskFlags = CGF.
Builder.CreateOr(TaskFlags, CGF.
Builder.getInt32(Flags));
4964 KmpTaskTWithPrivatesTySize, SharedsSize,
4966 TaskEntry, KmpRoutineEntryPtrTy)};
4971 NewTask, KmpTaskTWithPrivatesPtrTy);
4973 KmpTaskTWithPrivatesQTy);
4983 TDBase, *std::next(KmpTaskTQTyRD->field_begin(),
4993 if (!Privates.empty()) {
4994 emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, Base, KmpTaskTWithPrivatesQTyRD,
4995 SharedsTy, SharedsPtrTy, Data, Privates,
5000 CGM, Loc, D, KmpTaskTWithPrivatesPtrQTy, KmpTaskTWithPrivatesQTyRD,
5001 KmpTaskTQTyRD, SharedsTy, SharedsPtrTy, Data, Privates,
5006 enum { Priority = 0, Destructors = 1 };
5008 auto FI = std::next(KmpTaskTQTyRD->field_begin(), Data1);
5010 (*FI)->getType()->getAsUnionType()->getDecl();
5013 CGM, Loc, KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy,
5014 KmpTaskTWithPrivatesQTy);
5017 Data1LV, *std::next(KmpCmplrdataUD->field_begin(), Destructors));
5019 DestructorFn, KmpRoutineEntryPtrTy),
5025 TDBase, *std::next(KmpTaskTQTyRD->field_begin(), Data2));
5027 Data2LV, *std::next(KmpCmplrdataUD->field_begin(), Priority));
5048 emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
5057 unsigned NumDependencies = Data.
Dependences.size();
5058 if (NumDependencies) {
5060 enum RTLDependenceKindTy { DepIn = 0x01, DepInOut = 0x3 };
5061 enum RTLDependInfoFieldsTy { BaseAddr, Len, Flags };
5085 for (
unsigned I = 0; I < NumDependencies; ++I) {
5090 if (
const auto *ASE =
5099 Size = CGF.
Builder.CreateNUWSub(UpIntPtr, LowIntPtr);
5108 Base, *std::next(KmpDependInfoRD->
field_begin(), BaseAddr));
5114 Base, *std::next(KmpDependInfoRD->
field_begin(), Len));
5117 RTLDependenceKindTy DepKind;
5119 case OMPC_DEPEND_in:
5123 case OMPC_DEPEND_out:
5124 case OMPC_DEPEND_inout:
5127 case OMPC_DEPEND_source:
5128 case OMPC_DEPEND_sink:
5130 llvm_unreachable(
"Unknown task dependence type");
5133 Base, *std::next(KmpDependInfoRD->
field_begin(), Flags));
5150 llvm::Value *TaskArgs[] = { UpLoc, ThreadID, NewTask };
5152 if (NumDependencies) {
5153 DepTaskArgs[0] = UpLoc;
5154 DepTaskArgs[1] = ThreadID;
5155 DepTaskArgs[2] = NewTask;
5156 DepTaskArgs[3] = CGF.
Builder.getInt32(NumDependencies);
5157 DepTaskArgs[4] = DependenciesArray.
getPointer();
5158 DepTaskArgs[5] = CGF.
Builder.getInt32(0);
5159 DepTaskArgs[6] = llvm::ConstantPointerNull::get(CGF.
VoidPtrTy);
5161 auto &&ThenCodeGen = [
this, &Data, TDBase, KmpTaskTQTyRD, NumDependencies,
5165 auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
5166 LValue PartIdLVal = CGF.EmitLValueForField(TDBase, *PartIdFI);
5167 CGF.EmitStoreOfScalar(CGF.Builder.getInt32(0), PartIdLVal);
5169 if (NumDependencies) {
5170 CGF.EmitRuntimeCall(
5178 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
5179 Region->emitUntiedSwitch(CGF);
5183 if (NumDependencies) {
5184 DepWaitTaskArgs[0] = UpLoc;
5185 DepWaitTaskArgs[1] = ThreadID;
5186 DepWaitTaskArgs[2] = CGF.Builder.getInt32(NumDependencies);
5187 DepWaitTaskArgs[3] = DependenciesArray.
getPointer();
5188 DepWaitTaskArgs[4] = CGF.Builder.getInt32(0);
5189 DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
5191 auto &&ElseCodeGen = [&TaskArgs, ThreadID, NewTaskNewTaskTTy, TaskEntry,
5192 NumDependencies, &DepWaitTaskArgs,
5200 if (NumDependencies)
5204 auto &&CodeGen = [TaskEntry, ThreadID, NewTaskNewTaskTTy,
5207 llvm::Value *OutlinedFnArgs[] = {ThreadID, NewTaskNewTaskTTy};
5208 CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, Loc, TaskEntry,
5217 CommonActionTy Action(
5241 emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
5254 IfVal = llvm::ConstantInt::getSigned(CGF.
IntTy, 1);
5288 enum { NoSchedule = 0, Grainsize = 1, NumTasks = 2 };
5297 llvm::ConstantInt::getSigned(
5299 llvm::ConstantInt::getSigned(
5301 ? Data.
Schedule.getInt() ? NumTasks : Grainsize
5306 : llvm::ConstantInt::get(CGF.
Int64Ty, 0),
5309 : llvm::ConstantPointerNull::get(CGF.
VoidPtrTy)};
5326 const Expr *,
const Expr *)> &RedOpGen,
5327 const Expr *XExpr =
nullptr,
const Expr *EExpr =
nullptr,
5328 const Expr *UpExpr =
nullptr) {
5346 CGF.
Builder.CreateICmpEQ(LHSBegin, LHSEnd,
"omp.arraycpy.isempty");
5347 CGF.
Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
5350 llvm::BasicBlock *EntryBB = CGF.
Builder.GetInsertBlock();
5355 llvm::PHINode *RHSElementPHI = CGF.
Builder.CreatePHI(
5356 RHSBegin->getType(), 2,
"omp.arraycpy.srcElementPast");
5357 RHSElementPHI->addIncoming(RHSBegin, EntryBB);
5362 llvm::PHINode *LHSElementPHI = CGF.
Builder.CreatePHI(
5363 LHSBegin->getType(), 2,
"omp.arraycpy.destElementPast");
5364 LHSElementPHI->addIncoming(LHSBegin, EntryBB);
5371 Scope.addPrivate(LHSVar, [=]() {
return LHSElementCurrent; });
5372 Scope.addPrivate(RHSVar, [=]() {
return RHSElementCurrent; });
5374 RedOpGen(CGF, XExpr, EExpr, UpExpr);
5375 Scope.ForceCleanup();
5379 LHSElementPHI, 1,
"omp.arraycpy.dest.element");
5381 RHSElementPHI, 1,
"omp.arraycpy.src.element");
5384 CGF.
Builder.CreateICmpEQ(LHSElementNext, LHSEnd,
"omp.arraycpy.done");
5385 CGF.
Builder.CreateCondBr(Done, DoneBB, BodyBB);
5386 LHSElementPHI->addIncoming(LHSElementNext, CGF.
Builder.GetInsertBlock());
5387 RHSElementPHI->addIncoming(RHSElementNext, CGF.
Builder.GetInsertBlock());
5397 const Expr *ReductionOp) {
5398 if (
const auto *CE = dyn_cast<CallExpr>(ReductionOp))
5399 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
5400 if (
const auto *DRE =
5401 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
5402 if (
const auto *DRD =
5403 dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl())) {
5404 std::pair<llvm::Function *, llvm::Function *> Reduction =
5416 ArrayRef<const Expr *>
Privates, ArrayRef<const Expr *> LHSExprs,
5417 ArrayRef<const Expr *> RHSExprs, ArrayRef<const Expr *> ReductionOps) {
5426 Args.push_back(&LHSArg);
5427 Args.push_back(&RHSArg);
5430 std::string Name =
getName({
"omp",
"reduction",
"reduction_func"});
5435 Fn->setDoesNotRecurse();
5452 auto IPriv = Privates.begin();
5454 for (
unsigned I = 0, E = ReductionOps.size(); I < E; ++I, ++IPriv, ++Idx) {
5455 const auto *RHSVar =
5456 cast<VarDecl>(cast<DeclRefExpr>(RHSExprs[I])->getDecl());
5457 Scope.addPrivate(RHSVar, [&CGF, RHS, Idx, RHSVar]() {
5460 const auto *LHSVar =
5461 cast<VarDecl>(cast<DeclRefExpr>(LHSExprs[I])->getDecl());
5462 Scope.addPrivate(LHSVar, [&CGF, LHS, Idx, LHSVar]() {
5465 QualType PrivTy = (*IPriv)->getType();
5474 const auto *OVE = cast<OpaqueValueExpr>(VLA->
getSizeExpr());
5481 IPriv = Privates.begin();
5482 auto ILHS = LHSExprs.begin();
5483 auto IRHS = RHSExprs.begin();
5484 for (
const Expr *E : ReductionOps) {
5485 if ((*IPriv)->getType()->isArrayType()) {
5487 const auto *LHSVar = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5488 const auto *RHSVar = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
5490 CGF, (*IPriv)->getType(), LHSVar, RHSVar,
5502 Scope.ForceCleanup();
5508 const Expr *ReductionOp,
5509 const Expr *PrivateRef,
5514 const auto *LHSVar = cast<VarDecl>(LHS->
getDecl());
5515 const auto *RHSVar = cast<VarDecl>(RHS->
getDecl());
5517 CGF, PrivateRef->
getType(), LHSVar, RHSVar,
5576 if (SimpleReduction) {
5578 auto IPriv = Privates.begin();
5579 auto ILHS = LHSExprs.begin();
5580 auto IRHS = RHSExprs.begin();
5581 for (
const Expr *E : ReductionOps) {
5583 cast<DeclRefExpr>(*IRHS));
5593 auto Size = RHSExprs.size();
5594 for (
const Expr *E : Privates) {
5599 llvm::APInt ArraySize(32, Size);
5604 CGF.
CreateMemTemp(ReductionArrayTy,
".omp.reduction.red_list");
5605 auto IPriv = Privates.begin();
5607 for (
unsigned I = 0, E = RHSExprs.size(); I < E; ++I, ++IPriv, ++Idx) {
5614 if ((*IPriv)->getType()->isVariablyModifiedType()) {
5632 Privates, LHSExprs, RHSExprs, ReductionOps);
5635 std::string Name =
getName({
"reduction"});
5648 CGF.
Builder.getInt32(RHSExprs.size()),
5649 ReductionArrayTySize,
5660 llvm::BasicBlock *DefaultBB = CGF.
createBasicBlock(
".omp.reduction.default");
5661 llvm::SwitchInst *SwInst =
5662 CGF.
Builder.CreateSwitch(Res, DefaultBB, 2);
5671 SwInst->addCase(CGF.
Builder.getInt32(1), Case1BB);
5680 auto &&CodeGen = [
Privates, LHSExprs, RHSExprs, ReductionOps](
5683 auto IPriv = Privates.begin();
5684 auto ILHS = LHSExprs.begin();
5685 auto IRHS = RHSExprs.begin();
5686 for (
const Expr *E : ReductionOps) {
5687 RT.emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
5688 cast<DeclRefExpr>(*IRHS));
5695 CommonActionTy Action(
5703 CGF.EmitBranch(DefaultBB);
5710 llvm::BasicBlock *Case2BB = CGF.createBasicBlock(
".omp.reduction.case2");
5711 SwInst->addCase(CGF.Builder.getInt32(2), Case2BB);
5712 CGF.EmitBlock(Case2BB);
5714 auto &&AtomicCodeGen = [Loc,
Privates, LHSExprs, RHSExprs, ReductionOps](
5716 auto ILHS = LHSExprs.begin();
5717 auto IRHS = RHSExprs.begin();
5718 auto IPriv = Privates.begin();
5719 for (
const Expr *E : ReductionOps) {
5720 const Expr *XExpr =
nullptr;
5721 const Expr *EExpr =
nullptr;
5722 const Expr *UpExpr =
nullptr;
5724 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
5725 if (BO->getOpcode() == BO_Assign) {
5726 XExpr = BO->getLHS();
5727 UpExpr = BO->getRHS();
5731 const Expr *RHSExpr = UpExpr;
5734 if (
const auto *ACO = dyn_cast<AbstractConditionalOperator>(
5738 RHSExpr = ACO->getCond();
5740 if (
const auto *BORHS =
5742 EExpr = BORHS->getRHS();
5743 BO = BORHS->getOpcode();
5747 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5748 auto &&AtomicRedGen = [BO, VD,
5750 const Expr *EExpr,
const Expr *UpExpr) {
5751 LValue X = CGF.EmitLValue(XExpr);
5754 E = CGF.EmitAnyExpr(EExpr);
5755 CGF.EmitOMPAtomicSimpleUpdateExpr(
5757 llvm::AtomicOrdering::Monotonic, Loc,
5758 [&CGF, UpExpr, VD, Loc](
RValue XRValue) {
5761 VD, [&CGF, VD, XRValue, Loc]() {
5762 Address LHSTemp = CGF.CreateMemTemp(VD->getType());
5763 CGF.emitOMPSimpleStore(
5764 CGF.MakeAddrLValue(LHSTemp, VD->
getType()), XRValue,
5765 VD->getType().getNonReferenceType(), Loc);
5769 return CGF.EmitAnyExpr(UpExpr);
5772 if ((*IPriv)->getType()->isArrayType()) {
5774 const auto *RHSVar =
5775 cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
5777 AtomicRedGen, XExpr, EExpr, UpExpr);
5780 AtomicRedGen(CGF, XExpr, EExpr, UpExpr);
5785 const Expr *,
const Expr *) {
5787 std::string Name = RT.getName({
"atomic_reduction"});
5788 RT.emitCriticalRegion(
5796 if ((*IPriv)->getType()->isArrayType()) {
5797 const auto *LHSVar =
5798 cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5799 const auto *RHSVar =
5800 cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
5804 CritRedGen(CGF,
nullptr,
nullptr,
nullptr);
5829 CGF.EmitBranch(DefaultBB);
5830 CGF.EmitBlock(DefaultBB,
true);
5838 llvm::raw_svector_ostream Out(Buffer);
5842 D = cast<VarDecl>(cast<DeclRefExpr>(Ref)->getDecl());
5845 {D->isLocalVarDeclOrParm() ? D->getName() : CGM.
getMangledName(D)});
5846 Out << Prefix << Name <<
"_" 5847 << D->getCanonicalDecl()->getBeginLoc().getRawEncoding();
5866 Args.emplace_back(&Param);
5867 const auto &FnInfo =
5874 Fn->setDoesNotRecurse();
5906 llvm::ConstantPointerNull::get(CGM.
VoidPtrTy),
5931 const Expr *ReductionOp,
5933 const Expr *PrivateRef) {
5935 const auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(LHS)->getDecl());
5936 const auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(RHS)->getDecl());
5942 Args.emplace_back(&ParamInOut);
5943 Args.emplace_back(&ParamIn);
5944 const auto &FnInfo =
5951 Fn->setDoesNotRecurse();
5969 PrivateScope.
addPrivate(LHSVD, [&C, &CGF, &ParamInOut, LHSVD]() {
5977 PrivateScope.
addPrivate(RHSVD, [&C, &CGF, &ParamIn, RHSVD]() {
5990 CGF, ReductionOp, PrivateRef, cast<DeclRefExpr>(LHS),
5991 cast<DeclRefExpr>(RHS));
6013 Args.emplace_back(&Param);
6014 const auto &FnInfo =
6021 Fn->setDoesNotRecurse();
6047 ArrayRef<const Expr *> RHSExprs,
const OMPTaskDataTy &Data) {
6073 llvm::APInt ArraySize(64, Size);
6080 for (
unsigned Cnt = 0; Cnt < Size; ++Cnt) {
6083 llvm::ConstantInt::get(CGM.
SizeTy, Cnt)};
6091 RCG.emitSharedLValue(CGF, Cnt);
6098 std::tie(SizeValInChars, SizeVal) = RCG.
getSizes(Cnt);
6105 bool DelayedCreation = !!SizeVal;
6106 SizeValInChars = CGF.
Builder.CreateIntCast(SizeValInChars, CGM.
SizeTy,
6121 : llvm::ConstantPointerNull::get(CGM.
VoidPtrTy);
6126 CGM, Loc, RCG, Cnt, Data.
ReductionOps[Cnt], LHSExprs[Cnt],
6131 if (DelayedCreation) {
6133 llvm::ConstantInt::get(CGM.
Int32Ty, 1,
true),
6143 llvm::ConstantInt::get(CGM.
IntTy, Size,
true),
6204 if (
auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.
CapturedStmtInfo))
6205 Region->emitUntiedSwitch(CGF);
6214 InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind, HasCancel);
6230 if (CancelRegion == OMPD_parallel)
6231 CancelKind = CancelParallel;
6232 else if (CancelRegion == OMPD_for)
6233 CancelKind = CancelLoop;
6234 else if (CancelRegion == OMPD_sections)
6235 CancelKind = CancelSections;
6237 assert(CancelRegion == OMPD_taskgroup);
6238 CancelKind = CancelTaskgroup;
6250 if (
auto *OMPRegionInfo =
6254 if (CancelRegion == OMPD_taskgroup || OMPRegionInfo->hasCancel()) {
6267 CGF.
Builder.CreateCondBr(Cmp, ExitBB, ContBB);
6285 if (
auto *OMPRegionInfo =
6287 auto &&ThenGen = [Loc, CancelRegion, OMPRegionInfo](
CodeGenFunction &CGF,
6299 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(
".cancel.exit");
6300 llvm::BasicBlock *ContBB = CGF.createBasicBlock(
".cancel.continue");
6301 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Result);
6302 CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
6303 CGF.EmitBlock(ExitBB);
6306 CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
6307 CGF.EmitBranchThroughCleanup(CancelDest);
6308 CGF.EmitBlock(ContBB,
true);
6322 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
6324 assert(!ParentName.empty() &&
"Invalid target region parent name!");
6326 IsOffloadEntry, CodeGen);
6331 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
6349 llvm::raw_svector_ostream OS(EntryFnName);
6350 OS <<
"__omp_offloading" << llvm::format(
"_%x", DeviceID)
6351 << llvm::format(
"_%x_", FileID) << ParentName <<
"_l" <<
Line;
6357 CGOpenMPTargetRegionInfo CGInfo(CS, CodeGen, EntryFnName);
6364 if (!IsOffloadEntry)
6379 OutlinedFnID = llvm::ConstantExpr::getBitCast(OutlinedFn, CGM.
Int8PtrTy);
6380 OutlinedFn->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6381 OutlinedFn->setDSOLocal(
false);
6383 std::string Name =
getName({EntryFnName,
"region_id"});
6384 OutlinedFnID =
new llvm::GlobalVariable(
6386 llvm::GlobalValue::WeakAnyLinkage,
6387 llvm::Constant::getNullValue(CGM.
Int8Ty), Name);
6392 DeviceID, FileID, ParentName, Line, OutlinedFn, OutlinedFnID,
6398 while (
const auto *CS = dyn_cast_or_null<CompoundStmt>(Body))
6399 Body = CS->body_front();
6416 assert(!CGF.
getLangOpts().OpenMPIsDevice &&
"Clauses associated with the " 6417 "teams directive expected to be " 6418 "emitted only for the host!");
6430 return Bld.CreateIntCast(NumTeams, CGF.
Int32Ty,
6435 return Bld.getInt32(0);
6441 return Bld.getInt32(1);
6451 if (
const auto *TeamsDir = dyn_cast_or_null<OMPExecutableDirective>(
6455 CGOpenMPInnerExprInfo CGInfo(CGF, CS);
6458 return Bld.CreateIntCast(NumTeams, CGF.
Int32Ty,
6464 return Bld.getInt32(0);
6484 assert(!CGF.
getLangOpts().OpenMPIsDevice &&
"Clauses associated with the " 6485 "teams directive expected to be " 6486 "emitted only for the host!");
6506 llvm::Value *DefaultThreadLimitVal = Bld.getInt32(0);
6510 if (
const auto *ThreadLimitClause =
6516 ThreadLimitVal = Bld.CreateIntCast(ThreadLimit, CGF.
Int32Ty,
6520 if (
const auto *NumThreadsClause =
6527 Bld.CreateIntCast(NumThreads, CGF.
Int32Ty,
true);
6532 ThreadLimitVal = ThreadLimitVal
6533 ? Bld.CreateSelect(Bld.CreateICmpSLT(NumThreadsVal,
6535 NumThreadsVal, ThreadLimitVal)
6540 if (!ThreadLimitVal)
6541 ThreadLimitVal = DefaultThreadLimitVal;
6543 return ThreadLimitVal;
6554 if (
const auto *TeamsDir = dyn_cast_or_null<OMPExecutableDirective>(
6558 CGOpenMPInnerExprInfo CGInfo(CGF, CS);
6567 return CGF.
Builder.getInt32(0);
6582 class MappableExprsHandler {
6586 enum OpenMPOffloadMappingFlags : uint64_t {
6592 OMP_MAP_FROM = 0x02,
6595 OMP_MAP_ALWAYS = 0x04,
6598 OMP_MAP_DELETE = 0x08,
6601 OMP_MAP_PTR_AND_OBJ = 0x10,
6604 OMP_MAP_TARGET_PARAM = 0x20,
6608 OMP_MAP_RETURN_PARAM = 0x40,
6611 OMP_MAP_PRIVATE = 0x80,
6613 OMP_MAP_LITERAL = 0x100,
6615 OMP_MAP_IMPLICIT = 0x200,
6618 OMP_MAP_MEMBER_OF = 0xffff000000000000,
6619 LLVM_MARK_AS_BITMASK_ENUM( OMP_MAP_MEMBER_OF),
6624 class BasePointerInfo {
6633 : Ptr(Ptr), DevPtrDecl(DevPtrDecl) {}
6635 const ValueDecl *getDevicePtrDecl()
const {
return DevPtrDecl; }
6636 void setDevicePtrDecl(
const ValueDecl *D) { DevPtrDecl = D; }
6647 struct StructRangeInfoTy {
6648 std::pair<
unsigned ,
Address > LowestElem = {
6650 std::pair<
unsigned ,
Address > HighestElem = {
6660 ArrayRef<OpenMPMapModifierKind> MapModifiers;
6661 bool ReturnDevicePointer =
false;
6662 bool IsImplicit =
false;
6664 MapInfo() =
default;
6668 ArrayRef<OpenMPMapModifierKind> MapModifiers,
6669 bool ReturnDevicePointer,
bool IsImplicit)
6670 : Components(Components), MapType(MapType), MapModifiers(MapModifiers),
6671 ReturnDevicePointer(ReturnDevicePointer), IsImplicit(IsImplicit) {}
6677 struct DeferredDevicePtrEntryTy {
6678 const Expr *IE =
nullptr;
6681 DeferredDevicePtrEntryTy(
const Expr *IE,
const ValueDecl *VD)
6692 llvm::SmallPtrSet<const VarDecl *, 8> FirstPrivateDecls;
6711 if (
const auto *OAE = dyn_cast<OMPArraySectionExpr>(E)) {
6713 OAE->getBase()->IgnoreParenImpCasts())
6714 .getCanonicalType();
6718 if (!OAE->getLength() && OAE->getColonLoc().isValid())
6723 ElemSize = CGF.
getTypeSize(PTy->getPointeeType().getCanonicalType());
6725 const auto *ATy = cast<ArrayType>(BaseTy.
getTypePtr());
6726 assert(ATy &&
"Expecting array type if not a pointer type.");
6727 ElemSize = CGF.
getTypeSize(ATy->getElementType().getCanonicalType());
6732 if (!OAE->getLength())
6738 return CGF.
Builder.CreateNUWMul(LengthVal, ElemSize);
6747 OpenMPOffloadMappingFlags getMapTypeBits(
6749 bool IsImplicit,
bool AddPtrFlag,
bool AddIsTargetParamFlag)
const {
6750 OpenMPOffloadMappingFlags Bits =
6751 IsImplicit ? OMP_MAP_IMPLICIT : OMP_MAP_NONE;
6753 case OMPC_MAP_alloc:
6754 case OMPC_MAP_release:
6764 Bits |= OMP_MAP_FROM;
6766 case OMPC_MAP_tofrom:
6767 Bits |= OMP_MAP_TO | OMP_MAP_FROM;
6769 case OMPC_MAP_delete:
6770 Bits |= OMP_MAP_DELETE;
6773 llvm_unreachable(
"Unexpected map type!");
6776 Bits |= OMP_MAP_PTR_AND_OBJ;
6777 if (AddIsTargetParamFlag)
6778 Bits |= OMP_MAP_TARGET_PARAM;
6779 if (llvm::find(MapModifiers, OMPC_MAP_MODIFIER_always)
6780 != MapModifiers.end())
6781 Bits |= OMP_MAP_ALWAYS;
6787 bool isFinalArraySectionExpression(
const Expr *E)
const {
6795 if (OASE->getColonLoc().isInvalid())
6798 const Expr *Length = OASE->getLength();
6805 OASE->getBase()->IgnoreParenImpCasts())
6806 .getCanonicalType();
6807 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
6808 return ATy->getSize().getSExtValue() != 1;
6820 llvm::APSInt ConstLength = Result.
Val.
getInt();
6821 return ConstLength.getSExtValue() != 1;
6828 void generateInfoForComponentList(
6830 ArrayRef<OpenMPMapModifierKind> MapModifiers,
6832 MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers,
6833 MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types,
6834 StructRangeInfoTy &PartialStruct,
bool IsFirstComponentList,
6836 ArrayRef<OMPClauseMappableExprCommon::MappableExprComponentListRef>
6995 bool IsCaptureFirstInfo = IsFirstComponentList;
6996 bool IsLink =
false;
6999 auto CI = Components.rbegin();
7000 auto CE = Components.rend();
7005 bool IsExpressionFirstInfo =
true;
7007 const Expr *AssocExpr = I->getAssociatedExpression();
7011 if (isa<MemberExpr>(AssocExpr)) {
7015 }
else if ((AE && isa<CXXThisExpr>(AE->getBase()->IgnoreParenImpCasts())) ||
7017 isa<CXXThisExpr>(OASE->getBase()->IgnoreParenImpCasts()))) {
7023 if (
const auto *VD =
7024 dyn_cast_or_null<VarDecl>(I->getAssociatedDeclaration())) {
7026 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
7027 if (*Res == OMPDeclareTargetDeclAttr::MT_Link) {
7037 I->getAssociatedDeclaration()->getType().getNonReferenceType();
7061 bool ShouldBeMemberOf =
false;
7072 for (; I != CE; ++I) {
7074 if (!EncounteredME) {
7075 EncounteredME = dyn_cast<
MemberExpr>(I->getAssociatedExpression());
7079 ShouldBeMemberOf =
true;
7082 auto Next = std::next(I);
7090 bool IsFinalArraySection =
7091 isFinalArraySectionExpression(I->getAssociatedExpression());
7104 if (Next == CE || IsPointer || IsFinalArraySection) {
7107 assert((Next == CE ||
7108 isa<MemberExpr>(Next->getAssociatedExpression()) ||
7109 isa<ArraySubscriptExpr>(Next->getAssociatedExpression()) ||
7110 isa<OMPArraySectionExpr>(Next->getAssociatedExpression())) &&
7111 "Unexpected expression");
7119 bool IsMemberPointer =
7120 IsPointer && EncounteredME &&
7121 (dyn_cast<
MemberExpr>(I->getAssociatedExpression()) ==
7123 if (!OverlappedElements.empty()) {
7125 assert(!PartialStruct.Base.isValid() &&
"The base element is set.");
7126 assert(Next == CE &&
7127 "Expected last element for the overlapped elements.");
7128 assert(!IsPointer &&
7129 "Unexpected base element with the pointer type.");
7132 PartialStruct.LowestElem = {0, LB};
7134 I->getAssociatedExpression()->getType());
7139 PartialStruct.HighestElem = {
7140 std::numeric_limits<decltype(
7141 PartialStruct.HighestElem.first)>
::max(),
7143 PartialStruct.Base = BP;
7145 OpenMPOffloadMappingFlags Flags =
7147 getMapTypeBits(MapType, MapModifiers, IsImplicit,
7154 Component : OverlappedElements) {
7158 if (MC.getAssociatedDeclaration()) {
7162 Size = CGF.
Builder.CreatePtrDiff(
7169 Pointers.push_back(LB.getPointer());
7170 Sizes.push_back(Size);
7171 Types.push_back(Flags);
7176 Pointers.push_back(LB.getPointer());
7177 Size = CGF.
Builder.CreatePtrDiff(
7182 Sizes.push_back(Size);
7183 Types.push_back(Flags);
7186 llvm::Value *Size = getExprTypeSize(I->getAssociatedExpression());
7187 if (!IsMemberPointer) {
7189 Pointers.push_back(LB.getPointer());
7190 Sizes.push_back(Size);
7196 OpenMPOffloadMappingFlags Flags = getMapTypeBits(
7197 MapType, MapModifiers, IsImplicit,
7198 !IsExpressionFirstInfo || IsLink, IsCaptureFirstInfo && !IsLink);
7200 if (!IsExpressionFirstInfo) {
7204 Flags &= ~(OMP_MAP_TO | OMP_MAP_FROM | OMP_MAP_ALWAYS |
7207 if (ShouldBeMemberOf) {
7210 Flags |= OMP_MAP_MEMBER_OF;
7213 ShouldBeMemberOf =
false;
7217 Types.push_back(Flags);
7223 if (EncounteredME) {
7224 const auto *FD = dyn_cast<
FieldDecl>(EncounteredME->getMemberDecl());
7228 if (!PartialStruct.Base.isValid()) {
7229 PartialStruct.LowestElem = {FieldIndex, LB};
7230 PartialStruct.HighestElem = {FieldIndex, LB};
7231 PartialStruct.Base = BP;
7232 }
else if (FieldIndex < PartialStruct.LowestElem.first) {
7233 PartialStruct.LowestElem = {FieldIndex, LB};
7234 }
else if (FieldIndex > PartialStruct.HighestElem.first) {
7235 PartialStruct.HighestElem = {FieldIndex, LB};
7240 if (IsFinalArraySection)
7247 IsExpressionFirstInfo =
false;
7248 IsCaptureFirstInfo =
false;
7256 MappableExprsHandler::OpenMPOffloadMappingFlags
7264 return MappableExprsHandler::OMP_MAP_PRIVATE |
7265 MappableExprsHandler::OMP_MAP_TO;
7266 return MappableExprsHandler::OMP_MAP_TO |
7267 MappableExprsHandler::OMP_MAP_FROM;
7270 static OpenMPOffloadMappingFlags getMemberOfFlag(
unsigned Position) {
7272 return static_cast<OpenMPOffloadMappingFlags
>(((uint64_t)Position + 1)
7276 static void setCorrectMemberOfFlag(OpenMPOffloadMappingFlags &Flags,
7277 OpenMPOffloadMappingFlags MemberOfFlag) {
7281 if ((Flags & OMP_MAP_PTR_AND_OBJ) &&
7282 ((Flags & OMP_MAP_MEMBER_OF) != OMP_MAP_MEMBER_OF))
7287 Flags &= ~OMP_MAP_MEMBER_OF;
7288 Flags |= MemberOfFlag;
7293 bool AsBase)
const {
7296 llvm::StructType *St =
7299 unsigned NumElements = St->getNumElements();
7301 llvm::PointerUnion<const CXXRecordDecl *, const FieldDecl *>, 4>
7302 RecordLayout(NumElements);
7305 for (
const auto &I : RD->
bases()) {
7308 const auto *
Base = I.getType()->getAsCXXRecordDecl();
7317 RecordLayout[FieldIndex] =
Base;
7320 for (
const auto &I : RD->
vbases()) {
7321 const auto *
Base = I.getType()->getAsCXXRecordDecl();
7323 if (
Base->isEmpty())
7326 if (RecordLayout[FieldIndex])
7328 RecordLayout[FieldIndex] =
Base;
7331 assert(!RD->
isUnion() &&
"Unexpected union.");
7332 for (
const auto *Field : RD->
fields()) {
7335 if (!Field->isBitField()) {
7337 RecordLayout[FieldIndex] = Field;
7340 for (
const llvm::PointerUnion<const CXXRecordDecl *, const FieldDecl *>
7341 &Data : RecordLayout) {
7345 getPlainLayout(
Base, Layout,
true);
7347 Layout.push_back(Data.get<
const FieldDecl *>());
7353 : CurDir(Dir), CGF(CGF) {
7356 for (
const auto *D : C->varlists())
7357 FirstPrivateDecls.insert(
7361 for (
auto L : C->component_lists())
7362 DevPointersMap[L.first].push_back(L.second);
7368 void emitCombinedEntry(MapBaseValuesArrayTy &BasePointers,
7369 MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
7370 MapFlagsArrayTy &Types, MapFlagsArrayTy &CurTypes,
7371 const StructRangeInfoTy &PartialStruct)
const {
7373 BasePointers.push_back(PartialStruct.Base.getPointer());
7375 llvm::Value *LB = PartialStruct.LowestElem.second.getPointer();
7376 Pointers.push_back(LB);
7378 llvm::Value *HB = PartialStruct.HighestElem.second.getPointer();
7385 Sizes.push_back(Size);
7387 Types.push_back(OMP_MAP_TARGET_PARAM);
7389 (*CurTypes.begin()) &= ~OMP_MAP_TARGET_PARAM;
7394 OpenMPOffloadMappingFlags MemberOfFlag =
7395 getMemberOfFlag(BasePointers.size() - 1);
7396 for (
auto &M : CurTypes)
7397 setCorrectMemberOfFlag(M, MemberOfFlag);
7404 void generateAllInfo(MapBaseValuesArrayTy &BasePointers,
7405 MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
7406 MapFlagsArrayTy &Types)
const {
7410 llvm::MapVector<const ValueDecl *, SmallVector<MapInfo, 8>> Info;
7414 auto &&InfoGen = [&Info](
7418 ArrayRef<OpenMPMapModifierKind> MapModifiers,
7419 bool ReturnDevicePointer,
bool IsImplicit) {
7420 const ValueDecl *VD =
7422 Info[VD].emplace_back(L, MapType, MapModifiers, ReturnDevicePointer,
7428 for (
const auto &L : C->component_lists()) {
7429 InfoGen(L.first, L.second, C->getMapType(), C->getMapTypeModifiers(),
7430 false, C->isImplicit());
7433 for (
const auto &L : C->component_lists()) {
7434 InfoGen(L.first, L.second, OMPC_MAP_to,
llvm::None,
7435 false, C->isImplicit());
7438 for (
const auto &L : C->component_lists()) {
7439 InfoGen(L.first, L.second, OMPC_MAP_from,
llvm::None,
7440 false, C->isImplicit());
7449 llvm::MapVector<const ValueDecl *, SmallVector<DeferredDevicePtrEntryTy, 4>>
7453 for (
const auto *C :
7455 for (
const auto &L : C->component_lists()) {
7456 assert(!L.second.empty() &&
"Not expecting empty list of components!");
7457 const ValueDecl *VD = L.second.back().getAssociatedDeclaration();
7458 VD = cast<ValueDecl>(VD->getCanonicalDecl());
7459 const Expr *IE = L.second.back().getAssociatedExpression();
7463 auto It = Info.find(isa<MemberExpr>(IE) ?
nullptr : VD);
7467 if (It != Info.end()) {
7468 auto CI = std::find_if(
7469 It->second.begin(), It->second.end(), [VD](
const MapInfo &MI) {
7470 return MI.Components.back().getAssociatedDeclaration() == VD;
7474 if (CI != It->second.end()) {
7475 CI->ReturnDevicePointer =
true;
7484 if (isa<MemberExpr>(IE)) {
7493 false, C->isImplicit());
7494 DeferredInfo[
nullptr].emplace_back(IE, VD);
7498 BasePointers.emplace_back(Ptr, VD);
7499 Pointers.push_back(Ptr);
7500 Sizes.push_back(llvm::Constant::getNullValue(this->CGF.
SizeTy));
7501 Types.push_back(OMP_MAP_RETURN_PARAM | OMP_MAP_TARGET_PARAM);
7506 for (
const auto &M : Info) {
7509 bool IsFirstComponentList =
true;
7512 MapBaseValuesArrayTy CurBasePointers;
7513 MapValuesArrayTy CurPointers;
7514 MapValuesArrayTy CurSizes;
7515 MapFlagsArrayTy CurTypes;
7516 StructRangeInfoTy PartialStruct;
7518 for (
const MapInfo &L : M.second) {
7519 assert(!L.Components.empty() &&
7520 "Not expecting declaration with no component lists.");
7523 unsigned CurrentBasePointersIdx = CurBasePointers.size();
7525 this->generateInfoForComponentList(
7526 L.MapType, L.MapModifiers, L.Components, CurBasePointers,
7527 CurPointers, CurSizes, CurTypes, PartialStruct,
7528 IsFirstComponentList, L.IsImplicit);
7532 if (L.ReturnDevicePointer) {
7533 assert(CurBasePointers.size() > CurrentBasePointersIdx &&
7534 "Unexpected number of mapped base pointers.");
7536 const ValueDecl *RelevantVD =
7537 L.Components.back().getAssociatedDeclaration();
7538 assert(RelevantVD &&
7539 "No relevant declaration related with device pointer??");
7541 CurBasePointers[CurrentBasePointersIdx].setDevicePtrDecl(RelevantVD);
7542 CurTypes[CurrentBasePointersIdx] |= OMP_MAP_RETURN_PARAM;
7544 IsFirstComponentList =
false;
7549 auto CI = DeferredInfo.find(M.first);
7550 if (CI != DeferredInfo.end()) {
7551 for (
const DeferredDevicePtrEntryTy &L : CI->second) {
7554 this->CGF.
EmitLValue(L.IE), L.IE->getExprLoc());
7555 CurBasePointers.emplace_back(BasePtr, L.VD);
7556 CurPointers.push_back(Ptr);
7557 CurSizes.push_back(llvm::Constant::getNullValue(this->CGF.
SizeTy));
7561 CurTypes.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_RETURN_PARAM |
7568 if (PartialStruct.Base.isValid())
7569 emitCombinedEntry(BasePointers, Pointers, Sizes, Types, CurTypes,
7573 BasePointers.append(CurBasePointers.begin(), CurBasePointers.end());
7574 Pointers.append(CurPointers.begin(), CurPointers.end());
7575 Sizes.append(CurSizes.begin(), CurSizes.end());
7576 Types.append(CurTypes.begin(), CurTypes.end());
7581 void generateInfoForLambdaCaptures(
7582 const ValueDecl *VD,
llvm::Value *Arg, MapBaseValuesArrayTy &BasePointers,
7583 MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
7584 MapFlagsArrayTy &Types,
7585 llvm::DenseMap<llvm::Value *, llvm::Value *> &LambdaPointers)
const {
7586 const auto *RD = VD->
getType()
7595 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
7602 LambdaPointers.try_emplace(ThisLVal.
getPointer(), VDLVal.getPointer());
7603 BasePointers.push_back(ThisLVal.
getPointer());
7604 Pointers.push_back(ThisLValVal.
getPointer());
7606 Types.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL |
7607 OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT);
7612 const VarDecl *VD = LC.getCapturedVar();
7613 auto It = Captures.find(VD);
7614 assert(It != Captures.end() &&
"Found lambda capture without field.");
7617 LambdaPointers.try_emplace(VarLVal.getPointer(), VDLVal.getPointer());
7618 BasePointers.push_back(VarLVal.getPointer());
7622 Types.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL |
7623 OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT);
7628 void adjustMemberOfForLambdaCaptures(
7629 const llvm::DenseMap<llvm::Value *, llvm::Value *> &LambdaPointers,
7630 MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers,
7631 MapFlagsArrayTy &Types)
const {
7632 for (
unsigned I = 0, E = Types.size(); I < E; ++I) {
7634 if (Types[I] != (OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL |
7635 OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT))
7637 llvm::Value *BasePtr = LambdaPointers.lookup(*BasePointers[I]);
7638 assert(BasePtr &&
"Unable to find base lambda address.");
7640 for (
unsigned J = I; J > 0; --J) {
7641 unsigned Idx = J - 1;
7642 if (Pointers[Idx] != BasePtr)
7647 assert(TgtIdx != -1 &&
"Unable to find parent lambda.");
7651 OpenMPOffloadMappingFlags MemberOfFlag = getMemberOfFlag(TgtIdx);
7652 setCorrectMemberOfFlag(Types[I], MemberOfFlag);
7660 MapBaseValuesArrayTy &BasePointers,
7661 MapValuesArrayTy &Pointers,
7662 MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types,
7663 StructRangeInfoTy &PartialStruct)
const {
7665 "Not expecting to generate map info for a variable array type!");
7675 if (DevPointersMap.count(VD)) {
7676 BasePointers.emplace_back(Arg, VD);
7677 Pointers.push_back(Arg);
7679 Types.push_back(OMP_MAP_LITERAL | OMP_MAP_TARGET_PARAM);
7689 for (
const auto &L : C->decl_component_lists(VD)) {
7690 assert(L.first == VD &&
7691 "We got information for the wrong declaration??");
7692 assert(!L.second.empty() &&
7693 "Not expecting declaration with no component lists.");
7694 DeclComponentLists.emplace_back(L.second, C->getMapType(),
7695 C->getMapTypeModifiers(),
7701 llvm::SmallDenseMap<
7708 for (
const MapData &L : DeclComponentLists) {
7709 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
7710 OpenMPMapClauseKind MapType;
7711 ArrayRef<OpenMPMapModifierKind> MapModifiers;
7713 std::tie(Components, MapType, MapModifiers, IsImplicit) = L;
7715 for (
const MapData &L1 : makeArrayRef(DeclComponentLists).slice(Count)) {
7716 OMPClauseMappableExprCommon::MappableExprComponentListRef Components1;
7717 std::tie(Components1, MapType, MapModifiers, IsImplicit) = L1;
7718 auto CI = Components.rbegin();
7719 auto CE = Components.rend();
7720 auto SI = Components1.rbegin();
7721 auto SE = Components1.rend();
7722 for (; CI != CE && SI != SE; ++CI, ++SI) {
7723 if (CI->getAssociatedExpression()->getStmtClass() !=
7724 SI->getAssociatedExpression()->getStmtClass())
7727 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
7732 if (CI == CE || SI == SE) {
7733 assert((CI != CE || SI != SE) &&
7734 "Unexpected full match of the mapping components.");
7735 const MapData &BaseData = CI == CE ? L : L1;
7736 OMPClauseMappableExprCommon::MappableExprComponentListRef SubData =
7737 SI == SE ? Components : Components1;
7738 auto &OverlappedElements = OverlappedData.FindAndConstruct(&BaseData);
7739 OverlappedElements.getSecond().push_back(SubData);
7745 if (!OverlappedData.empty()) {
7746 if (
const auto *CRD =
7747 VD->getType().getCanonicalType()->getAsCXXRecordDecl())
7748 getPlainLayout(CRD, Layout,
false);
7750 const auto *RD = VD->getType().getCanonicalType()->getAsRecordDecl();
7754 for (
auto &Pair : OverlappedData) {
7758 OMPClauseMappableExprCommon::MappableExprComponentListRef
First,
7759 OMPClauseMappableExprCommon::MappableExprComponentListRef
7761 auto CI = First.rbegin();
7762 auto CE = First.rend();
7763 auto SI = Second.rbegin();
7764 auto SE = Second.rend();
7765 for (; CI != CE && SI != SE; ++CI, ++SI) {
7766 if (CI->getAssociatedExpression()->getStmtClass() !=
7767 SI->getAssociatedExpression()->getStmtClass())
7770 if (CI->getAssociatedDeclaration() !=
7771 SI->getAssociatedDeclaration())
7776 if (CI == CE && SI == SE)
7780 if (CI == CE || SI == SE)
7783 const auto *FD1 = cast<FieldDecl>(CI->getAssociatedDeclaration());
7784 const auto *FD2 = cast<FieldDecl>(SI->getAssociatedDeclaration());
7785 if (FD1->getParent() == FD2->getParent())
7786 return FD1->getFieldIndex() < FD2->getFieldIndex();
7788 llvm::find_if(Layout, [FD1, FD2](
const FieldDecl *FD) {
7789 return FD == FD1 || FD == FD2;
7797 for (
const auto &Pair : OverlappedData) {
7798 const MapData &L = *Pair.getFirst();
7799 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
7800 OpenMPMapClauseKind MapType;
7801 ArrayRef<OpenMPMapModifierKind> MapModifiers;
7803 std::tie(Components, MapType, MapModifiers, IsImplicit) = L;
7804 ArrayRef<OMPClauseMappableExprCommon::MappableExprComponentListRef>
7805 OverlappedComponents = Pair.getSecond();
7806 bool IsFirstComponentList =
true;
7807 generateInfoForComponentList(MapType, MapModifiers, Components,
7808 BasePointers, Pointers, Sizes, Types,
7809 PartialStruct, IsFirstComponentList,
7810 IsImplicit, OverlappedComponents);
7813 bool IsFirstComponentList = OverlappedData.empty();
7814 for (
const MapData &L : DeclComponentLists) {
7815 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
7816 OpenMPMapClauseKind MapType;
7817 ArrayRef<OpenMPMapModifierKind> MapModifiers;
7819 std::tie(Components, MapType, MapModifiers, IsImplicit) = L;
7820 auto It = OverlappedData.find(&L);
7821 if (It == OverlappedData.end())
7822 generateInfoForComponentList(MapType, MapModifiers, Components,
7823 BasePointers, Pointers, Sizes, Types,
7824 PartialStruct, IsFirstComponentList,
7826 IsFirstComponentList =
false;
7832 void generateInfoForDeclareTargetLink(MapBaseValuesArrayTy &BasePointers,
7833 MapValuesArrayTy &Pointers,
7834 MapValuesArrayTy &Sizes,
7835 MapFlagsArrayTy &Types)
const {
7839 for (
const auto &L : C->component_lists()) {
7842 const auto *VD = dyn_cast<
VarDecl>(L.first);
7846 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
7847 if (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)
7849 StructRangeInfoTy PartialStruct;
7850 generateInfoForComponentList(
7851 C->getMapType(), C->getMapTypeModifiers(), L.second, BasePointers,
7852 Pointers, Sizes, Types, PartialStruct,
7853 true, C->isImplicit());
7854 assert(!PartialStruct.Base.isValid() &&
7855 "No partial structs for declare target link expected.");
7864 MapBaseValuesArrayTy &CurBasePointers,
7865 MapValuesArrayTy &CurPointers,
7866 MapValuesArrayTy &CurSizes,
7867 MapFlagsArrayTy &CurMapTypes)
const {
7870 CurBasePointers.push_back(CV);
7871 CurPointers.push_back(CV);
7873 CurSizes.push_back(CGF.
getTypeSize(PtrTy->getPointeeType()));
7875 CurMapTypes.push_back(OMP_MAP_TO | OMP_MAP_FROM);
7877 CurBasePointers.push_back(CV);
7878 CurPointers.push_back(CV);
7882 CurMapTypes.push_back(OMP_MAP_LITERAL);
7887 CurMapTypes.push_back(OMP_MAP_NONE);
7888 CurSizes.push_back(llvm::Constant::getNullValue(CGF.
SizeTy));
7892 CurBasePointers.push_back(CV);
7893 CurPointers.push_back(CV);
7901 CurMapTypes.push_back(getMapModifiersForPrivateClauses(CI));
7904 CurMapTypes.back() |= OMP_MAP_TARGET_PARAM;
7907 CurMapTypes.back() |= OMP_MAP_IMPLICIT;
7914 OMP_DEVICEID_UNDEF = -1,
7924 MappableExprsHandler::MapValuesArrayTy &Pointers,
7925 MappableExprsHandler::MapValuesArrayTy &Sizes,
7927 CGOpenMPRuntime::TargetDataInfo &Info) {
7932 Info.clearArrayInfo();
7933 Info.NumberOfPtrs = BasePointers.size();
7935 if (Info.NumberOfPtrs) {
7938 bool hasRuntimeEvaluationCaptureSize =
false;
7940 if (!isa<llvm::Constant>(S)) {
7941 hasRuntimeEvaluationCaptureSize =
true;
7945 llvm::APInt PointerNumAP(32, Info.NumberOfPtrs,
true);
7950 Info.BasePointersArray =
7952 Info.PointersArray =
7958 if (hasRuntimeEvaluationCaptureSize) {
7969 ConstSizes.push_back(cast<llvm::Constant>(S));
7971 auto *SizesArrayInit = llvm::ConstantArray::get(
7972 llvm::ArrayType::get(CGM.
SizeTy, ConstSizes.size()), ConstSizes);
7974 auto *SizesArrayGbl =
new llvm::GlobalVariable(
7975 CGM.
getModule(), SizesArrayInit->getType(),
7976 true, llvm::GlobalValue::PrivateLinkage,
7977 SizesArrayInit, Name);
7978 SizesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
7979 Info.SizesArray = SizesArrayGbl;
7985 llvm::copy(MapTypes, Mapping.begin());
7986 llvm::Constant *MapTypesArrayInit =
7987 llvm::ConstantDataArray::get(CGF.
Builder.getContext(), Mapping);
7988 std::string MaptypesName =
7990 auto *MapTypesArrayGbl =
new llvm::GlobalVariable(
7991 CGM.
getModule(), MapTypesArrayInit->getType(),
7992 true, llvm::GlobalValue::PrivateLinkage,
7993 MapTypesArrayInit, MaptypesName);
7994 MapTypesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
7995 Info.MapTypesArray = MapTypesArrayGbl;
7997 for (
unsigned I = 0; I < Info.NumberOfPtrs; ++I) {
8000 llvm::ArrayType::get(CGM.
VoidPtrTy, Info.NumberOfPtrs),
8001 Info.BasePointersArray, 0, I);
8003 BP, BPVal->getType()->getPointerTo(0));
8007 if (Info.requiresDevicePointerInfo())
8008 if (
const ValueDecl *DevVD = BasePointers[I].getDevicePtrDecl())
8009 Info.CaptureDeviceAddrMap.try_emplace(DevVD, BPAddr);
8013 llvm::ArrayType::get(CGM.
VoidPtrTy, Info.NumberOfPtrs),
8014 Info.PointersArray, 0, I);
8016 P, PVal->getType()->getPointerTo(0));
8020 if (hasRuntimeEvaluationCaptureSize) {
8022 llvm::ArrayType::get(CGM.
SizeTy, Info.NumberOfPtrs),
8039 llvm::Value *&MapTypesArrayArg, CGOpenMPRuntime::TargetDataInfo &Info) {
8041 if (Info.NumberOfPtrs) {
8043 llvm::ArrayType::get(CGM.
VoidPtrTy, Info.NumberOfPtrs),
8044 Info.BasePointersArray,
8047 llvm::ArrayType::get(CGM.
VoidPtrTy, Info.NumberOfPtrs),
8052 llvm::ArrayType::get(CGM.
SizeTy, Info.NumberOfPtrs), Info.SizesArray,
8055 llvm::ArrayType::get(CGM.
Int64Ty, Info.NumberOfPtrs),
8060 BasePointersArrayArg = llvm::ConstantPointerNull::get(CGM.
VoidPtrPtrTy);
8061 PointersArrayArg = llvm::ConstantPointerNull::get(CGM.
VoidPtrPtrTy);
8062 SizesArrayArg = llvm::ConstantPointerNull::get(CGM.
SizeTy->getPointerTo());
8064 llvm::ConstantPointerNull::get(CGM.
Int64Ty->getPointerTo());
8081 if (
const auto *C = dyn_cast<CompoundStmt>(Body)) {
8082 const Stmt *Child =
nullptr;
8083 for (
const Stmt *S : C->body()) {
8084 if (
const auto *E = dyn_cast<Expr>(S)) {
8089 if (isa<AsmStmt>(S) || isa<NullStmt>(S) || isa<OMPFlushDirective>(S) ||
8090 isa<OMPBarrierDirective>(S) || isa<OMPTaskyieldDirective>(S))
8093 if (
const auto *DS = dyn_cast<DeclStmt>(S)) {
8094 if (llvm::all_of(DS->decls(), [&Ctx](
const Decl *D) {
8095 if (isa<EmptyDecl>(D) || isa<DeclContext>(D) ||
8096 isa<TypeDecl>(D) || isa<PragmaCommentDecl>(D) ||
8097 isa<PragmaDetectMismatchDecl>(D) || isa<UsingDecl>(D) ||
8098 isa<UsingDirectiveDecl>(D) ||
8099 isa<OMPDeclareReductionDecl>(D) ||
8100 isa<OMPThreadPrivateDecl>(D))
8102 const auto *VD = dyn_cast<
VarDecl>(D);
8131 if (
const auto *NestedDir = dyn_cast<OMPExecutableDirective>(ChildStmt)) {
8137 if (DKind == OMPD_teams) {
8138 Body = NestedDir->getInnermostCapturedStmt()->IgnoreContainers(
8143 if (
const auto *NND = dyn_cast<OMPExecutableDirective>(ChildStmt)) {
8144 DKind = NND->getDirectiveKind();
8150 case OMPD_target_teams:
8154 case OMPD_target_parallel:
8155 case OMPD_target_simd:
8156 case OMPD_target_parallel_for:
8157 case OMPD_target_parallel_for_simd:
8159 case OMPD_target_teams_distribute:
8160 case OMPD_target_teams_distribute_simd:
8161 case OMPD_target_teams_distribute_parallel_for:
8162 case OMPD_target_teams_distribute_parallel_for_simd:
8165 case OMPD_parallel_for:
8166 case OMPD_parallel_sections:
8168 case OMPD_parallel_for_simd:
8170 case OMPD_cancellation_point:
8172 case OMPD_threadprivate:
8180 case OMPD_taskyield:
8183 case OMPD_taskgroup:
8187 case OMPD_target_data:
8188 case OMPD_target_exit_data:
8189 case OMPD_target_enter_data:
8190 case OMPD_distribute:
8191 case OMPD_distribute_simd:
8192 case OMPD_distribute_parallel_for:
8193 case OMPD_distribute_parallel_for_simd:
8194 case OMPD_teams_distribute:
8195 case OMPD_teams_distribute_simd:
8196 case OMPD_teams_distribute_parallel_for:
8197 case OMPD_teams_distribute_parallel_for_simd:
8198 case OMPD_target_update:
8199 case OMPD_declare_simd:
8200 case OMPD_declare_target:
8201 case OMPD_end_declare_target:
8202 case OMPD_declare_reduction:
8204 case OMPD_taskloop_simd:
8207 llvm_unreachable(
"Unexpected directive.");
8225 const auto *LD = cast<OMPLoopDirective>(TD);
8226 auto &&CodeGen = [LD, &Device, &SizeEmitter,
this](
CodeGenFunction &CGF,
8228 llvm::Value *NumIterations = SizeEmitter(CGF, *LD);
8233 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
8236 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
8239 CGF.EmitRuntimeCall(
8249 const Expr *IfCond,
const Expr *Device) {
8253 assert(OutlinedFn &&
"Invalid outlined function!");
8260 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
8267 auto &&ThenGen = [
this, Device, OutlinedFn, OutlinedFnID, &D, &InputInfo,
8268 &MapTypesArray, &CS, RequiresOuterTask,
8280 assert(OutlinedFnID &&
"Invalid outlined function ID!");
8285 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
8288 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
8293 CGF.Builder.getInt32(InputInfo.NumberOfTargetItems);
8335 assert(NumThreads &&
"Thread limit expression should be available along " 8336 "with number of teams.");
8340 InputInfo.BasePointersArray.getPointer(),
8341 InputInfo.PointersArray.getPointer(),
8342 InputInfo.SizesArray.getPointer(),
8346 Return = CGF.EmitRuntimeCall(
8354 InputInfo.BasePointersArray.getPointer(),
8355 InputInfo.PointersArray.getPointer(),
8356 InputInfo.SizesArray.getPointer(),
8358 Return = CGF.EmitRuntimeCall(
8365 llvm::BasicBlock *OffloadFailedBlock =
8366 CGF.createBasicBlock(
"omp_offload.failed");
8367 llvm::BasicBlock *OffloadContBlock =
8368 CGF.createBasicBlock(
"omp_offload.cont");
8369 llvm::Value *Failed = CGF.Builder.CreateIsNotNull(Return);
8370 CGF.Builder.CreateCondBr(Failed, OffloadFailedBlock, OffloadContBlock);
8372 CGF.EmitBlock(OffloadFailedBlock);
8373 if (RequiresOuterTask) {
8374 CapturedVars.clear();
8375 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
8378 CGF.EmitBranch(OffloadContBlock);
8380 CGF.EmitBlock(OffloadContBlock,
true);
8384 auto &&ElseGen = [
this, &D, OutlinedFn, &CS, &CapturedVars,
8387 if (RequiresOuterTask) {
8388 CapturedVars.clear();
8389 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
8394 auto &&TargetThenGen = [
this, &ThenGen, &D, &InputInfo, &MapTypesArray,
8395 &CapturedVars, RequiresOuterTask,
8399 MappableExprsHandler::MapValuesArrayTy Pointers;
8400 MappableExprsHandler::MapValuesArrayTy Sizes;
8404 MappableExprsHandler MEHandler(D, CGF);
8405 llvm::DenseMap<llvm::Value *, llvm::Value *> LambdaPointers;
8407 auto RI = CS.getCapturedRecordDecl()->field_begin();
8408 auto CV = CapturedVars.begin();
8410 CE = CS.capture_end();
8411 CI != CE; ++CI, ++RI, ++CV) {
8413 MappableExprsHandler::MapValuesArrayTy CurPointers;
8414 MappableExprsHandler::MapValuesArrayTy CurSizes;
8416 MappableExprsHandler::StructRangeInfoTy PartialStruct;
8420 if (CI->capturesVariableArrayType()) {
8421 CurBasePointers.push_back(*CV);
8422 CurPointers.push_back(*CV);
8423 CurSizes.push_back(CGF.getTypeSize(RI->getType()));
8425 CurMapTypes.push_back(MappableExprsHandler::OMP_MAP_LITERAL |
8426 MappableExprsHandler::OMP_MAP_TARGET_PARAM);
8430 MEHandler.generateInfoForCapture(CI, *CV, CurBasePointers, CurPointers,
8431 CurSizes, CurMapTypes, PartialStruct);
8432 if (CurBasePointers.empty())
8433 MEHandler.generateDefaultMapInfo(*CI, **RI, *CV, CurBasePointers,
8434 CurPointers, CurSizes, CurMapTypes);
8437 if (CI->capturesVariable())
8438 MEHandler.generateInfoForLambdaCaptures(
8439 CI->getCapturedVar(), *CV, CurBasePointers, CurPointers, CurSizes,
8440 CurMapTypes, LambdaPointers);
8443 assert(!CurBasePointers.empty() &&
8444 "Non-existing map pointer for capture!");
8445 assert(CurBasePointers.size() == CurPointers.size() &&
8446 CurBasePointers.size() == CurSizes.size() &&
8447 CurBasePointers.size() == CurMapTypes.size() &&
8448 "Inconsistent map information sizes!");
8452 if (PartialStruct.Base.isValid())
8453 MEHandler.emitCombinedEntry(BasePointers, Pointers, Sizes, MapTypes,
8454 CurMapTypes, PartialStruct);
8457 BasePointers.append(CurBasePointers.begin(), CurBasePointers.end());
8458 Pointers.append(CurPointers.begin(), CurPointers.end());
8459 Sizes.append(CurSizes.begin(), CurSizes.end());
8460 MapTypes.append(CurMapTypes.begin(), CurMapTypes.end());
8463 MEHandler.adjustMemberOfForLambdaCaptures(LambdaPointers, BasePointers,
8464 Pointers, MapTypes);
8467 MEHandler.generateInfoForDeclareTargetLink(BasePointers, Pointers, Sizes,
8477 InputInfo.BasePointersArray =
8479 InputInfo.PointersArray =
8483 if (RequiresOuterTask)
8484 CGF.EmitOMPTargetTaskBasedDirective(D, ThenGen, InputInfo);
8489 auto &&TargetElseGen = [
this, &ElseGen, &D, RequiresOuterTask](
8491 if (RequiresOuterTask) {
8493 CGF.EmitOMPTargetTaskBasedDirective(D, ElseGen, InputInfo);
8517 StringRef ParentName) {
8522 bool RequiresDeviceCodegen =
8523 isa<OMPExecutableDirective>(S) &&
8525 cast<OMPExecutableDirective>(S)->getDirectiveKind());
8527 if (RequiresDeviceCodegen) {
8528 const auto &E = *cast<OMPExecutableDirective>(S);
8541 switch (E.getDirectiveKind()) {
8544 cast<OMPTargetDirective>(E));
8546 case OMPD_target_parallel:
8548 CGM, ParentName, cast<OMPTargetParallelDirective>(E));
8550 case OMPD_target_teams:
8552 CGM, ParentName, cast<OMPTargetTeamsDirective>(E));
8554 case OMPD_target_teams_distribute:
8556 CGM, ParentName, cast<OMPTargetTeamsDistributeDirective>(E));
8558 case OMPD_target_teams_distribute_simd:
8560 CGM, ParentName, cast<OMPTargetTeamsDistributeSimdDirective>(E));
8562 case OMPD_target_parallel_for:
8564 CGM, ParentName, cast<OMPTargetParallelForDirective>(E));
8566 case OMPD_target_parallel_for_simd:
8568 CGM, ParentName, cast<OMPTargetParallelForSimdDirective>(E));
8570 case OMPD_target_simd:
8572 CGM, ParentName, cast<OMPTargetSimdDirective>(E));
8574 case OMPD_target_teams_distribute_parallel_for:
8577 cast<OMPTargetTeamsDistributeParallelForDirective>(E));
8579 case OMPD_target_teams_distribute_parallel_for_simd:
8583 cast<OMPTargetTeamsDistributeParallelForSimdDirective>(E));
8587 case OMPD_parallel_for:
8588 case OMPD_parallel_sections:
8590 case OMPD_parallel_for_simd:
8592 case OMPD_cancellation_point:
8594 case OMPD_threadprivate:
8602 case OMPD_taskyield:
8605 case OMPD_taskgroup:
8609 case OMPD_target_data:
8610 case OMPD_target_exit_data:
8611 case OMPD_target_enter_data:
8612 case OMPD_distribute:
8613 case OMPD_distribute_simd:
8614 case OMPD_distribute_parallel_for:
8615 case OMPD_distribute_parallel_for_simd:
8616 case OMPD_teams_distribute:
8617 case OMPD_teams_distribute_simd:
8618 case OMPD_teams_distribute_parallel_for:
8619 case OMPD_teams_distribute_parallel_for_simd:
8620 case OMPD_target_update:
8621 case OMPD_declare_simd:
8622 case OMPD_declare_target:
8623 case OMPD_end_declare_target:
8624 case OMPD_declare_reduction:
8626 case OMPD_taskloop_simd:
8629 llvm_unreachable(
"Unknown target directive for OpenMP device codegen.");
8634 if (
const auto *E = dyn_cast<OMPExecutableDirective>(S)) {
8635 if (!E->hasAssociatedStmt() || !E->getAssociatedStmt())
8639 E->getInnermostCapturedStmt()->getCapturedStmt(), ParentName);
8644 if (
const auto *L = dyn_cast<LambdaExpr>(S))
8661 if (
const auto *FD = dyn_cast<FunctionDecl>(VD))
8665 return !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) &&
8679 StringRef ParentName =
8684 StringRef ParentName =
8692 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
8694 if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link) {
8702 llvm::Constant *Addr) {
8704 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
8718 llvm::GlobalValue::LinkageTypes
Linkage;
8720 case OMPDeclareTargetDeclAttr::MT_To:
8725 assert(!VarSize.
isZero() &&
"Expected non-zero size of the variable");
8732 std::string RefName =
getName({VarName,
"ref"});
8734 llvm::Constant *AddrRef =
8736 auto *GVAddrRef = cast<llvm::GlobalVariable>(AddrRef);
8737 GVAddrRef->setConstant(
true);
8739 GVAddrRef->setInitializer(Addr);
8744 case OMPDeclareTargetDeclAttr::MT_Link:
8747 VarName = Addr->getName();
8754 Linkage = llvm::GlobalValue::WeakAnyLinkage;
8758 VarName, Addr, VarSize, Flags, Linkage);
8762 if (isa<FunctionDecl>(GD.
getDecl()) ||
8763 isa<OMPDeclareReductionDecl>(GD.
getDecl()))
8772 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
8775 if (*Res == OMPDeclareTargetDeclAttr::MT_To) {
8778 assert(*Res == OMPDeclareTargetDeclAttr::MT_Link &&
8779 "Expected to or link clauses.");
8788 " Expected target-based directive.");
8810 const auto *D = cast<FunctionDecl>(GD.
getDecl());
8813 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(D)) {
8815 if (
auto *F = dyn_cast_or_null<llvm::Function>(CGM.
GetGlobalValue(Name)))
8816 return !F->isDeclaration();
8850 CGF.
Builder.getInt32(CapturedVars.size()),
8853 RealArgs.append(std::begin(Args), std::end(Args));
8854 RealArgs.append(CapturedVars.begin(), CapturedVars.end());
8861 const Expr *NumTeams,
8862 const Expr *ThreadLimit,
8901 auto &&BeginThenGen = [
this, &D, Device, &Info,
8905 MappableExprsHandler::MapValuesArrayTy Pointers;
8906 MappableExprsHandler::MapValuesArrayTy Sizes;
8910 MappableExprsHandler MCHandler(D, CGF);
8911 MCHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);
8921 SizesArrayArg, MapTypesArrayArg, Info);
8926 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
8929 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
8933 llvm::Value *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);
8936 DeviceID, PointerNum, BasePointersArrayArg,
8937 PointersArrayArg, SizesArrayArg, MapTypesArrayArg};
8943 if (!Info.CaptureDeviceAddrMap.empty())
8950 assert(Info.isValid() &&
"Invalid data environment closing arguments.");
8957 SizesArrayArg, MapTypesArrayArg, Info);
8962 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
8965 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
8969 llvm::Value *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);
8972 DeviceID, PointerNum, BasePointersArrayArg,
8973 PointersArrayArg, SizesArrayArg, MapTypesArrayArg};
8981 auto &&BeginElseGen = [&Info, &CodeGen, &NoPrivAction](
CodeGenFunction &CGF,
8983 if (!Info.CaptureDeviceAddrMap.empty()) {
8984 CodeGen.setAction(NoPrivAction);
9002 if (Info.CaptureDeviceAddrMap.empty()) {
9003 CodeGen.setAction(NoPrivAction);
9017 const Expr *Device) {
9021 assert((isa<OMPTargetEnterDataDirective>(D) ||
9022 isa<OMPTargetExitDataDirective>(D) ||
9023 isa<OMPTargetUpdateDirective>(D)) &&
9024 "Expecting either target enter, exit data, or update directives.");
9029 auto &&ThenGen = [
this, &D, Device, &InputInfo,
9034 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
9037 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
9041 llvm::Constant *PointerNum =
9042 CGF.Builder.getInt32(InputInfo.NumberOfTargetItems);
9046 InputInfo.BasePointersArray.getPointer(),
9047 InputInfo.PointersArray.getPointer(),
9048 InputInfo.SizesArray.getPointer(),
9056 case OMPD_target_enter_data:
9060 case OMPD_target_exit_data:
9064 case OMPD_target_update:
9070 case OMPD_parallel_for:
9071 case OMPD_parallel_sections:
9073 case OMPD_parallel_for_simd:
9075 case OMPD_cancellation_point:
9077 case OMPD_threadprivate:
9085 case OMPD_taskyield:
9088 case OMPD_taskgroup:
9092 case OMPD_target_data:
9093 case OMPD_distribute:
9094 case OMPD_distribute_simd:
9095 case OMPD_distribute_parallel_for:
9096 case OMPD_distribute_parallel_for_simd:
9097 case OMPD_teams_distribute:
9098 case OMPD_teams_distribute_simd:
9099 case OMPD_teams_distribute_parallel_for:
9100 case OMPD_teams_distribute_parallel_for_simd:
9101 case OMPD_declare_simd:
9102 case OMPD_declare_target:
9103 case OMPD_end_declare_target:
9104 case OMPD_declare_reduction:
9106 case OMPD_taskloop_simd:
9108 case OMPD_target_simd:
9109 case OMPD_target_teams_distribute:
9110 case OMPD_target_teams_distribute_simd:
9111 case OMPD_target_teams_distribute_parallel_for:
9112 case OMPD_target_teams_distribute_parallel_for_simd:
9113 case OMPD_target_teams:
9114 case OMPD_target_parallel:
9115 case OMPD_target_parallel_for:
9116 case OMPD_target_parallel_for_simd:
9119 llvm_unreachable(
"Unexpected standalone target data directive.");
9125 auto &&TargetThenGen = [
this, &ThenGen, &D, &InputInfo, &MapTypesArray](
9129 MappableExprsHandler::MapValuesArrayTy Pointers;
9130 MappableExprsHandler::MapValuesArrayTy Sizes;
9134 MappableExprsHandler MEHandler(D, CGF);
9135 MEHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);
9144 InputInfo.BasePointersArray =
9146 InputInfo.PointersArray =
9148 InputInfo.SizesArray =
9152 CGF.EmitOMPTargetTaskBasedDirective(D, ThenGen, InputInfo);
9170 struct ParamAttrTy {
9172 llvm::APSInt StrideOrArg;
9173 llvm::APSInt Alignment;
9178 ArrayRef<ParamAttrTy> ParamAttrs) {
9207 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
9208 if (ParamAttrs[Offset].Kind == Vector)
9213 for (
unsigned I = 0, E = FD->
getNumParams(); I < E; ++I) {
9214 if (ParamAttrs[I + Offset].Kind == Vector) {
9231 const llvm::APSInt &VLENVal,
9232 ArrayRef<ParamAttrTy> ParamAttrs,
9233 OMPDeclareSimdDeclAttr::BranchStateTy
State) {
9236 unsigned VecRegSize;
9238 ISADataTy ISAData[] = {
9254 case OMPDeclareSimdDeclAttr::BS_Undefined:
9255 Masked.push_back(
'N');
9256 Masked.push_back(
'M');
9258 case OMPDeclareSimdDeclAttr::BS_Notinbranch:
9259 Masked.push_back(
'N');
9261 case OMPDeclareSimdDeclAttr::BS_Inbranch:
9262 Masked.push_back(
'M');
9265 for (
char Mask : Masked) {
9266 for (
const ISADataTy &Data : ISAData) {
9268 llvm::raw_svector_ostream Out(Buffer);
9269 Out <<
"_ZGV" << Data.ISA << Mask;
9271 Out << llvm::APSInt::getUnsigned(Data.VecRegSize /
9276 for (
const ParamAttrTy &ParamAttr : ParamAttrs) {
9277 switch (ParamAttr.Kind){
9278 case LinearWithVarStride:
9279 Out <<
's' << ParamAttr.StrideOrArg;
9283 if (!!ParamAttr.StrideOrArg)
9284 Out << ParamAttr.StrideOrArg;
9293 if (!!ParamAttr.Alignment)
9294 Out <<
'a' << ParamAttr.Alignment;
9296 Out <<
'_' << Fn->getName();
9297 Fn->addFnAttr(Out.str());
9303 llvm::Function *Fn) {
9307 llvm::DenseMap<const Decl *, unsigned> ParamPositions;
9308 if (isa<CXXMethodDecl>(FD))
9309 ParamPositions.try_emplace(FD, 0);
9310 unsigned ParamPos = ParamPositions.size();
9312 ParamPositions.try_emplace(
P->getCanonicalDecl(), ParamPos);
9319 for (
const Expr *E :
Attr->uniforms()) {
9322 if (isa<CXXThisExpr>(E)) {
9323 Pos = ParamPositions[FD];
9325 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
9327 Pos = ParamPositions[PVD];
9329 ParamAttrs[Pos].Kind = Uniform;
9332 auto NI =
Attr->alignments_begin();
9333 for (
const Expr *E :
Attr->aligneds()) {
9337 if (isa<CXXThisExpr>(E)) {
9338 Pos = ParamPositions[FD];
9341 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
9343 Pos = ParamPositions[PVD];
9344 ParmTy = PVD->getType();
9346 ParamAttrs[Pos].Alignment =
9348 ? (*NI)->EvaluateKnownConstInt(C)
9349 : llvm::APSInt::getUnsigned(
9355 auto SI =
Attr->steps_begin();
9356 auto MI =
Attr->modifiers_begin();
9357 for (
const Expr *E :
Attr->linears()) {
9360 if (isa<CXXThisExpr>(E)) {
9361 Pos = ParamPositions[FD];
9363 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
9365 Pos = ParamPositions[PVD];
9367 ParamAttrTy &ParamAttr = ParamAttrs[Pos];
9368 ParamAttr.Kind = Linear;
9372 if (
const auto *DRE =
9373 cast<DeclRefExpr>((*SI)->IgnoreParenImpCasts())) {
9374 if (
const auto *StridePVD = cast<ParmVarDecl>(DRE->getDecl())) {
9375 ParamAttr.Kind = LinearWithVarStride;
9376 ParamAttr.StrideOrArg = llvm::APSInt::getUnsigned(
9377 ParamPositions[StridePVD->getCanonicalDecl()]);
9381 ParamAttr.StrideOrArg = Result.
Val.
getInt();
9387 llvm::APSInt VLENVal;
9388 if (
const Expr *VLEN =
Attr->getSimdlen())
9389 VLENVal = VLEN->EvaluateKnownConstInt(C);
9390 OMPDeclareSimdDeclAttr::BranchStateTy
State =
Attr->getBranchState();
9391 if (CGM.
getTriple().getArch() == llvm::Triple::x86 ||
9392 CGM.
getTriple().getArch() == llvm::Triple::x86_64)
9403 static const int DoacrossFinArgs = 2;
9412 assert(CallArgs.size() == DoacrossFinArgs);
9413 std::copy(CallArgs.begin(), CallArgs.end(), std::begin(Args));
9448 llvm::APInt Size(32, NumIterations.size());
9454 enum { LowerFD = 0, UpperFD, StrideFD };
9456 for (
unsigned I = 0, E = NumIterations.size(); I < E; ++I) {
9463 DimsLVal, *std::next(RD->
field_begin(), UpperFD));
9471 DimsLVal, *std::next(RD->
field_begin(), StrideFD));
9481 llvm::ConstantInt::getSigned(CGM.
Int32Ty, NumIterations.size()),
9490 llvm::Value *FiniArgs[DoacrossCleanupTy::DoacrossFinArgs] = {
9494 llvm::makeArrayRef(FiniArgs));
9505 for (
unsigned I = 0, E = C->
getNumLoops(); I < E; ++I) {
9537 assert(Loc.
isValid() &&
"Outlined function call location must be valid.");
9540 if (
auto *Fn = dyn_cast<llvm::Function>(Callee)) {
9541 if (Fn->doesNotThrow()) {
9552 emitCall(CGF, Loc, OutlinedFn, Args);
9557 const VarDecl *TargetParam)
const {
9569 llvm_unreachable(
"Not supported in SIMD-only mode");
9575 llvm_unreachable(
"Not supported in SIMD-only mode");
9582 bool Tied,
unsigned &NumberOfParts) {
9583 llvm_unreachable(
"Not supported in SIMD-only mode");
9590 const Expr *IfCond) {
9591 llvm_unreachable(
"Not supported in SIMD-only mode");
9598 llvm_unreachable(
"Not supported in SIMD-only mode");
9604 llvm_unreachable(
"Not supported in SIMD-only mode");
9609 llvm_unreachable(
"Not supported in SIMD-only mode");
9615 llvm_unreachable(
"Not supported in SIMD-only mode");
9623 llvm_unreachable(
"Not supported in SIMD-only mode");
9630 llvm_unreachable(
"Not supported in SIMD-only mode");
9637 bool ForceSimpleCall) {
9638 llvm_unreachable(
"Not supported in SIMD-only mode");
9645 llvm_unreachable(
"Not supported in SIMD-only mode");
9651 llvm_unreachable(
"Not supported in SIMD-only mode");
9657 llvm_unreachable(
"Not supported in SIMD-only mode");
9664 llvm_unreachable(
"Not supported in SIMD-only mode");
9670 llvm_unreachable(
"Not supported in SIMD-only mode");
9675 unsigned IVSize,
bool IVSigned,
9678 llvm_unreachable(
"Not supported in SIMD-only mode");
9684 llvm_unreachable(
"Not supported in SIMD-only mode");
9690 llvm_unreachable(
"Not supported in SIMD-only mode");
9697 llvm_unreachable(
"Not supported in SIMD-only mode");
9703 llvm_unreachable(
"Not supported in SIMD-only mode");
9708 llvm_unreachable(
"Not supported in SIMD-only mode");
9714 llvm_unreachable(
"Not supported in SIMD-only mode");
9723 llvm_unreachable(
"Not supported in SIMD-only mode");
9730 llvm_unreachable(
"Not supported in SIMD-only mode");
9737 assert(Options.
SimpleReduction &&
"Only simple reduction is expected.");
9739 ReductionOps, Options);
9745 llvm_unreachable(
"Not supported in SIMD-only mode");
9752 llvm_unreachable(
"Not supported in SIMD-only mode");
9759 llvm_unreachable(
"Not supported in SIMD-only mode");
9764 llvm_unreachable(
"Not supported in SIMD-only mode");
9770 llvm_unreachable(
"Not supported in SIMD-only mode");
9776 llvm_unreachable(
"Not supported in SIMD-only mode");
9781 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
9783 llvm_unreachable(
"Not supported in SIMD-only mode");
9790 const Expr *IfCond,
const Expr *Device) {
9791 llvm_unreachable(
"Not supported in SIMD-only mode");
9795 llvm_unreachable(
"Not supported in SIMD-only mode");
9799 llvm_unreachable(
"Not supported in SIMD-only mode");
9815 llvm_unreachable(
"Not supported in SIMD-only mode");
9819 const Expr *NumTeams,
9820 const Expr *ThreadLimit,
9822 llvm_unreachable(
"Not supported in SIMD-only mode");
9828 llvm_unreachable(
"Not supported in SIMD-only mode");
9833 const Expr *Device) {
9834 llvm_unreachable(
"Not supported in SIMD-only mode");
9840 llvm_unreachable(
"Not supported in SIMD-only mode");
9845 llvm_unreachable(
"Not supported in SIMD-only mode");
9850 const VarDecl *NativeParam)
const {
9851 llvm_unreachable(
"Not supported in SIMD-only mode");
9857 const VarDecl *TargetParam)
const {
9858 llvm_unreachable(
"Not supported in SIMD-only mode");
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
llvm::PointerType * Int8PtrPtrTy
RecordDecl * buildImplicitRecord(StringRef Name, RecordDecl::TagKind TK=TTK_Struct) const
Create a new implicit TU-level CXXRecordDecl or RecordDecl declaration.
TBAAAccessInfo getTBAAInfoForSubobject(LValue Base, QualType AccessType)
getTBAAInfoForSubobject - Get TBAA information for an access with a given base lvalue.
void pushTerminate()
Push a terminate handler on the stack.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, llvm::Type *BaseLVType, CharUnits BaseLVAlignment, llvm::Value *Addr)
virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S)
Emit the captured statement body.
DisableAutoDeclareTargetRAII(CodeGenModule &CGM)
static llvm::Value * emitParallelOrTeamsOutlinedFunction(CodeGenModule &CGM, const OMPExecutableDirective &D, const CapturedStmt *CS, const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind, const StringRef OutlinedHelperName, const RegionCodeGenTy &CodeGen)
This represents '#pragma omp task' directive.
static const Decl * getCanonicalDecl(const Decl *D)
Represents a function declaration or definition.
llvm::IntegerType * IntTy
int
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
External linkage, which indicates that the entity can be referred to from other translation units...
virtual Address getAddressOfLocalVariable(CodeGenFunction &CGF, const VarDecl *VD)
Gets the OpenMP-specific address of the local variable.
Expr * getUpperBoundVariable() const
Other implicit parameter.
QualType TgtDeviceImageQTy
struct __tgt_device_image{ void *ImageStart; // Pointer to the target code start. ...
unsigned getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it...
PointerType - C99 6.7.5.1 - Pointer Declarators.
Scheduling data for loop-based OpenMP directives.
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
A (possibly-)qualified type.
CodeGenTypes & getTypes()
llvm::Type * ConvertTypeForMem(QualType T)
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
const CodeGenOptions & getCodeGenOpts() const
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param IfCond Not a nullptr if if clause was nullptr *otherwise *param Data Additional data for task generation like final list of privates etc *void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D, llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds, const Expr *IfCond, const OMPTaskDataTy &Data) override
Address CreateMemTemp(QualType T, const Twine &Name="tmp", Address *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
const RecordDecl * KmpTaskTQTyRD
static void EmitOMPTargetParallelForSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelForSimdDirective &S)
Emit device code for the target parallel for simd directive.
void emitSingleReductionCombiner(CodeGenFunction &CGF, const Expr *ReductionOp, const Expr *PrivateRef, const DeclRefExpr *LHS, const DeclRefExpr *RHS)
Emits single reduction combiner.
Address CreateConstGEP(Address Addr, uint64_t Index, CharUnits EltSize, const llvm::Twine &Name="")
Given addr = T* ...
void actOnDeviceGlobalVarEntriesInfo(const OffloadDeviceGlobalVarEntryInfoActTy &Action)
The standard implementation of ConstantInitBuilder used in Clang.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
Stmt - This represents one statement.
Expr * getLowerBoundVariable() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
virtual void emitUserDefinedReduction(CodeGenFunction *CGF, const OMPDeclareReductionDecl *D)
Emit code for the specified user defined reduction construct.
Expr * getLoopData(unsigned NumLoop)
Get the loop data.
bool capturesThis() const
Determine whether this capture handles the C++ 'this' pointer.
VarDecl * getCapturedVar() const
Retrieve the declaration of the variable being captured.
bool emitTargetGlobal(GlobalDecl GD) override
Emit the global GD if it is meaningful for the target.
CharUnits getAlignOfGlobalVarInChars(QualType T) const
Return the alignment in characters that should be given to a global variable with type T...
QualType getTgtBinaryDescriptorQTy()
Returns __tgt_bin_desc type.
bool hasNonTrivialCall(const ASTContext &Ctx) const
Determine whether this expression involves a call to any function that is not trivial.
SmallVector< std::pair< OpenMPDependClauseKind, const Expr * >, 4 > Dependences
CGOpenMPRuntime(CodeGenModule &CGM, StringRef FirstSeparator, StringRef Separator)
Constructor allowing to redefine the name separator for the variables.
bool isRecordType() const
void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc, const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned, bool Ordered, const DispatchRTInput &DispatchValues) override
This is used for non static scheduled types and when the ordered clause is present on the loop constr...
void clearLocThreadIdInsertPt(CodeGenFunction &CGF)
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
Decl - This represents one declaration (or definition), e.g.
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
SourceLocation getBeginLoc() const
Returns starting location of directive kind.
Entry is a target region.
CharUnits getPointerSize() const
llvm::Constant * getOrCreateInternalVariable(llvm::Type *Ty, const llvm::Twine &Name)
Gets (if variable with the given name already exist) or creates internal global variable with the spe...
virtual llvm::Value * emitTaskReductionInit(CodeGenFunction &CGF, SourceLocation Loc, ArrayRef< const Expr *> LHSExprs, ArrayRef< const Expr *> RHSExprs, const OMPTaskDataTy &Data)
Emit a code for initialization of task reduction clause.
const RecordType * getAsStructureType() const
llvm::SmallDenseSet< const VarDecl * > DeferredGlobalVariables
List of variables that can become declare target implicitly and, thus, must be emitted.
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.
CapturedStmt * getInnermostCapturedStmt()
Get innermost captured statement for the construct.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
Call to void __kmpc_threadprivate_register( ident_t *, void *data, kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
ReductionCodeGen(ArrayRef< const Expr *> Shareds, ArrayRef< const Expr *> Privates, ArrayRef< const Expr *> ReductionOps)
static RecordDecl * createPrivatesRecordDecl(CodeGenModule &CGM, ArrayRef< PrivateDataTy > Privates)
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target data offload directive.
The base class of the type hierarchy.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
void emitReduction(CodeGenFunction &CGF, SourceLocation Loc, ArrayRef< const Expr *> Privates, ArrayRef< const Expr *> LHSExprs, ArrayRef< const Expr *> RHSExprs, ArrayRef< const Expr *> ReductionOps, ReductionOptionsTy Options) override
Emit a code for reduction clause.
void emitTargetDataStandAloneCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond, const Expr *Device) override
Emit the data mapping/movement code associated with the directive D that should be of the form 'targe...
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
virtual const FieldDecl * lookup(const VarDecl *VD) const
Lookup the captured field decl for a variable.
llvm::Value * PointersArray
The array of section pointers passed to the runtime library.
virtual void completeDefinition()
Note that the definition of this type is now complete.
bool isZero() const
isZero - Test whether the quantity equals zero.
QualType withConst() const
bool markAsGlobalTarget(GlobalDecl GD)
Marks the declaration as already emitted for the device code and returns true, if it was marked alrea...
const TargetInfo & getTargetInfo() const
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
capture_const_range captures() const
Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)
EmitLValueForFieldInitialization - Like EmitLValueForField, except that if the Field is a reference...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to...
Describes the capture of a variable or of this, or of a C++1y init-capture.
void scanForTargetRegionsFunctions(const Stmt *S, StringRef ParentName)
Start scanning from statement S and and emit all target regions found along the way.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Represents a C++ constructor within a class.
static void EmitOMPAggregateReduction(CodeGenFunction &CGF, QualType Type, const VarDecl *LHSVar, const VarDecl *RHSVar, const llvm::function_ref< void(CodeGenFunction &CGF, const Expr *, const Expr *, const Expr *)> &RedOpGen, const Expr *XExpr=nullptr, const Expr *EExpr=nullptr, const Expr *UpExpr=nullptr)
Emit reduction operation for each element of array (required for array sections) LHS op = RHS...
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...
bool isTrivialType(const ASTContext &Context) const
Return true if this is a trivial type per (C++0x [basic.types]p9)
SmallVector< const Expr *, 4 > ReductionCopies
SourceLocation getEndLoc() const
Returns ending location of directive.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
llvm::Function * GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S)
Represents a variable declaration or definition.
Objects with "hidden" visibility are not seen by the dynamic linker.
llvm::Value * getThreadID(CodeGenFunction &CGF, SourceLocation Loc)
Gets thread id value for the current thread.
QualType getReturnType() const
This represents 'num_threads' clause in the '#pragma omp ...' directive.
virtual void emitOutlinedFunctionCall(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn, ArrayRef< llvm::Value *> Args=llvm::None) const
Emits call of the outlined function with the provided arguments, translating these arguments to corre...
const T * getAs() const
Member-template getAs<specific type>'.
Extra information about a function prototype.
bool supportsCOMDAT() const
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
virtual llvm::Value * emitForNext(CodeGenFunction &CGF, SourceLocation Loc, unsigned IVSize, bool IVSigned, Address IL, Address LB, Address UB, Address ST)
Call __kmpc_dispatch_next( ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter, kmp_int[32|64] *p_lowe...
DiagnosticsEngine & getDiags() const
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
llvm::Value * getPointer() const
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
static llvm::GlobalVariable * createGlobalStruct(CodeGenModule &CGM, QualType Ty, bool IsConstant, ArrayRef< llvm::Constant *> Data, const Twine &Name, As &&... Args)
Represents a parameter to a function.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
static std::string generateUniqueName(CodeGenModule &CGM, StringRef Prefix, const Expr *Ref)
Generates unique name for artificial threadprivate variables.
void createOffloadEntriesAndInfoMetadata()
Creates all the offload entries in the current compilation unit along with the associated metadata...
static unsigned evaluateCDTSize(const FunctionDecl *FD, ArrayRef< ParamAttrTy > ParamAttrs)
std::string getName(ArrayRef< StringRef > Parts) const
Get the platform-specific name separator.
static void EmitOMPTargetParallelDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelDirective &S)
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
Struct that keeps all the relevant information that should be kept throughout a 'target data' region...
QualType getTgtOffloadEntryQTy()
Returns __tgt_offload_entry type.
virtual void emitTargetDataStandAloneCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond, const Expr *Device)
Emit the data mapping/movement code associated with the directive D that should be of the form 'targe...
SmallVector< const Expr *, 4 > PrivateVars
Represents a struct/union/class.
llvm::DenseMap< const VarDecl *, FieldDecl * > LambdaCaptureFields
Source[4] in Fortran, do not use for C++.
llvm::StringMap< llvm::WeakTrackingVH > EmittedNonTargetVariables
List of the global variables with their addresses that should not be emitted for the target...
static llvm::Value * emitDestructorsFunction(CodeGenModule &CGM, SourceLocation Loc, QualType KmpInt32Ty, QualType KmpTaskTWithPrivatesPtrQTy, QualType KmpTaskTWithPrivatesQTy)
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
emitDestroy - Immediately perform the destruction of the given object.
static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, LValue BaseLV)
Address getAddress() const
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
virtual void emitMasterRegion(CodeGenFunction &CGF, const RegionCodeGenTy &MasterOpGen, SourceLocation Loc)
Emits a master region.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
virtual void emitForOrderedIterationEnd(CodeGenFunction &CGF, SourceLocation Loc, unsigned IVSize, bool IVSigned)
Call the appropriate runtime routine to notify that we finished iteration of the ordered loop with th...
void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
EmitExprAsInit - Emits the code necessary to initialize a location in memory with the given initializ...
Call to void *__kmpc_threadprivate_cached(ident_t *loc, kmp_int32 global_tid, void *data...
llvm::IntegerType * Int64Ty
The scope used to remap some variables as private in the OpenMP loop body (or other captured region e...
field_range fields() const
SmallVector< const Expr *, 4 > LastprivateVars
SourceLocation getBeginLoc() const LLVM_READONLY
virtual void emitDoacrossOrdered(CodeGenFunction &CGF, const OMPDependClause *C)
Emit code for doacross ordered directive with 'depend' clause.
Represents a member of a struct/union/class.
CharUnits getAlignment() const
llvm::IntegerType * SizeTy
const CapturedStmt * getCapturedStmt(OpenMPDirectiveKind RegionKind) const
Returns the captured statement associated with the component region within the (combined) directive...
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
void setLocThreadIdInsertPt(CodeGenFunction &CGF, bool AtCurrentPoint=false)
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)
unsigned getNonVirtualBaseLLVMFieldNo(const CXXRecordDecl *RD) const
static void emitOffloadingArrays(CodeGenFunction &CGF, MappableExprsHandler::MapBaseValuesArrayTy &BasePointers, MappableExprsHandler::MapValuesArrayTy &Pointers, MappableExprsHandler::MapValuesArrayTy &Sizes, MappableExprsHandler::MapFlagsArrayTy &MapTypes, CGOpenMPRuntime::TargetDataInfo &Info)
Emit the arrays used to pass the captures and map information to the offloading runtime library...
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
void startDefinition()
Starts the definition of this tag declaration.
bool isReferenceType() const
This represents clause 'map' in the '#pragma omp ...' directives.
InitKind getInitializerKind() const
Get initializer kind.
void EmitOMPAggregateAssign(Address DestAddr, Address SrcAddr, QualType OriginalType, const llvm::function_ref< void(Address, Address)> CopyGen)
Perform element by element copying of arrays with type OriginalType from SrcAddr to DestAddr using co...
OMPTargetGlobalVarEntryKind
Kind of the global variable entry..
virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const
Check if the specified ScheduleKind is dynamic.
static Address emitAddrOfVarFromArray(CodeGenFunction &CGF, Address Array, unsigned Index, const VarDecl *Var)
Given an array of pointers to variables, project the address of a given variable. ...
This represents clause 'to' in the '#pragma omp ...' directives.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
clang::CharUnits operator*(clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU)
llvm::Type * getKmpc_MicroPointerTy()
Returns pointer to kmpc_micro type.
OpenMPDirectiveKind getDirectiveKind() const
SourceLocation getBeginLoc() const LLVM_READONLY
This is a common base class for loop directives ('omp simd', 'omp for', 'omp for simd' etc...
void emitNumThreadsClause(CodeGenFunction &CGF, llvm::Value *NumThreads, SourceLocation Loc) override
Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid, kmp_int32 num_threads)...
virtual bool emitTargetFunctions(GlobalDecl GD)
Emit the target regions enclosed in GD function definition or the function itself in case it is a val...
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const
Return the store size, in character units, of the given LLVM type.
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
ArrayRef< ParmVarDecl * > parameters() const
Mark the entry as a to declare target.
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
void emitProcBindClause(CodeGenFunction &CGF, OpenMPProcBindClauseKind ProcBind, SourceLocation Loc) override
Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid, int proc_bind) to generat...
virtual void emitDoacrossInit(CodeGenFunction &CGF, const OMPLoopDirective &D, ArrayRef< Expr *> NumIterations)
Emit initialization for doacross loop nesting support.
virtual void emitTargetCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, llvm::Value *OutlinedFn, llvm::Value *OutlinedFnID, const Expr *IfCond, const Expr *Device)
Emit the target offloading code associated with D.
Expr * getInitializer()
Get initializer expression (if specified) of the declare reduction construct.
QualType TgtOffloadEntryQTy
Type struct __tgt_offload_entry{ void *addr; // Pointer to the offload entry info.
static void buildStructValue(ConstantStructBuilder &Fields, CodeGenModule &CGM, const RecordDecl *RD, const CGRecordLayout &RL, ArrayRef< llvm::Constant *> Data)
static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr, QualType Type, bool EmitDeclareReductionInit, const Expr *Init, const OMPDeclareReductionDecl *DRD, Address SrcAddr=Address::invalid())
Emit initialization of arrays of complex types.
llvm::Function * emitRegistrationFunction() override
Creates the offloading descriptor in the event any target region was emitted in the current module an...
OpenMPScheduleClauseKind Schedule
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
CharUnits - This is an opaque type for sizes expressed in character units.
void emitForOrderedIterationEnd(CodeGenFunction &CGF, SourceLocation Loc, unsigned IVSize, bool IVSigned) override
Call the appropriate runtime routine to notify that we finished iteration of the ordered loop with th...
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
APValue Val
Val - This is the value the expression can be folded to.
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::StringSet ThreadPrivateWithDefinition
Set of threadprivate variables with the generated initializer.
llvm::PointerType * VoidPtrTy
bool empty() const
Return true if a there are no entries defined.
String describing the source location.
void emitMasterRegion(CodeGenFunction &CGF, const RegionCodeGenTy &MasterOpGen, SourceLocation Loc) override
Emits a master region.
virtual std::pair< llvm::Function *, llvm::Function * > getUserDefinedReduction(const OMPDeclareReductionDecl *D)
Get combiner/initializer for the specified user-defined reduction, if any.
void actOnTargetRegionEntriesInfo(const OffloadTargetRegionEntryInfoActTy &Action)
OpenMPScheduleClauseModifier M2
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind...
void emitTargetCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, llvm::Value *OutlinedFn, llvm::Value *OutlinedFnID, const Expr *IfCond, const Expr *Device) override
Emit the target offloading code associated with D.
SmallVector< const Expr *, 4 > PrivateCopies
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
llvm::StructType * getBaseSubobjectLLVMType() const
Return the "base subobject" LLVM type associated with this record.
unsigned NumberOfPtrs
The total number of pointers passed to the runtime library.
void operator()(CodeGenFunction &CGF) const
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
bool isLambda() const
Determine whether this class describes a lambda function object.
llvm::StringSet AlreadyEmittedTargetFunctions
List of the emitted functions.
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.
ArrayRef< MappableComponent > MappableExprComponentListRef
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
SmallVector< const Expr *, 4 > FirstprivateCopies
OpenMPDependClauseKind getDependencyKind() const
Get dependency type.
static void emitPrivatesInit(CodeGenFunction &CGF, const OMPExecutableDirective &D, Address KmpTaskSharedsPtr, LValue TDBase, const RecordDecl *KmpTaskTWithPrivatesQTyRD, QualType SharedsTy, QualType SharedsPtrTy, const OMPTaskDataTy &Data, ArrayRef< PrivateDataTy > Privates, bool ForDup)
Emit initialization for private variables in task-based directives.
static int addMonoNonMonoModifier(OpenMPSchedType Schedule, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2)
llvm::Value * emitReductionFunction(CodeGenModule &CGM, SourceLocation Loc, llvm::Type *ArgsType, ArrayRef< const Expr *> Privates, ArrayRef< const Expr *> LHSExprs, ArrayRef< const Expr *> RHSExprs, ArrayRef< const Expr *> ReductionOps)
Emits reduction function.
DiagnosticsEngine & getDiagnostics() const
static llvm::Function * emitCombinerOrInitializer(CodeGenModule &CGM, QualType Ty, const Expr *CombinerInitializer, const VarDecl *In, const VarDecl *Out, bool IsCombiner)
static void emitOffloadingArraysArgument(CodeGenFunction &CGF, llvm::Value *&BasePointersArrayArg, llvm::Value *&PointersArrayArg, llvm::Value *&SizesArrayArg, llvm::Value *&MapTypesArrayArg, CGOpenMPRuntime::TargetDataInfo &Info)
Emit the arguments to be passed to the runtime library based on the arrays of pointers, sizes and map types.
Support for OpenMP 4.5 monotonic and nonmonotonic schedule modifiers.
static const OMPDeclareReductionDecl * getReductionInit(const Expr *ReductionOp)
Check if the combiner is a call to UDR combiner and if it is so return the UDR decl used for reductio...
llvm::Value * emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc, unsigned Flags=0)
Emits object of ident_t type with info for source location.
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
virtual llvm::Value * emitTeamsOutlinedFunction(const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)
Emits outlined function for the specified OpenMP teams directive D.
CharUnits getPointerAlign() const
SmallVector< const Expr *, 4 > ReductionOps
This represents clause 'is_device_ptr' in the '#pragma omp ...' directives.
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.
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].
static CharUnits One()
One - Construct a CharUnits quantity of one.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
ASTContext & getContext() const
void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName, const RegionCodeGenTy &CriticalOpGen, SourceLocation Loc, const Expr *Hint=nullptr) override
Emits a critical region.
virtual Address getAddrOfDeclareTargetLink(const VarDecl *VD)
Returns the address of the variable marked as declare target with link clause.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
Describes the capture of either a variable, or 'this', or variable-length array type.
const CodeGen::CGBlockInfo * BlockInfo
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
virtual Address getParameterAddress(CodeGenFunction &CGF, const VarDecl *NativeParam, const VarDecl *TargetParam) const
Gets the address of the native argument basing on the address of the target-specific parameter...
llvm::Constant * createForStaticInitFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_for_static_init_* runtime function for the specified size IVSize and sign IVSigned...
CGBlockInfo - Information to generate a block literal.
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
OMP_IDENT_xxx flags; OMP_IDENT_KMPC identifies this union member.
LValueBaseInfo getBaseInfo() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
bool needCleanups(unsigned N)
Returns true if the private copy requires cleanups.
Class intended to support codegen of all kind of the reduction clauses.
llvm::Constant * createDispatchFiniFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_dispatch_fini_* runtime function for the specified size IVSize and sign IVSigned...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
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.
virtual bool isStaticChunked(OpenMPScheduleClauseKind ScheduleKind, bool Chunked) const
Check if the specified ScheduleKind is static chunked.
unsigned getNumLoops() const
Get number of loops associated with the clause.
virtual void createOffloadEntry(llvm::Constant *ID, llvm::Constant *Addr, uint64_t Size, int32_t Flags, llvm::GlobalValue::LinkageTypes Linkage)
Creates offloading entry for the provided entry ID ID, address Addr, size Size, and flags Flags...
llvm::CallingConv::ID getRuntimeCC() const
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
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.
void emitDeferredTargetDecls() const
Emit deferred declare target variables marked for deferred emission.
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
virtual void emitTaskReductionFixups(CodeGenFunction &CGF, SourceLocation Loc, ReductionCodeGen &RCG, unsigned N)
Required to resolve existing problems in the runtime.
virtual void emitFlush(CodeGenFunction &CGF, ArrayRef< const Expr *> Vars, SourceLocation Loc)
Emit flush of the variables specified in 'omp flush' directive.
static void createConstantGlobalStructAndAddToParent(CodeGenModule &CGM, QualType Ty, ArrayRef< llvm::Constant *> Data, T &Parent)
bool addPrivate(const VarDecl *LocalVD, const llvm::function_ref< Address()> PrivateGen)
Registers LocalVD variable as a private and apply PrivateGen function for it to generate correspondin...
void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc) override
Emit code for 'taskwait' directive.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
Allow any unmodeled side effect.
virtual llvm::Value * emitParallelOutlinedFunction(const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)
Emits outlined function for the specified OpenMP parallel directive D.
void loadOffloadInfoMetadata()
Loads all the offload entries information from the host IR metadata.
static void emitInitWithReductionInitializer(CodeGenFunction &CGF, const OMPDeclareReductionDecl *DRD, const Expr *InitOp, Address Private, Address Original, QualType Ty)
static llvm::Value * emitReduceCombFunction(CodeGenModule &CGM, SourceLocation Loc, ReductionCodeGen &RCG, unsigned N, const Expr *ReductionOp, const Expr *LHS, const Expr *RHS, const Expr *PrivateRef)
Emits reduction combiner function:
const AnnotatedLine * Line
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
Stmt * IgnoreContainers(bool IgnoreCaptured=false)
Skip no-op (attributed, compound) container stmts and skip captured stmt at the top, if IgnoreCaptured is true.
static llvm::Value * emitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc, OpenMPDirectiveKind Kind, QualType KmpInt32Ty, QualType KmpTaskTWithPrivatesPtrQTy, QualType KmpTaskTWithPrivatesQTy, QualType KmpTaskTQTy, QualType SharedsPtrTy, llvm::Value *TaskFunction, llvm::Value *TaskPrivatesMap)
Emit a proxy function which accepts kmp_task_t as the second argument.
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
std::string OMPHostIRFile
Name of the IR file that contains the result of the OpenMP target host code generation.
void emitKmpRoutineEntryT(QualType KmpInt32Ty)
Build type kmp_routine_entry_t (if not built yet).
const T * castAs() const
Member-template castAs<specific type>.
llvm::BasicBlock * getBlock() const
unsigned getLine() const
Return the presumed line number of this location.
llvm::Value * emitForNext(CodeGenFunction &CGF, SourceLocation Loc, unsigned IVSize, bool IVSigned, Address IL, Address LB, Address UB, Address ST) override
Call __kmpc_dispatch_next( ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter, kmp_int[32|64] *p_lowe...
static bool checkDestructorsRequired(const RecordDecl *KmpTaskTWithPrivatesQTyRD)
Checks if destructor function is required to be generated.
void emitSingleRegion(CodeGenFunction &CGF, const RegionCodeGenTy &SingleOpGen, SourceLocation Loc, ArrayRef< const Expr *> CopyprivateVars, ArrayRef< const Expr *> DestExprs, ArrayRef< const Expr *> SrcExprs, ArrayRef< const Expr *> AssignmentOps) override
Emits a single region.
Represents a C++ destructor within a class.
static RTCancelKind getCancellationKind(OpenMPDirectiveKind CancelRegion)
QualType SavedKmpTaskloopTQTy
Saved kmp_task_t for taskloop-based directive.
static RecordDecl * createKmpTaskTRecordDecl(CodeGenModule &CGM, OpenMPDirectiveKind Kind, QualType KmpInt32Ty, QualType KmpRoutineEntryPointerQTy)
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements, of a variable length array type, plus that largest non-variably-sized element type.
field_iterator field_end() const
llvm::PointerType * getType() const
Return the type of the pointer value.
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
Address getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF, QualType VarType, StringRef Name) override
Creates artificial threadprivate variable with name Name and type VarType.
DeclContext * getDeclContext()
static llvm::iterator_range< specific_clause_iterator< SpecificClause > > getClausesOfKind(ArrayRef< OMPClause *> Clauses)
Mark the entry as a to declare target link.
void emitFlush(CodeGenFunction &CGF, ArrayRef< const Expr *> Vars, SourceLocation Loc) override
Emit flush of the variables specified in 'omp flush' directive.
virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, llvm::Constant *Dtor, llvm::Constant *Addr)=0
Emit code to force the execution of a destructor during global teardown.
static OpenMPSchedType getRuntimeSchedule(OpenMPScheduleClauseKind ScheduleKind, bool Chunked, bool Ordered)
Map the OpenMP loop schedule to the runtime enumeration.
llvm::IntegerType * Int32Ty
llvm::GlobalValue::LinkageTypes getLLVMLinkageVarDefinition(const VarDecl *VD, bool IsConstant)
Returns LLVM linkage for a declarator.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
Provides LLVM's BitmaskEnum facility to enumeration types declared in namespace clang.
SmallVector< const Expr *, 4 > FirstprivateVars
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
TBAAAccessInfo getTBAAInfo() const
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
static llvm::Value * emitCopyprivateCopyFunction(CodeGenModule &CGM, llvm::Type *ArgsType, ArrayRef< const Expr *> CopyprivateVars, ArrayRef< const Expr *> DestExprs, ArrayRef< const Expr *> SrcExprs, ArrayRef< const Expr *> AssignmentOps, SourceLocation Loc)
virtual Address getAddrOfThreadPrivate(CodeGenFunction &CGF, const VarDecl *VD, Address VDAddr, SourceLocation Loc)
Returns address of the threadprivate variable for the current thread.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
QualType getRecordType(const RecordDecl *Decl) const
Represents an unpacked "presumed" location which can be presented to the user.
void Emit(CodeGenFunction &CGF, Flags) override
Emit the cleanup.
virtual void emitTargetOutlinedFunctionHelper(const OMPExecutableDirective &D, StringRef ParentName, llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID, bool IsOffloadEntry, const RegionCodeGenTy &CodeGen)
Helper to emit outlined function for 'target' directive.
void registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID, StringRef ParentName, unsigned LineNum, llvm::Constant *Addr, llvm::Constant *ID, OMPTargetRegionEntryKind Flags)
Register target region entry.
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
llvm::Function * emitThreadPrivateVarDefinition(const VarDecl *VD, Address VDAddr, SourceLocation Loc, bool PerformInit, CodeGenFunction *CGF=nullptr) override
Emit a code for initialization of threadprivate variable.
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
Expr * getInitPriv()
Get Priv variable of the initializer.
This represents clause 'firstprivate' in the '#pragma omp ...' directives.
void emitTaskgroupRegion(CodeGenFunction &CGF, const RegionCodeGenTy &TaskgroupOpGen, SourceLocation Loc) override
Emit a taskgroup region.
const Qualifiers & getQuals() const
Address getAddrOfThreadPrivate(CodeGenFunction &CGF, const VarDecl *VD, Address VDAddr, SourceLocation Loc) override
Returns address of the threadprivate variable for the current thread.
const LangOptions & getLangOpts() const
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()
ASTContext & getContext() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
OpenMPProcBindClauseKind
OpenMP attributes for 'proc_bind' clause.
llvm::Constant * createDispatchInitFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_dispatch_init_* runtime function for the specified size IVSize and sign IVSigned...
virtual void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName, const RegionCodeGenTy &CriticalOpGen, SourceLocation Loc, const Expr *Hint=nullptr)
Emits a critical region.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
GlobalDecl - represents a global declaration.
bool hasClausesOfKind() const
Returns true if the current directive has one or more clauses of a specific kind. ...
llvm::Value * emitParallelOutlinedFunction(const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) override
Emits outlined function for the specified OpenMP parallel directive D.
virtual bool emitTargetGlobalVariable(GlobalDecl GD)
Emit the global variable if it is a valid device global variable.
void finishAndAddTo(AggregateBuilderBase &parent)
Given that this builder was created by beginning an array or struct component on the given parent bui...
CanQualType getCanonicalTypeUnqualified() const
QualType KmpDependInfoTy
Type typedef struct kmp_depend_info { kmp_intptr_t base_addr; size_t len; struct { bool in:1; bool ou...
static llvm::Value * emitNumThreadsForTargetDirective(CGOpenMPRuntime &OMPRuntime, CodeGenFunction &CGF, const OMPExecutableDirective &D)
Emit the number of threads for a target directive.
LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy)
QualType TgtBinaryDescriptorQTy
struct __tgt_bin_desc{ int32_t NumDevices; // Number of devices supported.
The l-value was considered opaque, so the alignment was determined from a type.
RecordDecl * getDecl() const
const char * getFilename() const
Return the presumed filename of this location.
const SpecificClause * getSingleClause() const
Gets a single clause of the specified kind associated with the current directive iff there is only on...
static void emitReductionCombiner(CodeGenFunction &CGF, const Expr *ReductionOp)
Emit reduction combiner.
Expr * getStrideVariable() const
This represents 'num_teams' clause in the '#pragma omp ...' directive.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
virtual void registerTargetGlobalVariable(const VarDecl *VD, llvm::Constant *Addr)
Checks if the provided global decl GD is a declare target variable and registers it when emitting cod...
static llvm::Value * emitNumTeamsForTargetDirective(CGOpenMPRuntime &OMPRuntime, CodeGenFunction &CGF, const OMPExecutableDirective &D)
Emit the number of teams for a target directive.
CanProxy< U > castAs() const
This captures a statement into a function.
QualType getCanonicalType() const
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
static unsigned getDefaultFlagsForBarriers(OpenMPDirectiveKind Kind)
Returns default flags for the barriers depending on the directive, for which this barier is going to ...
unsigned getColumn() const
Return the presumed column number of this location.
static const Stmt * getSingleCompoundChild(ASTContext &Ctx, const Stmt *Body)
Checks if the Body is the CompoundStmt and returns its child statement iff there is only one that is ...
static with chunk adjustment (e.g., simd)
void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
pushDestroy - Push the standard destructor for the given type as at least a normal cleanup...
void emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond, const RegionCodeGenTy &ThenGen, const RegionCodeGenTy &ElseGen)
Emits code for OpenMP 'if' clause using specified CodeGen function.
void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, const Expr *IfCond, OpenMPDirectiveKind CancelRegion) override
Emit code for 'cancel' construct.
Encodes a location in the source.
static const OMPExecutableDirective * getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D)
Check for inner distribute directive.
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).
void emitDoacrossInit(CodeGenFunction &CGF, const OMPLoopDirective &D, ArrayRef< Expr *> NumIterations) override
Emit initialization for doacross loop nesting support.
Set if the nonmonotonic schedule modifier was present.
virtual llvm::Function * emitThreadPrivateVarDefinition(const VarDecl *VD, Address VDAddr, SourceLocation Loc, bool PerformInit, CodeGenFunction *CGF=nullptr)
Emit a code for initialization of threadprivate variable.
OpenMPLinearClauseKind Modifier
Modifier of 'linear' clause.
Target region entries info.
const ParmVarDecl * getParamDecl(unsigned i) const
static void EmitOMPTargetSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetSimdDirective &S)
Emit device code for the target simd directive.
Device global variable entries info.
void emitDistributeStaticInit(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDistScheduleClauseKind SchedKind, const StaticRTInput &Values) override
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
bool isTrivialInitializer(const Expr *Init)
Determine whether the given initializer is trivial in the sense that it requires no code to be genera...
void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind, const OpenMPScheduleTy &ScheduleKind, const StaticRTInput &Values) override
Call the appropriate runtime routine to initialize it before start of loop.
virtual llvm::Value * emitTaskOutlinedFunction(const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, const VarDecl *PartIDVar, const VarDecl *TaskTVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, bool Tied, unsigned &NumberOfParts)
Emits outlined function for the OpenMP task directive D.
void emitAggregateType(CodeGenFunction &CGF, unsigned N)
Emits the code for the variable-modified type, if required.
static void EmitOMPTargetTeamsDistributeParallelForDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeParallelForDirective &S)
bool isAnyPointerType() const
This declaration is only a declaration.
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...
llvm::Value * getCriticalRegionLock(StringRef CriticalName)
Returns corresponding lock object for the specified critical region name.
virtual void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn, ArrayRef< llvm::Value *> CapturedVars, const Expr *IfCond)
Emits code for parallel or serial call of the OutlinedFn with variables captured in a record which ad...
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
void emitThreadPrivateVarInit(CodeGenFunction &CGF, Address VDAddr, llvm::Value *Ctor, llvm::Value *CopyCtor, llvm::Value *Dtor, SourceLocation Loc)
Emits initialization code for the threadprivate variables.
Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, const llvm::DataLayout &DL, const llvm::Twine &Name="")
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
virtual void emitProcBindClause(CodeGenFunction &CGF, OpenMPProcBindClauseKind ProcBind, SourceLocation Loc)
Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid, int proc_bind) to generat...
virtual void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc)
Emits code for a taskyield directive.
void EmitAggregateAssign(LValue Dest, LValue Src, QualType EltTy)
Emit an aggregate assignment.
CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)
llvm::Value * NewTaskNewTaskTTy
bool hasTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID, StringRef ParentName, unsigned LineNum) const
Return true if a target region entry with the provided information exists.
virtual void functionFinished(CodeGenFunction &CGF)
Cleans up references to the objects in finished function.
const Expr * getRefExpr(unsigned N) const
Returns the base declaration of the reduction item.
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void emitTaskReductionFixups(CodeGenFunction &CGF, SourceLocation Loc, ReductionCodeGen &RCG, unsigned N) override
Required to resolve existing problems in the runtime.
Expr * getInitOrig()
Get Orig variable of the initializer.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
void registerDeviceGlobalVarEntryInfo(StringRef VarName, llvm::Constant *Addr, CharUnits VarSize, OMPTargetGlobalVarEntryKind Flags, llvm::GlobalValue::LinkageTypes Linkage)
Register device global variable entry.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character...
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final list of privates etc *TaskResultTy emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D, llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds, const OMPTaskDataTy &Data)
llvm::Constant * GetAddrOfGlobal(GlobalDecl GD, ForDefinition_t IsForDefinition=NotForDefinition)
static void EmitOMPTargetTeamsDistributeDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeDirective &S)
Emit device code for the target teams distribute directive.
A basic class for pre|post-action for advanced codegen sequence for OpenMP region.
JumpDest getOMPCancelDestination(OpenMPDirectiveKind Kind)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
void emitOrderedRegion(CodeGenFunction &CGF, const RegionCodeGenTy &OrderedOpGen, SourceLocation Loc, bool IsThreads) override
Emit an ordered region.
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
FunctionArgList - Type for representing both the decl and type of parameters to a function...
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param IfCond Not a nullptr if if clause was nullptr *otherwise *param Data Additional data for task generation like final list of privates etc *void emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D, llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds, const Expr *IfCond, const OMPTaskDataTy &Data) override
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
static void emitX86DeclareSimdFunction(const FunctionDecl *FD, llvm::Function *Fn, const llvm::APSInt &VLENVal, ArrayRef< ParamAttrTy > ParamAttrs, OMPDeclareSimdDeclAttr::BranchStateTy State)
void setAction(PrePostActionTy &Action) const
CGFunctionInfo - Class to encapsulate the information about a function definition.
This class organizes the cross-function state that is used while generating LLVM code.
QualType withRestrict() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
static const VarDecl * getBaseDecl(const Expr *Ref, const DeclRefExpr *&DE)
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
LValue EmitOMPSharedLValue(const Expr *E)
Emits the lvalue for the expression with possibly captured variable.
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
Dataflow Directional Tag Classes.
static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)
Apply TemporaryLocation if it is valid.
static void emitForStaticInitCall(CodeGenFunction &CGF, llvm::Value *UpdateLocation, llvm::Value *ThreadId, llvm::Constant *ForStaticInitFunction, OpenMPSchedType Schedule, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, const CGOpenMPRuntime::StaticRTInput &Values)
Class provides a way to call simple version of codegen for OpenMP region, or an advanced with possibl...
LValue EmitLoadOfReferenceLValue(LValue RefLVal)
static llvm::Value * emitReduceInitFunction(CodeGenModule &CGM, SourceLocation Loc, ReductionCodeGen &RCG, unsigned N)
Emits reduction initializer function:
bool isValid() const
Return true if this is a valid SourceLocation object.
bool emitTargetFunctions(GlobalDecl GD) override
Emit the target regions enclosed in GD function definition or the function itself in case it is a val...
llvm::Value * emitTaskOutlinedFunction(const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, const VarDecl *PartIDVar, const VarDecl *TaskTVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, bool Tied, unsigned &NumberOfParts) override
Emits outlined function for the OpenMP task directive D.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
EvalResult is a struct with detailed info about an evaluated expression.
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
virtual bool emitTargetGlobal(GlobalDecl GD)
Emit the global GD if it is meaningful for the target.
virtual void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, const Expr *IfCond, OpenMPDirectiveKind CancelRegion)
Emit code for 'cancel' construct.
std::vector< llvm::Triple > OMPTargetTriples
Triples of the OpenMP targets that the host code codegen should take into account in order to generat...
OpenMPScheduleClauseModifier M1
A basic class for pre|post-action for advanced codegen sequence for OpenMP region.
LValue getSharedLValue(unsigned N) const
Returns LValue for the reduction item.
const Expr * getInit() const
llvm::Constant * getPointer() const
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param IfCond Not a nullptr if if clause was nullptr *otherwise *param Data Additional data for task generation like final list of privates etc *virtual void emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D, llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds, const Expr *IfCond, const OMPTaskDataTy &Data)
void initializeTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID, StringRef ParentName, unsigned LineNum, unsigned Order)
Initialize target region entry.
llvm::Function * createOffloadingBinaryDescriptorRegistration()
Creates and registers offloading binary descriptor for the current compilation unit.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::IntegerType * IntPtrTy
llvm::PointerIntPair< llvm::Value *, 1, bool > Priority
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Module & getModule() const
Call to void __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro microtask, ...
Not really used in Fortran any more.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
virtual void emitTargetOutlinedFunction(const OMPExecutableDirective &D, StringRef ParentName, llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID, bool IsOffloadEntry, const RegionCodeGenTy &CodeGen)
Emit outilined function for 'target' directive.
llvm::StructType * ConvertRecordDeclType(const RecordDecl *TD)
ConvertRecordDeclType - Lay out a tagged decl type like struct or union.
virtual bool isDefaultLocationConstant() const
Check if the default location must be constant.
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
virtual Address emitThreadIDAddress(CodeGenFunction &CGF, SourceLocation Loc)
Emits address of the word in a memory where current thread id is stored.
void emitInitialization(CodeGenFunction &CGF, unsigned N, Address PrivateAddr, LValue SharedLVal, llvm::function_ref< bool(CodeGenFunction &)> DefaultInit)
Performs initialization of the private copy for the reduction item.
JumpDest ReturnBlock
ReturnBlock - Unified return block.
OffloadEntriesInfoManagerTy OffloadEntriesInfoManager
virtual bool isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind, bool Chunked) const
Check if the specified ScheduleKind is static non-chunked.
bool capturesVariableByCopy() const
Determine whether this capture handles a variable by copy.
Class that represents a component of a mappable expression.
API for captured statement code generation.
virtual bool emitDeclareTargetVarDefinition(const VarDecl *VD, llvm::GlobalVariable *Addr, bool PerformInit)
Emit a code for initialization of declare target variable.
virtual void emitDistributeStaticInit(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDistScheduleClauseKind SchedKind, const StaticRTInput &Values)
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
virtual StringRef getOutlinedHelperName() const
Get the function name of an outlined region.
static bool classof(const OMPClause *T)
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
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)
CodeGenTypes & getTypes() const
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
Address CreateConstArrayGEP(Address Addr, uint64_t Index, CharUnits EltSize, const llvm::Twine &Name="")
Given addr = [n x T]* ...
static void EmitOMPTargetTeamsDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDirective &S)
Emit device code for the target teams directive.
CleanupTy(PrePostActionTy *Action)
llvm::Type * getElementType() const
Return the type of the values stored in this address.
void initializeDeviceGlobalVarEntryInfo(StringRef Name, OMPTargetGlobalVarEntryKind Flags, unsigned Order)
Initialize device global variable entry.
static bool checkInitIsRequired(CodeGenFunction &CGF, ArrayRef< PrivateDataTy > Privates)
Check if duplication function is required for taskloops.
llvm::Value * EmitCheckedInBoundsGEP(llvm::Value *Ptr, ArrayRef< llvm::Value *> IdxList, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, const Twine &Name="")
Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to detect undefined behavior whe...
static void getTargetEntryUniqueInfo(ASTContext &C, SourceLocation Loc, unsigned &DeviceID, unsigned &FileID, unsigned &LineNum)
Obtain information that uniquely identifies a target entry.
llvm::PointerType * Int8PtrTy
Address getTaskReductionItem(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *ReductionsPtr, LValue SharedLVal) override
Get the address of void * type of the privatue copy of the reduction item specified by the SharedLVal...
llvm::AssertingVH< llvm::Instruction > AllocaInsertPt
AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...
OpenMPLocationFlags
Values for bit flags used in the ident_t to describe the fields.
virtual void emitInlinedDirective(CodeGenFunction &CGF, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, bool HasCancel=false)
Emit code for the directive that does not require outlining.
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
Expr * getNumIterations() const
llvm::StringRef getName() const
Return the IR name of the pointer value.
llvm::StructType * getLLVMType() const
Return the "complete object" LLVM type associated with this record.
Base for LValueReferenceType and RValueReferenceType.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Entity that registers the offloading constants that were emitted so far.
void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
StringRef getMangledName(GlobalDecl GD)
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void addDecl(Decl *D)
Add the declaration D into this context.
FieldDecl * LambdaThisCaptureField
void emitCall(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *Callee, ArrayRef< llvm::Value *> Args=llvm::None) const
Emits Callee function call with arguments Args with location Loc.
llvm::Constant * createDispatchNextFunction(unsigned IVSize, bool IVSigned)
Returns __kmpc_dispatch_next_* runtime function for the specified size IVSize and sign IVSigned...
void getCaptureFields(llvm::DenseMap< const VarDecl *, FieldDecl *> &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
Mark the entry as target region.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
virtual void emitTaskgroupRegion(CodeGenFunction &CGF, const RegionCodeGenTy &TaskgroupOpGen, SourceLocation Loc)
Emit a taskgroup region.
SourceManager & getSourceManager()
virtual llvm::Function * emitRegistrationFunction()
Creates the offloading descriptor in the event any target region was emitted in the current module an...
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
Mark the entry as a global destructor.
Address LoadCXXThisAddress()
virtual void adjustTargetSpecificDataForLambdas(CodeGenFunction &CGF, const OMPExecutableDirective &D) const
Adjust some parameters for the target-based directives, like addresses of the variables captured by r...
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
Lower bound for default (unordered) versions.
void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn, ArrayRef< llvm::Value *> CapturedVars, const Expr *IfCond) override
Emits code for parallel or serial call of the OutlinedFn with variables captured in a record which ad...
void emitNumTeamsClause(CodeGenFunction &CGF, const Expr *NumTeams, const Expr *ThreadLimit, SourceLocation Loc) override
Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32 global_tid, kmp_int32 num_teams...
TranslationUnitDecl * getTranslationUnitDecl() const
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
virtual void emitReduction(CodeGenFunction &CGF, SourceLocation Loc, ArrayRef< const Expr *> Privates, ArrayRef< const Expr *> LHSExprs, ArrayRef< const Expr *> RHSExprs, ArrayRef< const Expr *> ReductionOps, ReductionOptionsTy Options)
Emit a code for reduction clause.
This represents 'nowait' clause in the '#pragma omp ...' directive.
static bool isTrivial(ASTContext &Ctx, const Expr *E)
Checks if the expression is constant or does not have non-trivial function calls. ...
llvm::PointerIntPair< llvm::Value *, 1, bool > Schedule
Represents a C++ struct/union/class.
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block, taking care to avoid creation of branches from dummy blocks.
llvm::Function * CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false)
llvm::Value * BasePointersArray
The array of base pointer passed to the runtime library.
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
static llvm::Value * emitReduceFiniFunction(CodeGenModule &CGM, SourceLocation Loc, ReductionCodeGen &RCG, unsigned N)
Emits reduction finalizer function:
~DisableAutoDeclareTargetRAII()
OpenMPOffloadingReservedDeviceIDs
llvm::Type * ConvertType(QualType T)
bool isTLSSupported() const
Whether the target supports thread-local storage.
void emitDoacrossOrdered(CodeGenFunction &CGF, const OMPDependClause *C) override
Emit code for doacross ordered directive with 'depend' clause.
Privates[]
Gets the list of initial values for linear variables.
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
static const Stmt * ignoreCompoundStmts(const Stmt *Body)
discard all CompoundStmts intervening between two constructs
LValue EmitLValue(const Expr *E)
EmitLValue - Emit code to compute a designator that specifies the location of the expression...
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
void popTerminate()
Pops a terminate handler off the stack.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
unsigned getVirtualBaseIndex(const CXXRecordDecl *base) const
Return the LLVM field index corresponding to the given virtual base.
Entry is a declare target variable.
virtual void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind Kind, bool EmitChecks=true, bool ForceSimpleCall=false)
Emit an implicit/explicit barrier for OpenMP threads.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void emitTargetOutlinedFunction(const OMPExecutableDirective &D, StringRef ParentName, llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID, bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) override
Emit outilined function for 'target' directive.
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
static llvm::Value * emitTaskDupFunction(CodeGenModule &CGM, SourceLocation Loc, const OMPExecutableDirective &D, QualType KmpTaskTWithPrivatesPtrQTy, const RecordDecl *KmpTaskTWithPrivatesQTyRD, const RecordDecl *KmpTaskTQTyRD, QualType SharedsTy, QualType SharedsPtrTy, const OMPTaskDataTy &Data, ArrayRef< PrivateDataTy > Privates, bool WithLastIter)
Emit task_dup function (for initialization of private/firstprivate/lastprivate vars and last_iter fla...
virtual void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc, const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned, bool Ordered, const DispatchRTInput &DispatchValues)
Call the appropriate runtime routine to initialize it before start of loop.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
static RecordDecl * createKmpTaskTWithPrivatesRecordDecl(CodeGenModule &CGM, QualType KmpTaskTQTy, ArrayRef< PrivateDataTy > Privates)
CGCapturedStmtInfo * CapturedStmtInfo
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...
CGCXXABI & getCXXABI() const
Expr * getCombinerIn()
Get In variable of the combiner.
const VariableArrayType * getAsVariableArrayType(QualType T) const
__DEVICE__ int max(int __a, int __b)
Mark the entry as a global constructor.
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
A reference to a declared variable, function, enum, etc.
QualType getIntPtrType() const
Return a type compatible with "intptr_t" (C99 7.18.1.4), as defined by the target.
static RValue get(llvm::Value *V)
virtual void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind, const OpenMPScheduleTy &ScheduleKind, const StaticRTInput &Values)
Call the appropriate runtime routine to initialize it before start of loop.
llvm::Value * emitTaskReductionInit(CodeGenFunction &CGF, SourceLocation Loc, ArrayRef< const Expr *> LHSExprs, ArrayRef< const Expr *> RHSExprs, const OMPTaskDataTy &Data) override
Emit a code for initialization of task reduction clause.
bool isPointerType() const
static void EmitOMPTargetDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetDirective &S)
Emit device code for the target directive.
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
ParamKindTy
Kind of parameter in a function with 'declare simd' directive.
static void EmitOMPTargetParallelForDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelForDirective &S)
Emit device code for the target parallel for directive.
QualType KmpDimTy
struct kmp_dim { // loop bounds info casted to kmp_int64 kmp_int64 lo; // lower kmp_int64 up; // uppe...
void emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind) override
Call the appropriate runtime routine to notify that we finished all the work with current loop...
An l-value expression is a reference to an object with independent storage.
static RValue getAggregate(Address addr, bool isVolatile=false)
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
LValue - This represents an lvalue references.
virtual unsigned getDefaultLocationReserved2Flags() const
Returns additional flags that can be stored in reserved_2 field of the default location.
Information for lazily generating a cleanup.
QualType SavedKmpTaskTQTy
Saved kmp_task_t for task directive.
virtual Address getTaskReductionItem(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *ReductionsPtr, LValue SharedLVal)
Get the address of void * type of the privatue copy of the reduction item specified by the SharedLVal...
Represents a C array with a specified size that is not an integer-constant-expression.
void emitTeamsCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, SourceLocation Loc, llvm::Value *OutlinedFn, ArrayRef< llvm::Value *> CapturedVars) override
Emits code for teams call of the OutlinedFn with variables captured in a record which address is stor...
const LangOptions & getLangOpts() const
llvm::Constant * createRuntimeFunction(unsigned Function)
Returns specified OpenMP runtime function.
llvm::StringSet DeclareTargetWithDefinition
Set of declare target variables with the generated initializer.
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...
Expr * getCombinerOut()
Get Out variable of the combiner.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
llvm::Value * getPointer() const
base_class_range vbases()
This class handles loading and caching of source files into memory.
void emitCancellationPointCall(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind CancelRegion) override
Emit code for 'cancellation point' construct.
A helper class of ConstantInitBuilder, used for building constant array initializers.
void EmitGlobal(GlobalDecl D)
Emit code for a single global function or var decl.
virtual void emitNumThreadsClause(CodeGenFunction &CGF, llvm::Value *NumThreads, SourceLocation Loc)
Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid, kmp_int32 num_threads)...
bool capturesVariableArrayType() const
Determine whether this capture handles a variable-length array type.
bool isLocalVarDeclOrParm() const
Similar to isLocalVarDecl but also includes parameters.
Attr - This represents one attribute.
SmallVector< const Expr *, 4 > FirstprivateInits
SourceLocation getLocation() const
This represents clause 'use_device_ptr' in the '#pragma omp ...' directives.
static void EmitOMPTargetTeamsDistributeSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeSimdDirective &S)
Emit device code for the target teams distribute simd directive.
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
bool isExternallyVisible() const
llvm::Constant * getOrCreateThreadPrivateCache(const VarDecl *VD)
If the specified mangled name is not in the module, create and return threadprivate cache object...
llvm::Value * SizesArray
The array of sizes passed to the runtime library.
virtual void emitTargetNumIterationsCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *Device, const llvm::function_ref< llvm::Value *(CodeGenFunction &CGF, const OMPLoopDirective &D)> &SizeEmitter)
Emit code that pushes the trip count of loops associated with constructs 'target teams distribute' an...
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth, signed/unsigned.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
bool Privatize()
Privatizes local variables previously registered as private.
static void EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeParallelForSimdDirective &S)
Emit device code for the target teams distribute parallel for simd directive.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc)
Emit code for 'taskwait' directive.
unsigned getLLVMFieldNo(const FieldDecl *FD) const
Return llvm::StructType element number that corresponds to the field FD.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const llvm::Triple & getTriple() const