1 //===--- CGStmtOpenMP.cpp - Emit LLVM Code from Statements ----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This contains code to emit OpenMP nodes as LLVM code.
12 //===----------------------------------------------------------------------===//
14 #include "CGCleanup.h"
15 #include "CGOpenMPRuntime.h"
16 #include "CodeGenFunction.h"
17 #include "CodeGenModule.h"
18 #include "TargetInfo.h"
19 #include "clang/AST/Stmt.h"
20 #include "clang/AST/StmtOpenMP.h"
21 #include "clang/AST/DeclOpenMP.h"
22 #include "llvm/IR/CallSite.h"
23 using namespace clang;
24 using namespace CodeGen;
27 /// Lexical scope for OpenMP executable constructs, that handles correct codegen
28 /// for captured expressions.
29 class OMPLexicalScope final : public CodeGenFunction::LexicalScope {
30 void emitPreInitStmt(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
31 for (const auto *C : S.clauses()) {
32 if (auto *CPI = OMPClauseWithPreInit::get(C)) {
33 if (auto *PreInit = cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {
34 for (const auto *I : PreInit->decls()) {
35 if (!I->hasAttr<OMPCaptureNoInitAttr>())
36 CGF.EmitVarDecl(cast<VarDecl>(*I));
38 CodeGenFunction::AutoVarEmission Emission =
39 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
40 CGF.EmitAutoVarCleanups(Emission);
47 CodeGenFunction::OMPPrivateScope InlinedShareds;
49 static bool isCapturedVar(CodeGenFunction &CGF, const VarDecl *VD) {
50 return CGF.LambdaCaptureFields.lookup(VD) ||
51 (CGF.CapturedStmtInfo && CGF.CapturedStmtInfo->lookup(VD)) ||
52 (CGF.CurCodeDecl && isa<BlockDecl>(CGF.CurCodeDecl));
56 OMPLexicalScope(CodeGenFunction &CGF, const OMPExecutableDirective &S,
57 bool AsInlined = false)
58 : CodeGenFunction::LexicalScope(CGF, S.getSourceRange()),
60 emitPreInitStmt(CGF, S);
62 if (S.hasAssociatedStmt()) {
63 auto *CS = cast<CapturedStmt>(S.getAssociatedStmt());
64 for (auto &C : CS->captures()) {
65 if (C.capturesVariable() || C.capturesVariableByCopy()) {
66 auto *VD = C.getCapturedVar();
67 DeclRefExpr DRE(const_cast<VarDecl *>(VD),
68 isCapturedVar(CGF, VD) ||
69 (CGF.CapturedStmtInfo &&
70 InlinedShareds.isGlobalVarCaptured(VD)),
71 VD->getType().getNonReferenceType(), VK_LValue,
73 InlinedShareds.addPrivate(VD, [&CGF, &DRE]() -> Address {
74 return CGF.EmitLValue(&DRE).getAddress();
78 (void)InlinedShareds.Privatize();
84 /// Private scope for OpenMP loop-based directives, that supports capturing
85 /// of used expression from loop statement.
86 class OMPLoopScope : public CodeGenFunction::RunCleanupsScope {
87 void emitPreInitStmt(CodeGenFunction &CGF, const OMPLoopDirective &S) {
88 if (auto *LD = dyn_cast<OMPLoopDirective>(&S)) {
89 if (auto *PreInits = cast_or_null<DeclStmt>(LD->getPreInits())) {
90 for (const auto *I : PreInits->decls())
91 CGF.EmitVarDecl(cast<VarDecl>(*I));
97 OMPLoopScope(CodeGenFunction &CGF, const OMPLoopDirective &S)
98 : CodeGenFunction::RunCleanupsScope(CGF) {
99 emitPreInitStmt(CGF, S);
105 llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) {
106 auto &C = getContext();
107 llvm::Value *Size = nullptr;
108 auto SizeInChars = C.getTypeSizeInChars(Ty);
109 if (SizeInChars.isZero()) {
110 // getTypeSizeInChars() returns 0 for a VLA.
111 while (auto *VAT = C.getAsVariableArrayType(Ty)) {
112 llvm::Value *ArraySize;
113 std::tie(ArraySize, Ty) = getVLASize(VAT);
114 Size = Size ? Builder.CreateNUWMul(Size, ArraySize) : ArraySize;
116 SizeInChars = C.getTypeSizeInChars(Ty);
117 if (SizeInChars.isZero())
118 return llvm::ConstantInt::get(SizeTy, /*V=*/0);
119 Size = Builder.CreateNUWMul(Size, CGM.getSize(SizeInChars));
121 Size = CGM.getSize(SizeInChars);
125 void CodeGenFunction::GenerateOpenMPCapturedVars(
126 const CapturedStmt &S, SmallVectorImpl<llvm::Value *> &CapturedVars) {
127 const RecordDecl *RD = S.getCapturedRecordDecl();
128 auto CurField = RD->field_begin();
129 auto CurCap = S.captures().begin();
130 for (CapturedStmt::const_capture_init_iterator I = S.capture_init_begin(),
131 E = S.capture_init_end();
132 I != E; ++I, ++CurField, ++CurCap) {
133 if (CurField->hasCapturedVLAType()) {
134 auto VAT = CurField->getCapturedVLAType();
135 auto *Val = VLASizeMap[VAT->getSizeExpr()];
136 CapturedVars.push_back(Val);
137 } else if (CurCap->capturesThis())
138 CapturedVars.push_back(CXXThisValue);
139 else if (CurCap->capturesVariableByCopy()) {
141 EmitLoadOfLValue(EmitLValue(*I), SourceLocation()).getScalarVal();
143 // If the field is not a pointer, we need to save the actual value
144 // and load it as a void pointer.
145 if (!CurField->getType()->isAnyPointerType()) {
146 auto &Ctx = getContext();
147 auto DstAddr = CreateMemTemp(
148 Ctx.getUIntPtrType(),
149 Twine(CurCap->getCapturedVar()->getName()) + ".casted");
150 LValue DstLV = MakeAddrLValue(DstAddr, Ctx.getUIntPtrType());
152 auto *SrcAddrVal = EmitScalarConversion(
153 DstAddr.getPointer(), Ctx.getPointerType(Ctx.getUIntPtrType()),
154 Ctx.getPointerType(CurField->getType()), SourceLocation());
156 MakeNaturalAlignAddrLValue(SrcAddrVal, CurField->getType());
158 // Store the value using the source type pointer.
159 EmitStoreThroughLValue(RValue::get(CV), SrcLV);
161 // Load the value using the destination type pointer.
162 CV = EmitLoadOfLValue(DstLV, SourceLocation()).getScalarVal();
164 CapturedVars.push_back(CV);
166 assert(CurCap->capturesVariable() && "Expected capture by reference.");
167 CapturedVars.push_back(EmitLValue(*I).getAddress().getPointer());
172 static Address castValueFromUintptr(CodeGenFunction &CGF, QualType DstType,
173 StringRef Name, LValue AddrLV,
174 bool isReferenceType = false) {
175 ASTContext &Ctx = CGF.getContext();
177 auto *CastedPtr = CGF.EmitScalarConversion(
178 AddrLV.getAddress().getPointer(), Ctx.getUIntPtrType(),
179 Ctx.getPointerType(DstType), SourceLocation());
181 CGF.MakeNaturalAlignAddrLValue(CastedPtr, Ctx.getPointerType(DstType))
184 // If we are dealing with references we need to return the address of the
185 // reference instead of the reference of the value.
186 if (isReferenceType) {
187 QualType RefType = Ctx.getLValueReferenceType(DstType);
188 auto *RefVal = TmpAddr.getPointer();
189 TmpAddr = CGF.CreateMemTemp(RefType, Twine(Name) + ".ref");
190 auto TmpLVal = CGF.MakeAddrLValue(TmpAddr, RefType);
191 CGF.EmitScalarInit(RefVal, TmpLVal);
198 CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
201 "CapturedStmtInfo should be set when generating the captured function");
202 const CapturedDecl *CD = S.getCapturedDecl();
203 const RecordDecl *RD = S.getCapturedRecordDecl();
204 assert(CD->hasBody() && "missing CapturedDecl body");
206 // Build the argument list.
207 ASTContext &Ctx = CGM.getContext();
208 FunctionArgList Args;
209 Args.append(CD->param_begin(),
210 std::next(CD->param_begin(), CD->getContextParamPosition()));
211 auto I = S.captures().begin();
212 for (auto *FD : RD->fields()) {
213 QualType ArgType = FD->getType();
214 IdentifierInfo *II = nullptr;
215 VarDecl *CapVar = nullptr;
217 // If this is a capture by copy and the type is not a pointer, the outlined
218 // function argument type should be uintptr and the value properly casted to
219 // uintptr. This is necessary given that the runtime library is only able to
220 // deal with pointers. We can pass in the same way the VLA type sizes to the
221 // outlined function.
222 if ((I->capturesVariableByCopy() && !ArgType->isAnyPointerType()) ||
223 I->capturesVariableArrayType())
224 ArgType = Ctx.getUIntPtrType();
226 if (I->capturesVariable() || I->capturesVariableByCopy()) {
227 CapVar = I->getCapturedVar();
228 II = CapVar->getIdentifier();
229 } else if (I->capturesThis())
230 II = &getContext().Idents.get("this");
232 assert(I->capturesVariableArrayType());
233 II = &getContext().Idents.get("vla");
235 if (ArgType->isVariablyModifiedType()) {
236 bool IsReference = ArgType->isLValueReferenceType();
238 getContext().getCanonicalParamType(ArgType.getNonReferenceType());
239 if (IsReference && !ArgType->isPointerType()) {
240 ArgType = getContext().getLValueReferenceType(
241 ArgType, /*SpelledAsLValue=*/false);
244 Args.push_back(ImplicitParamDecl::Create(getContext(), nullptr,
245 FD->getLocation(), II, ArgType));
249 std::next(CD->param_begin(), CD->getContextParamPosition() + 1),
252 // Create the function declaration.
253 FunctionType::ExtInfo ExtInfo;
254 const CGFunctionInfo &FuncInfo =
255 CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
256 llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo);
258 llvm::Function *F = llvm::Function::Create(
259 FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
260 CapturedStmtInfo->getHelperName(), &CGM.getModule());
261 CGM.SetInternalFunctionAttributes(CD, F, FuncInfo);
263 F->addFnAttr(llvm::Attribute::NoUnwind);
265 // Generate the function.
266 StartFunction(CD, Ctx.VoidTy, F, FuncInfo, Args, CD->getLocation(),
267 CD->getBody()->getLocStart());
268 unsigned Cnt = CD->getContextParamPosition();
269 I = S.captures().begin();
270 for (auto *FD : RD->fields()) {
271 // If we are capturing a pointer by copy we don't need to do anything, just
272 // use the value that we get from the arguments.
273 if (I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) {
274 setAddrOfLocalVar(I->getCapturedVar(), GetAddrOfLocalVar(Args[Cnt]));
281 MakeAddrLValue(GetAddrOfLocalVar(Args[Cnt]), Args[Cnt]->getType(),
282 AlignmentSource::Decl);
283 if (FD->hasCapturedVLAType()) {
284 LValue CastedArgLVal =
285 MakeAddrLValue(castValueFromUintptr(*this, FD->getType(),
286 Args[Cnt]->getName(), ArgLVal),
287 FD->getType(), AlignmentSource::Decl);
289 EmitLoadOfLValue(CastedArgLVal, SourceLocation()).getScalarVal();
290 auto VAT = FD->getCapturedVLAType();
291 VLASizeMap[VAT->getSizeExpr()] = ExprArg;
292 } else if (I->capturesVariable()) {
293 auto *Var = I->getCapturedVar();
294 QualType VarTy = Var->getType();
295 Address ArgAddr = ArgLVal.getAddress();
296 if (!VarTy->isReferenceType()) {
297 if (ArgLVal.getType()->isLValueReferenceType()) {
298 ArgAddr = EmitLoadOfReference(
299 ArgAddr, ArgLVal.getType()->castAs<ReferenceType>());
300 } else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) {
301 assert(ArgLVal.getType()->isPointerType());
302 ArgAddr = EmitLoadOfPointer(
303 ArgAddr, ArgLVal.getType()->castAs<PointerType>());
307 Var, Address(ArgAddr.getPointer(), getContext().getDeclAlign(Var)));
308 } else if (I->capturesVariableByCopy()) {
309 assert(!FD->getType()->isAnyPointerType() &&
310 "Not expecting a captured pointer.");
311 auto *Var = I->getCapturedVar();
312 QualType VarTy = Var->getType();
313 setAddrOfLocalVar(Var, castValueFromUintptr(*this, FD->getType(),
314 Args[Cnt]->getName(), ArgLVal,
315 VarTy->isReferenceType()));
317 // If 'this' is captured, load it into CXXThisValue.
318 assert(I->capturesThis());
320 EmitLoadOfLValue(ArgLVal, Args[Cnt]->getLocation()).getScalarVal();
326 PGO.assignRegionCounters(GlobalDecl(CD), F);
327 CapturedStmtInfo->EmitBody(*this, CD->getBody());
328 FinishFunction(CD->getBodyRBrace());
333 //===----------------------------------------------------------------------===//
334 // OpenMP Directive Emission
335 //===----------------------------------------------------------------------===//
336 void CodeGenFunction::EmitOMPAggregateAssign(
337 Address DestAddr, Address SrcAddr, QualType OriginalType,
338 const llvm::function_ref<void(Address, Address)> &CopyGen) {
339 // Perform element-by-element initialization.
342 // Drill down to the base element type on both arrays.
343 auto ArrayTy = OriginalType->getAsArrayTypeUnsafe();
344 auto NumElements = emitArrayLength(ArrayTy, ElementTy, DestAddr);
345 SrcAddr = Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());
347 auto SrcBegin = SrcAddr.getPointer();
348 auto DestBegin = DestAddr.getPointer();
349 // Cast from pointer to array type to pointer to single element.
350 auto DestEnd = Builder.CreateGEP(DestBegin, NumElements);
351 // The basic structure here is a while-do loop.
352 auto BodyBB = createBasicBlock("omp.arraycpy.body");
353 auto DoneBB = createBasicBlock("omp.arraycpy.done");
355 Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty");
356 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
358 // Enter the loop body, making that address the current address.
359 auto EntryBB = Builder.GetInsertBlock();
362 CharUnits ElementSize = getContext().getTypeSizeInChars(ElementTy);
364 llvm::PHINode *SrcElementPHI =
365 Builder.CreatePHI(SrcBegin->getType(), 2, "omp.arraycpy.srcElementPast");
366 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
367 Address SrcElementCurrent =
368 Address(SrcElementPHI,
369 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
371 llvm::PHINode *DestElementPHI =
372 Builder.CreatePHI(DestBegin->getType(), 2, "omp.arraycpy.destElementPast");
373 DestElementPHI->addIncoming(DestBegin, EntryBB);
374 Address DestElementCurrent =
375 Address(DestElementPHI,
376 DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));
379 CopyGen(DestElementCurrent, SrcElementCurrent);
381 // Shift the address forward by one element.
382 auto DestElementNext = Builder.CreateConstGEP1_32(
383 DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
384 auto SrcElementNext = Builder.CreateConstGEP1_32(
385 SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.src.element");
386 // Check whether we've reached the end.
388 Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");
389 Builder.CreateCondBr(Done, DoneBB, BodyBB);
390 DestElementPHI->addIncoming(DestElementNext, Builder.GetInsertBlock());
391 SrcElementPHI->addIncoming(SrcElementNext, Builder.GetInsertBlock());
394 EmitBlock(DoneBB, /*IsFinished=*/true);
397 /// Check if the combiner is a call to UDR combiner and if it is so return the
398 /// UDR decl used for reduction.
399 static const OMPDeclareReductionDecl *
400 getReductionInit(const Expr *ReductionOp) {
401 if (auto *CE = dyn_cast<CallExpr>(ReductionOp))
402 if (auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
404 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
405 if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl()))
410 static void emitInitWithReductionInitializer(CodeGenFunction &CGF,
411 const OMPDeclareReductionDecl *DRD,
413 Address Private, Address Original,
415 if (DRD->getInitializer()) {
416 std::pair<llvm::Function *, llvm::Function *> Reduction =
417 CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD);
418 auto *CE = cast<CallExpr>(InitOp);
419 auto *OVE = cast<OpaqueValueExpr>(CE->getCallee());
420 const Expr *LHS = CE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
421 const Expr *RHS = CE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
422 auto *LHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(LHS)->getSubExpr());
423 auto *RHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(RHS)->getSubExpr());
424 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
425 PrivateScope.addPrivate(cast<VarDecl>(LHSDRE->getDecl()),
426 [=]() -> Address { return Private; });
427 PrivateScope.addPrivate(cast<VarDecl>(RHSDRE->getDecl()),
428 [=]() -> Address { return Original; });
429 (void)PrivateScope.Privatize();
430 RValue Func = RValue::get(Reduction.second);
431 CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func);
432 CGF.EmitIgnoredExpr(InitOp);
434 llvm::Constant *Init = CGF.CGM.EmitNullConstant(Ty);
435 auto *GV = new llvm::GlobalVariable(
436 CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
437 llvm::GlobalValue::PrivateLinkage, Init, ".init");
438 LValue LV = CGF.MakeNaturalAlignAddrLValue(GV, Ty);
440 switch (CGF.getEvaluationKind(Ty)) {
442 InitRVal = CGF.EmitLoadOfLValue(LV, SourceLocation());
446 RValue::getComplex(CGF.EmitLoadOfComplex(LV, SourceLocation()));
449 InitRVal = RValue::getAggregate(LV.getAddress());
452 OpaqueValueExpr OVE(SourceLocation(), Ty, VK_RValue);
453 CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, InitRVal);
454 CGF.EmitAnyExprToMem(&OVE, Private, Ty.getQualifiers(),
455 /*IsInitializer=*/false);
459 /// \brief Emit initialization of arrays of complex types.
460 /// \param DestAddr Address of the array.
461 /// \param Type Type of array.
462 /// \param Init Initial expression of array.
463 /// \param SrcAddr Address of the original array.
464 static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr,
465 QualType Type, const Expr *Init,
466 Address SrcAddr = Address::invalid()) {
467 auto *DRD = getReductionInit(Init);
468 // Perform element-by-element initialization.
471 // Drill down to the base element type on both arrays.
472 auto ArrayTy = Type->getAsArrayTypeUnsafe();
473 auto NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, DestAddr);
475 CGF.Builder.CreateElementBitCast(DestAddr, DestAddr.getElementType());
478 CGF.Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());
480 llvm::Value *SrcBegin = nullptr;
482 SrcBegin = SrcAddr.getPointer();
483 auto DestBegin = DestAddr.getPointer();
484 // Cast from pointer to array type to pointer to single element.
485 auto DestEnd = CGF.Builder.CreateGEP(DestBegin, NumElements);
486 // The basic structure here is a while-do loop.
487 auto BodyBB = CGF.createBasicBlock("omp.arrayinit.body");
488 auto DoneBB = CGF.createBasicBlock("omp.arrayinit.done");
490 CGF.Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arrayinit.isempty");
491 CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
493 // Enter the loop body, making that address the current address.
494 auto EntryBB = CGF.Builder.GetInsertBlock();
495 CGF.EmitBlock(BodyBB);
497 CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy);
499 llvm::PHINode *SrcElementPHI = nullptr;
500 Address SrcElementCurrent = Address::invalid();
502 SrcElementPHI = CGF.Builder.CreatePHI(SrcBegin->getType(), 2,
503 "omp.arraycpy.srcElementPast");
504 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
506 Address(SrcElementPHI,
507 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
509 llvm::PHINode *DestElementPHI = CGF.Builder.CreatePHI(
510 DestBegin->getType(), 2, "omp.arraycpy.destElementPast");
511 DestElementPHI->addIncoming(DestBegin, EntryBB);
512 Address DestElementCurrent =
513 Address(DestElementPHI,
514 DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));
518 CodeGenFunction::RunCleanupsScope InitScope(CGF);
519 if (DRD && (DRD->getInitializer() || !Init)) {
520 emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent,
521 SrcElementCurrent, ElementTy);
523 CGF.EmitAnyExprToMem(Init, DestElementCurrent, ElementTy.getQualifiers(),
524 /*IsInitializer=*/false);
528 // Shift the address forward by one element.
529 auto SrcElementNext = CGF.Builder.CreateConstGEP1_32(
530 SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
531 SrcElementPHI->addIncoming(SrcElementNext, CGF.Builder.GetInsertBlock());
534 // Shift the address forward by one element.
535 auto DestElementNext = CGF.Builder.CreateConstGEP1_32(
536 DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
537 // Check whether we've reached the end.
539 CGF.Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");
540 CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB);
541 DestElementPHI->addIncoming(DestElementNext, CGF.Builder.GetInsertBlock());
544 CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
547 void CodeGenFunction::EmitOMPCopy(QualType OriginalType, Address DestAddr,
548 Address SrcAddr, const VarDecl *DestVD,
549 const VarDecl *SrcVD, const Expr *Copy) {
550 if (OriginalType->isArrayType()) {
551 auto *BO = dyn_cast<BinaryOperator>(Copy);
552 if (BO && BO->getOpcode() == BO_Assign) {
553 // Perform simple memcpy for simple copying.
554 EmitAggregateAssign(DestAddr, SrcAddr, OriginalType);
556 // For arrays with complex element types perform element by element
558 EmitOMPAggregateAssign(
559 DestAddr, SrcAddr, OriginalType,
560 [this, Copy, SrcVD, DestVD](Address DestElement, Address SrcElement) {
561 // Working with the single array element, so have to remap
562 // destination and source variables to corresponding array
564 CodeGenFunction::OMPPrivateScope Remap(*this);
565 Remap.addPrivate(DestVD, [DestElement]() -> Address {
569 SrcVD, [SrcElement]() -> Address { return SrcElement; });
570 (void)Remap.Privatize();
571 EmitIgnoredExpr(Copy);
575 // Remap pseudo source variable to private copy.
576 CodeGenFunction::OMPPrivateScope Remap(*this);
577 Remap.addPrivate(SrcVD, [SrcAddr]() -> Address { return SrcAddr; });
578 Remap.addPrivate(DestVD, [DestAddr]() -> Address { return DestAddr; });
579 (void)Remap.Privatize();
580 // Emit copying of the whole variable.
581 EmitIgnoredExpr(Copy);
585 bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
586 OMPPrivateScope &PrivateScope) {
587 if (!HaveInsertPoint())
589 bool FirstprivateIsLastprivate = false;
590 llvm::DenseSet<const VarDecl *> Lastprivates;
591 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
592 for (const auto *D : C->varlists())
594 cast<VarDecl>(cast<DeclRefExpr>(D)->getDecl())->getCanonicalDecl());
596 llvm::DenseSet<const VarDecl *> EmittedAsFirstprivate;
597 CGCapturedStmtInfo CapturesInfo(cast<CapturedStmt>(*D.getAssociatedStmt()));
598 for (const auto *C : D.getClausesOfKind<OMPFirstprivateClause>()) {
599 auto IRef = C->varlist_begin();
600 auto InitsRef = C->inits().begin();
601 for (auto IInit : C->private_copies()) {
602 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
603 bool ThisFirstprivateIsLastprivate =
604 Lastprivates.count(OrigVD->getCanonicalDecl()) > 0;
605 auto *CapFD = CapturesInfo.lookup(OrigVD);
606 auto *FD = CapturedStmtInfo->lookup(OrigVD);
607 if (!ThisFirstprivateIsLastprivate && FD && (FD == CapFD) &&
608 !FD->getType()->isReferenceType()) {
609 EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl());
614 FirstprivateIsLastprivate =
615 FirstprivateIsLastprivate || ThisFirstprivateIsLastprivate;
616 if (EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()).second) {
617 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
618 auto *VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
620 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),
621 /*RefersToEnclosingVariableOrCapture=*/FD != nullptr,
622 (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
623 Address OriginalAddr = EmitLValue(&DRE).getAddress();
624 QualType Type = VD->getType();
625 if (Type->isArrayType()) {
626 // Emit VarDecl with copy init for arrays.
627 // Get the address of the original variable captured in current
629 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address {
630 auto Emission = EmitAutoVarAlloca(*VD);
631 auto *Init = VD->getInit();
632 if (!isa<CXXConstructExpr>(Init) || isTrivialInitializer(Init)) {
633 // Perform simple memcpy.
634 EmitAggregateAssign(Emission.getAllocatedAddress(), OriginalAddr,
637 EmitOMPAggregateAssign(
638 Emission.getAllocatedAddress(), OriginalAddr, Type,
639 [this, VDInit, Init](Address DestElement,
640 Address SrcElement) {
641 // Clean up any temporaries needed by the initialization.
642 RunCleanupsScope InitScope(*this);
643 // Emit initialization for single element.
644 setAddrOfLocalVar(VDInit, SrcElement);
645 EmitAnyExprToMem(Init, DestElement,
646 Init->getType().getQualifiers(),
647 /*IsInitializer*/ false);
648 LocalDeclMap.erase(VDInit);
651 EmitAutoVarCleanups(Emission);
652 return Emission.getAllocatedAddress();
655 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address {
656 // Emit private VarDecl with copy init.
657 // Remap temp VDInit variable to the address of the original
659 // (for proper handling of captured global variables).
660 setAddrOfLocalVar(VDInit, OriginalAddr);
662 LocalDeclMap.erase(VDInit);
663 return GetAddrOfLocalVar(VD);
666 assert(IsRegistered &&
667 "firstprivate var already registered as private");
668 // Silence the warning about unused variable.
675 return FirstprivateIsLastprivate && !EmittedAsFirstprivate.empty();
678 void CodeGenFunction::EmitOMPPrivateClause(
679 const OMPExecutableDirective &D,
680 CodeGenFunction::OMPPrivateScope &PrivateScope) {
681 if (!HaveInsertPoint())
683 llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
684 for (const auto *C : D.getClausesOfKind<OMPPrivateClause>()) {
685 auto IRef = C->varlist_begin();
686 for (auto IInit : C->private_copies()) {
687 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
688 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
689 auto VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
691 PrivateScope.addPrivate(OrigVD, [&]() -> Address {
692 // Emit private VarDecl with copy init.
694 return GetAddrOfLocalVar(VD);
696 assert(IsRegistered && "private var already registered as private");
697 // Silence the warning about unused variable.
705 bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) {
706 if (!HaveInsertPoint())
708 // threadprivate_var1 = master_threadprivate_var1;
709 // operator=(threadprivate_var2, master_threadprivate_var2);
711 // __kmpc_barrier(&loc, global_tid);
712 llvm::DenseSet<const VarDecl *> CopiedVars;
713 llvm::BasicBlock *CopyBegin = nullptr, *CopyEnd = nullptr;
714 for (const auto *C : D.getClausesOfKind<OMPCopyinClause>()) {
715 auto IRef = C->varlist_begin();
716 auto ISrcRef = C->source_exprs().begin();
717 auto IDestRef = C->destination_exprs().begin();
718 for (auto *AssignOp : C->assignment_ops()) {
719 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
720 QualType Type = VD->getType();
721 if (CopiedVars.insert(VD->getCanonicalDecl()).second) {
722 // Get the address of the master variable. If we are emitting code with
723 // TLS support, the address is passed from the master as field in the
724 // captured declaration.
725 Address MasterAddr = Address::invalid();
726 if (getLangOpts().OpenMPUseTLS &&
727 getContext().getTargetInfo().isTLSSupported()) {
728 assert(CapturedStmtInfo->lookup(VD) &&
729 "Copyin threadprivates should have been captured!");
730 DeclRefExpr DRE(const_cast<VarDecl *>(VD), true, (*IRef)->getType(),
731 VK_LValue, (*IRef)->getExprLoc());
732 MasterAddr = EmitLValue(&DRE).getAddress();
733 LocalDeclMap.erase(VD);
736 Address(VD->isStaticLocal() ? CGM.getStaticLocalDeclAddress(VD)
737 : CGM.GetAddrOfGlobal(VD),
738 getContext().getDeclAlign(VD));
740 // Get the address of the threadprivate variable.
741 Address PrivateAddr = EmitLValue(*IRef).getAddress();
742 if (CopiedVars.size() == 1) {
743 // At first check if current thread is a master thread. If it is, no
744 // need to copy data.
745 CopyBegin = createBasicBlock("copyin.not.master");
746 CopyEnd = createBasicBlock("copyin.not.master.end");
747 Builder.CreateCondBr(
748 Builder.CreateICmpNE(
749 Builder.CreatePtrToInt(MasterAddr.getPointer(), CGM.IntPtrTy),
750 Builder.CreatePtrToInt(PrivateAddr.getPointer(), CGM.IntPtrTy)),
752 EmitBlock(CopyBegin);
754 auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
755 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
756 EmitOMPCopy(Type, PrivateAddr, MasterAddr, DestVD, SrcVD, AssignOp);
764 // Exit out of copying procedure for non-master thread.
765 EmitBlock(CopyEnd, /*IsFinished=*/true);
771 bool CodeGenFunction::EmitOMPLastprivateClauseInit(
772 const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) {
773 if (!HaveInsertPoint())
775 bool HasAtLeastOneLastprivate = false;
776 llvm::DenseSet<const VarDecl *> SIMDLCVs;
777 if (isOpenMPSimdDirective(D.getDirectiveKind())) {
778 auto *LoopDirective = cast<OMPLoopDirective>(&D);
779 for (auto *C : LoopDirective->counters()) {
781 cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl());
784 llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
785 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
786 HasAtLeastOneLastprivate = true;
787 if (isOpenMPTaskLoopDirective(D.getDirectiveKind()))
789 auto IRef = C->varlist_begin();
790 auto IDestRef = C->destination_exprs().begin();
791 for (auto *IInit : C->private_copies()) {
792 // Keep the address of the original variable for future update at the end
794 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
795 // Taskloops do not require additional initialization, it is done in
796 // runtime support library.
797 if (AlreadyEmittedVars.insert(OrigVD->getCanonicalDecl()).second) {
798 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
799 PrivateScope.addPrivate(DestVD, [this, OrigVD, IRef]() -> Address {
801 const_cast<VarDecl *>(OrigVD),
802 /*RefersToEnclosingVariableOrCapture=*/CapturedStmtInfo->lookup(
804 (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
805 return EmitLValue(&DRE).getAddress();
807 // Check if the variable is also a firstprivate: in this case IInit is
808 // not generated. Initialization of this variable will happen in codegen
809 // for 'firstprivate' clause.
810 if (IInit && !SIMDLCVs.count(OrigVD->getCanonicalDecl())) {
811 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
812 bool IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address {
813 // Emit private VarDecl with copy init.
815 return GetAddrOfLocalVar(VD);
817 assert(IsRegistered &&
818 "lastprivate var already registered as private");
826 return HasAtLeastOneLastprivate;
829 void CodeGenFunction::EmitOMPLastprivateClauseFinal(
830 const OMPExecutableDirective &D, bool NoFinals,
831 llvm::Value *IsLastIterCond) {
832 if (!HaveInsertPoint())
834 // Emit following code:
835 // if (<IsLastIterCond>) {
836 // orig_var1 = private_orig_var1;
838 // orig_varn = private_orig_varn;
840 llvm::BasicBlock *ThenBB = nullptr;
841 llvm::BasicBlock *DoneBB = nullptr;
842 if (IsLastIterCond) {
843 ThenBB = createBasicBlock(".omp.lastprivate.then");
844 DoneBB = createBasicBlock(".omp.lastprivate.done");
845 Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB);
848 llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
849 llvm::DenseMap<const VarDecl *, const Expr *> LoopCountersAndUpdates;
850 if (auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) {
851 auto IC = LoopDirective->counters().begin();
852 for (auto F : LoopDirective->finals()) {
854 cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl())->getCanonicalDecl();
856 AlreadyEmittedVars.insert(D);
858 LoopCountersAndUpdates[D] = F;
862 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
863 auto IRef = C->varlist_begin();
864 auto ISrcRef = C->source_exprs().begin();
865 auto IDestRef = C->destination_exprs().begin();
866 for (auto *AssignOp : C->assignment_ops()) {
867 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
868 QualType Type = PrivateVD->getType();
869 auto *CanonicalVD = PrivateVD->getCanonicalDecl();
870 if (AlreadyEmittedVars.insert(CanonicalVD).second) {
871 // If lastprivate variable is a loop control variable for loop-based
872 // directive, update its value before copyin back to original
874 if (auto *FinalExpr = LoopCountersAndUpdates.lookup(CanonicalVD))
875 EmitIgnoredExpr(FinalExpr);
876 auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
877 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
878 // Get the address of the original variable.
879 Address OriginalAddr = GetAddrOfLocalVar(DestVD);
880 // Get the address of the private variable.
881 Address PrivateAddr = GetAddrOfLocalVar(PrivateVD);
882 if (auto RefTy = PrivateVD->getType()->getAs<ReferenceType>())
884 Address(Builder.CreateLoad(PrivateAddr),
885 getNaturalTypeAlignment(RefTy->getPointeeType()));
886 EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp);
892 if (auto *PostUpdate = C->getPostUpdateExpr())
893 EmitIgnoredExpr(PostUpdate);
896 EmitBlock(DoneBB, /*IsFinished=*/true);
899 static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
900 LValue BaseLV, llvm::Value *Addr) {
901 Address Tmp = Address::invalid();
902 Address TopTmp = Address::invalid();
903 Address MostTopTmp = Address::invalid();
904 BaseTy = BaseTy.getNonReferenceType();
905 while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
906 !CGF.getContext().hasSameType(BaseTy, ElTy)) {
907 Tmp = CGF.CreateMemTemp(BaseTy);
908 if (TopTmp.isValid())
909 CGF.Builder.CreateStore(Tmp.getPointer(), TopTmp);
913 BaseTy = BaseTy->getPointeeType();
915 llvm::Type *Ty = BaseLV.getPointer()->getType();
917 Ty = Tmp.getElementType();
918 Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Ty);
920 CGF.Builder.CreateStore(Addr, Tmp);
923 return Address(Addr, BaseLV.getAlignment());
926 static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
928 BaseTy = BaseTy.getNonReferenceType();
929 while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
930 !CGF.getContext().hasSameType(BaseTy, ElTy)) {
931 if (auto *PtrTy = BaseTy->getAs<PointerType>())
932 BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(), PtrTy);
934 BaseLV = CGF.EmitLoadOfReferenceLValue(BaseLV.getAddress(),
935 BaseTy->castAs<ReferenceType>());
937 BaseTy = BaseTy->getPointeeType();
939 return CGF.MakeAddrLValue(
941 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
942 BaseLV.getPointer(), CGF.ConvertTypeForMem(ElTy)->getPointerTo()),
943 BaseLV.getAlignment()),
944 BaseLV.getType(), BaseLV.getAlignmentSource());
947 void CodeGenFunction::EmitOMPReductionClauseInit(
948 const OMPExecutableDirective &D,
949 CodeGenFunction::OMPPrivateScope &PrivateScope) {
950 if (!HaveInsertPoint())
952 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
953 auto ILHS = C->lhs_exprs().begin();
954 auto IRHS = C->rhs_exprs().begin();
955 auto IPriv = C->privates().begin();
956 auto IRed = C->reduction_ops().begin();
957 for (auto IRef : C->varlists()) {
958 auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
959 auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
960 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl());
961 auto *DRD = getReductionInit(*IRed);
962 if (auto *OASE = dyn_cast<OMPArraySectionExpr>(IRef)) {
963 auto *Base = OASE->getBase()->IgnoreParenImpCasts();
964 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
965 Base = TempOASE->getBase()->IgnoreParenImpCasts();
966 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
967 Base = TempASE->getBase()->IgnoreParenImpCasts();
968 auto *DE = cast<DeclRefExpr>(Base);
969 auto *OrigVD = cast<VarDecl>(DE->getDecl());
970 auto OASELValueLB = EmitOMPArraySectionExpr(OASE);
972 EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false);
973 auto OriginalBaseLValue = EmitLValue(DE);
975 loadToBegin(*this, OrigVD->getType(), OASELValueLB.getType(),
977 // Store the address of the original variable associated with the LHS
978 // implicit variable.
979 PrivateScope.addPrivate(LHSVD, [this, OASELValueLB]() -> Address {
980 return OASELValueLB.getAddress();
982 // Emit reduction copy.
983 bool IsRegistered = PrivateScope.addPrivate(
984 OrigVD, [this, OrigVD, PrivateVD, BaseLValue, OASELValueLB,
985 OASELValueUB, OriginalBaseLValue, DRD, IRed]() -> Address {
986 // Emit VarDecl with copy init for arrays.
987 // Get the address of the original variable captured in current
989 auto *Size = Builder.CreatePtrDiff(OASELValueUB.getPointer(),
990 OASELValueLB.getPointer());
991 Size = Builder.CreateNUWAdd(
992 Size, llvm::ConstantInt::get(Size->getType(), /*V=*/1));
993 CodeGenFunction::OpaqueValueMapping OpaqueMap(
994 *this, cast<OpaqueValueExpr>(
996 .getAsVariableArrayType(PrivateVD->getType())
999 EmitVariablyModifiedType(PrivateVD->getType());
1000 auto Emission = EmitAutoVarAlloca(*PrivateVD);
1001 auto Addr = Emission.getAllocatedAddress();
1002 auto *Init = PrivateVD->getInit();
1003 EmitOMPAggregateInit(*this, Addr, PrivateVD->getType(),
1005 OASELValueLB.getAddress());
1006 EmitAutoVarCleanups(Emission);
1007 // Emit private VarDecl with reduction init.
1008 auto *Offset = Builder.CreatePtrDiff(BaseLValue.getPointer(),
1009 OASELValueLB.getPointer());
1010 auto *Ptr = Builder.CreateGEP(Addr.getPointer(), Offset);
1011 return castToBase(*this, OrigVD->getType(),
1012 OASELValueLB.getType(), OriginalBaseLValue,
1015 assert(IsRegistered && "private var already registered as private");
1016 // Silence the warning about unused variable.
1018 PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address {
1019 return GetAddrOfLocalVar(PrivateVD);
1021 } else if (auto *ASE = dyn_cast<ArraySubscriptExpr>(IRef)) {
1022 auto *Base = ASE->getBase()->IgnoreParenImpCasts();
1023 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
1024 Base = TempASE->getBase()->IgnoreParenImpCasts();
1025 auto *DE = cast<DeclRefExpr>(Base);
1026 auto *OrigVD = cast<VarDecl>(DE->getDecl());
1027 auto ASELValue = EmitLValue(ASE);
1028 auto OriginalBaseLValue = EmitLValue(DE);
1029 LValue BaseLValue = loadToBegin(
1030 *this, OrigVD->getType(), ASELValue.getType(), OriginalBaseLValue);
1031 // Store the address of the original variable associated with the LHS
1032 // implicit variable.
1033 PrivateScope.addPrivate(LHSVD, [this, ASELValue]() -> Address {
1034 return ASELValue.getAddress();
1036 // Emit reduction copy.
1037 bool IsRegistered = PrivateScope.addPrivate(
1038 OrigVD, [this, OrigVD, PrivateVD, BaseLValue, ASELValue,
1039 OriginalBaseLValue, DRD, IRed]() -> Address {
1040 // Emit private VarDecl with reduction init.
1041 AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD);
1042 auto Addr = Emission.getAllocatedAddress();
1043 if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
1044 emitInitWithReductionInitializer(*this, DRD, *IRed, Addr,
1045 ASELValue.getAddress(),
1046 ASELValue.getType());
1048 EmitAutoVarInit(Emission);
1049 EmitAutoVarCleanups(Emission);
1050 auto *Offset = Builder.CreatePtrDiff(BaseLValue.getPointer(),
1051 ASELValue.getPointer());
1052 auto *Ptr = Builder.CreateGEP(Addr.getPointer(), Offset);
1053 return castToBase(*this, OrigVD->getType(), ASELValue.getType(),
1054 OriginalBaseLValue, Ptr);
1056 assert(IsRegistered && "private var already registered as private");
1057 // Silence the warning about unused variable.
1059 PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() -> Address {
1060 return Builder.CreateElementBitCast(
1061 GetAddrOfLocalVar(PrivateVD), ConvertTypeForMem(RHSVD->getType()),
1065 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl());
1066 QualType Type = PrivateVD->getType();
1067 if (getContext().getAsArrayType(Type)) {
1068 // Store the address of the original variable associated with the LHS
1069 // implicit variable.
1070 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),
1071 CapturedStmtInfo->lookup(OrigVD) != nullptr,
1072 IRef->getType(), VK_LValue, IRef->getExprLoc());
1073 Address OriginalAddr = EmitLValue(&DRE).getAddress();
1074 PrivateScope.addPrivate(LHSVD, [this, &OriginalAddr,
1075 LHSVD]() -> Address {
1076 OriginalAddr = Builder.CreateElementBitCast(
1077 OriginalAddr, ConvertTypeForMem(LHSVD->getType()), "lhs.begin");
1078 return OriginalAddr;
1080 bool IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address {
1081 if (Type->isVariablyModifiedType()) {
1082 CodeGenFunction::OpaqueValueMapping OpaqueMap(
1083 *this, cast<OpaqueValueExpr>(
1085 .getAsVariableArrayType(PrivateVD->getType())
1088 getTypeSize(OrigVD->getType().getNonReferenceType())));
1089 EmitVariablyModifiedType(Type);
1091 auto Emission = EmitAutoVarAlloca(*PrivateVD);
1092 auto Addr = Emission.getAllocatedAddress();
1093 auto *Init = PrivateVD->getInit();
1094 EmitOMPAggregateInit(*this, Addr, PrivateVD->getType(),
1095 DRD ? *IRed : Init, OriginalAddr);
1096 EmitAutoVarCleanups(Emission);
1097 return Emission.getAllocatedAddress();
1099 assert(IsRegistered && "private var already registered as private");
1100 // Silence the warning about unused variable.
1102 PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() -> Address {
1103 return Builder.CreateElementBitCast(
1104 GetAddrOfLocalVar(PrivateVD),
1105 ConvertTypeForMem(RHSVD->getType()), "rhs.begin");
1108 // Store the address of the original variable associated with the LHS
1109 // implicit variable.
1110 Address OriginalAddr = Address::invalid();
1111 PrivateScope.addPrivate(LHSVD, [this, OrigVD, IRef,
1112 &OriginalAddr]() -> Address {
1113 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),
1114 CapturedStmtInfo->lookup(OrigVD) != nullptr,
1115 IRef->getType(), VK_LValue, IRef->getExprLoc());
1116 OriginalAddr = EmitLValue(&DRE).getAddress();
1117 return OriginalAddr;
1119 // Emit reduction copy.
1120 bool IsRegistered = PrivateScope.addPrivate(
1121 OrigVD, [this, PrivateVD, OriginalAddr, DRD, IRed]() -> Address {
1122 // Emit private VarDecl with reduction init.
1123 AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD);
1124 auto Addr = Emission.getAllocatedAddress();
1125 if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
1126 emitInitWithReductionInitializer(*this, DRD, *IRed, Addr,
1128 PrivateVD->getType());
1130 EmitAutoVarInit(Emission);
1131 EmitAutoVarCleanups(Emission);
1134 assert(IsRegistered && "private var already registered as private");
1135 // Silence the warning about unused variable.
1137 PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address {
1138 return GetAddrOfLocalVar(PrivateVD);
1150 void CodeGenFunction::EmitOMPReductionClauseFinal(
1151 const OMPExecutableDirective &D) {
1152 if (!HaveInsertPoint())
1154 llvm::SmallVector<const Expr *, 8> Privates;
1155 llvm::SmallVector<const Expr *, 8> LHSExprs;
1156 llvm::SmallVector<const Expr *, 8> RHSExprs;
1157 llvm::SmallVector<const Expr *, 8> ReductionOps;
1158 bool HasAtLeastOneReduction = false;
1159 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
1160 HasAtLeastOneReduction = true;
1161 Privates.append(C->privates().begin(), C->privates().end());
1162 LHSExprs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
1163 RHSExprs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
1164 ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
1166 if (HasAtLeastOneReduction) {
1167 // Emit nowait reduction if nowait clause is present or directive is a
1168 // parallel directive (it always has implicit barrier).
1169 CGM.getOpenMPRuntime().emitReduction(
1170 *this, D.getLocEnd(), Privates, LHSExprs, RHSExprs, ReductionOps,
1171 D.getSingleClause<OMPNowaitClause>() ||
1172 isOpenMPParallelDirective(D.getDirectiveKind()) ||
1173 D.getDirectiveKind() == OMPD_simd,
1174 D.getDirectiveKind() == OMPD_simd);
1178 static void emitPostUpdateForReductionClause(
1179 CodeGenFunction &CGF, const OMPExecutableDirective &D,
1180 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen) {
1181 if (!CGF.HaveInsertPoint())
1183 llvm::BasicBlock *DoneBB = nullptr;
1184 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
1185 if (auto *PostUpdate = C->getPostUpdateExpr()) {
1187 if (auto *Cond = CondGen(CGF)) {
1188 // If the first post-update expression is found, emit conditional
1189 // block if it was requested.
1190 auto *ThenBB = CGF.createBasicBlock(".omp.reduction.pu");
1191 DoneBB = CGF.createBasicBlock(".omp.reduction.pu.done");
1192 CGF.Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1193 CGF.EmitBlock(ThenBB);
1196 CGF.EmitIgnoredExpr(PostUpdate);
1200 CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
1203 static void emitCommonOMPParallelDirective(CodeGenFunction &CGF,
1204 const OMPExecutableDirective &S,
1205 OpenMPDirectiveKind InnermostKind,
1206 const RegionCodeGenTy &CodeGen) {
1207 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
1208 auto OutlinedFn = CGF.CGM.getOpenMPRuntime().
1209 emitParallelOrTeamsOutlinedFunction(S,
1210 *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
1211 if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>()) {
1212 CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
1213 auto NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(),
1214 /*IgnoreResultAssign*/ true);
1215 CGF.CGM.getOpenMPRuntime().emitNumThreadsClause(
1216 CGF, NumThreads, NumThreadsClause->getLocStart());
1218 if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>()) {
1219 CodeGenFunction::RunCleanupsScope ProcBindScope(CGF);
1220 CGF.CGM.getOpenMPRuntime().emitProcBindClause(
1221 CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getLocStart());
1223 const Expr *IfCond = nullptr;
1224 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
1225 if (C->getNameModifier() == OMPD_unknown ||
1226 C->getNameModifier() == OMPD_parallel) {
1227 IfCond = C->getCondition();
1232 OMPLexicalScope Scope(CGF, S);
1233 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
1234 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
1235 CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getLocStart(), OutlinedFn,
1236 CapturedVars, IfCond);
1239 void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
1240 // Emit parallel region as a standalone region.
1241 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
1242 OMPPrivateScope PrivateScope(CGF);
1243 bool Copyins = CGF.EmitOMPCopyinClause(S);
1244 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
1246 // Emit implicit barrier to synchronize threads and avoid data races on
1247 // propagation master's thread values of threadprivate variables to local
1248 // instances of that variables of all other implicit threads.
1249 CGF.CGM.getOpenMPRuntime().emitBarrierCall(
1250 CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
1251 /*ForceSimpleCall=*/true);
1253 CGF.EmitOMPPrivateClause(S, PrivateScope);
1254 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
1255 (void)PrivateScope.Privatize();
1256 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
1257 CGF.EmitOMPReductionClauseFinal(S);
1259 emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen);
1260 emitPostUpdateForReductionClause(
1261 *this, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
1264 void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D,
1265 JumpDest LoopExit) {
1266 RunCleanupsScope BodyScope(*this);
1267 // Update counters values on current iteration.
1268 for (auto I : D.updates()) {
1271 // Update the linear variables.
1272 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
1273 for (auto *U : C->updates())
1277 // On a continue in the body, jump to the end.
1278 auto Continue = getJumpDestInCurrentScope("omp.body.continue");
1279 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1281 EmitStmt(D.getBody());
1282 // The end (updates/cleanups).
1283 EmitBlock(Continue.getBlock());
1284 BreakContinueStack.pop_back();
1287 void CodeGenFunction::EmitOMPInnerLoop(
1288 const Stmt &S, bool RequiresCleanup, const Expr *LoopCond,
1289 const Expr *IncExpr,
1290 const llvm::function_ref<void(CodeGenFunction &)> &BodyGen,
1291 const llvm::function_ref<void(CodeGenFunction &)> &PostIncGen) {
1292 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
1294 // Start the loop with a block that tests the condition.
1295 auto CondBlock = createBasicBlock("omp.inner.for.cond");
1296 EmitBlock(CondBlock);
1297 LoopStack.push(CondBlock, Builder.getCurrentDebugLocation());
1299 // If there are any cleanups between here and the loop-exit scope,
1300 // create a block to stage a loop exit along.
1301 auto ExitBlock = LoopExit.getBlock();
1302 if (RequiresCleanup)
1303 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
1305 auto LoopBody = createBasicBlock("omp.inner.for.body");
1308 EmitBranchOnBoolExpr(LoopCond, LoopBody, ExitBlock, getProfileCount(&S));
1309 if (ExitBlock != LoopExit.getBlock()) {
1310 EmitBlock(ExitBlock);
1311 EmitBranchThroughCleanup(LoopExit);
1314 EmitBlock(LoopBody);
1315 incrementProfileCounter(&S);
1317 // Create a block for the increment.
1318 auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
1319 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1323 // Emit "IV = IV + 1" and a back-edge to the condition block.
1324 EmitBlock(Continue.getBlock());
1325 EmitIgnoredExpr(IncExpr);
1327 BreakContinueStack.pop_back();
1328 EmitBranch(CondBlock);
1330 // Emit the fall-through block.
1331 EmitBlock(LoopExit.getBlock());
1334 void CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) {
1335 if (!HaveInsertPoint())
1337 // Emit inits for the linear variables.
1338 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
1339 for (auto *Init : C->inits()) {
1340 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl());
1341 if (auto *Ref = dyn_cast<DeclRefExpr>(VD->getInit()->IgnoreImpCasts())) {
1342 AutoVarEmission Emission = EmitAutoVarAlloca(*VD);
1343 auto *OrigVD = cast<VarDecl>(Ref->getDecl());
1344 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),
1345 CapturedStmtInfo->lookup(OrigVD) != nullptr,
1346 VD->getInit()->getType(), VK_LValue,
1347 VD->getInit()->getExprLoc());
1348 EmitExprAsInit(&DRE, VD, MakeAddrLValue(Emission.getAllocatedAddress(),
1350 /*capturedByInit=*/false);
1351 EmitAutoVarCleanups(Emission);
1355 // Emit the linear steps for the linear clauses.
1356 // If a step is not constant, it is pre-calculated before the loop.
1357 if (auto CS = cast_or_null<BinaryOperator>(C->getCalcStep()))
1358 if (auto SaveRef = cast<DeclRefExpr>(CS->getLHS())) {
1359 EmitVarDecl(*cast<VarDecl>(SaveRef->getDecl()));
1360 // Emit calculation of the linear step.
1361 EmitIgnoredExpr(CS);
1366 void CodeGenFunction::EmitOMPLinearClauseFinal(
1367 const OMPLoopDirective &D,
1368 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen) {
1369 if (!HaveInsertPoint())
1371 llvm::BasicBlock *DoneBB = nullptr;
1372 // Emit the final values of the linear variables.
1373 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
1374 auto IC = C->varlist_begin();
1375 for (auto *F : C->finals()) {
1377 if (auto *Cond = CondGen(*this)) {
1378 // If the first post-update expression is found, emit conditional
1379 // block if it was requested.
1380 auto *ThenBB = createBasicBlock(".omp.linear.pu");
1381 DoneBB = createBasicBlock(".omp.linear.pu.done");
1382 Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1386 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl());
1387 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),
1388 CapturedStmtInfo->lookup(OrigVD) != nullptr,
1389 (*IC)->getType(), VK_LValue, (*IC)->getExprLoc());
1390 Address OrigAddr = EmitLValue(&DRE).getAddress();
1391 CodeGenFunction::OMPPrivateScope VarScope(*this);
1392 VarScope.addPrivate(OrigVD, [OrigAddr]() -> Address { return OrigAddr; });
1393 (void)VarScope.Privatize();
1397 if (auto *PostUpdate = C->getPostUpdateExpr())
1398 EmitIgnoredExpr(PostUpdate);
1401 EmitBlock(DoneBB, /*IsFinished=*/true);
1404 static void emitAlignedClause(CodeGenFunction &CGF,
1405 const OMPExecutableDirective &D) {
1406 if (!CGF.HaveInsertPoint())
1408 for (const auto *Clause : D.getClausesOfKind<OMPAlignedClause>()) {
1409 unsigned ClauseAlignment = 0;
1410 if (auto AlignmentExpr = Clause->getAlignment()) {
1412 cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
1413 ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue());
1415 for (auto E : Clause->varlists()) {
1416 unsigned Alignment = ClauseAlignment;
1417 if (Alignment == 0) {
1418 // OpenMP [2.8.1, Description]
1419 // If no optional parameter is specified, implementation-defined default
1420 // alignments for SIMD instructions on the target platforms are assumed.
1423 .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign(
1424 E->getType()->getPointeeType()))
1427 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
1428 "alignment is not power of 2");
1429 if (Alignment != 0) {
1430 llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
1431 CGF.EmitAlignmentAssumption(PtrValue, Alignment);
1437 void CodeGenFunction::EmitOMPPrivateLoopCounters(
1438 const OMPLoopDirective &S, CodeGenFunction::OMPPrivateScope &LoopScope) {
1439 if (!HaveInsertPoint())
1441 auto I = S.private_counters().begin();
1442 for (auto *E : S.counters()) {
1443 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
1444 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl());
1445 (void)LoopScope.addPrivate(VD, [&]() -> Address {
1446 // Emit var without initialization.
1447 if (!LocalDeclMap.count(PrivateVD)) {
1448 auto VarEmission = EmitAutoVarAlloca(*PrivateVD);
1449 EmitAutoVarCleanups(VarEmission);
1451 DeclRefExpr DRE(const_cast<VarDecl *>(PrivateVD),
1452 /*RefersToEnclosingVariableOrCapture=*/false,
1453 (*I)->getType(), VK_LValue, (*I)->getExprLoc());
1454 return EmitLValue(&DRE).getAddress();
1456 if (LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD) ||
1457 VD->hasGlobalStorage()) {
1458 (void)LoopScope.addPrivate(PrivateVD, [&]() -> Address {
1459 DeclRefExpr DRE(const_cast<VarDecl *>(VD),
1460 LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD),
1461 E->getType(), VK_LValue, E->getExprLoc());
1462 return EmitLValue(&DRE).getAddress();
1469 static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S,
1470 const Expr *Cond, llvm::BasicBlock *TrueBlock,
1471 llvm::BasicBlock *FalseBlock, uint64_t TrueCount) {
1472 if (!CGF.HaveInsertPoint())
1475 CodeGenFunction::OMPPrivateScope PreCondScope(CGF);
1476 CGF.EmitOMPPrivateLoopCounters(S, PreCondScope);
1477 (void)PreCondScope.Privatize();
1478 // Get initial values of real counters.
1479 for (auto I : S.inits()) {
1480 CGF.EmitIgnoredExpr(I);
1483 // Check that loop is executed at least one time.
1484 CGF.EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount);
1487 void CodeGenFunction::EmitOMPLinearClause(
1488 const OMPLoopDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) {
1489 if (!HaveInsertPoint())
1491 llvm::DenseSet<const VarDecl *> SIMDLCVs;
1492 if (isOpenMPSimdDirective(D.getDirectiveKind())) {
1493 auto *LoopDirective = cast<OMPLoopDirective>(&D);
1494 for (auto *C : LoopDirective->counters()) {
1496 cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl());
1499 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
1500 auto CurPrivate = C->privates().begin();
1501 for (auto *E : C->varlists()) {
1502 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
1504 cast<VarDecl>(cast<DeclRefExpr>(*CurPrivate)->getDecl());
1505 if (!SIMDLCVs.count(VD->getCanonicalDecl())) {
1506 bool IsRegistered = PrivateScope.addPrivate(VD, [&]() -> Address {
1507 // Emit private VarDecl with copy init.
1508 EmitVarDecl(*PrivateVD);
1509 return GetAddrOfLocalVar(PrivateVD);
1511 assert(IsRegistered && "linear var already registered as private");
1512 // Silence the warning about unused variable.
1515 EmitVarDecl(*PrivateVD);
1521 static void emitSimdlenSafelenClause(CodeGenFunction &CGF,
1522 const OMPExecutableDirective &D,
1524 if (!CGF.HaveInsertPoint())
1526 if (const auto *C = D.getSingleClause<OMPSimdlenClause>()) {
1527 RValue Len = CGF.EmitAnyExpr(C->getSimdlen(), AggValueSlot::ignored(),
1528 /*ignoreResult=*/true);
1529 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
1530 CGF.LoopStack.setVectorizeWidth(Val->getZExtValue());
1531 // In presence of finite 'safelen', it may be unsafe to mark all
1532 // the memory instructions parallel, because loop-carried
1533 // dependences of 'safelen' iterations are possible.
1535 CGF.LoopStack.setParallel(!D.getSingleClause<OMPSafelenClause>());
1536 } else if (const auto *C = D.getSingleClause<OMPSafelenClause>()) {
1537 RValue Len = CGF.EmitAnyExpr(C->getSafelen(), AggValueSlot::ignored(),
1538 /*ignoreResult=*/true);
1539 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
1540 CGF.LoopStack.setVectorizeWidth(Val->getZExtValue());
1541 // In presence of finite 'safelen', it may be unsafe to mark all
1542 // the memory instructions parallel, because loop-carried
1543 // dependences of 'safelen' iterations are possible.
1544 CGF.LoopStack.setParallel(false);
1548 void CodeGenFunction::EmitOMPSimdInit(const OMPLoopDirective &D,
1550 // Walk clauses and process safelen/lastprivate.
1551 LoopStack.setParallel(!IsMonotonic);
1552 LoopStack.setVectorizeEnable(true);
1553 emitSimdlenSafelenClause(*this, D, IsMonotonic);
1556 void CodeGenFunction::EmitOMPSimdFinal(
1557 const OMPLoopDirective &D,
1558 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen) {
1559 if (!HaveInsertPoint())
1561 llvm::BasicBlock *DoneBB = nullptr;
1562 auto IC = D.counters().begin();
1563 auto IPC = D.private_counters().begin();
1564 for (auto F : D.finals()) {
1565 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl());
1566 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>((*IPC))->getDecl());
1567 auto *CED = dyn_cast<OMPCapturedExprDecl>(OrigVD);
1568 if (LocalDeclMap.count(OrigVD) || CapturedStmtInfo->lookup(OrigVD) ||
1569 OrigVD->hasGlobalStorage() || CED) {
1571 if (auto *Cond = CondGen(*this)) {
1572 // If the first post-update expression is found, emit conditional
1573 // block if it was requested.
1574 auto *ThenBB = createBasicBlock(".omp.final.then");
1575 DoneBB = createBasicBlock(".omp.final.done");
1576 Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1580 Address OrigAddr = Address::invalid();
1582 OrigAddr = EmitLValue(CED->getInit()->IgnoreImpCasts()).getAddress();
1584 DeclRefExpr DRE(const_cast<VarDecl *>(PrivateVD),
1585 /*RefersToEnclosingVariableOrCapture=*/false,
1586 (*IPC)->getType(), VK_LValue, (*IPC)->getExprLoc());
1587 OrigAddr = EmitLValue(&DRE).getAddress();
1589 OMPPrivateScope VarScope(*this);
1590 VarScope.addPrivate(OrigVD,
1591 [OrigAddr]() -> Address { return OrigAddr; });
1592 (void)VarScope.Privatize();
1599 EmitBlock(DoneBB, /*IsFinished=*/true);
1602 void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
1603 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
1604 OMPLoopScope PreInitScope(CGF, S);
1606 // for (IV in 0..LastIteration) BODY;
1607 // <Final counter/linear vars updates>;
1611 // Emit: if (PreCond) - begin.
1612 // If the condition constant folds and can be elided, avoid emitting the
1615 llvm::BasicBlock *ContBlock = nullptr;
1616 if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
1620 auto *ThenBlock = CGF.createBasicBlock("simd.if.then");
1621 ContBlock = CGF.createBasicBlock("simd.if.end");
1622 emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
1623 CGF.getProfileCount(&S));
1624 CGF.EmitBlock(ThenBlock);
1625 CGF.incrementProfileCounter(&S);
1628 // Emit the loop iteration variable.
1629 const Expr *IVExpr = S.getIterationVariable();
1630 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
1631 CGF.EmitVarDecl(*IVDecl);
1632 CGF.EmitIgnoredExpr(S.getInit());
1634 // Emit the iterations count variable.
1635 // If it is not a variable, Sema decided to calculate iterations count on
1636 // each iteration (e.g., it is foldable into a constant).
1637 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
1638 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
1639 // Emit calculation of the iterations count.
1640 CGF.EmitIgnoredExpr(S.getCalcLastIteration());
1643 CGF.EmitOMPSimdInit(S);
1645 emitAlignedClause(CGF, S);
1646 CGF.EmitOMPLinearClauseInit(S);
1648 OMPPrivateScope LoopScope(CGF);
1649 CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
1650 CGF.EmitOMPLinearClause(S, LoopScope);
1651 CGF.EmitOMPPrivateClause(S, LoopScope);
1652 CGF.EmitOMPReductionClauseInit(S, LoopScope);
1653 bool HasLastprivateClause =
1654 CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
1655 (void)LoopScope.Privatize();
1656 CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
1658 [&S](CodeGenFunction &CGF) {
1659 CGF.EmitOMPLoopBody(S, JumpDest());
1660 CGF.EmitStopPoint(&S);
1662 [](CodeGenFunction &) {});
1663 CGF.EmitOMPSimdFinal(
1664 S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
1665 // Emit final copy of the lastprivate variables at the end of loops.
1666 if (HasLastprivateClause)
1667 CGF.EmitOMPLastprivateClauseFinal(S, /*NoFinals=*/true);
1668 CGF.EmitOMPReductionClauseFinal(S);
1669 emitPostUpdateForReductionClause(
1670 CGF, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
1672 CGF.EmitOMPLinearClauseFinal(
1673 S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
1674 // Emit: if (PreCond) - end.
1676 CGF.EmitBranch(ContBlock);
1677 CGF.EmitBlock(ContBlock, true);
1680 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
1681 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
1684 void CodeGenFunction::EmitOMPOuterLoop(bool DynamicOrOrdered, bool IsMonotonic,
1685 const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered,
1686 Address LB, Address UB, Address ST, Address IL, llvm::Value *Chunk) {
1687 auto &RT = CGM.getOpenMPRuntime();
1689 const Expr *IVExpr = S.getIterationVariable();
1690 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
1691 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
1693 auto LoopExit = getJumpDestInCurrentScope("omp.dispatch.end");
1695 // Start the loop with a block that tests the condition.
1696 auto CondBlock = createBasicBlock("omp.dispatch.cond");
1697 EmitBlock(CondBlock);
1698 LoopStack.push(CondBlock, Builder.getCurrentDebugLocation());
1700 llvm::Value *BoolCondVal = nullptr;
1701 if (!DynamicOrOrdered) {
1702 // UB = min(UB, GlobalUB)
1703 EmitIgnoredExpr(S.getEnsureUpperBound());
1705 EmitIgnoredExpr(S.getInit());
1707 BoolCondVal = EvaluateExprAsBool(S.getCond());
1709 BoolCondVal = RT.emitForNext(*this, S.getLocStart(), IVSize, IVSigned, IL,
1713 // If there are any cleanups between here and the loop-exit scope,
1714 // create a block to stage a loop exit along.
1715 auto ExitBlock = LoopExit.getBlock();
1716 if (LoopScope.requiresCleanups())
1717 ExitBlock = createBasicBlock("omp.dispatch.cleanup");
1719 auto LoopBody = createBasicBlock("omp.dispatch.body");
1720 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
1721 if (ExitBlock != LoopExit.getBlock()) {
1722 EmitBlock(ExitBlock);
1723 EmitBranchThroughCleanup(LoopExit);
1725 EmitBlock(LoopBody);
1727 // Emit "IV = LB" (in case of static schedule, we have already calculated new
1728 // LB for loop condition and emitted it above).
1729 if (DynamicOrOrdered)
1730 EmitIgnoredExpr(S.getInit());
1732 // Create a block for the increment.
1733 auto Continue = getJumpDestInCurrentScope("omp.dispatch.inc");
1734 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1736 // Generate !llvm.loop.parallel metadata for loads and stores for loops
1737 // with dynamic/guided scheduling and without ordered clause.
1738 if (!isOpenMPSimdDirective(S.getDirectiveKind()))
1739 LoopStack.setParallel(!IsMonotonic);
1741 EmitOMPSimdInit(S, IsMonotonic);
1743 SourceLocation Loc = S.getLocStart();
1744 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(),
1745 [&S, LoopExit](CodeGenFunction &CGF) {
1746 CGF.EmitOMPLoopBody(S, LoopExit);
1747 CGF.EmitStopPoint(&S);
1749 [Ordered, IVSize, IVSigned, Loc](CodeGenFunction &CGF) {
1751 CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd(
1752 CGF, Loc, IVSize, IVSigned);
1756 EmitBlock(Continue.getBlock());
1757 BreakContinueStack.pop_back();
1758 if (!DynamicOrOrdered) {
1759 // Emit "LB = LB + Stride", "UB = UB + Stride".
1760 EmitIgnoredExpr(S.getNextLowerBound());
1761 EmitIgnoredExpr(S.getNextUpperBound());
1764 EmitBranch(CondBlock);
1766 // Emit the fall-through block.
1767 EmitBlock(LoopExit.getBlock());
1769 // Tell the runtime we are done.
1770 auto &&CodeGen = [DynamicOrOrdered, &S](CodeGenFunction &CGF) {
1771 if (!DynamicOrOrdered)
1772 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocEnd());
1774 OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen);
1777 void CodeGenFunction::EmitOMPForOuterLoop(
1778 const OpenMPScheduleTy &ScheduleKind, bool IsMonotonic,
1779 const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered,
1780 Address LB, Address UB, Address ST, Address IL, llvm::Value *Chunk) {
1781 auto &RT = CGM.getOpenMPRuntime();
1783 // Dynamic scheduling of the outer loop (dynamic, guided, auto, runtime).
1784 const bool DynamicOrOrdered =
1785 Ordered || RT.isDynamic(ScheduleKind.Schedule);
1788 !RT.isStaticNonchunked(ScheduleKind.Schedule,
1789 /*Chunked=*/Chunk != nullptr)) &&
1790 "static non-chunked schedule does not need outer loop");
1794 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
1795 // When schedule(dynamic,chunk_size) is specified, the iterations are
1796 // distributed to threads in the team in chunks as the threads request them.
1797 // Each thread executes a chunk of iterations, then requests another chunk,
1798 // until no chunks remain to be distributed. Each chunk contains chunk_size
1799 // iterations, except for the last chunk to be distributed, which may have
1800 // fewer iterations. When no chunk_size is specified, it defaults to 1.
1802 // When schedule(guided,chunk_size) is specified, the iterations are assigned
1803 // to threads in the team in chunks as the executing threads request them.
1804 // Each thread executes a chunk of iterations, then requests another chunk,
1805 // until no chunks remain to be assigned. For a chunk_size of 1, the size of
1806 // each chunk is proportional to the number of unassigned iterations divided
1807 // by the number of threads in the team, decreasing to 1. For a chunk_size
1808 // with value k (greater than 1), the size of each chunk is determined in the
1809 // same way, with the restriction that the chunks do not contain fewer than k
1810 // iterations (except for the last chunk to be assigned, which may have fewer
1811 // than k iterations).
1813 // When schedule(auto) is specified, the decision regarding scheduling is
1814 // delegated to the compiler and/or runtime system. The programmer gives the
1815 // implementation the freedom to choose any possible mapping of iterations to
1816 // threads in the team.
1818 // When schedule(runtime) is specified, the decision regarding scheduling is
1819 // deferred until run time, and the schedule and chunk size are taken from the
1820 // run-sched-var ICV. If the ICV is set to auto, the schedule is
1821 // implementation defined
1823 // while(__kmpc_dispatch_next(&LB, &UB)) {
1825 // while (idx <= UB) { BODY; ++idx;
1826 // __kmpc_dispatch_fini_(4|8)[u](); // For ordered loops only.
1830 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
1831 // When schedule(static, chunk_size) is specified, iterations are divided into
1832 // chunks of size chunk_size, and the chunks are assigned to the threads in
1833 // the team in a round-robin fashion in the order of the thread number.
1835 // while(UB = min(UB, GlobalUB), idx = LB, idx < UB) {
1836 // while (idx <= UB) { BODY; ++idx; } // inner loop
1842 const Expr *IVExpr = S.getIterationVariable();
1843 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
1844 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
1846 if (DynamicOrOrdered) {
1847 llvm::Value *UBVal = EmitScalarExpr(S.getLastIteration());
1848 RT.emitForDispatchInit(*this, S.getLocStart(), ScheduleKind, IVSize,
1849 IVSigned, Ordered, UBVal, Chunk);
1851 RT.emitForStaticInit(*this, S.getLocStart(), ScheduleKind, IVSize, IVSigned,
1852 Ordered, IL, LB, UB, ST, Chunk);
1855 EmitOMPOuterLoop(DynamicOrOrdered, IsMonotonic, S, LoopScope, Ordered, LB, UB,
1859 void CodeGenFunction::EmitOMPDistributeOuterLoop(
1860 OpenMPDistScheduleClauseKind ScheduleKind,
1861 const OMPDistributeDirective &S, OMPPrivateScope &LoopScope,
1862 Address LB, Address UB, Address ST, Address IL, llvm::Value *Chunk) {
1864 auto &RT = CGM.getOpenMPRuntime();
1867 // Same behavior as a OMPForOuterLoop, except that schedule cannot be
1871 const Expr *IVExpr = S.getIterationVariable();
1872 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
1873 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
1875 RT.emitDistributeStaticInit(*this, S.getLocStart(), ScheduleKind,
1876 IVSize, IVSigned, /* Ordered = */ false,
1877 IL, LB, UB, ST, Chunk);
1879 EmitOMPOuterLoop(/* DynamicOrOrdered = */ false, /* IsMonotonic = */ false,
1880 S, LoopScope, /* Ordered = */ false, LB, UB, ST, IL, Chunk);
1883 void CodeGenFunction::EmitOMPDistributeParallelForDirective(
1884 const OMPDistributeParallelForDirective &S) {
1885 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
1886 CGM.getOpenMPRuntime().emitInlinedDirective(
1887 *this, OMPD_distribute_parallel_for,
1888 [&S](CodeGenFunction &CGF, PrePostActionTy &) {
1889 OMPLoopScope PreInitScope(CGF, S);
1890 OMPCancelStackRAII CancelRegion(CGF, OMPD_distribute_parallel_for,
1891 /*HasCancel=*/false);
1893 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
1897 void CodeGenFunction::EmitOMPDistributeParallelForSimdDirective(
1898 const OMPDistributeParallelForSimdDirective &S) {
1899 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
1900 CGM.getOpenMPRuntime().emitInlinedDirective(
1901 *this, OMPD_distribute_parallel_for_simd,
1902 [&S](CodeGenFunction &CGF, PrePostActionTy &) {
1903 OMPLoopScope PreInitScope(CGF, S);
1905 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
1909 void CodeGenFunction::EmitOMPDistributeSimdDirective(
1910 const OMPDistributeSimdDirective &S) {
1911 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
1912 CGM.getOpenMPRuntime().emitInlinedDirective(
1913 *this, OMPD_distribute_simd,
1914 [&S](CodeGenFunction &CGF, PrePostActionTy &) {
1915 OMPLoopScope PreInitScope(CGF, S);
1917 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
1921 void CodeGenFunction::EmitOMPTargetParallelForSimdDirective(
1922 const OMPTargetParallelForSimdDirective &S) {
1923 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
1924 CGM.getOpenMPRuntime().emitInlinedDirective(
1925 *this, OMPD_target_parallel_for_simd,
1926 [&S](CodeGenFunction &CGF, PrePostActionTy &) {
1927 OMPLoopScope PreInitScope(CGF, S);
1929 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
1933 /// \brief Emit a helper variable and return corresponding lvalue.
1934 static LValue EmitOMPHelperVar(CodeGenFunction &CGF,
1935 const DeclRefExpr *Helper) {
1936 auto VDecl = cast<VarDecl>(Helper->getDecl());
1937 CGF.EmitVarDecl(*VDecl);
1938 return CGF.EmitLValue(Helper);
1942 struct ScheduleKindModifiersTy {
1943 OpenMPScheduleClauseKind Kind;
1944 OpenMPScheduleClauseModifier M1;
1945 OpenMPScheduleClauseModifier M2;
1946 ScheduleKindModifiersTy(OpenMPScheduleClauseKind Kind,
1947 OpenMPScheduleClauseModifier M1,
1948 OpenMPScheduleClauseModifier M2)
1949 : Kind(Kind), M1(M1), M2(M2) {}
1953 bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) {
1954 // Emit the loop iteration variable.
1955 auto IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
1956 auto IVDecl = cast<VarDecl>(IVExpr->getDecl());
1957 EmitVarDecl(*IVDecl);
1959 // Emit the iterations count variable.
1960 // If it is not a variable, Sema decided to calculate iterations count on each
1961 // iteration (e.g., it is foldable into a constant).
1962 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
1963 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
1964 // Emit calculation of the iterations count.
1965 EmitIgnoredExpr(S.getCalcLastIteration());
1968 auto &RT = CGM.getOpenMPRuntime();
1970 bool HasLastprivateClause;
1971 // Check pre-condition.
1973 OMPLoopScope PreInitScope(*this, S);
1974 // Skip the entire loop if we don't meet the precondition.
1975 // If the condition constant folds and can be elided, avoid emitting the
1978 llvm::BasicBlock *ContBlock = nullptr;
1979 if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
1983 auto *ThenBlock = createBasicBlock("omp.precond.then");
1984 ContBlock = createBasicBlock("omp.precond.end");
1985 emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock,
1986 getProfileCount(&S));
1987 EmitBlock(ThenBlock);
1988 incrementProfileCounter(&S);
1991 bool Ordered = false;
1992 if (auto *OrderedClause = S.getSingleClause<OMPOrderedClause>()) {
1993 if (OrderedClause->getNumForLoops())
1994 RT.emitDoacrossInit(*this, S);
1999 llvm::DenseSet<const Expr *> EmittedFinals;
2000 emitAlignedClause(*this, S);
2001 EmitOMPLinearClauseInit(S);
2002 // Emit helper vars inits.
2004 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getLowerBoundVariable()));
2006 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getUpperBoundVariable()));
2008 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable()));
2010 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
2012 // Emit 'then' code.
2014 OMPPrivateScope LoopScope(*this);
2015 if (EmitOMPFirstprivateClause(S, LoopScope)) {
2016 // Emit implicit barrier to synchronize threads and avoid data races on
2017 // initialization of firstprivate variables and post-update of
2018 // lastprivate variables.
2019 CGM.getOpenMPRuntime().emitBarrierCall(
2020 *this, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
2021 /*ForceSimpleCall=*/true);
2023 EmitOMPPrivateClause(S, LoopScope);
2024 HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
2025 EmitOMPReductionClauseInit(S, LoopScope);
2026 EmitOMPPrivateLoopCounters(S, LoopScope);
2027 EmitOMPLinearClause(S, LoopScope);
2028 (void)LoopScope.Privatize();
2030 // Detect the loop schedule kind and chunk.
2031 llvm::Value *Chunk = nullptr;
2032 OpenMPScheduleTy ScheduleKind;
2033 if (auto *C = S.getSingleClause<OMPScheduleClause>()) {
2034 ScheduleKind.Schedule = C->getScheduleKind();
2035 ScheduleKind.M1 = C->getFirstScheduleModifier();
2036 ScheduleKind.M2 = C->getSecondScheduleModifier();
2037 if (const auto *Ch = C->getChunkSize()) {
2038 Chunk = EmitScalarExpr(Ch);
2039 Chunk = EmitScalarConversion(Chunk, Ch->getType(),
2040 S.getIterationVariable()->getType(),
2044 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
2045 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
2046 // OpenMP 4.5, 2.7.1 Loop Construct, Description.
2047 // If the static schedule kind is specified or if the ordered clause is
2048 // specified, and if no monotonic modifier is specified, the effect will
2049 // be as if the monotonic modifier was specified.
2050 if (RT.isStaticNonchunked(ScheduleKind.Schedule,
2051 /* Chunked */ Chunk != nullptr) &&
2053 if (isOpenMPSimdDirective(S.getDirectiveKind()))
2054 EmitOMPSimdInit(S, /*IsMonotonic=*/true);
2055 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
2056 // When no chunk_size is specified, the iteration space is divided into
2057 // chunks that are approximately equal in size, and at most one chunk is
2058 // distributed to each thread. Note that the size of the chunks is
2059 // unspecified in this case.
2060 RT.emitForStaticInit(*this, S.getLocStart(), ScheduleKind,
2061 IVSize, IVSigned, Ordered,
2062 IL.getAddress(), LB.getAddress(),
2063 UB.getAddress(), ST.getAddress());
2065 getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit"));
2066 // UB = min(UB, GlobalUB);
2067 EmitIgnoredExpr(S.getEnsureUpperBound());
2069 EmitIgnoredExpr(S.getInit());
2070 // while (idx <= UB) { BODY; ++idx; }
2071 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
2073 [&S, LoopExit](CodeGenFunction &CGF) {
2074 CGF.EmitOMPLoopBody(S, LoopExit);
2075 CGF.EmitStopPoint(&S);
2077 [](CodeGenFunction &) {});
2078 EmitBlock(LoopExit.getBlock());
2079 // Tell the runtime we are done.
2080 auto &&CodeGen = [&S](CodeGenFunction &CGF) {
2081 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocEnd());
2083 OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen);
2085 const bool IsMonotonic =
2086 Ordered || ScheduleKind.Schedule == OMPC_SCHEDULE_static ||
2087 ScheduleKind.Schedule == OMPC_SCHEDULE_unknown ||
2088 ScheduleKind.M1 == OMPC_SCHEDULE_MODIFIER_monotonic ||
2089 ScheduleKind.M2 == OMPC_SCHEDULE_MODIFIER_monotonic;
2090 // Emit the outer loop, which requests its work chunk [LB..UB] from
2091 // runtime and runs the inner loop to process it.
2092 EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered,
2093 LB.getAddress(), UB.getAddress(), ST.getAddress(),
2094 IL.getAddress(), Chunk);
2096 if (isOpenMPSimdDirective(S.getDirectiveKind())) {
2098 [&](CodeGenFunction &CGF) -> llvm::Value * {
2099 return CGF.Builder.CreateIsNotNull(
2100 CGF.EmitLoadOfScalar(IL, S.getLocStart()));
2103 EmitOMPReductionClauseFinal(S);
2104 // Emit post-update of the reduction variables if IsLastIter != 0.
2105 emitPostUpdateForReductionClause(
2106 *this, S, [&](CodeGenFunction &CGF) -> llvm::Value * {
2107 return CGF.Builder.CreateIsNotNull(
2108 CGF.EmitLoadOfScalar(IL, S.getLocStart()));
2110 // Emit final copy of the lastprivate variables if IsLastIter != 0.
2111 if (HasLastprivateClause)
2112 EmitOMPLastprivateClauseFinal(
2113 S, isOpenMPSimdDirective(S.getDirectiveKind()),
2114 Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getLocStart())));
2116 EmitOMPLinearClauseFinal(S, [&](CodeGenFunction &CGF) -> llvm::Value * {
2117 return CGF.Builder.CreateIsNotNull(
2118 CGF.EmitLoadOfScalar(IL, S.getLocStart()));
2120 // We're now done with the loop, so jump to the continuation block.
2122 EmitBranch(ContBlock);
2123 EmitBlock(ContBlock, true);
2126 return HasLastprivateClause;
2129 void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {
2130 bool HasLastprivates = false;
2131 auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF,
2132 PrePostActionTy &) {
2133 OMPCancelStackRAII CancelRegion(CGF, OMPD_for, S.hasCancel());
2134 HasLastprivates = CGF.EmitOMPWorksharingLoop(S);
2137 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2138 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen,
2142 // Emit an implicit barrier at the end.
2143 if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) {
2144 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_for);
2148 void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) {
2149 bool HasLastprivates = false;
2150 auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF,
2151 PrePostActionTy &) {
2152 HasLastprivates = CGF.EmitOMPWorksharingLoop(S);
2155 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2156 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
2159 // Emit an implicit barrier at the end.
2160 if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) {
2161 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_for);
2165 static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty,
2167 llvm::Value *Init = nullptr) {
2168 auto LVal = CGF.MakeAddrLValue(CGF.CreateMemTemp(Ty, Name), Ty);
2170 CGF.EmitScalarInit(Init, LVal);
2174 void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
2175 auto *Stmt = cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt();
2176 auto *CS = dyn_cast<CompoundStmt>(Stmt);
2177 bool HasLastprivates = false;
2178 auto &&CodeGen = [&S, Stmt, CS, &HasLastprivates](CodeGenFunction &CGF,
2179 PrePostActionTy &) {
2180 auto &C = CGF.CGM.getContext();
2181 auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
2182 // Emit helper vars inits.
2183 LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.",
2184 CGF.Builder.getInt32(0));
2185 auto *GlobalUBVal = CS != nullptr ? CGF.Builder.getInt32(CS->size() - 1)
2186 : CGF.Builder.getInt32(0);
2188 createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal);
2189 LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.",
2190 CGF.Builder.getInt32(1));
2191 LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.",
2192 CGF.Builder.getInt32(0));
2194 LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv.");
2195 OpaqueValueExpr IVRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
2196 CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV);
2197 OpaqueValueExpr UBRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
2198 CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
2199 // Generate condition for loop.
2200 BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue,
2201 OK_Ordinary, S.getLocStart(),
2202 /*fpContractable=*/false);
2203 // Increment for loop counter.
2204 UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary,
2206 auto BodyGen = [Stmt, CS, &S, &IV](CodeGenFunction &CGF) {
2207 // Iterate through all sections and emit a switch construct:
2210 // <SectionStmt[0]>;
2213 // case <NumSection> - 1:
2214 // <SectionStmt[<NumSection> - 1]>;
2217 // .omp.sections.exit:
2218 auto *ExitBB = CGF.createBasicBlock(".omp.sections.exit");
2219 auto *SwitchStmt = CGF.Builder.CreateSwitch(
2220 CGF.EmitLoadOfLValue(IV, S.getLocStart()).getScalarVal(), ExitBB,
2221 CS == nullptr ? 1 : CS->size());
2223 unsigned CaseNumber = 0;
2224 for (auto *SubStmt : CS->children()) {
2225 auto CaseBB = CGF.createBasicBlock(".omp.sections.case");
2226 CGF.EmitBlock(CaseBB);
2227 SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB);
2228 CGF.EmitStmt(SubStmt);
2229 CGF.EmitBranch(ExitBB);
2233 auto CaseBB = CGF.createBasicBlock(".omp.sections.case");
2234 CGF.EmitBlock(CaseBB);
2235 SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB);
2237 CGF.EmitBranch(ExitBB);
2239 CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
2242 CodeGenFunction::OMPPrivateScope LoopScope(CGF);
2243 if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
2244 // Emit implicit barrier to synchronize threads and avoid data races on
2245 // initialization of firstprivate variables and post-update of lastprivate
2247 CGF.CGM.getOpenMPRuntime().emitBarrierCall(
2248 CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
2249 /*ForceSimpleCall=*/true);
2251 CGF.EmitOMPPrivateClause(S, LoopScope);
2252 HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
2253 CGF.EmitOMPReductionClauseInit(S, LoopScope);
2254 (void)LoopScope.Privatize();
2256 // Emit static non-chunked loop.
2257 OpenMPScheduleTy ScheduleKind;
2258 ScheduleKind.Schedule = OMPC_SCHEDULE_static;
2259 CGF.CGM.getOpenMPRuntime().emitForStaticInit(
2260 CGF, S.getLocStart(), ScheduleKind, /*IVSize=*/32,
2261 /*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(), LB.getAddress(),
2262 UB.getAddress(), ST.getAddress());
2263 // UB = min(UB, GlobalUB);
2264 auto *UBVal = CGF.EmitLoadOfScalar(UB, S.getLocStart());
2265 auto *MinUBGlobalUB = CGF.Builder.CreateSelect(
2266 CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
2267 CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
2269 CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getLocStart()), IV);
2270 // while (idx <= UB) { BODY; ++idx; }
2271 CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen,
2272 [](CodeGenFunction &) {});
2273 // Tell the runtime we are done.
2274 auto &&CodeGen = [&S](CodeGenFunction &CGF) {
2275 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocEnd());
2277 CGF.OMPCancelStack.emitExit(CGF, S.getDirectiveKind(), CodeGen);
2278 CGF.EmitOMPReductionClauseFinal(S);
2279 // Emit post-update of the reduction variables if IsLastIter != 0.
2280 emitPostUpdateForReductionClause(
2281 CGF, S, [&](CodeGenFunction &CGF) -> llvm::Value * {
2282 return CGF.Builder.CreateIsNotNull(
2283 CGF.EmitLoadOfScalar(IL, S.getLocStart()));
2286 // Emit final copy of the lastprivate variables if IsLastIter != 0.
2287 if (HasLastprivates)
2288 CGF.EmitOMPLastprivateClauseFinal(
2289 S, /*NoFinals=*/false,
2290 CGF.Builder.CreateIsNotNull(
2291 CGF.EmitLoadOfScalar(IL, S.getLocStart())));
2294 bool HasCancel = false;
2295 if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
2296 HasCancel = OSD->hasCancel();
2297 else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
2298 HasCancel = OPSD->hasCancel();
2299 OMPCancelStackRAII CancelRegion(*this, S.getDirectiveKind(), HasCancel);
2300 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen,
2302 // Emit barrier for lastprivates only if 'sections' directive has 'nowait'
2303 // clause. Otherwise the barrier will be generated by the codegen for the
2305 if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) {
2306 // Emit implicit barrier to synchronize threads and avoid data races on
2307 // initialization of firstprivate variables.
2308 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
2313 void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
2315 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2318 // Emit an implicit barrier at the end.
2319 if (!S.getSingleClause<OMPNowaitClause>()) {
2320 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
2325 void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) {
2326 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2327 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2329 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2330 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen,
2334 void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {
2335 llvm::SmallVector<const Expr *, 8> CopyprivateVars;
2336 llvm::SmallVector<const Expr *, 8> DestExprs;
2337 llvm::SmallVector<const Expr *, 8> SrcExprs;
2338 llvm::SmallVector<const Expr *, 8> AssignmentOps;
2339 // Check if there are any 'copyprivate' clauses associated with this
2340 // 'single' construct.
2341 // Build a list of copyprivate variables along with helper expressions
2342 // (<source>, <destination>, <destination>=<source> expressions)
2343 for (const auto *C : S.getClausesOfKind<OMPCopyprivateClause>()) {
2344 CopyprivateVars.append(C->varlists().begin(), C->varlists().end());
2345 DestExprs.append(C->destination_exprs().begin(),
2346 C->destination_exprs().end());
2347 SrcExprs.append(C->source_exprs().begin(), C->source_exprs().end());
2348 AssignmentOps.append(C->assignment_ops().begin(),
2349 C->assignment_ops().end());
2351 // Emit code for 'single' region along with 'copyprivate' clauses
2352 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2354 OMPPrivateScope SingleScope(CGF);
2355 (void)CGF.EmitOMPFirstprivateClause(S, SingleScope);
2356 CGF.EmitOMPPrivateClause(S, SingleScope);
2357 (void)SingleScope.Privatize();
2358 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2361 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2362 CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(),
2363 CopyprivateVars, DestExprs,
2364 SrcExprs, AssignmentOps);
2366 // Emit an implicit barrier at the end (to avoid data race on firstprivate
2367 // init or if no 'nowait' clause was specified and no 'copyprivate' clause).
2368 if (!S.getSingleClause<OMPNowaitClause>() && CopyprivateVars.empty()) {
2369 CGM.getOpenMPRuntime().emitBarrierCall(
2370 *this, S.getLocStart(),
2371 S.getSingleClause<OMPNowaitClause>() ? OMPD_unknown : OMPD_single);
2375 void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {
2376 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2378 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2380 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2381 CGM.getOpenMPRuntime().emitMasterRegion(*this, CodeGen, S.getLocStart());
2384 void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
2385 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2387 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2389 Expr *Hint = nullptr;
2390 if (auto *HintClause = S.getSingleClause<OMPHintClause>())
2391 Hint = HintClause->getHint();
2392 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2393 CGM.getOpenMPRuntime().emitCriticalRegion(*this,
2394 S.getDirectiveName().getAsString(),
2395 CodeGen, S.getLocStart(), Hint);
2398 void CodeGenFunction::EmitOMPParallelForDirective(
2399 const OMPParallelForDirective &S) {
2400 // Emit directive as a combined directive that consists of two implicit
2401 // directives: 'parallel' with 'for' directive.
2402 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2403 OMPCancelStackRAII CancelRegion(CGF, OMPD_parallel_for, S.hasCancel());
2404 CGF.EmitOMPWorksharingLoop(S);
2406 emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen);
2409 void CodeGenFunction::EmitOMPParallelForSimdDirective(
2410 const OMPParallelForSimdDirective &S) {
2411 // Emit directive as a combined directive that consists of two implicit
2412 // directives: 'parallel' with 'for' directive.
2413 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2414 CGF.EmitOMPWorksharingLoop(S);
2416 emitCommonOMPParallelDirective(*this, S, OMPD_simd, CodeGen);
2419 void CodeGenFunction::EmitOMPParallelSectionsDirective(
2420 const OMPParallelSectionsDirective &S) {
2421 // Emit directive as a combined directive that consists of two implicit
2422 // directives: 'parallel' with 'sections' directive.
2423 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2424 CGF.EmitSections(S);
2426 emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen);
2429 void CodeGenFunction::EmitOMPTaskBasedDirective(const OMPExecutableDirective &S,
2430 const RegionCodeGenTy &BodyGen,
2431 const TaskGenTy &TaskGen,
2432 OMPTaskDataTy &Data) {
2433 // Emit outlined function for task construct.
2434 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
2435 auto *I = CS->getCapturedDecl()->param_begin();
2436 auto *PartId = std::next(I);
2437 auto *TaskT = std::next(I, 4);
2438 // Check if the task is final
2439 if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) {
2440 // If the condition constant folds and can be elided, try to avoid emitting
2441 // the condition and the dead arm of the if/else.
2442 auto *Cond = Clause->getCondition();
2444 if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
2445 Data.Final.setInt(CondConstant);
2447 Data.Final.setPointer(EvaluateExprAsBool(Cond));
2449 // By default the task is not final.
2450 Data.Final.setInt(/*IntVal=*/false);
2452 // Check if the task has 'priority' clause.
2453 if (const auto *Clause = S.getSingleClause<OMPPriorityClause>()) {
2454 // Runtime currently does not support codegen for priority clause argument.
2455 // TODO: Add codegen for priority clause arg when runtime lib support it.
2456 auto *Prio = Clause->getPriority();
2457 Data.Priority.setInt(Prio);
2458 Data.Priority.setPointer(EmitScalarConversion(
2459 EmitScalarExpr(Prio), Prio->getType(),
2460 getContext().getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1),
2461 Prio->getExprLoc()));
2463 // The first function argument for tasks is a thread id, the second one is a
2464 // part id (0 for tied tasks, >=0 for untied task).
2465 llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
2466 // Get list of private variables.
2467 for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) {
2468 auto IRef = C->varlist_begin();
2469 for (auto *IInit : C->private_copies()) {
2470 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
2471 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
2472 Data.PrivateVars.push_back(*IRef);
2473 Data.PrivateCopies.push_back(IInit);
2478 EmittedAsPrivate.clear();
2479 // Get list of firstprivate variables.
2480 for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) {
2481 auto IRef = C->varlist_begin();
2482 auto IElemInitRef = C->inits().begin();
2483 for (auto *IInit : C->private_copies()) {
2484 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
2485 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
2486 Data.FirstprivateVars.push_back(*IRef);
2487 Data.FirstprivateCopies.push_back(IInit);
2488 Data.FirstprivateInits.push_back(*IElemInitRef);
2494 // Get list of lastprivate variables (for taskloops).
2495 llvm::DenseMap<const VarDecl *, const DeclRefExpr *> LastprivateDstsOrigs;
2496 for (const auto *C : S.getClausesOfKind<OMPLastprivateClause>()) {
2497 auto IRef = C->varlist_begin();
2498 auto ID = C->destination_exprs().begin();
2499 for (auto *IInit : C->private_copies()) {
2500 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
2501 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
2502 Data.LastprivateVars.push_back(*IRef);
2503 Data.LastprivateCopies.push_back(IInit);
2505 LastprivateDstsOrigs.insert(
2506 {cast<VarDecl>(cast<DeclRefExpr>(*ID)->getDecl()),
2507 cast<DeclRefExpr>(*IRef)});
2512 // Build list of dependences.
2513 for (const auto *C : S.getClausesOfKind<OMPDependClause>())
2514 for (auto *IRef : C->varlists())
2515 Data.Dependences.push_back(std::make_pair(C->getDependencyKind(), IRef));
2516 auto &&CodeGen = [PartId, &S, &Data, CS, &BodyGen, &LastprivateDstsOrigs](
2517 CodeGenFunction &CGF, PrePostActionTy &Action) {
2518 // Set proper addresses for generated private copies.
2519 OMPPrivateScope Scope(CGF);
2520 if (!Data.PrivateVars.empty() || !Data.FirstprivateVars.empty() ||
2521 !Data.LastprivateVars.empty()) {
2522 auto *CopyFn = CGF.Builder.CreateLoad(
2523 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(3)));
2524 auto *PrivatesPtr = CGF.Builder.CreateLoad(
2525 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(2)));
2527 llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> PrivatePtrs;
2528 llvm::SmallVector<llvm::Value *, 16> CallArgs;
2529 CallArgs.push_back(PrivatesPtr);
2530 for (auto *E : Data.PrivateVars) {
2531 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
2532 Address PrivatePtr = CGF.CreateMemTemp(
2533 CGF.getContext().getPointerType(E->getType()), ".priv.ptr.addr");
2534 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
2535 CallArgs.push_back(PrivatePtr.getPointer());
2537 for (auto *E : Data.FirstprivateVars) {
2538 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
2539 Address PrivatePtr =
2540 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
2541 ".firstpriv.ptr.addr");
2542 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
2543 CallArgs.push_back(PrivatePtr.getPointer());
2545 for (auto *E : Data.LastprivateVars) {
2546 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
2547 Address PrivatePtr =
2548 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
2549 ".lastpriv.ptr.addr");
2550 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
2551 CallArgs.push_back(PrivatePtr.getPointer());
2553 CGF.EmitRuntimeCall(CopyFn, CallArgs);
2554 for (auto &&Pair : LastprivateDstsOrigs) {
2555 auto *OrigVD = cast<VarDecl>(Pair.second->getDecl());
2557 const_cast<VarDecl *>(OrigVD),
2558 /*RefersToEnclosingVariableOrCapture=*/CGF.CapturedStmtInfo->lookup(
2560 Pair.second->getType(), VK_LValue, Pair.second->getExprLoc());
2561 Scope.addPrivate(Pair.first, [&CGF, &DRE]() {
2562 return CGF.EmitLValue(&DRE).getAddress();
2565 for (auto &&Pair : PrivatePtrs) {
2566 Address Replacement(CGF.Builder.CreateLoad(Pair.second),
2567 CGF.getContext().getDeclAlign(Pair.first));
2568 Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; });
2571 (void)Scope.Privatize();
2576 auto *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
2577 S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, Data.Tied,
2578 Data.NumberOfParts);
2579 OMPLexicalScope Scope(*this, S);
2580 TaskGen(*this, OutlinedFn, Data);
2583 void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
2584 // Emit outlined function for task construct.
2585 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
2586 auto CapturedStruct = GenerateCapturedStmtArgument(*CS);
2587 auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
2588 const Expr *IfCond = nullptr;
2589 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
2590 if (C->getNameModifier() == OMPD_unknown ||
2591 C->getNameModifier() == OMPD_task) {
2592 IfCond = C->getCondition();
2598 // Check if we should emit tied or untied task.
2599 Data.Tied = !S.getSingleClause<OMPUntiedClause>();
2600 auto &&BodyGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) {
2601 CGF.EmitStmt(CS->getCapturedStmt());
2603 auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
2604 IfCond](CodeGenFunction &CGF, llvm::Value *OutlinedFn,
2605 const OMPTaskDataTy &Data) {
2606 CGF.CGM.getOpenMPRuntime().emitTaskCall(CGF, S.getLocStart(), S, OutlinedFn,
2607 SharedsTy, CapturedStruct, IfCond,
2610 EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Data);
2613 void CodeGenFunction::EmitOMPTaskyieldDirective(
2614 const OMPTaskyieldDirective &S) {
2615 CGM.getOpenMPRuntime().emitTaskyieldCall(*this, S.getLocStart());
2618 void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) {
2619 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_barrier);
2622 void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S) {
2623 CGM.getOpenMPRuntime().emitTaskwaitCall(*this, S.getLocStart());
2626 void CodeGenFunction::EmitOMPTaskgroupDirective(
2627 const OMPTaskgroupDirective &S) {
2628 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2630 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2632 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2633 CGM.getOpenMPRuntime().emitTaskgroupRegion(*this, CodeGen, S.getLocStart());
2636 void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) {
2637 CGM.getOpenMPRuntime().emitFlush(*this, [&]() -> ArrayRef<const Expr *> {
2638 if (const auto *FlushClause = S.getSingleClause<OMPFlushClause>()) {
2639 return llvm::makeArrayRef(FlushClause->varlist_begin(),
2640 FlushClause->varlist_end());
2643 }(), S.getLocStart());
2646 void CodeGenFunction::EmitOMPDistributeLoop(const OMPDistributeDirective &S) {
2647 // Emit the loop iteration variable.
2648 auto IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
2649 auto IVDecl = cast<VarDecl>(IVExpr->getDecl());
2650 EmitVarDecl(*IVDecl);
2652 // Emit the iterations count variable.
2653 // If it is not a variable, Sema decided to calculate iterations count on each
2654 // iteration (e.g., it is foldable into a constant).
2655 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
2656 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
2657 // Emit calculation of the iterations count.
2658 EmitIgnoredExpr(S.getCalcLastIteration());
2661 auto &RT = CGM.getOpenMPRuntime();
2663 // Check pre-condition.
2665 OMPLoopScope PreInitScope(*this, S);
2666 // Skip the entire loop if we don't meet the precondition.
2667 // If the condition constant folds and can be elided, avoid emitting the
2670 llvm::BasicBlock *ContBlock = nullptr;
2671 if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
2675 auto *ThenBlock = createBasicBlock("omp.precond.then");
2676 ContBlock = createBasicBlock("omp.precond.end");
2677 emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock,
2678 getProfileCount(&S));
2679 EmitBlock(ThenBlock);
2680 incrementProfileCounter(&S);
2683 // Emit 'then' code.
2685 // Emit helper vars inits.
2687 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getLowerBoundVariable()));
2689 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getUpperBoundVariable()));
2691 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable()));
2693 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
2695 OMPPrivateScope LoopScope(*this);
2696 EmitOMPPrivateLoopCounters(S, LoopScope);
2697 (void)LoopScope.Privatize();
2699 // Detect the distribute schedule kind and chunk.
2700 llvm::Value *Chunk = nullptr;
2701 OpenMPDistScheduleClauseKind ScheduleKind = OMPC_DIST_SCHEDULE_unknown;
2702 if (auto *C = S.getSingleClause<OMPDistScheduleClause>()) {
2703 ScheduleKind = C->getDistScheduleKind();
2704 if (const auto *Ch = C->getChunkSize()) {
2705 Chunk = EmitScalarExpr(Ch);
2706 Chunk = EmitScalarConversion(Chunk, Ch->getType(),
2707 S.getIterationVariable()->getType(),
2711 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
2712 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
2714 // OpenMP [2.10.8, distribute Construct, Description]
2715 // If dist_schedule is specified, kind must be static. If specified,
2716 // iterations are divided into chunks of size chunk_size, chunks are
2717 // assigned to the teams of the league in a round-robin fashion in the
2718 // order of the team number. When no chunk_size is specified, the
2719 // iteration space is divided into chunks that are approximately equal
2720 // in size, and at most one chunk is distributed to each team of the
2721 // league. The size of the chunks is unspecified in this case.
2722 if (RT.isStaticNonchunked(ScheduleKind,
2723 /* Chunked */ Chunk != nullptr)) {
2724 RT.emitDistributeStaticInit(*this, S.getLocStart(), ScheduleKind,
2725 IVSize, IVSigned, /* Ordered = */ false,
2726 IL.getAddress(), LB.getAddress(),
2727 UB.getAddress(), ST.getAddress());
2729 getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit"));
2730 // UB = min(UB, GlobalUB);
2731 EmitIgnoredExpr(S.getEnsureUpperBound());
2733 EmitIgnoredExpr(S.getInit());
2734 // while (idx <= UB) { BODY; ++idx; }
2735 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
2737 [&S, LoopExit](CodeGenFunction &CGF) {
2738 CGF.EmitOMPLoopBody(S, LoopExit);
2739 CGF.EmitStopPoint(&S);
2741 [](CodeGenFunction &) {});
2742 EmitBlock(LoopExit.getBlock());
2743 // Tell the runtime we are done.
2744 RT.emitForStaticFinish(*this, S.getLocStart());
2746 // Emit the outer loop, which requests its work chunk [LB..UB] from
2747 // runtime and runs the inner loop to process it.
2748 EmitOMPDistributeOuterLoop(ScheduleKind, S, LoopScope,
2749 LB.getAddress(), UB.getAddress(), ST.getAddress(),
2750 IL.getAddress(), Chunk);
2754 // We're now done with the loop, so jump to the continuation block.
2756 EmitBranch(ContBlock);
2757 EmitBlock(ContBlock, true);
2762 void CodeGenFunction::EmitOMPDistributeDirective(
2763 const OMPDistributeDirective &S) {
2764 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2765 CGF.EmitOMPDistributeLoop(S);
2767 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2768 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen,
2772 static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM,
2773 const CapturedStmt *S) {
2774 CodeGenFunction CGF(CGM, /*suppressNewContext=*/true);
2775 CodeGenFunction::CGCapturedStmtInfo CapStmtInfo;
2776 CGF.CapturedStmtInfo = &CapStmtInfo;
2777 auto *Fn = CGF.GenerateOpenMPCapturedStmtFunction(*S);
2778 Fn->addFnAttr(llvm::Attribute::NoInline);
2782 void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) {
2783 if (!S.getAssociatedStmt()) {
2784 for (const auto *DC : S.getClausesOfKind<OMPDependClause>())
2785 CGM.getOpenMPRuntime().emitDoacrossOrdered(*this, DC);
2788 auto *C = S.getSingleClause<OMPSIMDClause>();
2789 auto &&CodeGen = [&S, C, this](CodeGenFunction &CGF,
2790 PrePostActionTy &Action) {
2792 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
2793 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
2794 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
2795 auto *OutlinedFn = emitOutlinedOrderedFunction(CGM, CS);
2796 CGF.EmitNounwindRuntimeCall(OutlinedFn, CapturedVars);
2800 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2803 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2804 CGM.getOpenMPRuntime().emitOrderedRegion(*this, CodeGen, S.getLocStart(), !C);
2807 static llvm::Value *convertToScalarValue(CodeGenFunction &CGF, RValue Val,
2808 QualType SrcType, QualType DestType,
2809 SourceLocation Loc) {
2810 assert(CGF.hasScalarEvaluationKind(DestType) &&
2811 "DestType must have scalar evaluation kind.");
2812 assert(!Val.isAggregate() && "Must be a scalar or complex.");
2813 return Val.isScalar()
2814 ? CGF.EmitScalarConversion(Val.getScalarVal(), SrcType, DestType,
2816 : CGF.EmitComplexToScalarConversion(Val.getComplexVal(), SrcType,
2820 static CodeGenFunction::ComplexPairTy
2821 convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType,
2822 QualType DestType, SourceLocation Loc) {
2823 assert(CGF.getEvaluationKind(DestType) == TEK_Complex &&
2824 "DestType must have complex evaluation kind.");
2825 CodeGenFunction::ComplexPairTy ComplexVal;
2826 if (Val.isScalar()) {
2827 // Convert the input element to the element type of the complex.
2828 auto DestElementType = DestType->castAs<ComplexType>()->getElementType();
2829 auto ScalarVal = CGF.EmitScalarConversion(Val.getScalarVal(), SrcType,
2830 DestElementType, Loc);
2831 ComplexVal = CodeGenFunction::ComplexPairTy(
2832 ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType()));
2834 assert(Val.isComplex() && "Must be a scalar or complex.");
2835 auto SrcElementType = SrcType->castAs<ComplexType>()->getElementType();
2836 auto DestElementType = DestType->castAs<ComplexType>()->getElementType();
2837 ComplexVal.first = CGF.EmitScalarConversion(
2838 Val.getComplexVal().first, SrcElementType, DestElementType, Loc);
2839 ComplexVal.second = CGF.EmitScalarConversion(
2840 Val.getComplexVal().second, SrcElementType, DestElementType, Loc);
2845 static void emitSimpleAtomicStore(CodeGenFunction &CGF, bool IsSeqCst,
2846 LValue LVal, RValue RVal) {
2847 if (LVal.isGlobalReg()) {
2848 CGF.EmitStoreThroughGlobalRegLValue(RVal, LVal);
2850 CGF.EmitAtomicStore(RVal, LVal,
2851 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
2852 : llvm::AtomicOrdering::Monotonic,
2853 LVal.isVolatile(), /*IsInit=*/false);
2857 void CodeGenFunction::emitOMPSimpleStore(LValue LVal, RValue RVal,
2858 QualType RValTy, SourceLocation Loc) {
2859 switch (getEvaluationKind(LVal.getType())) {
2861 EmitStoreThroughLValue(RValue::get(convertToScalarValue(
2862 *this, RVal, RValTy, LVal.getType(), Loc)),
2867 convertToComplexValue(*this, RVal, RValTy, LVal.getType(), Loc), LVal,
2871 llvm_unreachable("Must be a scalar or complex.");
2875 static void EmitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst,
2876 const Expr *X, const Expr *V,
2877 SourceLocation Loc) {
2879 assert(V->isLValue() && "V of 'omp atomic read' is not lvalue");
2880 assert(X->isLValue() && "X of 'omp atomic read' is not lvalue");
2881 LValue XLValue = CGF.EmitLValue(X);
2882 LValue VLValue = CGF.EmitLValue(V);
2883 RValue Res = XLValue.isGlobalReg()
2884 ? CGF.EmitLoadOfLValue(XLValue, Loc)
2885 : CGF.EmitAtomicLoad(
2887 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
2888 : llvm::AtomicOrdering::Monotonic,
2889 XLValue.isVolatile());
2890 // OpenMP, 2.12.6, atomic Construct
2891 // Any atomic construct with a seq_cst clause forces the atomically
2892 // performed operation to include an implicit flush operation without a
2895 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
2896 CGF.emitOMPSimpleStore(VLValue, Res, X->getType().getNonReferenceType(), Loc);
2899 static void EmitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst,
2900 const Expr *X, const Expr *E,
2901 SourceLocation Loc) {
2903 assert(X->isLValue() && "X of 'omp atomic write' is not lvalue");
2904 emitSimpleAtomicStore(CGF, IsSeqCst, CGF.EmitLValue(X), CGF.EmitAnyExpr(E));
2905 // OpenMP, 2.12.6, atomic Construct
2906 // Any atomic construct with a seq_cst clause forces the atomically
2907 // performed operation to include an implicit flush operation without a
2910 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
2913 static std::pair<bool, RValue> emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X,
2915 BinaryOperatorKind BO,
2916 llvm::AtomicOrdering AO,
2917 bool IsXLHSInRHSPart) {
2918 auto &Context = CGF.CGM.getContext();
2919 // Allow atomicrmw only if 'x' and 'update' are integer values, lvalue for 'x'
2920 // expression is simple and atomic is allowed for the given type for the
2922 if (BO == BO_Comma || !Update.isScalar() ||
2923 !Update.getScalarVal()->getType()->isIntegerTy() ||
2924 !X.isSimple() || (!isa<llvm::ConstantInt>(Update.getScalarVal()) &&
2925 (Update.getScalarVal()->getType() !=
2926 X.getAddress().getElementType())) ||
2927 !X.getAddress().getElementType()->isIntegerTy() ||
2928 !Context.getTargetInfo().hasBuiltinAtomic(
2929 Context.getTypeSize(X.getType()), Context.toBits(X.getAlignment())))
2930 return std::make_pair(false, RValue::get(nullptr));
2932 llvm::AtomicRMWInst::BinOp RMWOp;
2935 RMWOp = llvm::AtomicRMWInst::Add;
2938 if (!IsXLHSInRHSPart)
2939 return std::make_pair(false, RValue::get(nullptr));
2940 RMWOp = llvm::AtomicRMWInst::Sub;
2943 RMWOp = llvm::AtomicRMWInst::And;
2946 RMWOp = llvm::AtomicRMWInst::Or;
2949 RMWOp = llvm::AtomicRMWInst::Xor;
2952 RMWOp = X.getType()->hasSignedIntegerRepresentation()
2953 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min
2954 : llvm::AtomicRMWInst::Max)
2955 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin
2956 : llvm::AtomicRMWInst::UMax);
2959 RMWOp = X.getType()->hasSignedIntegerRepresentation()
2960 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max
2961 : llvm::AtomicRMWInst::Min)
2962 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax
2963 : llvm::AtomicRMWInst::UMin);
2966 RMWOp = llvm::AtomicRMWInst::Xchg;
2975 return std::make_pair(false, RValue::get(nullptr));
2993 llvm_unreachable("Unsupported atomic update operation");
2995 auto *UpdateVal = Update.getScalarVal();
2996 if (auto *IC = dyn_cast<llvm::ConstantInt>(UpdateVal)) {
2997 UpdateVal = CGF.Builder.CreateIntCast(
2998 IC, X.getAddress().getElementType(),
2999 X.getType()->hasSignedIntegerRepresentation());
3001 auto *Res = CGF.Builder.CreateAtomicRMW(RMWOp, X.getPointer(), UpdateVal, AO);
3002 return std::make_pair(true, RValue::get(Res));
3005 std::pair<bool, RValue> CodeGenFunction::EmitOMPAtomicSimpleUpdateExpr(
3006 LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart,
3007 llvm::AtomicOrdering AO, SourceLocation Loc,
3008 const llvm::function_ref<RValue(RValue)> &CommonGen) {
3009 // Update expressions are allowed to have the following forms:
3010 // x binop= expr; -> xrval + expr;
3011 // x++, ++x -> xrval + 1;
3012 // x--, --x -> xrval - 1;
3013 // x = x binop expr; -> xrval binop expr
3014 // x = expr Op x; - > expr binop xrval;
3015 auto Res = emitOMPAtomicRMW(*this, X, E, BO, AO, IsXLHSInRHSPart);
3017 if (X.isGlobalReg()) {
3018 // Emit an update expression: 'xrval' binop 'expr' or 'expr' binop
3020 EmitStoreThroughLValue(CommonGen(EmitLoadOfLValue(X, Loc)), X);
3022 // Perform compare-and-swap procedure.
3023 EmitAtomicUpdate(X, AO, CommonGen, X.getType().isVolatileQualified());
3029 static void EmitOMPAtomicUpdateExpr(CodeGenFunction &CGF, bool IsSeqCst,
3030 const Expr *X, const Expr *E,
3031 const Expr *UE, bool IsXLHSInRHSPart,
3032 SourceLocation Loc) {
3033 assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) &&
3034 "Update expr in 'atomic update' must be a binary operator.");
3035 auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts());
3036 // Update expressions are allowed to have the following forms:
3037 // x binop= expr; -> xrval + expr;
3038 // x++, ++x -> xrval + 1;
3039 // x--, --x -> xrval - 1;
3040 // x = x binop expr; -> xrval binop expr
3041 // x = expr Op x; - > expr binop xrval;
3042 assert(X->isLValue() && "X of 'omp atomic update' is not lvalue");
3043 LValue XLValue = CGF.EmitLValue(X);
3044 RValue ExprRValue = CGF.EmitAnyExpr(E);
3045 auto AO = IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3046 : llvm::AtomicOrdering::Monotonic;
3047 auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
3048 auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
3049 auto *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
3050 auto *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
3052 [&CGF, UE, ExprRValue, XRValExpr, ERValExpr](RValue XRValue) -> RValue {
3053 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
3054 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);
3055 return CGF.EmitAnyExpr(UE);
3057 (void)CGF.EmitOMPAtomicSimpleUpdateExpr(
3058 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
3059 // OpenMP, 2.12.6, atomic Construct
3060 // Any atomic construct with a seq_cst clause forces the atomically
3061 // performed operation to include an implicit flush operation without a
3064 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
3067 static RValue convertToType(CodeGenFunction &CGF, RValue Value,
3068 QualType SourceType, QualType ResType,
3069 SourceLocation Loc) {
3070 switch (CGF.getEvaluationKind(ResType)) {
3073 convertToScalarValue(CGF, Value, SourceType, ResType, Loc));
3075 auto Res = convertToComplexValue(CGF, Value, SourceType, ResType, Loc);
3076 return RValue::getComplex(Res.first, Res.second);
3081 llvm_unreachable("Must be a scalar or complex.");
3084 static void EmitOMPAtomicCaptureExpr(CodeGenFunction &CGF, bool IsSeqCst,
3085 bool IsPostfixUpdate, const Expr *V,
3086 const Expr *X, const Expr *E,
3087 const Expr *UE, bool IsXLHSInRHSPart,
3088 SourceLocation Loc) {
3089 assert(X->isLValue() && "X of 'omp atomic capture' is not lvalue");
3090 assert(V->isLValue() && "V of 'omp atomic capture' is not lvalue");
3092 LValue VLValue = CGF.EmitLValue(V);
3093 LValue XLValue = CGF.EmitLValue(X);
3094 RValue ExprRValue = CGF.EmitAnyExpr(E);
3095 auto AO = IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3096 : llvm::AtomicOrdering::Monotonic;
3097 QualType NewVValType;
3099 // 'x' is updated with some additional value.
3100 assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) &&
3101 "Update expr in 'atomic capture' must be a binary operator.");
3102 auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts());
3103 // Update expressions are allowed to have the following forms:
3104 // x binop= expr; -> xrval + expr;
3105 // x++, ++x -> xrval + 1;
3106 // x--, --x -> xrval - 1;
3107 // x = x binop expr; -> xrval binop expr
3108 // x = expr Op x; - > expr binop xrval;
3109 auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
3110 auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
3111 auto *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
3112 NewVValType = XRValExpr->getType();
3113 auto *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
3114 auto &&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr,
3115 IsSeqCst, IsPostfixUpdate](RValue XRValue) -> RValue {
3116 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
3117 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);
3118 RValue Res = CGF.EmitAnyExpr(UE);
3119 NewVVal = IsPostfixUpdate ? XRValue : Res;
3122 auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr(
3123 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
3125 // 'atomicrmw' instruction was generated.
3126 if (IsPostfixUpdate) {
3127 // Use old value from 'atomicrmw'.
3128 NewVVal = Res.second;
3130 // 'atomicrmw' does not provide new value, so evaluate it using old
3132 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
3133 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, Res.second);
3134 NewVVal = CGF.EmitAnyExpr(UE);
3138 // 'x' is simply rewritten with some 'expr'.
3139 NewVValType = X->getType().getNonReferenceType();
3140 ExprRValue = convertToType(CGF, ExprRValue, E->getType(),
3141 X->getType().getNonReferenceType(), Loc);
3142 auto &&Gen = [&CGF, &NewVVal, ExprRValue](RValue XRValue) -> RValue {
3146 // Try to perform atomicrmw xchg, otherwise simple exchange.
3147 auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr(
3148 XLValue, ExprRValue, /*BO=*/BO_Assign, /*IsXLHSInRHSPart=*/false, AO,
3151 // 'atomicrmw' instruction was generated.
3152 NewVVal = IsPostfixUpdate ? Res.second : ExprRValue;
3155 // Emit post-update store to 'v' of old/new 'x' value.
3156 CGF.emitOMPSimpleStore(VLValue, NewVVal, NewVValType, Loc);
3157 // OpenMP, 2.12.6, atomic Construct
3158 // Any atomic construct with a seq_cst clause forces the atomically
3159 // performed operation to include an implicit flush operation without a
3162 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
3165 static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
3166 bool IsSeqCst, bool IsPostfixUpdate,
3167 const Expr *X, const Expr *V, const Expr *E,
3168 const Expr *UE, bool IsXLHSInRHSPart,
3169 SourceLocation Loc) {
3172 EmitOMPAtomicReadExpr(CGF, IsSeqCst, X, V, Loc);
3175 EmitOMPAtomicWriteExpr(CGF, IsSeqCst, X, E, Loc);
3179 EmitOMPAtomicUpdateExpr(CGF, IsSeqCst, X, E, UE, IsXLHSInRHSPart, Loc);
3182 EmitOMPAtomicCaptureExpr(CGF, IsSeqCst, IsPostfixUpdate, V, X, E, UE,
3183 IsXLHSInRHSPart, Loc);
3187 case OMPC_num_threads:
3189 case OMPC_firstprivate:
3190 case OMPC_lastprivate:
3191 case OMPC_reduction:
3201 case OMPC_copyprivate:
3203 case OMPC_proc_bind:
3208 case OMPC_threadprivate:
3210 case OMPC_mergeable:
3215 case OMPC_num_teams:
3216 case OMPC_thread_limit:
3218 case OMPC_grainsize:
3220 case OMPC_num_tasks:
3222 case OMPC_dist_schedule:
3223 case OMPC_defaultmap:
3227 case OMPC_use_device_ptr:
3228 case OMPC_is_device_ptr:
3229 llvm_unreachable("Clause is not allowed in 'omp atomic'.");
3233 void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
3234 bool IsSeqCst = S.getSingleClause<OMPSeqCstClause>();
3235 OpenMPClauseKind Kind = OMPC_unknown;
3236 for (auto *C : S.clauses()) {
3237 // Find first clause (skip seq_cst clause, if it is first).
3238 if (C->getClauseKind() != OMPC_seq_cst) {
3239 Kind = C->getClauseKind();
3245 S.getAssociatedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
3246 if (const auto *EWC = dyn_cast<ExprWithCleanups>(CS)) {
3247 enterFullExpression(EWC);
3249 // Processing for statements under 'atomic capture'.
3250 if (const auto *Compound = dyn_cast<CompoundStmt>(CS)) {
3251 for (const auto *C : Compound->body()) {
3252 if (const auto *EWC = dyn_cast<ExprWithCleanups>(C)) {
3253 enterFullExpression(EWC);
3258 auto &&CodeGen = [&S, Kind, IsSeqCst, CS](CodeGenFunction &CGF,
3259 PrePostActionTy &) {
3260 CGF.EmitStopPoint(CS);
3261 EmitOMPAtomicExpr(CGF, Kind, IsSeqCst, S.isPostfixUpdate(), S.getX(),
3262 S.getV(), S.getExpr(), S.getUpdateExpr(),
3263 S.isXLHSInRHSPart(), S.getLocStart());
3265 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
3266 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_atomic, CodeGen);
3269 std::pair<llvm::Function * /*OutlinedFn*/, llvm::Constant * /*OutlinedFnID*/>
3270 CodeGenFunction::EmitOMPTargetDirectiveOutlinedFunction(
3271 CodeGenModule &CGM, const OMPTargetDirective &S, StringRef ParentName,
3272 bool IsOffloadEntry) {
3273 llvm::Function *OutlinedFn = nullptr;
3274 llvm::Constant *OutlinedFnID = nullptr;
3275 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
3276 OMPPrivateScope PrivateScope(CGF);
3277 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
3278 CGF.EmitOMPPrivateClause(S, PrivateScope);
3279 (void)PrivateScope.Privatize();
3282 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
3284 // Emit target region as a standalone region.
3285 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
3286 S, ParentName, OutlinedFn, OutlinedFnID, IsOffloadEntry, CodeGen);
3287 return std::make_pair(OutlinedFn, OutlinedFnID);
3290 void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) {
3291 const CapturedStmt &CS = *cast<CapturedStmt>(S.getAssociatedStmt());
3293 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
3294 GenerateOpenMPCapturedVars(CS, CapturedVars);
3296 llvm::Function *Fn = nullptr;
3297 llvm::Constant *FnID = nullptr;
3299 // Check if we have any if clause associated with the directive.
3300 const Expr *IfCond = nullptr;
3302 if (auto *C = S.getSingleClause<OMPIfClause>()) {
3303 IfCond = C->getCondition();
3306 // Check if we have any device clause associated with the directive.
3307 const Expr *Device = nullptr;
3308 if (auto *C = S.getSingleClause<OMPDeviceClause>()) {
3309 Device = C->getDevice();
3312 // Check if we have an if clause whose conditional always evaluates to false
3313 // or if we do not have any targets specified. If so the target region is not
3314 // an offload entry point.
3315 bool IsOffloadEntry = true;
3318 if (ConstantFoldsToSimpleInteger(IfCond, Val) && !Val)
3319 IsOffloadEntry = false;
3321 if (CGM.getLangOpts().OMPTargetTriples.empty())
3322 IsOffloadEntry = false;
3324 assert(CurFuncDecl && "No parent declaration for target region!");
3325 StringRef ParentName;
3326 // In case we have Ctors/Dtors we use the complete type variant to produce
3327 // the mangling of the device outlined kernel.
3328 if (auto *D = dyn_cast<CXXConstructorDecl>(CurFuncDecl))
3329 ParentName = CGM.getMangledName(GlobalDecl(D, Ctor_Complete));
3330 else if (auto *D = dyn_cast<CXXDestructorDecl>(CurFuncDecl))
3331 ParentName = CGM.getMangledName(GlobalDecl(D, Dtor_Complete));
3334 CGM.getMangledName(GlobalDecl(cast<FunctionDecl>(CurFuncDecl)));
3336 std::tie(Fn, FnID) = EmitOMPTargetDirectiveOutlinedFunction(
3337 CGM, S, ParentName, IsOffloadEntry);
3338 OMPLexicalScope Scope(*this, S);
3339 CGM.getOpenMPRuntime().emitTargetCall(*this, S, Fn, FnID, IfCond, Device,
3343 static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF,
3344 const OMPExecutableDirective &S,
3345 OpenMPDirectiveKind InnermostKind,
3346 const RegionCodeGenTy &CodeGen) {
3347 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
3348 auto OutlinedFn = CGF.CGM.getOpenMPRuntime().
3349 emitParallelOrTeamsOutlinedFunction(S,
3350 *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
3352 const OMPTeamsDirective &TD = *dyn_cast<OMPTeamsDirective>(&S);
3353 const OMPNumTeamsClause *NT = TD.getSingleClause<OMPNumTeamsClause>();
3354 const OMPThreadLimitClause *TL = TD.getSingleClause<OMPThreadLimitClause>();
3356 Expr *NumTeams = (NT) ? NT->getNumTeams() : nullptr;
3357 Expr *ThreadLimit = (TL) ? TL->getThreadLimit() : nullptr;
3359 CGF.CGM.getOpenMPRuntime().emitNumTeamsClause(CGF, NumTeams, ThreadLimit,
3363 OMPLexicalScope Scope(CGF, S);
3364 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
3365 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
3366 CGF.CGM.getOpenMPRuntime().emitTeamsCall(CGF, S, S.getLocStart(), OutlinedFn,
3370 void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &S) {
3371 // Emit parallel region as a standalone region.
3372 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
3373 OMPPrivateScope PrivateScope(CGF);
3374 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
3375 CGF.EmitOMPPrivateClause(S, PrivateScope);
3376 (void)PrivateScope.Privatize();
3377 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
3379 emitCommonOMPTeamsDirective(*this, S, OMPD_teams, CodeGen);
3382 void CodeGenFunction::EmitOMPCancellationPointDirective(
3383 const OMPCancellationPointDirective &S) {
3384 CGM.getOpenMPRuntime().emitCancellationPointCall(*this, S.getLocStart(),
3385 S.getCancelRegion());
3388 void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) {
3389 const Expr *IfCond = nullptr;
3390 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
3391 if (C->getNameModifier() == OMPD_unknown ||
3392 C->getNameModifier() == OMPD_cancel) {
3393 IfCond = C->getCondition();
3397 CGM.getOpenMPRuntime().emitCancelCall(*this, S.getLocStart(), IfCond,
3398 S.getCancelRegion());
3401 CodeGenFunction::JumpDest
3402 CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) {
3403 if (Kind == OMPD_parallel || Kind == OMPD_task ||
3404 Kind == OMPD_target_parallel)
3406 assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
3407 Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for ||
3408 Kind == OMPD_distribute_parallel_for ||
3409 Kind == OMPD_target_parallel_for);
3410 return OMPCancelStack.getExitBlock();
3413 // Generate the instructions for '#pragma omp target data' directive.
3414 void CodeGenFunction::EmitOMPTargetDataDirective(
3415 const OMPTargetDataDirective &S) {
3416 // The target data enclosed region is implemented just by emitting the
3418 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
3419 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
3422 // If we don't have target devices, don't bother emitting the data mapping
3424 if (CGM.getLangOpts().OMPTargetTriples.empty()) {
3425 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
3427 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_target_data,
3432 // Check if we have any if clause associated with the directive.
3433 const Expr *IfCond = nullptr;
3434 if (auto *C = S.getSingleClause<OMPIfClause>())
3435 IfCond = C->getCondition();
3437 // Check if we have any device clause associated with the directive.
3438 const Expr *Device = nullptr;
3439 if (auto *C = S.getSingleClause<OMPDeviceClause>())
3440 Device = C->getDevice();
3442 CGM.getOpenMPRuntime().emitTargetDataCalls(*this, S, IfCond, Device, CodeGen);
3445 void CodeGenFunction::EmitOMPTargetEnterDataDirective(
3446 const OMPTargetEnterDataDirective &S) {
3447 // If we don't have target devices, don't bother emitting the data mapping
3449 if (CGM.getLangOpts().OMPTargetTriples.empty())
3452 // Check if we have any if clause associated with the directive.
3453 const Expr *IfCond = nullptr;
3454 if (auto *C = S.getSingleClause<OMPIfClause>())
3455 IfCond = C->getCondition();
3457 // Check if we have any device clause associated with the directive.
3458 const Expr *Device = nullptr;
3459 if (auto *C = S.getSingleClause<OMPDeviceClause>())
3460 Device = C->getDevice();
3462 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
3465 void CodeGenFunction::EmitOMPTargetExitDataDirective(
3466 const OMPTargetExitDataDirective &S) {
3467 // If we don't have target devices, don't bother emitting the data mapping
3469 if (CGM.getLangOpts().OMPTargetTriples.empty())
3472 // Check if we have any if clause associated with the directive.
3473 const Expr *IfCond = nullptr;
3474 if (auto *C = S.getSingleClause<OMPIfClause>())
3475 IfCond = C->getCondition();
3477 // Check if we have any device clause associated with the directive.
3478 const Expr *Device = nullptr;
3479 if (auto *C = S.getSingleClause<OMPDeviceClause>())
3480 Device = C->getDevice();
3482 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
3485 void CodeGenFunction::EmitOMPTargetParallelDirective(
3486 const OMPTargetParallelDirective &S) {
3487 // TODO: codegen for target parallel.
3490 void CodeGenFunction::EmitOMPTargetParallelForDirective(
3491 const OMPTargetParallelForDirective &S) {
3492 // TODO: codegen for target parallel for.
3495 /// Emit a helper variable and return corresponding lvalue.
3496 static void mapParam(CodeGenFunction &CGF, const DeclRefExpr *Helper,
3497 const ImplicitParamDecl *PVD,
3498 CodeGenFunction::OMPPrivateScope &Privates) {
3499 auto *VDecl = cast<VarDecl>(Helper->getDecl());
3500 Privates.addPrivate(
3501 VDecl, [&CGF, PVD]() -> Address { return CGF.GetAddrOfLocalVar(PVD); });
3504 void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) {
3505 assert(isOpenMPTaskLoopDirective(S.getDirectiveKind()));
3506 // Emit outlined function for task construct.
3507 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
3508 auto CapturedStruct = GenerateCapturedStmtArgument(*CS);
3509 auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
3510 const Expr *IfCond = nullptr;
3511 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
3512 if (C->getNameModifier() == OMPD_unknown ||
3513 C->getNameModifier() == OMPD_taskloop) {
3514 IfCond = C->getCondition();
3520 // Check if taskloop must be emitted without taskgroup.
3521 Data.Nogroup = S.getSingleClause<OMPNogroupClause>();
3522 // TODO: Check if we should emit tied or untied task.
3524 // Set scheduling for taskloop
3525 if (const auto* Clause = S.getSingleClause<OMPGrainsizeClause>()) {
3527 Data.Schedule.setInt(/*IntVal=*/false);
3528 Data.Schedule.setPointer(EmitScalarExpr(Clause->getGrainsize()));
3529 } else if (const auto* Clause = S.getSingleClause<OMPNumTasksClause>()) {
3531 Data.Schedule.setInt(/*IntVal=*/true);
3532 Data.Schedule.setPointer(EmitScalarExpr(Clause->getNumTasks()));
3535 auto &&BodyGen = [CS, &S](CodeGenFunction &CGF, PrePostActionTy &) {
3537 // for (IV in 0..LastIteration) BODY;
3538 // <Final counter/linear vars updates>;
3542 // Emit: if (PreCond) - begin.
3543 // If the condition constant folds and can be elided, avoid emitting the
3546 llvm::BasicBlock *ContBlock = nullptr;
3547 OMPLoopScope PreInitScope(CGF, S);
3548 if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
3552 auto *ThenBlock = CGF.createBasicBlock("taskloop.if.then");
3553 ContBlock = CGF.createBasicBlock("taskloop.if.end");
3554 emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
3555 CGF.getProfileCount(&S));
3556 CGF.EmitBlock(ThenBlock);
3557 CGF.incrementProfileCounter(&S);
3560 if (isOpenMPSimdDirective(S.getDirectiveKind()))
3561 CGF.EmitOMPSimdInit(S);
3563 OMPPrivateScope LoopScope(CGF);
3564 // Emit helper vars inits.
3565 enum { LowerBound = 5, UpperBound, Stride, LastIter };
3566 auto *I = CS->getCapturedDecl()->param_begin();
3567 auto *LBP = std::next(I, LowerBound);
3568 auto *UBP = std::next(I, UpperBound);
3569 auto *STP = std::next(I, Stride);
3570 auto *LIP = std::next(I, LastIter);
3571 mapParam(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()), *LBP,
3573 mapParam(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()), *UBP,
3575 mapParam(CGF, cast<DeclRefExpr>(S.getStrideVariable()), *STP, LoopScope);
3576 mapParam(CGF, cast<DeclRefExpr>(S.getIsLastIterVariable()), *LIP,
3578 CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
3579 bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
3580 (void)LoopScope.Privatize();
3581 // Emit the loop iteration variable.
3582 const Expr *IVExpr = S.getIterationVariable();
3583 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
3584 CGF.EmitVarDecl(*IVDecl);
3585 CGF.EmitIgnoredExpr(S.getInit());
3587 // Emit the iterations count variable.
3588 // If it is not a variable, Sema decided to calculate iterations count on
3589 // each iteration (e.g., it is foldable into a constant).
3590 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
3591 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
3592 // Emit calculation of the iterations count.
3593 CGF.EmitIgnoredExpr(S.getCalcLastIteration());
3596 CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
3598 [&S](CodeGenFunction &CGF) {
3599 CGF.EmitOMPLoopBody(S, JumpDest());
3600 CGF.EmitStopPoint(&S);
3602 [](CodeGenFunction &) {});
3603 // Emit: if (PreCond) - end.
3605 CGF.EmitBranch(ContBlock);
3606 CGF.EmitBlock(ContBlock, true);
3608 // Emit final copy of the lastprivate variables if IsLastIter != 0.
3609 if (HasLastprivateClause) {
3610 CGF.EmitOMPLastprivateClauseFinal(
3611 S, isOpenMPSimdDirective(S.getDirectiveKind()),
3612 CGF.Builder.CreateIsNotNull(CGF.EmitLoadOfScalar(
3613 CGF.GetAddrOfLocalVar(*LIP), /*Volatile=*/false,
3614 (*LIP)->getType(), S.getLocStart())));
3617 auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
3618 IfCond](CodeGenFunction &CGF, llvm::Value *OutlinedFn,
3619 const OMPTaskDataTy &Data) {
3620 auto &&CodeGen = [&](CodeGenFunction &CGF, PrePostActionTy &) {
3621 OMPLoopScope PreInitScope(CGF, S);
3622 CGF.CGM.getOpenMPRuntime().emitTaskLoopCall(CGF, S.getLocStart(), S,
3623 OutlinedFn, SharedsTy,
3624 CapturedStruct, IfCond, Data);
3626 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop,
3629 EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Data);
3632 void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) {
3633 EmitOMPTaskLoopBasedDirective(S);
3636 void CodeGenFunction::EmitOMPTaskLoopSimdDirective(
3637 const OMPTaskLoopSimdDirective &S) {
3638 EmitOMPTaskLoopBasedDirective(S);
3641 // Generate the instructions for '#pragma omp target update' directive.
3642 void CodeGenFunction::EmitOMPTargetUpdateDirective(
3643 const OMPTargetUpdateDirective &S) {
3644 // If we don't have target devices, don't bother emitting the data mapping
3646 if (CGM.getLangOpts().OMPTargetTriples.empty())
3649 // Check if we have any if clause associated with the directive.
3650 const Expr *IfCond = nullptr;
3651 if (auto *C = S.getSingleClause<OMPIfClause>())
3652 IfCond = C->getCondition();
3654 // Check if we have any device clause associated with the directive.
3655 const Expr *Device = nullptr;
3656 if (auto *C = S.getSingleClause<OMPDeviceClause>())
3657 Device = C->getDevice();
3659 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);