blob: 7f6b7955a71aedd0891acaf3e40eba7b7ac5262e [file] [log] [blame]
Alexey Bataev9959db52014-05-06 10:08:46 +00001//===--- CGStmtOpenMP.cpp - Emit LLVM Code from Statements ----------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Alexey Bataev9959db52014-05-06 10:08:46 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This contains code to emit OpenMP nodes as LLVM code.
10//
11//===----------------------------------------------------------------------===//
12
Alexey Bataev3392d762016-02-16 11:18:12 +000013#include "CGCleanup.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000014#include "CGOpenMPRuntime.h"
15#include "CodeGenFunction.h"
16#include "CodeGenModule.h"
Chandler Carruth0d9593d2015-01-14 11:29:14 +000017#include "TargetInfo.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000018#include "clang/AST/Stmt.h"
19#include "clang/AST/StmtOpenMP.h"
Alexey Bataev2bbf7212016-03-03 03:52:24 +000020#include "clang/AST/DeclOpenMP.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000021using namespace clang;
22using namespace CodeGen;
23
Alexey Bataev3392d762016-02-16 11:18:12 +000024namespace {
25/// Lexical scope for OpenMP executable constructs, that handles correct codegen
26/// for captured expressions.
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000027class OMPLexicalScope : public CodeGenFunction::LexicalScope {
Alexey Bataev3392d762016-02-16 11:18:12 +000028 void emitPreInitStmt(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
29 for (const auto *C : S.clauses()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +000030 if (const auto *CPI = OMPClauseWithPreInit::get(C)) {
31 if (const auto *PreInit =
32 cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {
Alexey Bataev2bbf7212016-03-03 03:52:24 +000033 for (const auto *I : PreInit->decls()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +000034 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
Alexey Bataev2bbf7212016-03-03 03:52:24 +000035 CGF.EmitVarDecl(cast<VarDecl>(*I));
Alexey Bataevddf3db92018-04-13 17:31:06 +000036 } else {
Alexey Bataev2bbf7212016-03-03 03:52:24 +000037 CodeGenFunction::AutoVarEmission Emission =
38 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
39 CGF.EmitAutoVarCleanups(Emission);
40 }
41 }
Alexey Bataev3392d762016-02-16 11:18:12 +000042 }
43 }
44 }
45 }
Alexey Bataev4ba78a42016-04-27 07:56:03 +000046 CodeGenFunction::OMPPrivateScope InlinedShareds;
47
48 static bool isCapturedVar(CodeGenFunction &CGF, const VarDecl *VD) {
49 return CGF.LambdaCaptureFields.lookup(VD) ||
50 (CGF.CapturedStmtInfo && CGF.CapturedStmtInfo->lookup(VD)) ||
51 (CGF.CurCodeDecl && isa<BlockDecl>(CGF.CurCodeDecl));
52 }
Alexey Bataev3392d762016-02-16 11:18:12 +000053
Alexey Bataev3392d762016-02-16 11:18:12 +000054public:
Alexey Bataev475a7442018-01-12 19:39:11 +000055 OMPLexicalScope(
56 CodeGenFunction &CGF, const OMPExecutableDirective &S,
57 const llvm::Optional<OpenMPDirectiveKind> CapturedRegion = llvm::None,
58 const bool EmitPreInitStmt = true)
Alexey Bataev4ba78a42016-04-27 07:56:03 +000059 : CodeGenFunction::LexicalScope(CGF, S.getSourceRange()),
60 InlinedShareds(CGF) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000061 if (EmitPreInitStmt)
62 emitPreInitStmt(CGF, S);
Alexey Bataev475a7442018-01-12 19:39:11 +000063 if (!CapturedRegion.hasValue())
64 return;
65 assert(S.hasAssociatedStmt() &&
66 "Expected associated statement for inlined directive.");
67 const CapturedStmt *CS = S.getCapturedStmt(*CapturedRegion);
Alexey Bataevddf3db92018-04-13 17:31:06 +000068 for (const auto &C : CS->captures()) {
Alexey Bataev475a7442018-01-12 19:39:11 +000069 if (C.capturesVariable() || C.capturesVariableByCopy()) {
70 auto *VD = C.getCapturedVar();
71 assert(VD == VD->getCanonicalDecl() &&
72 "Canonical decl must be captured.");
73 DeclRefExpr DRE(
Bruno Ricci5fc4db72018-12-21 14:10:18 +000074 CGF.getContext(), const_cast<VarDecl *>(VD),
Alexey Bataev475a7442018-01-12 19:39:11 +000075 isCapturedVar(CGF, VD) || (CGF.CapturedStmtInfo &&
76 InlinedShareds.isGlobalVarCaptured(VD)),
Alexey Bataeva9b9cc02018-01-23 18:12:38 +000077 VD->getType().getNonReferenceType(), VK_LValue, C.getLocation());
Alexey Bataev475a7442018-01-12 19:39:11 +000078 InlinedShareds.addPrivate(VD, [&CGF, &DRE]() -> Address {
79 return CGF.EmitLValue(&DRE).getAddress();
80 });
Alexey Bataev4ba78a42016-04-27 07:56:03 +000081 }
82 }
Alexey Bataev475a7442018-01-12 19:39:11 +000083 (void)InlinedShareds.Privatize();
Alexey Bataev3392d762016-02-16 11:18:12 +000084 }
85};
Alexey Bataev14fa1c62016-03-29 05:34:15 +000086
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000087/// Lexical scope for OpenMP parallel construct, that handles correct codegen
88/// for captured expressions.
89class OMPParallelScope final : public OMPLexicalScope {
90 bool EmitPreInitStmt(const OMPExecutableDirective &S) {
91 OpenMPDirectiveKind Kind = S.getDirectiveKind();
Carlo Bertollib0ff0a62017-04-25 17:52:12 +000092 return !(isOpenMPTargetExecutionDirective(Kind) ||
93 isOpenMPLoopBoundSharingDirective(Kind)) &&
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000094 isOpenMPParallelDirective(Kind);
95 }
96
97public:
98 OMPParallelScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
Alexey Bataev475a7442018-01-12 19:39:11 +000099 : OMPLexicalScope(CGF, S, /*CapturedRegion=*/llvm::None,
100 EmitPreInitStmt(S)) {}
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +0000101};
102
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +0000103/// Lexical scope for OpenMP teams construct, that handles correct codegen
104/// for captured expressions.
105class OMPTeamsScope final : public OMPLexicalScope {
106 bool EmitPreInitStmt(const OMPExecutableDirective &S) {
107 OpenMPDirectiveKind Kind = S.getDirectiveKind();
108 return !isOpenMPTargetExecutionDirective(Kind) &&
109 isOpenMPTeamsDirective(Kind);
110 }
111
112public:
113 OMPTeamsScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
Alexey Bataev475a7442018-01-12 19:39:11 +0000114 : OMPLexicalScope(CGF, S, /*CapturedRegion=*/llvm::None,
115 EmitPreInitStmt(S)) {}
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +0000116};
117
Alexey Bataev5a3af132016-03-29 08:58:54 +0000118/// Private scope for OpenMP loop-based directives, that supports capturing
119/// of used expression from loop statement.
120class OMPLoopScope : public CodeGenFunction::RunCleanupsScope {
121 void emitPreInitStmt(CodeGenFunction &CGF, const OMPLoopDirective &S) {
Alexey Bataevab4ea222018-03-07 18:17:06 +0000122 CodeGenFunction::OMPMapVars PreCondVars;
Alexey Bataevddf3db92018-04-13 17:31:06 +0000123 for (const auto *E : S.counters()) {
Alexey Bataeve83b3e82017-12-08 20:18:58 +0000124 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataevab4ea222018-03-07 18:17:06 +0000125 (void)PreCondVars.setVarAddr(
126 CGF, VD, CGF.CreateMemTemp(VD->getType().getNonReferenceType()));
Alexey Bataeve83b3e82017-12-08 20:18:58 +0000127 }
Alexey Bataevab4ea222018-03-07 18:17:06 +0000128 (void)PreCondVars.apply(CGF);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000129 if (const auto *PreInits = cast_or_null<DeclStmt>(S.getPreInits())) {
George Burgess IV00f70bd2018-03-01 05:43:23 +0000130 for (const auto *I : PreInits->decls())
131 CGF.EmitVarDecl(cast<VarDecl>(*I));
Alexey Bataev5a3af132016-03-29 08:58:54 +0000132 }
Alexey Bataevab4ea222018-03-07 18:17:06 +0000133 PreCondVars.restore(CGF);
Alexey Bataev5a3af132016-03-29 08:58:54 +0000134 }
135
136public:
137 OMPLoopScope(CodeGenFunction &CGF, const OMPLoopDirective &S)
138 : CodeGenFunction::RunCleanupsScope(CGF) {
139 emitPreInitStmt(CGF, S);
140 }
141};
142
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000143class OMPSimdLexicalScope : public CodeGenFunction::LexicalScope {
144 CodeGenFunction::OMPPrivateScope InlinedShareds;
145
146 static bool isCapturedVar(CodeGenFunction &CGF, const VarDecl *VD) {
147 return CGF.LambdaCaptureFields.lookup(VD) ||
148 (CGF.CapturedStmtInfo && CGF.CapturedStmtInfo->lookup(VD)) ||
149 (CGF.CurCodeDecl && isa<BlockDecl>(CGF.CurCodeDecl) &&
150 cast<BlockDecl>(CGF.CurCodeDecl)->capturesVariable(VD));
151 }
152
153public:
154 OMPSimdLexicalScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
155 : CodeGenFunction::LexicalScope(CGF, S.getSourceRange()),
156 InlinedShareds(CGF) {
157 for (const auto *C : S.clauses()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000158 if (const auto *CPI = OMPClauseWithPreInit::get(C)) {
159 if (const auto *PreInit =
160 cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000161 for (const auto *I : PreInit->decls()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000162 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000163 CGF.EmitVarDecl(cast<VarDecl>(*I));
Alexey Bataevddf3db92018-04-13 17:31:06 +0000164 } else {
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000165 CodeGenFunction::AutoVarEmission Emission =
166 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
167 CGF.EmitAutoVarCleanups(Emission);
168 }
169 }
170 }
171 } else if (const auto *UDP = dyn_cast<OMPUseDevicePtrClause>(C)) {
172 for (const Expr *E : UDP->varlists()) {
173 const Decl *D = cast<DeclRefExpr>(E)->getDecl();
174 if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(D))
175 CGF.EmitVarDecl(*OED);
176 }
177 }
178 }
179 if (!isOpenMPSimdDirective(S.getDirectiveKind()))
180 CGF.EmitOMPPrivateClause(S, InlinedShareds);
181 if (const auto *TG = dyn_cast<OMPTaskgroupDirective>(&S)) {
182 if (const Expr *E = TG->getReductionRef())
183 CGF.EmitVarDecl(*cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()));
184 }
185 const auto *CS = cast_or_null<CapturedStmt>(S.getAssociatedStmt());
186 while (CS) {
187 for (auto &C : CS->captures()) {
188 if (C.capturesVariable() || C.capturesVariableByCopy()) {
189 auto *VD = C.getCapturedVar();
190 assert(VD == VD->getCanonicalDecl() &&
191 "Canonical decl must be captured.");
Bruno Ricci5fc4db72018-12-21 14:10:18 +0000192 DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(VD),
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000193 isCapturedVar(CGF, VD) ||
194 (CGF.CapturedStmtInfo &&
195 InlinedShareds.isGlobalVarCaptured(VD)),
196 VD->getType().getNonReferenceType(), VK_LValue,
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000197 C.getLocation());
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000198 InlinedShareds.addPrivate(VD, [&CGF, &DRE]() -> Address {
199 return CGF.EmitLValue(&DRE).getAddress();
200 });
201 }
202 }
203 CS = dyn_cast<CapturedStmt>(CS->getCapturedStmt());
204 }
205 (void)InlinedShareds.Privatize();
206 }
207};
208
Alexey Bataev3392d762016-02-16 11:18:12 +0000209} // namespace
210
Alexey Bataevf8365372017-11-17 17:57:25 +0000211static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
212 const OMPExecutableDirective &S,
213 const RegionCodeGenTy &CodeGen);
214
Alexey Bataevf47c4b42017-09-26 13:47:31 +0000215LValue CodeGenFunction::EmitOMPSharedLValue(const Expr *E) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000216 if (const auto *OrigDRE = dyn_cast<DeclRefExpr>(E)) {
217 if (const auto *OrigVD = dyn_cast<VarDecl>(OrigDRE->getDecl())) {
Alexey Bataevf47c4b42017-09-26 13:47:31 +0000218 OrigVD = OrigVD->getCanonicalDecl();
219 bool IsCaptured =
220 LambdaCaptureFields.lookup(OrigVD) ||
221 (CapturedStmtInfo && CapturedStmtInfo->lookup(OrigVD)) ||
222 (CurCodeDecl && isa<BlockDecl>(CurCodeDecl));
Bruno Ricci5fc4db72018-12-21 14:10:18 +0000223 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD), IsCaptured,
Alexey Bataevf47c4b42017-09-26 13:47:31 +0000224 OrigDRE->getType(), VK_LValue, OrigDRE->getExprLoc());
225 return EmitLValue(&DRE);
226 }
227 }
228 return EmitLValue(E);
229}
230
Alexey Bataev1189bd02016-01-26 12:20:39 +0000231llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000232 ASTContext &C = getContext();
Alexey Bataev1189bd02016-01-26 12:20:39 +0000233 llvm::Value *Size = nullptr;
234 auto SizeInChars = C.getTypeSizeInChars(Ty);
235 if (SizeInChars.isZero()) {
236 // getTypeSizeInChars() returns 0 for a VLA.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000237 while (const VariableArrayType *VAT = C.getAsVariableArrayType(Ty)) {
238 VlaSizePair VlaSize = getVLASize(VAT);
Sander de Smalen891af03a2018-02-03 13:55:59 +0000239 Ty = VlaSize.Type;
240 Size = Size ? Builder.CreateNUWMul(Size, VlaSize.NumElts)
241 : VlaSize.NumElts;
Alexey Bataev1189bd02016-01-26 12:20:39 +0000242 }
243 SizeInChars = C.getTypeSizeInChars(Ty);
244 if (SizeInChars.isZero())
245 return llvm::ConstantInt::get(SizeTy, /*V=*/0);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000246 return Builder.CreateNUWMul(Size, CGM.getSize(SizeInChars));
247 }
248 return CGM.getSize(SizeInChars);
Alexey Bataev1189bd02016-01-26 12:20:39 +0000249}
250
Alexey Bataev2377fe92015-09-10 08:12:02 +0000251void CodeGenFunction::GenerateOpenMPCapturedVars(
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000252 const CapturedStmt &S, SmallVectorImpl<llvm::Value *> &CapturedVars) {
Alexey Bataev2377fe92015-09-10 08:12:02 +0000253 const RecordDecl *RD = S.getCapturedRecordDecl();
254 auto CurField = RD->field_begin();
255 auto CurCap = S.captures().begin();
256 for (CapturedStmt::const_capture_init_iterator I = S.capture_init_begin(),
257 E = S.capture_init_end();
258 I != E; ++I, ++CurField, ++CurCap) {
259 if (CurField->hasCapturedVLAType()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000260 const VariableArrayType *VAT = CurField->getCapturedVLAType();
261 llvm::Value *Val = VLASizeMap[VAT->getSizeExpr()];
Samuel Antaobed3c462015-10-02 16:14:20 +0000262 CapturedVars.push_back(Val);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000263 } else if (CurCap->capturesThis()) {
Alexey Bataev2377fe92015-09-10 08:12:02 +0000264 CapturedVars.push_back(CXXThisValue);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000265 } else if (CurCap->capturesVariableByCopy()) {
Alexey Bataev1e491372018-01-23 18:44:14 +0000266 llvm::Value *CV = EmitLoadOfScalar(EmitLValue(*I), CurCap->getLocation());
Samuel Antao6d004262016-06-16 18:39:34 +0000267
268 // If the field is not a pointer, we need to save the actual value
269 // and load it as a void pointer.
270 if (!CurField->getType()->isAnyPointerType()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000271 ASTContext &Ctx = getContext();
272 Address DstAddr = CreateMemTemp(
Samuel Antao6d004262016-06-16 18:39:34 +0000273 Ctx.getUIntPtrType(),
Alexey Bataevddf3db92018-04-13 17:31:06 +0000274 Twine(CurCap->getCapturedVar()->getName(), ".casted"));
Samuel Antao6d004262016-06-16 18:39:34 +0000275 LValue DstLV = MakeAddrLValue(DstAddr, Ctx.getUIntPtrType());
276
Alexey Bataevddf3db92018-04-13 17:31:06 +0000277 llvm::Value *SrcAddrVal = EmitScalarConversion(
Samuel Antao6d004262016-06-16 18:39:34 +0000278 DstAddr.getPointer(), Ctx.getPointerType(Ctx.getUIntPtrType()),
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000279 Ctx.getPointerType(CurField->getType()), CurCap->getLocation());
Samuel Antao6d004262016-06-16 18:39:34 +0000280 LValue SrcLV =
281 MakeNaturalAlignAddrLValue(SrcAddrVal, CurField->getType());
282
283 // Store the value using the source type pointer.
284 EmitStoreThroughLValue(RValue::get(CV), SrcLV);
285
286 // Load the value using the destination type pointer.
Alexey Bataev1e491372018-01-23 18:44:14 +0000287 CV = EmitLoadOfScalar(DstLV, CurCap->getLocation());
Samuel Antao6d004262016-06-16 18:39:34 +0000288 }
289 CapturedVars.push_back(CV);
290 } else {
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000291 assert(CurCap->capturesVariable() && "Expected capture by reference.");
Alexey Bataev2377fe92015-09-10 08:12:02 +0000292 CapturedVars.push_back(EmitLValue(*I).getAddress().getPointer());
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000293 }
Alexey Bataev2377fe92015-09-10 08:12:02 +0000294 }
295}
296
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000297static Address castValueFromUintptr(CodeGenFunction &CGF, SourceLocation Loc,
298 QualType DstType, StringRef Name,
299 LValue AddrLV,
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000300 bool isReferenceType = false) {
301 ASTContext &Ctx = CGF.getContext();
302
Alexey Bataevddf3db92018-04-13 17:31:06 +0000303 llvm::Value *CastedPtr = CGF.EmitScalarConversion(
304 AddrLV.getAddress().getPointer(), Ctx.getUIntPtrType(),
305 Ctx.getPointerType(DstType), Loc);
306 Address TmpAddr =
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000307 CGF.MakeNaturalAlignAddrLValue(CastedPtr, Ctx.getPointerType(DstType))
308 .getAddress();
309
310 // If we are dealing with references we need to return the address of the
311 // reference instead of the reference of the value.
312 if (isReferenceType) {
313 QualType RefType = Ctx.getLValueReferenceType(DstType);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000314 llvm::Value *RefVal = TmpAddr.getPointer();
315 TmpAddr = CGF.CreateMemTemp(RefType, Twine(Name, ".ref"));
316 LValue TmpLVal = CGF.MakeAddrLValue(TmpAddr, RefType);
317 CGF.EmitStoreThroughLValue(RValue::get(RefVal), TmpLVal, /*isInit=*/true);
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000318 }
319
320 return TmpAddr;
321}
322
Alexey Bataevf7ce1662017-04-10 19:16:45 +0000323static QualType getCanonicalParamType(ASTContext &C, QualType T) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000324 if (T->isLValueReferenceType())
Alexey Bataevf7ce1662017-04-10 19:16:45 +0000325 return C.getLValueReferenceType(
326 getCanonicalParamType(C, T.getNonReferenceType()),
327 /*SpelledAsLValue=*/false);
Alexey Bataevf7ce1662017-04-10 19:16:45 +0000328 if (T->isPointerType())
329 return C.getPointerType(getCanonicalParamType(C, T->getPointeeType()));
Alexey Bataevddf3db92018-04-13 17:31:06 +0000330 if (const ArrayType *A = T->getAsArrayTypeUnsafe()) {
331 if (const auto *VLA = dyn_cast<VariableArrayType>(A))
Alexey Bataev1b48c5e2017-10-24 19:52:31 +0000332 return getCanonicalParamType(C, VLA->getElementType());
Alexey Bataevddf3db92018-04-13 17:31:06 +0000333 if (!A->isVariablyModifiedType())
Alexey Bataev1b48c5e2017-10-24 19:52:31 +0000334 return C.getCanonicalType(T);
335 }
Alexey Bataevf7ce1662017-04-10 19:16:45 +0000336 return C.getCanonicalParamType(T);
337}
338
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000339namespace {
340 /// Contains required data for proper outlined function codegen.
341 struct FunctionOptions {
342 /// Captured statement for which the function is generated.
343 const CapturedStmt *S = nullptr;
344 /// true if cast to/from UIntPtr is required for variables captured by
345 /// value.
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000346 const bool UIntPtrCastRequired = true;
Alexey Bataeve754b182017-08-09 19:38:53 +0000347 /// true if only casted arguments must be registered as local args or VLA
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000348 /// sizes.
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000349 const bool RegisterCastedArgsOnly = false;
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000350 /// Name of the generated function.
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000351 const StringRef FunctionName;
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000352 explicit FunctionOptions(const CapturedStmt *S, bool UIntPtrCastRequired,
353 bool RegisterCastedArgsOnly,
Alexey Bataev4aa19052017-08-08 16:45:36 +0000354 StringRef FunctionName)
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000355 : S(S), UIntPtrCastRequired(UIntPtrCastRequired),
356 RegisterCastedArgsOnly(UIntPtrCastRequired && RegisterCastedArgsOnly),
Alexey Bataev4aa19052017-08-08 16:45:36 +0000357 FunctionName(FunctionName) {}
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000358 };
359}
360
Alexey Bataeve754b182017-08-09 19:38:53 +0000361static llvm::Function *emitOutlinedFunctionPrologue(
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000362 CodeGenFunction &CGF, FunctionArgList &Args,
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000363 llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>>
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000364 &LocalAddrs,
365 llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>>
366 &VLASizes,
367 llvm::Value *&CXXThisValue, const FunctionOptions &FO) {
368 const CapturedDecl *CD = FO.S->getCapturedDecl();
369 const RecordDecl *RD = FO.S->getCapturedRecordDecl();
Alexey Bataev2377fe92015-09-10 08:12:02 +0000370 assert(CD->hasBody() && "missing CapturedDecl body");
371
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000372 CXXThisValue = nullptr;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000373 // Build the argument list.
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000374 CodeGenModule &CGM = CGF.CGM;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000375 ASTContext &Ctx = CGM.getContext();
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000376 FunctionArgList TargetArgs;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000377 Args.append(CD->param_begin(),
378 std::next(CD->param_begin(), CD->getContextParamPosition()));
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000379 TargetArgs.append(
380 CD->param_begin(),
381 std::next(CD->param_begin(), CD->getContextParamPosition()));
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000382 auto I = FO.S->captures().begin();
Alexey Bataevb45d43c2017-11-22 16:02:03 +0000383 FunctionDecl *DebugFunctionDecl = nullptr;
384 if (!FO.UIntPtrCastRequired) {
385 FunctionProtoType::ExtProtoInfo EPI;
Jonas Devlieghere64a26302018-11-11 00:56:15 +0000386 QualType FunctionTy = Ctx.getFunctionType(Ctx.VoidTy, llvm::None, EPI);
Alexey Bataevb45d43c2017-11-22 16:02:03 +0000387 DebugFunctionDecl = FunctionDecl::Create(
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000388 Ctx, Ctx.getTranslationUnitDecl(), FO.S->getBeginLoc(),
Jonas Devlieghere64a26302018-11-11 00:56:15 +0000389 SourceLocation(), DeclarationName(), FunctionTy,
390 Ctx.getTrivialTypeSourceInfo(FunctionTy), SC_Static,
391 /*isInlineSpecified=*/false, /*hasWrittenPrototype=*/false);
Alexey Bataevb45d43c2017-11-22 16:02:03 +0000392 }
Alexey Bataevddf3db92018-04-13 17:31:06 +0000393 for (const FieldDecl *FD : RD->fields()) {
Alexey Bataev2377fe92015-09-10 08:12:02 +0000394 QualType ArgType = FD->getType();
395 IdentifierInfo *II = nullptr;
396 VarDecl *CapVar = nullptr;
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000397
398 // If this is a capture by copy and the type is not a pointer, the outlined
399 // function argument type should be uintptr and the value properly casted to
400 // uintptr. This is necessary given that the runtime library is only able to
401 // deal with pointers. We can pass in the same way the VLA type sizes to the
402 // outlined function.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000403 if (FO.UIntPtrCastRequired &&
404 ((I->capturesVariableByCopy() && !ArgType->isAnyPointerType()) ||
405 I->capturesVariableArrayType()))
406 ArgType = Ctx.getUIntPtrType();
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000407
408 if (I->capturesVariable() || I->capturesVariableByCopy()) {
Alexey Bataev2377fe92015-09-10 08:12:02 +0000409 CapVar = I->getCapturedVar();
410 II = CapVar->getIdentifier();
Alexey Bataevddf3db92018-04-13 17:31:06 +0000411 } else if (I->capturesThis()) {
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000412 II = &Ctx.Idents.get("this");
Alexey Bataevddf3db92018-04-13 17:31:06 +0000413 } else {
Alexey Bataev2377fe92015-09-10 08:12:02 +0000414 assert(I->capturesVariableArrayType());
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000415 II = &Ctx.Idents.get("vla");
Alexey Bataev2377fe92015-09-10 08:12:02 +0000416 }
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000417 if (ArgType->isVariablyModifiedType())
Alexey Bataev1b48c5e2017-10-24 19:52:31 +0000418 ArgType = getCanonicalParamType(Ctx, ArgType);
Alexey Bataevb45d43c2017-11-22 16:02:03 +0000419 VarDecl *Arg;
420 if (DebugFunctionDecl && (CapVar || I->capturesThis())) {
421 Arg = ParmVarDecl::Create(
422 Ctx, DebugFunctionDecl,
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000423 CapVar ? CapVar->getBeginLoc() : FD->getBeginLoc(),
Alexey Bataevb45d43c2017-11-22 16:02:03 +0000424 CapVar ? CapVar->getLocation() : FD->getLocation(), II, ArgType,
425 /*TInfo=*/nullptr, SC_None, /*DefArg=*/nullptr);
426 } else {
427 Arg = ImplicitParamDecl::Create(Ctx, /*DC=*/nullptr, FD->getLocation(),
428 II, ArgType, ImplicitParamDecl::Other);
429 }
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000430 Args.emplace_back(Arg);
431 // Do not cast arguments if we emit function with non-original types.
432 TargetArgs.emplace_back(
433 FO.UIntPtrCastRequired
434 ? Arg
435 : CGM.getOpenMPRuntime().translateParameter(FD, Arg));
Alexey Bataev2377fe92015-09-10 08:12:02 +0000436 ++I;
437 }
438 Args.append(
439 std::next(CD->param_begin(), CD->getContextParamPosition() + 1),
440 CD->param_end());
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000441 TargetArgs.append(
442 std::next(CD->param_begin(), CD->getContextParamPosition() + 1),
443 CD->param_end());
Alexey Bataev2377fe92015-09-10 08:12:02 +0000444
445 // Create the function declaration.
Alexey Bataev2377fe92015-09-10 08:12:02 +0000446 const CGFunctionInfo &FuncInfo =
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000447 CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, TargetArgs);
Alexey Bataev2377fe92015-09-10 08:12:02 +0000448 llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo);
449
Alexey Bataevddf3db92018-04-13 17:31:06 +0000450 auto *F =
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000451 llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
452 FO.FunctionName, &CGM.getModule());
Alexey Bataev2377fe92015-09-10 08:12:02 +0000453 CGM.SetInternalFunctionAttributes(CD, F, FuncInfo);
454 if (CD->isNothrow())
Alexey Bataev2c7eee52017-08-04 19:10:54 +0000455 F->setDoesNotThrow();
Alexey Bataevc0f879b2018-04-10 20:10:53 +0000456 F->setDoesNotRecurse();
Alexey Bataev2377fe92015-09-10 08:12:02 +0000457
458 // Generate the function.
Alexey Bataev6e01dc12017-08-14 16:03:47 +0000459 CGF.StartFunction(CD, Ctx.VoidTy, F, FuncInfo, TargetArgs,
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000460 FO.S->getBeginLoc(), CD->getBody()->getBeginLoc());
Alexey Bataev2377fe92015-09-10 08:12:02 +0000461 unsigned Cnt = CD->getContextParamPosition();
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000462 I = FO.S->captures().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +0000463 for (const FieldDecl *FD : RD->fields()) {
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000464 // Do not map arguments if we emit function with non-original types.
465 Address LocalAddr(Address::invalid());
466 if (!FO.UIntPtrCastRequired && Args[Cnt] != TargetArgs[Cnt]) {
467 LocalAddr = CGM.getOpenMPRuntime().getParameterAddress(CGF, Args[Cnt],
468 TargetArgs[Cnt]);
469 } else {
470 LocalAddr = CGF.GetAddrOfLocalVar(Args[Cnt]);
471 }
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000472 // If we are capturing a pointer by copy we don't need to do anything, just
473 // use the value that we get from the arguments.
474 if (I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) {
Samuel Antao403ffd42016-07-27 22:49:49 +0000475 const VarDecl *CurVD = I->getCapturedVar();
Samuel Antao403ffd42016-07-27 22:49:49 +0000476 // If the variable is a reference we need to materialize it here.
477 if (CurVD->getType()->isReferenceType()) {
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000478 Address RefAddr = CGF.CreateMemTemp(
479 CurVD->getType(), CGM.getPointerAlign(), ".materialized_ref");
480 CGF.EmitStoreOfScalar(LocalAddr.getPointer(), RefAddr,
481 /*Volatile=*/false, CurVD->getType());
Samuel Antao403ffd42016-07-27 22:49:49 +0000482 LocalAddr = RefAddr;
483 }
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000484 if (!FO.RegisterCastedArgsOnly)
485 LocalAddrs.insert({Args[Cnt], {CurVD, LocalAddr}});
Richard Trieucc3949d2016-02-18 22:34:54 +0000486 ++Cnt;
487 ++I;
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000488 continue;
489 }
490
Ivan A. Kosarev5f8c0ca2017-10-10 09:39:32 +0000491 LValue ArgLVal = CGF.MakeAddrLValue(LocalAddr, Args[Cnt]->getType(),
492 AlignmentSource::Decl);
Alexey Bataev2377fe92015-09-10 08:12:02 +0000493 if (FD->hasCapturedVLAType()) {
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000494 if (FO.UIntPtrCastRequired) {
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000495 ArgLVal = CGF.MakeAddrLValue(
496 castValueFromUintptr(CGF, I->getLocation(), FD->getType(),
497 Args[Cnt]->getName(), ArgLVal),
498 FD->getType(), AlignmentSource::Decl);
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000499 }
Alexey Bataevddf3db92018-04-13 17:31:06 +0000500 llvm::Value *ExprArg = CGF.EmitLoadOfScalar(ArgLVal, I->getLocation());
501 const VariableArrayType *VAT = FD->getCapturedVLAType();
502 VLASizes.try_emplace(Args[Cnt], VAT->getSizeExpr(), ExprArg);
Alexey Bataev2377fe92015-09-10 08:12:02 +0000503 } else if (I->capturesVariable()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000504 const VarDecl *Var = I->getCapturedVar();
Alexey Bataev2377fe92015-09-10 08:12:02 +0000505 QualType VarTy = Var->getType();
506 Address ArgAddr = ArgLVal.getAddress();
507 if (!VarTy->isReferenceType()) {
Alexey Bataev2f5ed342016-10-13 09:52:46 +0000508 if (ArgLVal.getType()->isLValueReferenceType()) {
Ivan A. Kosarev9f9d1572017-10-30 11:49:31 +0000509 ArgAddr = CGF.EmitLoadOfReference(ArgLVal);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000510 } else if (!VarTy->isVariablyModifiedType() ||
511 !VarTy->isPointerType()) {
Alexey Bataev2f5ed342016-10-13 09:52:46 +0000512 assert(ArgLVal.getType()->isPointerType());
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000513 ArgAddr = CGF.EmitLoadOfPointer(
Alexey Bataev2f5ed342016-10-13 09:52:46 +0000514 ArgAddr, ArgLVal.getType()->castAs<PointerType>());
515 }
Alexey Bataev2377fe92015-09-10 08:12:02 +0000516 }
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000517 if (!FO.RegisterCastedArgsOnly) {
518 LocalAddrs.insert(
519 {Args[Cnt],
520 {Var, Address(ArgAddr.getPointer(), Ctx.getDeclAlign(Var))}});
521 }
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000522 } else if (I->capturesVariableByCopy()) {
523 assert(!FD->getType()->isAnyPointerType() &&
524 "Not expecting a captured pointer.");
Alexey Bataevddf3db92018-04-13 17:31:06 +0000525 const VarDecl *Var = I->getCapturedVar();
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000526 QualType VarTy = Var->getType();
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000527 LocalAddrs.insert(
528 {Args[Cnt],
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000529 {Var, FO.UIntPtrCastRequired
530 ? castValueFromUintptr(CGF, I->getLocation(),
531 FD->getType(), Args[Cnt]->getName(),
532 ArgLVal, VarTy->isReferenceType())
533 : ArgLVal.getAddress()}});
Alexey Bataev2377fe92015-09-10 08:12:02 +0000534 } else {
535 // If 'this' is captured, load it into CXXThisValue.
536 assert(I->capturesThis());
Alexey Bataev1e491372018-01-23 18:44:14 +0000537 CXXThisValue = CGF.EmitLoadOfScalar(ArgLVal, I->getLocation());
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000538 LocalAddrs.insert({Args[Cnt], {nullptr, ArgLVal.getAddress()}});
Alexey Bataev2377fe92015-09-10 08:12:02 +0000539 }
Richard Trieucc3949d2016-02-18 22:34:54 +0000540 ++Cnt;
541 ++I;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000542 }
543
Alexey Bataeve754b182017-08-09 19:38:53 +0000544 return F;
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000545}
546
547llvm::Function *
548CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
549 assert(
550 CapturedStmtInfo &&
551 "CapturedStmtInfo should be set when generating the captured function");
552 const CapturedDecl *CD = S.getCapturedDecl();
553 // Build the argument list.
554 bool NeedWrapperFunction =
555 getDebugInfo() &&
556 CGM.getCodeGenOpts().getDebugInfo() >= codegenoptions::LimitedDebugInfo;
557 FunctionArgList Args;
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000558 llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>> LocalAddrs;
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000559 llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> VLASizes;
Alexey Bataeve754b182017-08-09 19:38:53 +0000560 SmallString<256> Buffer;
561 llvm::raw_svector_ostream Out(Buffer);
562 Out << CapturedStmtInfo->getHelperName();
563 if (NeedWrapperFunction)
564 Out << "_debug__";
Alexey Bataev4aa19052017-08-08 16:45:36 +0000565 FunctionOptions FO(&S, !NeedWrapperFunction, /*RegisterCastedArgsOnly=*/false,
Alexey Bataeve754b182017-08-09 19:38:53 +0000566 Out.str());
567 llvm::Function *F = emitOutlinedFunctionPrologue(*this, Args, LocalAddrs,
568 VLASizes, CXXThisValue, FO);
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000569 for (const auto &LocalAddrPair : LocalAddrs) {
570 if (LocalAddrPair.second.first) {
571 setAddrOfLocalVar(LocalAddrPair.second.first,
572 LocalAddrPair.second.second);
573 }
574 }
575 for (const auto &VLASizePair : VLASizes)
576 VLASizeMap[VLASizePair.second.first] = VLASizePair.second.second;
Serge Pavlov3a561452015-12-06 14:32:39 +0000577 PGO.assignRegionCounters(GlobalDecl(CD), F);
Alexey Bataev2377fe92015-09-10 08:12:02 +0000578 CapturedStmtInfo->EmitBody(*this, CD->getBody());
579 FinishFunction(CD->getBodyRBrace());
Alexey Bataeve754b182017-08-09 19:38:53 +0000580 if (!NeedWrapperFunction)
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000581 return F;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000582
Alexey Bataevefd884d2017-08-04 21:26:25 +0000583 FunctionOptions WrapperFO(&S, /*UIntPtrCastRequired=*/true,
Alexey Bataeve754b182017-08-09 19:38:53 +0000584 /*RegisterCastedArgsOnly=*/true,
585 CapturedStmtInfo->getHelperName());
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000586 CodeGenFunction WrapperCGF(CGM, /*suppressNewContext=*/true);
Gheorghe-Teodor Bercead3dcf2f2018-03-14 14:17:45 +0000587 WrapperCGF.CapturedStmtInfo = CapturedStmtInfo;
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000588 Args.clear();
589 LocalAddrs.clear();
590 VLASizes.clear();
591 llvm::Function *WrapperF =
592 emitOutlinedFunctionPrologue(WrapperCGF, Args, LocalAddrs, VLASizes,
Alexey Bataeve754b182017-08-09 19:38:53 +0000593 WrapperCGF.CXXThisValue, WrapperFO);
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000594 llvm::SmallVector<llvm::Value *, 4> CallArgs;
595 for (const auto *Arg : Args) {
596 llvm::Value *CallArg;
597 auto I = LocalAddrs.find(Arg);
598 if (I != LocalAddrs.end()) {
Alexey Bataev7ba57af2017-10-17 16:47:34 +0000599 LValue LV = WrapperCGF.MakeAddrLValue(
600 I->second.second,
601 I->second.first ? I->second.first->getType() : Arg->getType(),
602 AlignmentSource::Decl);
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000603 CallArg = WrapperCGF.EmitLoadOfScalar(LV, S.getBeginLoc());
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000604 } else {
605 auto EI = VLASizes.find(Arg);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000606 if (EI != VLASizes.end()) {
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000607 CallArg = EI->second.second;
Alexey Bataevddf3db92018-04-13 17:31:06 +0000608 } else {
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000609 LValue LV = WrapperCGF.MakeAddrLValue(WrapperCGF.GetAddrOfLocalVar(Arg),
Ivan A. Kosarev5f8c0ca2017-10-10 09:39:32 +0000610 Arg->getType(),
611 AlignmentSource::Decl);
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000612 CallArg = WrapperCGF.EmitLoadOfScalar(LV, S.getBeginLoc());
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000613 }
614 }
Alexey Bataev7ba57af2017-10-17 16:47:34 +0000615 CallArgs.emplace_back(WrapperCGF.EmitFromMemory(CallArg, Arg->getType()));
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000616 }
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000617 CGM.getOpenMPRuntime().emitOutlinedFunctionCall(WrapperCGF, S.getBeginLoc(),
Alexey Bataev3c595a62017-08-14 15:01:03 +0000618 F, CallArgs);
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000619 WrapperCGF.FinishFunction();
620 return WrapperF;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000621}
622
Alexey Bataev9959db52014-05-06 10:08:46 +0000623//===----------------------------------------------------------------------===//
624// OpenMP Directive Emission
625//===----------------------------------------------------------------------===//
Alexey Bataev420d45b2015-04-14 05:11:24 +0000626void CodeGenFunction::EmitOMPAggregateAssign(
John McCall7f416cc2015-09-08 08:05:57 +0000627 Address DestAddr, Address SrcAddr, QualType OriginalType,
Alexey Bataevddf3db92018-04-13 17:31:06 +0000628 const llvm::function_ref<void(Address, Address)> CopyGen) {
Alexey Bataev420d45b2015-04-14 05:11:24 +0000629 // Perform element-by-element initialization.
630 QualType ElementTy;
John McCall7f416cc2015-09-08 08:05:57 +0000631
632 // Drill down to the base element type on both arrays.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000633 const ArrayType *ArrayTy = OriginalType->getAsArrayTypeUnsafe();
634 llvm::Value *NumElements = emitArrayLength(ArrayTy, ElementTy, DestAddr);
John McCall7f416cc2015-09-08 08:05:57 +0000635 SrcAddr = Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());
636
Alexey Bataevddf3db92018-04-13 17:31:06 +0000637 llvm::Value *SrcBegin = SrcAddr.getPointer();
638 llvm::Value *DestBegin = DestAddr.getPointer();
Alexey Bataev420d45b2015-04-14 05:11:24 +0000639 // Cast from pointer to array type to pointer to single element.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000640 llvm::Value *DestEnd = Builder.CreateGEP(DestBegin, NumElements);
Alexey Bataev420d45b2015-04-14 05:11:24 +0000641 // The basic structure here is a while-do loop.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000642 llvm::BasicBlock *BodyBB = createBasicBlock("omp.arraycpy.body");
643 llvm::BasicBlock *DoneBB = createBasicBlock("omp.arraycpy.done");
644 llvm::Value *IsEmpty =
Alexey Bataev420d45b2015-04-14 05:11:24 +0000645 Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty");
646 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000647
Alexey Bataev420d45b2015-04-14 05:11:24 +0000648 // Enter the loop body, making that address the current address.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000649 llvm::BasicBlock *EntryBB = Builder.GetInsertBlock();
Alexey Bataev420d45b2015-04-14 05:11:24 +0000650 EmitBlock(BodyBB);
John McCall7f416cc2015-09-08 08:05:57 +0000651
652 CharUnits ElementSize = getContext().getTypeSizeInChars(ElementTy);
653
654 llvm::PHINode *SrcElementPHI =
655 Builder.CreatePHI(SrcBegin->getType(), 2, "omp.arraycpy.srcElementPast");
656 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
657 Address SrcElementCurrent =
658 Address(SrcElementPHI,
659 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
660
661 llvm::PHINode *DestElementPHI =
662 Builder.CreatePHI(DestBegin->getType(), 2, "omp.arraycpy.destElementPast");
663 DestElementPHI->addIncoming(DestBegin, EntryBB);
664 Address DestElementCurrent =
665 Address(DestElementPHI,
666 DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000667
Alexey Bataev420d45b2015-04-14 05:11:24 +0000668 // Emit copy.
669 CopyGen(DestElementCurrent, SrcElementCurrent);
670
671 // Shift the address forward by one element.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000672 llvm::Value *DestElementNext = Builder.CreateConstGEP1_32(
John McCall7f416cc2015-09-08 08:05:57 +0000673 DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
Alexey Bataevddf3db92018-04-13 17:31:06 +0000674 llvm::Value *SrcElementNext = Builder.CreateConstGEP1_32(
John McCall7f416cc2015-09-08 08:05:57 +0000675 SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.src.element");
Alexey Bataev420d45b2015-04-14 05:11:24 +0000676 // Check whether we've reached the end.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000677 llvm::Value *Done =
Alexey Bataev420d45b2015-04-14 05:11:24 +0000678 Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");
679 Builder.CreateCondBr(Done, DoneBB, BodyBB);
John McCall7f416cc2015-09-08 08:05:57 +0000680 DestElementPHI->addIncoming(DestElementNext, Builder.GetInsertBlock());
681 SrcElementPHI->addIncoming(SrcElementNext, Builder.GetInsertBlock());
Alexey Bataev420d45b2015-04-14 05:11:24 +0000682
683 // Done.
684 EmitBlock(DoneBB, /*IsFinished=*/true);
685}
686
John McCall7f416cc2015-09-08 08:05:57 +0000687void CodeGenFunction::EmitOMPCopy(QualType OriginalType, Address DestAddr,
688 Address SrcAddr, const VarDecl *DestVD,
Alexey Bataev420d45b2015-04-14 05:11:24 +0000689 const VarDecl *SrcVD, const Expr *Copy) {
690 if (OriginalType->isArrayType()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000691 const auto *BO = dyn_cast<BinaryOperator>(Copy);
Alexey Bataev420d45b2015-04-14 05:11:24 +0000692 if (BO && BO->getOpcode() == BO_Assign) {
693 // Perform simple memcpy for simple copying.
Ivan A. Kosarev1860b522018-01-25 14:21:55 +0000694 LValue Dest = MakeAddrLValue(DestAddr, OriginalType);
695 LValue Src = MakeAddrLValue(SrcAddr, OriginalType);
696 EmitAggregateAssign(Dest, Src, OriginalType);
Alexey Bataev420d45b2015-04-14 05:11:24 +0000697 } else {
698 // For arrays with complex element types perform element by element
699 // copying.
John McCall7f416cc2015-09-08 08:05:57 +0000700 EmitOMPAggregateAssign(
Alexey Bataev420d45b2015-04-14 05:11:24 +0000701 DestAddr, SrcAddr, OriginalType,
John McCall7f416cc2015-09-08 08:05:57 +0000702 [this, Copy, SrcVD, DestVD](Address DestElement, Address SrcElement) {
Alexey Bataev420d45b2015-04-14 05:11:24 +0000703 // Working with the single array element, so have to remap
704 // destination and source variables to corresponding array
705 // elements.
John McCall7f416cc2015-09-08 08:05:57 +0000706 CodeGenFunction::OMPPrivateScope Remap(*this);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000707 Remap.addPrivate(DestVD, [DestElement]() { return DestElement; });
708 Remap.addPrivate(SrcVD, [SrcElement]() { return SrcElement; });
Alexey Bataev420d45b2015-04-14 05:11:24 +0000709 (void)Remap.Privatize();
John McCall7f416cc2015-09-08 08:05:57 +0000710 EmitIgnoredExpr(Copy);
Alexey Bataev420d45b2015-04-14 05:11:24 +0000711 });
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000712 }
Alexey Bataev420d45b2015-04-14 05:11:24 +0000713 } else {
714 // Remap pseudo source variable to private copy.
John McCall7f416cc2015-09-08 08:05:57 +0000715 CodeGenFunction::OMPPrivateScope Remap(*this);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000716 Remap.addPrivate(SrcVD, [SrcAddr]() { return SrcAddr; });
717 Remap.addPrivate(DestVD, [DestAddr]() { return DestAddr; });
Alexey Bataev420d45b2015-04-14 05:11:24 +0000718 (void)Remap.Privatize();
719 // Emit copying of the whole variable.
John McCall7f416cc2015-09-08 08:05:57 +0000720 EmitIgnoredExpr(Copy);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000721 }
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000722}
723
Alexey Bataev69c62a92015-04-15 04:52:20 +0000724bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
725 OMPPrivateScope &PrivateScope) {
Alexey Bataev8ef31412015-12-18 07:58:25 +0000726 if (!HaveInsertPoint())
727 return false;
Alexey Bataevcd8b6a22016-02-15 08:07:17 +0000728 bool FirstprivateIsLastprivate = false;
729 llvm::DenseSet<const VarDecl *> Lastprivates;
730 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
731 for (const auto *D : C->varlists())
732 Lastprivates.insert(
733 cast<VarDecl>(cast<DeclRefExpr>(D)->getDecl())->getCanonicalDecl());
734 }
Alexey Bataev69c62a92015-04-15 04:52:20 +0000735 llvm::DenseSet<const VarDecl *> EmittedAsFirstprivate;
Alexey Bataev475a7442018-01-12 19:39:11 +0000736 llvm::SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
737 getOpenMPCaptureRegions(CaptureRegions, D.getDirectiveKind());
738 // Force emission of the firstprivate copy if the directive does not emit
739 // outlined function, like omp for, omp simd, omp distribute etc.
740 bool MustEmitFirstprivateCopy =
741 CaptureRegions.size() == 1 && CaptureRegions.back() == OMPD_unknown;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +0000742 for (const auto *C : D.getClausesOfKind<OMPFirstprivateClause>()) {
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000743 auto IRef = C->varlist_begin();
744 auto InitsRef = C->inits().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +0000745 for (const Expr *IInit : C->private_copies()) {
746 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000747 bool ThisFirstprivateIsLastprivate =
748 Lastprivates.count(OrigVD->getCanonicalDecl()) > 0;
Alexey Bataevddf3db92018-04-13 17:31:06 +0000749 const FieldDecl *FD = CapturedStmtInfo->lookup(OrigVD);
Alexey Bataev475a7442018-01-12 19:39:11 +0000750 if (!MustEmitFirstprivateCopy && !ThisFirstprivateIsLastprivate && FD &&
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000751 !FD->getType()->isReferenceType()) {
752 EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl());
753 ++IRef;
754 ++InitsRef;
755 continue;
756 }
Alexey Bataevcd8b6a22016-02-15 08:07:17 +0000757 FirstprivateIsLastprivate =
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000758 FirstprivateIsLastprivate || ThisFirstprivateIsLastprivate;
Alexey Bataevcd8b6a22016-02-15 08:07:17 +0000759 if (EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()).second) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000760 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
761 const auto *VDInit =
762 cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
Alexey Bataev69c62a92015-04-15 04:52:20 +0000763 bool IsRegistered;
Bruno Ricci5fc4db72018-12-21 14:10:18 +0000764 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000765 /*RefersToEnclosingVariableOrCapture=*/FD != nullptr,
766 (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
Ivan A. Kosarev1860b522018-01-25 14:21:55 +0000767 LValue OriginalLVal = EmitLValue(&DRE);
Alexey Bataevfeddd642016-04-22 09:05:03 +0000768 QualType Type = VD->getType();
Alexey Bataev1d9c15c2015-05-19 12:31:28 +0000769 if (Type->isArrayType()) {
Alexey Bataev69c62a92015-04-15 04:52:20 +0000770 // Emit VarDecl with copy init for arrays.
771 // Get the address of the original variable captured in current
772 // captured region.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000773 IsRegistered = PrivateScope.addPrivate(
774 OrigVD, [this, VD, Type, OriginalLVal, VDInit]() {
775 AutoVarEmission Emission = EmitAutoVarAlloca(*VD);
776 const Expr *Init = VD->getInit();
777 if (!isa<CXXConstructExpr>(Init) ||
778 isTrivialInitializer(Init)) {
779 // Perform simple memcpy.
780 LValue Dest =
781 MakeAddrLValue(Emission.getAllocatedAddress(), Type);
782 EmitAggregateAssign(Dest, OriginalLVal, Type);
783 } else {
784 EmitOMPAggregateAssign(
785 Emission.getAllocatedAddress(), OriginalLVal.getAddress(),
786 Type,
787 [this, VDInit, Init](Address DestElement,
788 Address SrcElement) {
789 // Clean up any temporaries needed by the
790 // initialization.
791 RunCleanupsScope InitScope(*this);
792 // Emit initialization for single element.
793 setAddrOfLocalVar(VDInit, SrcElement);
794 EmitAnyExprToMem(Init, DestElement,
795 Init->getType().getQualifiers(),
796 /*IsInitializer*/ false);
797 LocalDeclMap.erase(VDInit);
798 });
799 }
800 EmitAutoVarCleanups(Emission);
801 return Emission.getAllocatedAddress();
802 });
Alexey Bataev69c62a92015-04-15 04:52:20 +0000803 } else {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000804 Address OriginalAddr = OriginalLVal.getAddress();
805 IsRegistered = PrivateScope.addPrivate(
806 OrigVD, [this, VDInit, OriginalAddr, VD]() {
807 // Emit private VarDecl with copy init.
808 // Remap temp VDInit variable to the address of the original
809 // variable (for proper handling of captured global variables).
810 setAddrOfLocalVar(VDInit, OriginalAddr);
811 EmitDecl(*VD);
812 LocalDeclMap.erase(VDInit);
813 return GetAddrOfLocalVar(VD);
814 });
Alexey Bataev69c62a92015-04-15 04:52:20 +0000815 }
816 assert(IsRegistered &&
817 "firstprivate var already registered as private");
818 // Silence the warning about unused variable.
819 (void)IsRegistered;
820 }
Richard Trieucc3949d2016-02-18 22:34:54 +0000821 ++IRef;
822 ++InitsRef;
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000823 }
824 }
Alexey Bataevcd8b6a22016-02-15 08:07:17 +0000825 return FirstprivateIsLastprivate && !EmittedAsFirstprivate.empty();
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000826}
827
Alexey Bataev03b340a2014-10-21 03:16:40 +0000828void CodeGenFunction::EmitOMPPrivateClause(
829 const OMPExecutableDirective &D,
830 CodeGenFunction::OMPPrivateScope &PrivateScope) {
Alexey Bataev8ef31412015-12-18 07:58:25 +0000831 if (!HaveInsertPoint())
832 return;
Alexey Bataev50a64582015-04-22 12:24:45 +0000833 llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +0000834 for (const auto *C : D.getClausesOfKind<OMPPrivateClause>()) {
Alexey Bataev03b340a2014-10-21 03:16:40 +0000835 auto IRef = C->varlist_begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +0000836 for (const Expr *IInit : C->private_copies()) {
837 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataev50a64582015-04-22 12:24:45 +0000838 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000839 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
840 bool IsRegistered = PrivateScope.addPrivate(OrigVD, [this, VD]() {
841 // Emit private VarDecl with copy init.
842 EmitDecl(*VD);
843 return GetAddrOfLocalVar(VD);
844 });
Alexey Bataev50a64582015-04-22 12:24:45 +0000845 assert(IsRegistered && "private var already registered as private");
846 // Silence the warning about unused variable.
847 (void)IsRegistered;
848 }
Alexey Bataev03b340a2014-10-21 03:16:40 +0000849 ++IRef;
850 }
851 }
852}
853
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000854bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) {
Alexey Bataev8ef31412015-12-18 07:58:25 +0000855 if (!HaveInsertPoint())
856 return false;
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000857 // threadprivate_var1 = master_threadprivate_var1;
858 // operator=(threadprivate_var2, master_threadprivate_var2);
859 // ...
860 // __kmpc_barrier(&loc, global_tid);
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000861 llvm::DenseSet<const VarDecl *> CopiedVars;
862 llvm::BasicBlock *CopyBegin = nullptr, *CopyEnd = nullptr;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +0000863 for (const auto *C : D.getClausesOfKind<OMPCopyinClause>()) {
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000864 auto IRef = C->varlist_begin();
865 auto ISrcRef = C->source_exprs().begin();
866 auto IDestRef = C->destination_exprs().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +0000867 for (const Expr *AssignOp : C->assignment_ops()) {
868 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataev1d9c15c2015-05-19 12:31:28 +0000869 QualType Type = VD->getType();
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000870 if (CopiedVars.insert(VD->getCanonicalDecl()).second) {
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000871 // Get the address of the master variable. If we are emitting code with
872 // TLS support, the address is passed from the master as field in the
873 // captured declaration.
John McCall7f416cc2015-09-08 08:05:57 +0000874 Address MasterAddr = Address::invalid();
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000875 if (getLangOpts().OpenMPUseTLS &&
876 getContext().getTargetInfo().isTLSSupported()) {
877 assert(CapturedStmtInfo->lookup(VD) &&
878 "Copyin threadprivates should have been captured!");
Bruno Ricci5fc4db72018-12-21 14:10:18 +0000879 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(VD), true,
880 (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000881 MasterAddr = EmitLValue(&DRE).getAddress();
Alexey Bataev2377fe92015-09-10 08:12:02 +0000882 LocalDeclMap.erase(VD);
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000883 } else {
John McCall7f416cc2015-09-08 08:05:57 +0000884 MasterAddr =
885 Address(VD->isStaticLocal() ? CGM.getStaticLocalDeclAddress(VD)
886 : CGM.GetAddrOfGlobal(VD),
887 getContext().getDeclAlign(VD));
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000888 }
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000889 // Get the address of the threadprivate variable.
John McCall7f416cc2015-09-08 08:05:57 +0000890 Address PrivateAddr = EmitLValue(*IRef).getAddress();
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000891 if (CopiedVars.size() == 1) {
892 // At first check if current thread is a master thread. If it is, no
893 // need to copy data.
894 CopyBegin = createBasicBlock("copyin.not.master");
895 CopyEnd = createBasicBlock("copyin.not.master.end");
896 Builder.CreateCondBr(
897 Builder.CreateICmpNE(
John McCall7f416cc2015-09-08 08:05:57 +0000898 Builder.CreatePtrToInt(MasterAddr.getPointer(), CGM.IntPtrTy),
Alexey Bataevddf3db92018-04-13 17:31:06 +0000899 Builder.CreatePtrToInt(PrivateAddr.getPointer(),
900 CGM.IntPtrTy)),
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000901 CopyBegin, CopyEnd);
902 EmitBlock(CopyBegin);
903 }
Alexey Bataevddf3db92018-04-13 17:31:06 +0000904 const auto *SrcVD =
905 cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
906 const auto *DestVD =
907 cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
John McCall7f416cc2015-09-08 08:05:57 +0000908 EmitOMPCopy(Type, PrivateAddr, MasterAddr, DestVD, SrcVD, AssignOp);
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000909 }
910 ++IRef;
911 ++ISrcRef;
912 ++IDestRef;
913 }
914 }
915 if (CopyEnd) {
916 // Exit out of copying procedure for non-master thread.
917 EmitBlock(CopyEnd, /*IsFinished=*/true);
918 return true;
919 }
920 return false;
921}
922
Alexey Bataev38e89532015-04-16 04:54:05 +0000923bool CodeGenFunction::EmitOMPLastprivateClauseInit(
924 const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) {
Alexey Bataev8ef31412015-12-18 07:58:25 +0000925 if (!HaveInsertPoint())
926 return false;
Alexey Bataev38e89532015-04-16 04:54:05 +0000927 bool HasAtLeastOneLastprivate = false;
Alexey Bataev5dff95c2016-04-22 03:56:56 +0000928 llvm::DenseSet<const VarDecl *> SIMDLCVs;
929 if (isOpenMPSimdDirective(D.getDirectiveKind())) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000930 const auto *LoopDirective = cast<OMPLoopDirective>(&D);
931 for (const Expr *C : LoopDirective->counters()) {
Alexey Bataev5dff95c2016-04-22 03:56:56 +0000932 SIMDLCVs.insert(
933 cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl());
934 }
935 }
Alexey Bataev38e89532015-04-16 04:54:05 +0000936 llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +0000937 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
Alexey Bataevd130fd12015-05-13 10:23:02 +0000938 HasAtLeastOneLastprivate = true;
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000939 if (isOpenMPTaskLoopDirective(D.getDirectiveKind()) &&
940 !getLangOpts().OpenMPSimd)
Alexey Bataevf93095a2016-05-05 08:46:22 +0000941 break;
Alexey Bataev38e89532015-04-16 04:54:05 +0000942 auto IRef = C->varlist_begin();
943 auto IDestRef = C->destination_exprs().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +0000944 for (const Expr *IInit : C->private_copies()) {
Alexey Bataev38e89532015-04-16 04:54:05 +0000945 // Keep the address of the original variable for future update at the end
946 // of the loop.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000947 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataevf93095a2016-05-05 08:46:22 +0000948 // Taskloops do not require additional initialization, it is done in
949 // runtime support library.
Alexey Bataev38e89532015-04-16 04:54:05 +0000950 if (AlreadyEmittedVars.insert(OrigVD->getCanonicalDecl()).second) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000951 const auto *DestVD =
952 cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
953 PrivateScope.addPrivate(DestVD, [this, OrigVD, IRef]() {
Bruno Ricci5fc4db72018-12-21 14:10:18 +0000954 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
955 /*RefersToEnclosingVariableOrCapture=*/
956 CapturedStmtInfo->lookup(OrigVD) != nullptr,
957 (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
Alexey Bataev38e89532015-04-16 04:54:05 +0000958 return EmitLValue(&DRE).getAddress();
959 });
960 // Check if the variable is also a firstprivate: in this case IInit is
961 // not generated. Initialization of this variable will happen in codegen
962 // for 'firstprivate' clause.
Alexey Bataev5dff95c2016-04-22 03:56:56 +0000963 if (IInit && !SIMDLCVs.count(OrigVD->getCanonicalDecl())) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000964 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
965 bool IsRegistered = PrivateScope.addPrivate(OrigVD, [this, VD]() {
Alexey Bataevf93095a2016-05-05 08:46:22 +0000966 // Emit private VarDecl with copy init.
967 EmitDecl(*VD);
968 return GetAddrOfLocalVar(VD);
969 });
Alexey Bataevd130fd12015-05-13 10:23:02 +0000970 assert(IsRegistered &&
971 "lastprivate var already registered as private");
972 (void)IsRegistered;
973 }
Alexey Bataev38e89532015-04-16 04:54:05 +0000974 }
Richard Trieucc3949d2016-02-18 22:34:54 +0000975 ++IRef;
976 ++IDestRef;
Alexey Bataev38e89532015-04-16 04:54:05 +0000977 }
978 }
979 return HasAtLeastOneLastprivate;
980}
981
982void CodeGenFunction::EmitOMPLastprivateClauseFinal(
Alexey Bataev5dff95c2016-04-22 03:56:56 +0000983 const OMPExecutableDirective &D, bool NoFinals,
984 llvm::Value *IsLastIterCond) {
Alexey Bataev8ef31412015-12-18 07:58:25 +0000985 if (!HaveInsertPoint())
986 return;
Alexey Bataev38e89532015-04-16 04:54:05 +0000987 // Emit following code:
988 // if (<IsLastIterCond>) {
989 // orig_var1 = private_orig_var1;
990 // ...
991 // orig_varn = private_orig_varn;
992 // }
Alexey Bataevfc087ec2015-06-16 13:14:42 +0000993 llvm::BasicBlock *ThenBB = nullptr;
994 llvm::BasicBlock *DoneBB = nullptr;
995 if (IsLastIterCond) {
996 ThenBB = createBasicBlock(".omp.lastprivate.then");
997 DoneBB = createBasicBlock(".omp.lastprivate.done");
998 Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB);
999 EmitBlock(ThenBB);
1000 }
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001001 llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
1002 llvm::DenseMap<const VarDecl *, const Expr *> LoopCountersAndUpdates;
Alexey Bataevddf3db92018-04-13 17:31:06 +00001003 if (const auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) {
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001004 auto IC = LoopDirective->counters().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001005 for (const Expr *F : LoopDirective->finals()) {
1006 const auto *D =
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001007 cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl())->getCanonicalDecl();
1008 if (NoFinals)
1009 AlreadyEmittedVars.insert(D);
1010 else
1011 LoopCountersAndUpdates[D] = F;
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001012 ++IC;
Alexey Bataev7a228ff2015-05-21 07:59:51 +00001013 }
1014 }
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001015 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
1016 auto IRef = C->varlist_begin();
1017 auto ISrcRef = C->source_exprs().begin();
1018 auto IDestRef = C->destination_exprs().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001019 for (const Expr *AssignOp : C->assignment_ops()) {
1020 const auto *PrivateVD =
1021 cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001022 QualType Type = PrivateVD->getType();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001023 const auto *CanonicalVD = PrivateVD->getCanonicalDecl();
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001024 if (AlreadyEmittedVars.insert(CanonicalVD).second) {
1025 // If lastprivate variable is a loop control variable for loop-based
1026 // directive, update its value before copyin back to original
1027 // variable.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001028 if (const Expr *FinalExpr = LoopCountersAndUpdates.lookup(CanonicalVD))
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001029 EmitIgnoredExpr(FinalExpr);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001030 const auto *SrcVD =
1031 cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
1032 const auto *DestVD =
1033 cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001034 // Get the address of the original variable.
1035 Address OriginalAddr = GetAddrOfLocalVar(DestVD);
1036 // Get the address of the private variable.
1037 Address PrivateAddr = GetAddrOfLocalVar(PrivateVD);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001038 if (const auto *RefTy = PrivateVD->getType()->getAs<ReferenceType>())
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001039 PrivateAddr =
John McCall7f416cc2015-09-08 08:05:57 +00001040 Address(Builder.CreateLoad(PrivateAddr),
1041 getNaturalTypeAlignment(RefTy->getPointeeType()));
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001042 EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp);
Alexey Bataev38e89532015-04-16 04:54:05 +00001043 }
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001044 ++IRef;
1045 ++ISrcRef;
1046 ++IDestRef;
Alexey Bataev38e89532015-04-16 04:54:05 +00001047 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00001048 if (const Expr *PostUpdate = C->getPostUpdateExpr())
Alexey Bataev005248a2016-02-25 05:25:57 +00001049 EmitIgnoredExpr(PostUpdate);
Alexey Bataev38e89532015-04-16 04:54:05 +00001050 }
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001051 if (IsLastIterCond)
Alexey Bataevfc087ec2015-06-16 13:14:42 +00001052 EmitBlock(DoneBB, /*IsFinished=*/true);
Alexey Bataev38e89532015-04-16 04:54:05 +00001053}
1054
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001055void CodeGenFunction::EmitOMPReductionClauseInit(
1056 const OMPExecutableDirective &D,
1057 CodeGenFunction::OMPPrivateScope &PrivateScope) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001058 if (!HaveInsertPoint())
1059 return;
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001060 SmallVector<const Expr *, 4> Shareds;
1061 SmallVector<const Expr *, 4> Privates;
1062 SmallVector<const Expr *, 4> ReductionOps;
1063 SmallVector<const Expr *, 4> LHSs;
1064 SmallVector<const Expr *, 4> RHSs;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001065 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001066 auto IPriv = C->privates().begin();
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001067 auto IRed = C->reduction_ops().begin();
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001068 auto ILHS = C->lhs_exprs().begin();
1069 auto IRHS = C->rhs_exprs().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001070 for (const Expr *Ref : C->varlists()) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001071 Shareds.emplace_back(Ref);
1072 Privates.emplace_back(*IPriv);
1073 ReductionOps.emplace_back(*IRed);
1074 LHSs.emplace_back(*ILHS);
1075 RHSs.emplace_back(*IRHS);
1076 std::advance(IPriv, 1);
1077 std::advance(IRed, 1);
1078 std::advance(ILHS, 1);
1079 std::advance(IRHS, 1);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001080 }
1081 }
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001082 ReductionCodeGen RedCG(Shareds, Privates, ReductionOps);
1083 unsigned Count = 0;
1084 auto ILHS = LHSs.begin();
1085 auto IRHS = RHSs.begin();
1086 auto IPriv = Privates.begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001087 for (const Expr *IRef : Shareds) {
1088 const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl());
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001089 // Emit private VarDecl with reduction init.
1090 RedCG.emitSharedLValue(*this, Count);
1091 RedCG.emitAggregateType(*this, Count);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001092 AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001093 RedCG.emitInitialization(*this, Count, Emission.getAllocatedAddress(),
1094 RedCG.getSharedLValue(Count),
1095 [&Emission](CodeGenFunction &CGF) {
1096 CGF.EmitAutoVarInit(Emission);
1097 return true;
1098 });
1099 EmitAutoVarCleanups(Emission);
1100 Address BaseAddr = RedCG.adjustPrivateAddress(
1101 *this, Count, Emission.getAllocatedAddress());
1102 bool IsRegistered = PrivateScope.addPrivate(
Alexey Bataevddf3db92018-04-13 17:31:06 +00001103 RedCG.getBaseDecl(Count), [BaseAddr]() { return BaseAddr; });
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001104 assert(IsRegistered && "private var already registered as private");
1105 // Silence the warning about unused variable.
1106 (void)IsRegistered;
1107
Alexey Bataevddf3db92018-04-13 17:31:06 +00001108 const auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
1109 const auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
Jonas Hahnfeld4525c822017-10-23 19:01:35 +00001110 QualType Type = PrivateVD->getType();
1111 bool isaOMPArraySectionExpr = isa<OMPArraySectionExpr>(IRef);
1112 if (isaOMPArraySectionExpr && Type->isVariablyModifiedType()) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001113 // Store the address of the original variable associated with the LHS
1114 // implicit variable.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001115 PrivateScope.addPrivate(LHSVD, [&RedCG, Count]() {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001116 return RedCG.getSharedLValue(Count).getAddress();
1117 });
Alexey Bataevddf3db92018-04-13 17:31:06 +00001118 PrivateScope.addPrivate(
1119 RHSVD, [this, PrivateVD]() { return GetAddrOfLocalVar(PrivateVD); });
Jonas Hahnfeld4525c822017-10-23 19:01:35 +00001120 } else if ((isaOMPArraySectionExpr && Type->isScalarType()) ||
1121 isa<ArraySubscriptExpr>(IRef)) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001122 // Store the address of the original variable associated with the LHS
1123 // implicit variable.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001124 PrivateScope.addPrivate(LHSVD, [&RedCG, Count]() {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001125 return RedCG.getSharedLValue(Count).getAddress();
1126 });
Alexey Bataevddf3db92018-04-13 17:31:06 +00001127 PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001128 return Builder.CreateElementBitCast(GetAddrOfLocalVar(PrivateVD),
1129 ConvertTypeForMem(RHSVD->getType()),
1130 "rhs.begin");
1131 });
1132 } else {
1133 QualType Type = PrivateVD->getType();
1134 bool IsArray = getContext().getAsArrayType(Type) != nullptr;
1135 Address OriginalAddr = RedCG.getSharedLValue(Count).getAddress();
1136 // Store the address of the original variable associated with the LHS
1137 // implicit variable.
1138 if (IsArray) {
1139 OriginalAddr = Builder.CreateElementBitCast(
1140 OriginalAddr, ConvertTypeForMem(LHSVD->getType()), "lhs.begin");
1141 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00001142 PrivateScope.addPrivate(LHSVD, [OriginalAddr]() { return OriginalAddr; });
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001143 PrivateScope.addPrivate(
Alexey Bataevddf3db92018-04-13 17:31:06 +00001144 RHSVD, [this, PrivateVD, RHSVD, IsArray]() {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001145 return IsArray
1146 ? Builder.CreateElementBitCast(
1147 GetAddrOfLocalVar(PrivateVD),
1148 ConvertTypeForMem(RHSVD->getType()), "rhs.begin")
1149 : GetAddrOfLocalVar(PrivateVD);
1150 });
1151 }
1152 ++ILHS;
1153 ++IRHS;
1154 ++IPriv;
1155 ++Count;
1156 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001157}
1158
1159void CodeGenFunction::EmitOMPReductionClauseFinal(
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001160 const OMPExecutableDirective &D, const OpenMPDirectiveKind ReductionKind) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001161 if (!HaveInsertPoint())
1162 return;
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001163 llvm::SmallVector<const Expr *, 8> Privates;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001164 llvm::SmallVector<const Expr *, 8> LHSExprs;
1165 llvm::SmallVector<const Expr *, 8> RHSExprs;
1166 llvm::SmallVector<const Expr *, 8> ReductionOps;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001167 bool HasAtLeastOneReduction = false;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001168 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001169 HasAtLeastOneReduction = true;
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001170 Privates.append(C->privates().begin(), C->privates().end());
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001171 LHSExprs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
1172 RHSExprs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
1173 ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
1174 }
1175 if (HasAtLeastOneReduction) {
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001176 bool WithNowait = D.getSingleClause<OMPNowaitClause>() ||
1177 isOpenMPParallelDirective(D.getDirectiveKind()) ||
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001178 ReductionKind == OMPD_simd;
1179 bool SimpleReduction = ReductionKind == OMPD_simd;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001180 // Emit nowait reduction if nowait clause is present or directive is a
1181 // parallel directive (it always has implicit barrier).
1182 CGM.getOpenMPRuntime().emitReduction(
Stephen Kelly1c301dc2018-08-09 21:09:38 +00001183 *this, D.getEndLoc(), Privates, LHSExprs, RHSExprs, ReductionOps,
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001184 {WithNowait, SimpleReduction, ReductionKind});
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001185 }
1186}
1187
Alexey Bataev61205072016-03-02 04:57:40 +00001188static void emitPostUpdateForReductionClause(
1189 CodeGenFunction &CGF, const OMPExecutableDirective &D,
Alexey Bataevddf3db92018-04-13 17:31:06 +00001190 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) {
Alexey Bataev61205072016-03-02 04:57:40 +00001191 if (!CGF.HaveInsertPoint())
1192 return;
1193 llvm::BasicBlock *DoneBB = nullptr;
1194 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001195 if (const Expr *PostUpdate = C->getPostUpdateExpr()) {
Alexey Bataev61205072016-03-02 04:57:40 +00001196 if (!DoneBB) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001197 if (llvm::Value *Cond = CondGen(CGF)) {
Alexey Bataev61205072016-03-02 04:57:40 +00001198 // If the first post-update expression is found, emit conditional
1199 // block if it was requested.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001200 llvm::BasicBlock *ThenBB = CGF.createBasicBlock(".omp.reduction.pu");
Alexey Bataev61205072016-03-02 04:57:40 +00001201 DoneBB = CGF.createBasicBlock(".omp.reduction.pu.done");
1202 CGF.Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1203 CGF.EmitBlock(ThenBB);
1204 }
1205 }
1206 CGF.EmitIgnoredExpr(PostUpdate);
1207 }
1208 }
1209 if (DoneBB)
1210 CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
1211}
1212
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001213namespace {
1214/// Codegen lambda for appending distribute lower and upper bounds to outlined
1215/// parallel function. This is necessary for combined constructs such as
1216/// 'distribute parallel for'
1217typedef llvm::function_ref<void(CodeGenFunction &,
1218 const OMPExecutableDirective &,
1219 llvm::SmallVectorImpl<llvm::Value *> &)>
1220 CodeGenBoundParametersTy;
1221} // anonymous namespace
1222
1223static void emitCommonOMPParallelDirective(
1224 CodeGenFunction &CGF, const OMPExecutableDirective &S,
1225 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
1226 const CodeGenBoundParametersTy &CodeGenBoundParameters) {
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00001227 const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel);
James Y Knight9871db02019-02-05 16:42:33 +00001228 llvm::Function *OutlinedFn =
Alexey Bataevddf3db92018-04-13 17:31:06 +00001229 CGF.CGM.getOpenMPRuntime().emitParallelOutlinedFunction(
1230 S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001231 if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>()) {
Alexey Bataev1d677132015-04-22 13:57:31 +00001232 CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001233 llvm::Value *NumThreads =
1234 CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(),
1235 /*IgnoreResultAssign=*/true);
Alexey Bataev1d677132015-04-22 13:57:31 +00001236 CGF.CGM.getOpenMPRuntime().emitNumThreadsClause(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001237 CGF, NumThreads, NumThreadsClause->getBeginLoc());
Alexey Bataev1d677132015-04-22 13:57:31 +00001238 }
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001239 if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>()) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001240 CodeGenFunction::RunCleanupsScope ProcBindScope(CGF);
Alexey Bataev7f210c62015-06-18 13:40:03 +00001241 CGF.CGM.getOpenMPRuntime().emitProcBindClause(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001242 CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getBeginLoc());
Alexey Bataev7f210c62015-06-18 13:40:03 +00001243 }
Alexey Bataev1d677132015-04-22 13:57:31 +00001244 const Expr *IfCond = nullptr;
Alexey Bataev7371aa32015-09-03 08:45:56 +00001245 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
1246 if (C->getNameModifier() == OMPD_unknown ||
1247 C->getNameModifier() == OMPD_parallel) {
1248 IfCond = C->getCondition();
1249 break;
1250 }
Alexey Bataev1d677132015-04-22 13:57:31 +00001251 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001252
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00001253 OMPParallelScope Scope(CGF, S);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001254 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001255 // Combining 'distribute' with 'for' requires sharing each 'distribute' chunk
1256 // lower and upper bounds with the pragma 'for' chunking mechanism.
1257 // The following lambda takes care of appending the lower and upper bound
1258 // parameters when necessary
1259 CodeGenBoundParameters(CGF, S, CapturedVars);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001260 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001261 CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getBeginLoc(), OutlinedFn,
Alexey Bataev2377fe92015-09-10 08:12:02 +00001262 CapturedVars, IfCond);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001263}
1264
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001265static void emitEmptyBoundParameters(CodeGenFunction &,
1266 const OMPExecutableDirective &,
1267 llvm::SmallVectorImpl<llvm::Value *> &) {}
1268
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001269void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001270 // Emit parallel region as a standalone region.
Alexey Bataevc99042b2018-03-15 18:10:54 +00001271 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00001272 Action.Enter(CGF);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001273 OMPPrivateScope PrivateScope(CGF);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00001274 bool Copyins = CGF.EmitOMPCopyinClause(S);
Alexey Bataevcd8b6a22016-02-15 08:07:17 +00001275 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
1276 if (Copyins) {
Alexey Bataev69c62a92015-04-15 04:52:20 +00001277 // Emit implicit barrier to synchronize threads and avoid data races on
Alexey Bataevcd8b6a22016-02-15 08:07:17 +00001278 // propagation master's thread values of threadprivate variables to local
1279 // instances of that variables of all other implicit threads.
Alexey Bataev25e5b442015-09-15 12:52:43 +00001280 CGF.CGM.getOpenMPRuntime().emitBarrierCall(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001281 CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
Alexey Bataev25e5b442015-09-15 12:52:43 +00001282 /*ForceSimpleCall=*/true);
Alexey Bataev69c62a92015-04-15 04:52:20 +00001283 }
1284 CGF.EmitOMPPrivateClause(S, PrivateScope);
1285 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
1286 (void)PrivateScope.Privatize();
Alexey Bataev475a7442018-01-12 19:39:11 +00001287 CGF.EmitStmt(S.getCapturedStmt(OMPD_parallel)->getCapturedStmt());
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001288 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001289 };
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001290 emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen,
1291 emitEmptyBoundParameters);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001292 emitPostUpdateForReductionClause(*this, S,
1293 [](CodeGenFunction &) { return nullptr; });
Alexey Bataev9959db52014-05-06 10:08:46 +00001294}
Alexander Musman515ad8c2014-05-22 08:54:05 +00001295
Alexey Bataev0f34da12015-07-02 04:17:07 +00001296void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D,
1297 JumpDest LoopExit) {
Alexander Musmana5f070a2014-10-01 06:03:56 +00001298 RunCleanupsScope BodyScope(*this);
1299 // Update counters values on current iteration.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001300 for (const Expr *UE : D.updates())
1301 EmitIgnoredExpr(UE);
Alexander Musman3276a272015-03-21 10:12:56 +00001302 // Update the linear variables.
Alexey Bataev617db5f2017-12-04 15:38:33 +00001303 // In distribute directives only loop counters may be marked as linear, no
1304 // need to generate the code for them.
1305 if (!isOpenMPDistributeDirective(D.getDirectiveKind())) {
1306 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001307 for (const Expr *UE : C->updates())
1308 EmitIgnoredExpr(UE);
Alexey Bataev617db5f2017-12-04 15:38:33 +00001309 }
Alexander Musman3276a272015-03-21 10:12:56 +00001310 }
1311
Alexander Musmana5f070a2014-10-01 06:03:56 +00001312 // On a continue in the body, jump to the end.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001313 JumpDest Continue = getJumpDestInCurrentScope("omp.body.continue");
Alexey Bataev0f34da12015-07-02 04:17:07 +00001314 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
Alexander Musmana5f070a2014-10-01 06:03:56 +00001315 // Emit loop body.
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001316 EmitStmt(D.getBody());
Alexander Musmana5f070a2014-10-01 06:03:56 +00001317 // The end (updates/cleanups).
1318 EmitBlock(Continue.getBlock());
1319 BreakContinueStack.pop_back();
Alexander Musmana5f070a2014-10-01 06:03:56 +00001320}
1321
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001322void CodeGenFunction::EmitOMPInnerLoop(
1323 const Stmt &S, bool RequiresCleanup, const Expr *LoopCond,
1324 const Expr *IncExpr,
Alexey Bataevddf3db92018-04-13 17:31:06 +00001325 const llvm::function_ref<void(CodeGenFunction &)> BodyGen,
1326 const llvm::function_ref<void(CodeGenFunction &)> PostIncGen) {
Alexander Musmand196ef22014-10-07 08:57:09 +00001327 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
Alexander Musmana5f070a2014-10-01 06:03:56 +00001328
1329 // Start the loop with a block that tests the condition.
Alexander Musmand196ef22014-10-07 08:57:09 +00001330 auto CondBlock = createBasicBlock("omp.inner.for.cond");
Alexander Musmana5f070a2014-10-01 06:03:56 +00001331 EmitBlock(CondBlock);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001332 const SourceRange R = S.getSourceRange();
Amara Emerson652795d2016-11-10 14:44:30 +00001333 LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()),
1334 SourceLocToDebugLoc(R.getEnd()));
Alexander Musmana5f070a2014-10-01 06:03:56 +00001335
1336 // If there are any cleanups between here and the loop-exit scope,
1337 // create a block to stage a loop exit along.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001338 llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
Alexey Bataev2df54a02015-03-12 08:53:29 +00001339 if (RequiresCleanup)
Alexander Musmand196ef22014-10-07 08:57:09 +00001340 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
Alexander Musmana5f070a2014-10-01 06:03:56 +00001341
Alexey Bataevddf3db92018-04-13 17:31:06 +00001342 llvm::BasicBlock *LoopBody = createBasicBlock("omp.inner.for.body");
Alexander Musmana5f070a2014-10-01 06:03:56 +00001343
Alexey Bataev2df54a02015-03-12 08:53:29 +00001344 // Emit condition.
Justin Bogner66242d62015-04-23 23:06:47 +00001345 EmitBranchOnBoolExpr(LoopCond, LoopBody, ExitBlock, getProfileCount(&S));
Alexander Musmana5f070a2014-10-01 06:03:56 +00001346 if (ExitBlock != LoopExit.getBlock()) {
1347 EmitBlock(ExitBlock);
1348 EmitBranchThroughCleanup(LoopExit);
1349 }
1350
1351 EmitBlock(LoopBody);
Justin Bogner66242d62015-04-23 23:06:47 +00001352 incrementProfileCounter(&S);
Alexander Musmana5f070a2014-10-01 06:03:56 +00001353
1354 // Create a block for the increment.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001355 JumpDest Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
Alexander Musmana5f070a2014-10-01 06:03:56 +00001356 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1357
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001358 BodyGen(*this);
Alexander Musmana5f070a2014-10-01 06:03:56 +00001359
1360 // Emit "IV = IV + 1" and a back-edge to the condition block.
1361 EmitBlock(Continue.getBlock());
Alexey Bataev2df54a02015-03-12 08:53:29 +00001362 EmitIgnoredExpr(IncExpr);
Alexey Bataev98eb6e32015-04-22 11:15:40 +00001363 PostIncGen(*this);
Alexander Musmana5f070a2014-10-01 06:03:56 +00001364 BreakContinueStack.pop_back();
1365 EmitBranch(CondBlock);
1366 LoopStack.pop();
1367 // Emit the fall-through block.
1368 EmitBlock(LoopExit.getBlock());
1369}
1370
Alexey Bataev8c3edfe2017-08-16 15:58:46 +00001371bool CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001372 if (!HaveInsertPoint())
Alexey Bataev8c3edfe2017-08-16 15:58:46 +00001373 return false;
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001374 // Emit inits for the linear variables.
Alexey Bataev8c3edfe2017-08-16 15:58:46 +00001375 bool HasLinears = false;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001376 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001377 for (const Expr *Init : C->inits()) {
Alexey Bataev8c3edfe2017-08-16 15:58:46 +00001378 HasLinears = true;
Alexey Bataevddf3db92018-04-13 17:31:06 +00001379 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl());
1380 if (const auto *Ref =
1381 dyn_cast<DeclRefExpr>(VD->getInit()->IgnoreImpCasts())) {
Alexey Bataevef549a82016-03-09 09:49:09 +00001382 AutoVarEmission Emission = EmitAutoVarAlloca(*VD);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001383 const auto *OrigVD = cast<VarDecl>(Ref->getDecl());
Bruno Ricci5fc4db72018-12-21 14:10:18 +00001384 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
Alexey Bataevef549a82016-03-09 09:49:09 +00001385 CapturedStmtInfo->lookup(OrigVD) != nullptr,
1386 VD->getInit()->getType(), VK_LValue,
1387 VD->getInit()->getExprLoc());
1388 EmitExprAsInit(&DRE, VD, MakeAddrLValue(Emission.getAllocatedAddress(),
1389 VD->getType()),
1390 /*capturedByInit=*/false);
1391 EmitAutoVarCleanups(Emission);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001392 } else {
Alexey Bataevef549a82016-03-09 09:49:09 +00001393 EmitVarDecl(*VD);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001394 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00001395 }
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001396 // Emit the linear steps for the linear clauses.
1397 // If a step is not constant, it is pre-calculated before the loop.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001398 if (const auto *CS = cast_or_null<BinaryOperator>(C->getCalcStep()))
1399 if (const auto *SaveRef = cast<DeclRefExpr>(CS->getLHS())) {
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00001400 EmitVarDecl(*cast<VarDecl>(SaveRef->getDecl()));
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001401 // Emit calculation of the linear step.
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00001402 EmitIgnoredExpr(CS);
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001403 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00001404 }
Alexey Bataev8c3edfe2017-08-16 15:58:46 +00001405 return HasLinears;
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001406}
1407
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001408void CodeGenFunction::EmitOMPLinearClauseFinal(
1409 const OMPLoopDirective &D,
Alexey Bataevddf3db92018-04-13 17:31:06 +00001410 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) {
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001411 if (!HaveInsertPoint())
Alexey Bataev8ef31412015-12-18 07:58:25 +00001412 return;
Alexey Bataevef549a82016-03-09 09:49:09 +00001413 llvm::BasicBlock *DoneBB = nullptr;
Alexander Musman3276a272015-03-21 10:12:56 +00001414 // Emit the final values of the linear variables.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001415 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
Alexey Bataev39f915b82015-05-08 10:41:21 +00001416 auto IC = C->varlist_begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001417 for (const Expr *F : C->finals()) {
Alexey Bataevef549a82016-03-09 09:49:09 +00001418 if (!DoneBB) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001419 if (llvm::Value *Cond = CondGen(*this)) {
Alexey Bataevef549a82016-03-09 09:49:09 +00001420 // If the first post-update expression is found, emit conditional
1421 // block if it was requested.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001422 llvm::BasicBlock *ThenBB = createBasicBlock(".omp.linear.pu");
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001423 DoneBB = createBasicBlock(".omp.linear.pu.done");
1424 Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1425 EmitBlock(ThenBB);
Alexey Bataevef549a82016-03-09 09:49:09 +00001426 }
1427 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00001428 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl());
Bruno Ricci5fc4db72018-12-21 14:10:18 +00001429 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001430 CapturedStmtInfo->lookup(OrigVD) != nullptr,
Alexey Bataev39f915b82015-05-08 10:41:21 +00001431 (*IC)->getType(), VK_LValue, (*IC)->getExprLoc());
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001432 Address OrigAddr = EmitLValue(&DRE).getAddress();
1433 CodeGenFunction::OMPPrivateScope VarScope(*this);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001434 VarScope.addPrivate(OrigVD, [OrigAddr]() { return OrigAddr; });
Alexey Bataev39f915b82015-05-08 10:41:21 +00001435 (void)VarScope.Privatize();
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001436 EmitIgnoredExpr(F);
Alexey Bataev39f915b82015-05-08 10:41:21 +00001437 ++IC;
Alexander Musman3276a272015-03-21 10:12:56 +00001438 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00001439 if (const Expr *PostUpdate = C->getPostUpdateExpr())
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001440 EmitIgnoredExpr(PostUpdate);
Alexander Musman3276a272015-03-21 10:12:56 +00001441 }
Alexey Bataevef549a82016-03-09 09:49:09 +00001442 if (DoneBB)
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001443 EmitBlock(DoneBB, /*IsFinished=*/true);
Alexander Musmana5f070a2014-10-01 06:03:56 +00001444}
1445
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001446static void emitAlignedClause(CodeGenFunction &CGF,
1447 const OMPExecutableDirective &D) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001448 if (!CGF.HaveInsertPoint())
1449 return;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001450 for (const auto *Clause : D.getClausesOfKind<OMPAlignedClause>()) {
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001451 unsigned ClauseAlignment = 0;
Alexey Bataevddf3db92018-04-13 17:31:06 +00001452 if (const Expr *AlignmentExpr = Clause->getAlignment()) {
1453 auto *AlignmentCI =
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001454 cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
1455 ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue());
Alexander Musman09184fe2014-09-30 05:29:28 +00001456 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00001457 for (const Expr *E : Clause->varlists()) {
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001458 unsigned Alignment = ClauseAlignment;
1459 if (Alignment == 0) {
1460 // OpenMP [2.8.1, Description]
1461 // If no optional parameter is specified, implementation-defined default
1462 // alignments for SIMD instructions on the target platforms are assumed.
1463 Alignment =
Alexey Bataev00396512015-07-02 03:40:19 +00001464 CGF.getContext()
1465 .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign(
1466 E->getType()->getPointeeType()))
1467 .getQuantity();
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001468 }
1469 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
1470 "alignment is not power of 2");
1471 if (Alignment != 0) {
1472 llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
Roman Lebedevbd1c0872019-01-15 09:44:25 +00001473 CGF.EmitAlignmentAssumption(
1474 PtrValue, E, /*No second loc needed*/ SourceLocation(), Alignment);
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001475 }
Alexander Musman09184fe2014-09-30 05:29:28 +00001476 }
1477 }
1478}
1479
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001480void CodeGenFunction::EmitOMPPrivateLoopCounters(
1481 const OMPLoopDirective &S, CodeGenFunction::OMPPrivateScope &LoopScope) {
1482 if (!HaveInsertPoint())
Alexey Bataev8ef31412015-12-18 07:58:25 +00001483 return;
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001484 auto I = S.private_counters().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001485 for (const Expr *E : S.counters()) {
1486 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
1487 const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl());
Alexey Bataevab4ea222018-03-07 18:17:06 +00001488 // Emit var without initialization.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001489 AutoVarEmission VarEmission = EmitAutoVarAlloca(*PrivateVD);
Alexey Bataevab4ea222018-03-07 18:17:06 +00001490 EmitAutoVarCleanups(VarEmission);
1491 LocalDeclMap.erase(PrivateVD);
1492 (void)LoopScope.addPrivate(VD, [&VarEmission]() {
1493 return VarEmission.getAllocatedAddress();
Alexey Bataev435ad7b2014-10-10 09:48:26 +00001494 });
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001495 if (LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD) ||
1496 VD->hasGlobalStorage()) {
Alexey Bataevab4ea222018-03-07 18:17:06 +00001497 (void)LoopScope.addPrivate(PrivateVD, [this, VD, E]() {
Bruno Ricci5fc4db72018-12-21 14:10:18 +00001498 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(VD),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001499 LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD),
1500 E->getType(), VK_LValue, E->getExprLoc());
1501 return EmitLValue(&DRE).getAddress();
1502 });
Alexey Bataevab4ea222018-03-07 18:17:06 +00001503 } else {
1504 (void)LoopScope.addPrivate(PrivateVD, [&VarEmission]() {
1505 return VarEmission.getAllocatedAddress();
1506 });
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001507 }
Alexey Bataeva8899172015-08-06 12:30:57 +00001508 ++I;
Alexey Bataev435ad7b2014-10-10 09:48:26 +00001509 }
Alexey Bataevf138fda2018-08-13 19:04:24 +00001510 // Privatize extra loop counters used in loops for ordered(n) clauses.
1511 for (const auto *C : S.getClausesOfKind<OMPOrderedClause>()) {
1512 if (!C->getNumForLoops())
1513 continue;
1514 for (unsigned I = S.getCollapsedNumber(),
1515 E = C->getLoopNumIterations().size();
1516 I < E; ++I) {
Mike Rice0ed46662018-09-20 17:19:41 +00001517 const auto *DRE = cast<DeclRefExpr>(C->getLoopCounter(I));
Alexey Bataevf138fda2018-08-13 19:04:24 +00001518 const auto *VD = cast<VarDecl>(DRE->getDecl());
1519 // Override only those variables that are really emitted already.
1520 if (LocalDeclMap.count(VD)) {
1521 (void)LoopScope.addPrivate(VD, [this, DRE, VD]() {
1522 return CreateMemTemp(DRE->getType(), VD->getName());
1523 });
1524 }
1525 }
1526 }
Alexey Bataev435ad7b2014-10-10 09:48:26 +00001527}
1528
Alexey Bataev62dbb972015-04-22 11:59:37 +00001529static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S,
1530 const Expr *Cond, llvm::BasicBlock *TrueBlock,
1531 llvm::BasicBlock *FalseBlock, uint64_t TrueCount) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001532 if (!CGF.HaveInsertPoint())
1533 return;
Alexey Bataev6e8248f2015-06-11 10:53:56 +00001534 {
1535 CodeGenFunction::OMPPrivateScope PreCondScope(CGF);
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001536 CGF.EmitOMPPrivateLoopCounters(S, PreCondScope);
Alexey Bataev6e8248f2015-06-11 10:53:56 +00001537 (void)PreCondScope.Privatize();
Alexey Bataev6e8248f2015-06-11 10:53:56 +00001538 // Get initial values of real counters.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001539 for (const Expr *I : S.inits()) {
Alexey Bataev6e8248f2015-06-11 10:53:56 +00001540 CGF.EmitIgnoredExpr(I);
1541 }
Alexey Bataev62dbb972015-04-22 11:59:37 +00001542 }
1543 // Check that loop is executed at least one time.
1544 CGF.EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount);
1545}
1546
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001547void CodeGenFunction::EmitOMPLinearClause(
1548 const OMPLoopDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) {
1549 if (!HaveInsertPoint())
Alexey Bataev8ef31412015-12-18 07:58:25 +00001550 return;
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001551 llvm::DenseSet<const VarDecl *> SIMDLCVs;
1552 if (isOpenMPSimdDirective(D.getDirectiveKind())) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001553 const auto *LoopDirective = cast<OMPLoopDirective>(&D);
1554 for (const Expr *C : LoopDirective->counters()) {
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001555 SIMDLCVs.insert(
1556 cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl());
1557 }
1558 }
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001559 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
Alexey Bataevbd9fec12015-08-18 06:47:21 +00001560 auto CurPrivate = C->privates().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001561 for (const Expr *E : C->varlists()) {
1562 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
1563 const auto *PrivateVD =
Alexey Bataevbd9fec12015-08-18 06:47:21 +00001564 cast<VarDecl>(cast<DeclRefExpr>(*CurPrivate)->getDecl());
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001565 if (!SIMDLCVs.count(VD->getCanonicalDecl())) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001566 bool IsRegistered = PrivateScope.addPrivate(VD, [this, PrivateVD]() {
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001567 // Emit private VarDecl with copy init.
1568 EmitVarDecl(*PrivateVD);
1569 return GetAddrOfLocalVar(PrivateVD);
1570 });
1571 assert(IsRegistered && "linear var already registered as private");
1572 // Silence the warning about unused variable.
1573 (void)IsRegistered;
Alexey Bataevddf3db92018-04-13 17:31:06 +00001574 } else {
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001575 EmitVarDecl(*PrivateVD);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001576 }
Alexey Bataevbd9fec12015-08-18 06:47:21 +00001577 ++CurPrivate;
Alexander Musman3276a272015-03-21 10:12:56 +00001578 }
1579 }
1580}
1581
Alexey Bataev45bfad52015-08-21 12:19:04 +00001582static void emitSimdlenSafelenClause(CodeGenFunction &CGF,
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001583 const OMPExecutableDirective &D,
1584 bool IsMonotonic) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001585 if (!CGF.HaveInsertPoint())
1586 return;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001587 if (const auto *C = D.getSingleClause<OMPSimdlenClause>()) {
Alexey Bataev45bfad52015-08-21 12:19:04 +00001588 RValue Len = CGF.EmitAnyExpr(C->getSimdlen(), AggValueSlot::ignored(),
1589 /*ignoreResult=*/true);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001590 auto *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
Alexey Bataev45bfad52015-08-21 12:19:04 +00001591 CGF.LoopStack.setVectorizeWidth(Val->getZExtValue());
1592 // In presence of finite 'safelen', it may be unsafe to mark all
1593 // the memory instructions parallel, because loop-carried
1594 // dependences of 'safelen' iterations are possible.
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001595 if (!IsMonotonic)
1596 CGF.LoopStack.setParallel(!D.getSingleClause<OMPSafelenClause>());
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001597 } else if (const auto *C = D.getSingleClause<OMPSafelenClause>()) {
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001598 RValue Len = CGF.EmitAnyExpr(C->getSafelen(), AggValueSlot::ignored(),
1599 /*ignoreResult=*/true);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001600 auto *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
Tyler Nowickida46d0e2015-07-14 23:03:09 +00001601 CGF.LoopStack.setVectorizeWidth(Val->getZExtValue());
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001602 // In presence of finite 'safelen', it may be unsafe to mark all
1603 // the memory instructions parallel, because loop-carried
1604 // dependences of 'safelen' iterations are possible.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001605 CGF.LoopStack.setParallel(/*Enable=*/false);
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001606 }
1607}
1608
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001609void CodeGenFunction::EmitOMPSimdInit(const OMPLoopDirective &D,
1610 bool IsMonotonic) {
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001611 // Walk clauses and process safelen/lastprivate.
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001612 LoopStack.setParallel(!IsMonotonic);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001613 LoopStack.setVectorizeEnable();
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001614 emitSimdlenSafelenClause(*this, D, IsMonotonic);
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001615}
1616
Alexey Bataevef549a82016-03-09 09:49:09 +00001617void CodeGenFunction::EmitOMPSimdFinal(
1618 const OMPLoopDirective &D,
Alexey Bataevddf3db92018-04-13 17:31:06 +00001619 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001620 if (!HaveInsertPoint())
1621 return;
Alexey Bataevef549a82016-03-09 09:49:09 +00001622 llvm::BasicBlock *DoneBB = nullptr;
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001623 auto IC = D.counters().begin();
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001624 auto IPC = D.private_counters().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001625 for (const Expr *F : D.finals()) {
1626 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl());
1627 const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>((*IPC))->getDecl());
1628 const auto *CED = dyn_cast<OMPCapturedExprDecl>(OrigVD);
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001629 if (LocalDeclMap.count(OrigVD) || CapturedStmtInfo->lookup(OrigVD) ||
1630 OrigVD->hasGlobalStorage() || CED) {
Alexey Bataevef549a82016-03-09 09:49:09 +00001631 if (!DoneBB) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001632 if (llvm::Value *Cond = CondGen(*this)) {
Alexey Bataevef549a82016-03-09 09:49:09 +00001633 // If the first post-update expression is found, emit conditional
1634 // block if it was requested.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001635 llvm::BasicBlock *ThenBB = createBasicBlock(".omp.final.then");
Alexey Bataevef549a82016-03-09 09:49:09 +00001636 DoneBB = createBasicBlock(".omp.final.done");
1637 Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1638 EmitBlock(ThenBB);
1639 }
1640 }
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001641 Address OrigAddr = Address::invalid();
Alexey Bataevab4ea222018-03-07 18:17:06 +00001642 if (CED) {
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001643 OrigAddr = EmitLValue(CED->getInit()->IgnoreImpCasts()).getAddress();
Alexey Bataevab4ea222018-03-07 18:17:06 +00001644 } else {
Bruno Ricci5fc4db72018-12-21 14:10:18 +00001645 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(PrivateVD),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001646 /*RefersToEnclosingVariableOrCapture=*/false,
1647 (*IPC)->getType(), VK_LValue, (*IPC)->getExprLoc());
1648 OrigAddr = EmitLValue(&DRE).getAddress();
1649 }
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001650 OMPPrivateScope VarScope(*this);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001651 VarScope.addPrivate(OrigVD, [OrigAddr]() { return OrigAddr; });
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001652 (void)VarScope.Privatize();
1653 EmitIgnoredExpr(F);
1654 }
1655 ++IC;
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001656 ++IPC;
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001657 }
Alexey Bataevef549a82016-03-09 09:49:09 +00001658 if (DoneBB)
1659 EmitBlock(DoneBB, /*IsFinished=*/true);
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001660}
1661
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001662static void emitOMPLoopBodyWithStopPoint(CodeGenFunction &CGF,
1663 const OMPLoopDirective &S,
1664 CodeGenFunction::JumpDest LoopExit) {
1665 CGF.EmitOMPLoopBody(S, LoopExit);
1666 CGF.EmitStopPoint(&S);
Hans Wennborged129ae2017-04-27 17:02:25 +00001667}
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001668
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001669/// Emit a helper variable and return corresponding lvalue.
1670static LValue EmitOMPHelperVar(CodeGenFunction &CGF,
1671 const DeclRefExpr *Helper) {
1672 auto VDecl = cast<VarDecl>(Helper->getDecl());
1673 CGF.EmitVarDecl(*VDecl);
1674 return CGF.EmitLValue(Helper);
1675}
1676
Alexey Bataevf8365372017-11-17 17:57:25 +00001677static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S,
1678 PrePostActionTy &Action) {
1679 Action.Enter(CGF);
1680 assert(isOpenMPSimdDirective(S.getDirectiveKind()) &&
1681 "Expected simd directive");
1682 OMPLoopScope PreInitScope(CGF, S);
1683 // if (PreCond) {
1684 // for (IV in 0..LastIteration) BODY;
1685 // <Final counter/linear vars updates>;
1686 // }
1687 //
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001688 if (isOpenMPDistributeDirective(S.getDirectiveKind()) ||
1689 isOpenMPWorksharingDirective(S.getDirectiveKind()) ||
1690 isOpenMPTaskLoopDirective(S.getDirectiveKind())) {
1691 (void)EmitOMPHelperVar(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()));
1692 (void)EmitOMPHelperVar(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()));
1693 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00001694
Alexey Bataevf8365372017-11-17 17:57:25 +00001695 // Emit: if (PreCond) - begin.
1696 // If the condition constant folds and can be elided, avoid emitting the
1697 // whole loop.
1698 bool CondConstant;
1699 llvm::BasicBlock *ContBlock = nullptr;
1700 if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
1701 if (!CondConstant)
1702 return;
1703 } else {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001704 llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("simd.if.then");
Alexey Bataevf8365372017-11-17 17:57:25 +00001705 ContBlock = CGF.createBasicBlock("simd.if.end");
1706 emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
1707 CGF.getProfileCount(&S));
1708 CGF.EmitBlock(ThenBlock);
1709 CGF.incrementProfileCounter(&S);
1710 }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001711
Alexey Bataevf8365372017-11-17 17:57:25 +00001712 // Emit the loop iteration variable.
1713 const Expr *IVExpr = S.getIterationVariable();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001714 const auto *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
Alexey Bataevf8365372017-11-17 17:57:25 +00001715 CGF.EmitVarDecl(*IVDecl);
1716 CGF.EmitIgnoredExpr(S.getInit());
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001717
Alexey Bataevf8365372017-11-17 17:57:25 +00001718 // Emit the iterations count variable.
1719 // If it is not a variable, Sema decided to calculate iterations count on
1720 // each iteration (e.g., it is foldable into a constant).
Alexey Bataevddf3db92018-04-13 17:31:06 +00001721 if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
Alexey Bataevf8365372017-11-17 17:57:25 +00001722 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
1723 // Emit calculation of the iterations count.
1724 CGF.EmitIgnoredExpr(S.getCalcLastIteration());
1725 }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001726
Alexey Bataevf8365372017-11-17 17:57:25 +00001727 CGF.EmitOMPSimdInit(S);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001728
Alexey Bataevf8365372017-11-17 17:57:25 +00001729 emitAlignedClause(CGF, S);
1730 (void)CGF.EmitOMPLinearClauseInit(S);
1731 {
1732 CodeGenFunction::OMPPrivateScope LoopScope(CGF);
1733 CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
1734 CGF.EmitOMPLinearClause(S, LoopScope);
1735 CGF.EmitOMPPrivateClause(S, LoopScope);
1736 CGF.EmitOMPReductionClauseInit(S, LoopScope);
1737 bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
1738 (void)LoopScope.Privatize();
Alexey Bataev60705422018-10-30 15:50:12 +00001739 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
1740 CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
Alexey Bataevf8365372017-11-17 17:57:25 +00001741 CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
1742 S.getInc(),
1743 [&S](CodeGenFunction &CGF) {
1744 CGF.EmitOMPLoopBody(S, CodeGenFunction::JumpDest());
1745 CGF.EmitStopPoint(&S);
1746 },
1747 [](CodeGenFunction &) {});
Alexey Bataevddf3db92018-04-13 17:31:06 +00001748 CGF.EmitOMPSimdFinal(S, [](CodeGenFunction &) { return nullptr; });
Alexey Bataevf8365372017-11-17 17:57:25 +00001749 // Emit final copy of the lastprivate variables at the end of loops.
1750 if (HasLastprivateClause)
1751 CGF.EmitOMPLastprivateClauseFinal(S, /*NoFinals=*/true);
1752 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_simd);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001753 emitPostUpdateForReductionClause(CGF, S,
1754 [](CodeGenFunction &) { return nullptr; });
Alexey Bataevf8365372017-11-17 17:57:25 +00001755 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00001756 CGF.EmitOMPLinearClauseFinal(S, [](CodeGenFunction &) { return nullptr; });
Alexey Bataevf8365372017-11-17 17:57:25 +00001757 // Emit: if (PreCond) - end.
1758 if (ContBlock) {
1759 CGF.EmitBranch(ContBlock);
1760 CGF.EmitBlock(ContBlock, true);
1761 }
1762}
1763
1764void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
1765 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
1766 emitOMPSimdRegion(CGF, S, Action);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001767 };
Alexey Bataev475a7442018-01-12 19:39:11 +00001768 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001769 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
Alexander Musman515ad8c2014-05-22 08:54:05 +00001770}
1771
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001772void CodeGenFunction::EmitOMPOuterLoop(
1773 bool DynamicOrOrdered, bool IsMonotonic, const OMPLoopDirective &S,
1774 CodeGenFunction::OMPPrivateScope &LoopScope,
1775 const CodeGenFunction::OMPLoopArguments &LoopArgs,
1776 const CodeGenFunction::CodeGenLoopTy &CodeGenLoop,
1777 const CodeGenFunction::CodeGenOrderedTy &CodeGenOrdered) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001778 CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
Alexander Musman92bdaab2015-03-12 13:37:50 +00001779
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001780 const Expr *IVExpr = S.getIterationVariable();
1781 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
1782 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
1783
Alexey Bataevddf3db92018-04-13 17:31:06 +00001784 JumpDest LoopExit = getJumpDestInCurrentScope("omp.dispatch.end");
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001785
1786 // Start the loop with a block that tests the condition.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001787 llvm::BasicBlock *CondBlock = createBasicBlock("omp.dispatch.cond");
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001788 EmitBlock(CondBlock);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001789 const SourceRange R = S.getSourceRange();
Amara Emerson652795d2016-11-10 14:44:30 +00001790 LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()),
1791 SourceLocToDebugLoc(R.getEnd()));
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001792
1793 llvm::Value *BoolCondVal = nullptr;
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00001794 if (!DynamicOrOrdered) {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001795 // UB = min(UB, GlobalUB) or
1796 // UB = min(UB, PrevUB) for combined loop sharing constructs (e.g.
1797 // 'distribute parallel for')
1798 EmitIgnoredExpr(LoopArgs.EUB);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001799 // IV = LB
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001800 EmitIgnoredExpr(LoopArgs.Init);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001801 // IV < UB
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001802 BoolCondVal = EvaluateExprAsBool(LoopArgs.Cond);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001803 } else {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001804 BoolCondVal =
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001805 RT.emitForNext(*this, S.getBeginLoc(), IVSize, IVSigned, LoopArgs.IL,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001806 LoopArgs.LB, LoopArgs.UB, LoopArgs.ST);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001807 }
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001808
1809 // If there are any cleanups between here and the loop-exit scope,
1810 // create a block to stage a loop exit along.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001811 llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001812 if (LoopScope.requiresCleanups())
1813 ExitBlock = createBasicBlock("omp.dispatch.cleanup");
1814
Alexey Bataevddf3db92018-04-13 17:31:06 +00001815 llvm::BasicBlock *LoopBody = createBasicBlock("omp.dispatch.body");
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001816 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
1817 if (ExitBlock != LoopExit.getBlock()) {
1818 EmitBlock(ExitBlock);
1819 EmitBranchThroughCleanup(LoopExit);
1820 }
1821 EmitBlock(LoopBody);
1822
Alexander Musman92bdaab2015-03-12 13:37:50 +00001823 // Emit "IV = LB" (in case of static schedule, we have already calculated new
1824 // LB for loop condition and emitted it above).
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00001825 if (DynamicOrOrdered)
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001826 EmitIgnoredExpr(LoopArgs.Init);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001827
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001828 // Create a block for the increment.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001829 JumpDest Continue = getJumpDestInCurrentScope("omp.dispatch.inc");
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001830 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1831
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001832 // Generate !llvm.loop.parallel metadata for loads and stores for loops
1833 // with dynamic/guided scheduling and without ordered clause.
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001834 if (!isOpenMPSimdDirective(S.getDirectiveKind()))
1835 LoopStack.setParallel(!IsMonotonic);
1836 else
1837 EmitOMPSimdInit(S, IsMonotonic);
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001838
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001839 SourceLocation Loc = S.getBeginLoc();
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001840
1841 // when 'distribute' is not combined with a 'for':
1842 // while (idx <= UB) { BODY; ++idx; }
1843 // when 'distribute' is combined with a 'for'
1844 // (e.g. 'distribute parallel for')
1845 // while (idx <= UB) { <CodeGen rest of pragma>; idx += ST; }
1846 EmitOMPInnerLoop(
1847 S, LoopScope.requiresCleanups(), LoopArgs.Cond, LoopArgs.IncExpr,
1848 [&S, LoopExit, &CodeGenLoop](CodeGenFunction &CGF) {
1849 CodeGenLoop(CGF, S, LoopExit);
1850 },
1851 [IVSize, IVSigned, Loc, &CodeGenOrdered](CodeGenFunction &CGF) {
1852 CodeGenOrdered(CGF, Loc, IVSize, IVSigned);
1853 });
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001854
1855 EmitBlock(Continue.getBlock());
1856 BreakContinueStack.pop_back();
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00001857 if (!DynamicOrOrdered) {
Alexander Musman92bdaab2015-03-12 13:37:50 +00001858 // Emit "LB = LB + Stride", "UB = UB + Stride".
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001859 EmitIgnoredExpr(LoopArgs.NextLB);
1860 EmitIgnoredExpr(LoopArgs.NextUB);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001861 }
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001862
1863 EmitBranch(CondBlock);
1864 LoopStack.pop();
1865 // Emit the fall-through block.
1866 EmitBlock(LoopExit.getBlock());
1867
1868 // Tell the runtime we are done.
Alexey Bataev957d8562016-11-17 15:12:05 +00001869 auto &&CodeGen = [DynamicOrOrdered, &S](CodeGenFunction &CGF) {
1870 if (!DynamicOrOrdered)
Stephen Kelly1c301dc2018-08-09 21:09:38 +00001871 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),
Alexey Bataevf43f7142017-09-06 16:17:35 +00001872 S.getDirectiveKind());
Alexey Bataev957d8562016-11-17 15:12:05 +00001873 };
1874 OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001875}
1876
1877void CodeGenFunction::EmitOMPForOuterLoop(
Alexey Bataev9ebd7422016-05-10 09:57:36 +00001878 const OpenMPScheduleTy &ScheduleKind, bool IsMonotonic,
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001879 const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001880 const OMPLoopArguments &LoopArgs,
1881 const CodeGenDispatchBoundsTy &CGDispatchBounds) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001882 CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001883
1884 // Dynamic scheduling of the outer loop (dynamic, guided, auto, runtime).
Alexey Bataev9ebd7422016-05-10 09:57:36 +00001885 const bool DynamicOrOrdered =
1886 Ordered || RT.isDynamic(ScheduleKind.Schedule);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001887
1888 assert((Ordered ||
Alexey Bataev9ebd7422016-05-10 09:57:36 +00001889 !RT.isStaticNonchunked(ScheduleKind.Schedule,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001890 LoopArgs.Chunk != nullptr)) &&
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001891 "static non-chunked schedule does not need outer loop");
1892
1893 // Emit outer loop.
1894 //
1895 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
1896 // When schedule(dynamic,chunk_size) is specified, the iterations are
1897 // distributed to threads in the team in chunks as the threads request them.
1898 // Each thread executes a chunk of iterations, then requests another chunk,
1899 // until no chunks remain to be distributed. Each chunk contains chunk_size
1900 // iterations, except for the last chunk to be distributed, which may have
1901 // fewer iterations. When no chunk_size is specified, it defaults to 1.
1902 //
1903 // When schedule(guided,chunk_size) is specified, the iterations are assigned
1904 // to threads in the team in chunks as the executing threads request them.
1905 // Each thread executes a chunk of iterations, then requests another chunk,
1906 // until no chunks remain to be assigned. For a chunk_size of 1, the size of
1907 // each chunk is proportional to the number of unassigned iterations divided
1908 // by the number of threads in the team, decreasing to 1. For a chunk_size
1909 // with value k (greater than 1), the size of each chunk is determined in the
1910 // same way, with the restriction that the chunks do not contain fewer than k
1911 // iterations (except for the last chunk to be assigned, which may have fewer
1912 // than k iterations).
1913 //
1914 // When schedule(auto) is specified, the decision regarding scheduling is
1915 // delegated to the compiler and/or runtime system. The programmer gives the
1916 // implementation the freedom to choose any possible mapping of iterations to
1917 // threads in the team.
1918 //
1919 // When schedule(runtime) is specified, the decision regarding scheduling is
1920 // deferred until run time, and the schedule and chunk size are taken from the
1921 // run-sched-var ICV. If the ICV is set to auto, the schedule is
1922 // implementation defined
1923 //
1924 // while(__kmpc_dispatch_next(&LB, &UB)) {
1925 // idx = LB;
1926 // while (idx <= UB) { BODY; ++idx;
1927 // __kmpc_dispatch_fini_(4|8)[u](); // For ordered loops only.
1928 // } // inner loop
1929 // }
1930 //
1931 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
1932 // When schedule(static, chunk_size) is specified, iterations are divided into
1933 // chunks of size chunk_size, and the chunks are assigned to the threads in
1934 // the team in a round-robin fashion in the order of the thread number.
1935 //
1936 // while(UB = min(UB, GlobalUB), idx = LB, idx < UB) {
1937 // while (idx <= UB) { BODY; ++idx; } // inner loop
1938 // LB = LB + ST;
1939 // UB = UB + ST;
1940 // }
1941 //
1942
1943 const Expr *IVExpr = S.getIterationVariable();
1944 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
1945 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
1946
1947 if (DynamicOrOrdered) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001948 const std::pair<llvm::Value *, llvm::Value *> DispatchBounds =
1949 CGDispatchBounds(*this, S, LoopArgs.LB, LoopArgs.UB);
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001950 llvm::Value *LBVal = DispatchBounds.first;
1951 llvm::Value *UBVal = DispatchBounds.second;
1952 CGOpenMPRuntime::DispatchRTInput DipatchRTInputValues = {LBVal, UBVal,
1953 LoopArgs.Chunk};
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001954 RT.emitForDispatchInit(*this, S.getBeginLoc(), ScheduleKind, IVSize,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001955 IVSigned, Ordered, DipatchRTInputValues);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001956 } else {
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00001957 CGOpenMPRuntime::StaticRTInput StaticInit(
1958 IVSize, IVSigned, Ordered, LoopArgs.IL, LoopArgs.LB, LoopArgs.UB,
1959 LoopArgs.ST, LoopArgs.Chunk);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001960 RT.emitForStaticInit(*this, S.getBeginLoc(), S.getDirectiveKind(),
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00001961 ScheduleKind, StaticInit);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001962 }
1963
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001964 auto &&CodeGenOrdered = [Ordered](CodeGenFunction &CGF, SourceLocation Loc,
1965 const unsigned IVSize,
1966 const bool IVSigned) {
1967 if (Ordered) {
1968 CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd(CGF, Loc, IVSize,
1969 IVSigned);
1970 }
1971 };
1972
1973 OMPLoopArguments OuterLoopArgs(LoopArgs.LB, LoopArgs.UB, LoopArgs.ST,
1974 LoopArgs.IL, LoopArgs.Chunk, LoopArgs.EUB);
1975 OuterLoopArgs.IncExpr = S.getInc();
1976 OuterLoopArgs.Init = S.getInit();
1977 OuterLoopArgs.Cond = S.getCond();
1978 OuterLoopArgs.NextLB = S.getNextLowerBound();
1979 OuterLoopArgs.NextUB = S.getNextUpperBound();
1980 EmitOMPOuterLoop(DynamicOrOrdered, IsMonotonic, S, LoopScope, OuterLoopArgs,
1981 emitOMPLoopBodyWithStopPoint, CodeGenOrdered);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001982}
1983
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001984static void emitEmptyOrdered(CodeGenFunction &, SourceLocation Loc,
1985 const unsigned IVSize, const bool IVSigned) {}
1986
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001987void CodeGenFunction::EmitOMPDistributeOuterLoop(
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001988 OpenMPDistScheduleClauseKind ScheduleKind, const OMPLoopDirective &S,
1989 OMPPrivateScope &LoopScope, const OMPLoopArguments &LoopArgs,
1990 const CodeGenLoopTy &CodeGenLoopContent) {
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001991
Alexey Bataevddf3db92018-04-13 17:31:06 +00001992 CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001993
1994 // Emit outer loop.
1995 // Same behavior as a OMPForOuterLoop, except that schedule cannot be
1996 // dynamic
1997 //
1998
1999 const Expr *IVExpr = S.getIterationVariable();
2000 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
2001 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
2002
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00002003 CGOpenMPRuntime::StaticRTInput StaticInit(
2004 IVSize, IVSigned, /* Ordered = */ false, LoopArgs.IL, LoopArgs.LB,
2005 LoopArgs.UB, LoopArgs.ST, LoopArgs.Chunk);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002006 RT.emitDistributeStaticInit(*this, S.getBeginLoc(), ScheduleKind, StaticInit);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00002007
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002008 // for combined 'distribute' and 'for' the increment expression of distribute
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002009 // is stored in DistInc. For 'distribute' alone, it is in Inc.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002010 Expr *IncExpr;
2011 if (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()))
2012 IncExpr = S.getDistInc();
2013 else
2014 IncExpr = S.getInc();
2015
2016 // this routine is shared by 'omp distribute parallel for' and
2017 // 'omp distribute': select the right EUB expression depending on the
2018 // directive
2019 OMPLoopArguments OuterLoopArgs;
2020 OuterLoopArgs.LB = LoopArgs.LB;
2021 OuterLoopArgs.UB = LoopArgs.UB;
2022 OuterLoopArgs.ST = LoopArgs.ST;
2023 OuterLoopArgs.IL = LoopArgs.IL;
2024 OuterLoopArgs.Chunk = LoopArgs.Chunk;
2025 OuterLoopArgs.EUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
2026 ? S.getCombinedEnsureUpperBound()
2027 : S.getEnsureUpperBound();
2028 OuterLoopArgs.IncExpr = IncExpr;
2029 OuterLoopArgs.Init = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
2030 ? S.getCombinedInit()
2031 : S.getInit();
2032 OuterLoopArgs.Cond = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
2033 ? S.getCombinedCond()
2034 : S.getCond();
2035 OuterLoopArgs.NextLB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
2036 ? S.getCombinedNextLowerBound()
2037 : S.getNextLowerBound();
2038 OuterLoopArgs.NextUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
2039 ? S.getCombinedNextUpperBound()
2040 : S.getNextUpperBound();
2041
2042 EmitOMPOuterLoop(/* DynamicOrOrdered = */ false, /* IsMonotonic = */ false, S,
2043 LoopScope, OuterLoopArgs, CodeGenLoopContent,
2044 emitEmptyOrdered);
2045}
2046
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002047static std::pair<LValue, LValue>
2048emitDistributeParallelForInnerBounds(CodeGenFunction &CGF,
2049 const OMPExecutableDirective &S) {
2050 const OMPLoopDirective &LS = cast<OMPLoopDirective>(S);
2051 LValue LB =
2052 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getLowerBoundVariable()));
2053 LValue UB =
2054 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getUpperBoundVariable()));
2055
2056 // When composing 'distribute' with 'for' (e.g. as in 'distribute
2057 // parallel for') we need to use the 'distribute'
2058 // chunk lower and upper bounds rather than the whole loop iteration
2059 // space. These are parameters to the outlined function for 'parallel'
2060 // and we copy the bounds of the previous schedule into the
2061 // the current ones.
2062 LValue PrevLB = CGF.EmitLValue(LS.getPrevLowerBoundVariable());
2063 LValue PrevUB = CGF.EmitLValue(LS.getPrevUpperBoundVariable());
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00002064 llvm::Value *PrevLBVal = CGF.EmitLoadOfScalar(
2065 PrevLB, LS.getPrevLowerBoundVariable()->getExprLoc());
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002066 PrevLBVal = CGF.EmitScalarConversion(
2067 PrevLBVal, LS.getPrevLowerBoundVariable()->getType(),
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00002068 LS.getIterationVariable()->getType(),
2069 LS.getPrevLowerBoundVariable()->getExprLoc());
2070 llvm::Value *PrevUBVal = CGF.EmitLoadOfScalar(
2071 PrevUB, LS.getPrevUpperBoundVariable()->getExprLoc());
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002072 PrevUBVal = CGF.EmitScalarConversion(
2073 PrevUBVal, LS.getPrevUpperBoundVariable()->getType(),
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00002074 LS.getIterationVariable()->getType(),
2075 LS.getPrevUpperBoundVariable()->getExprLoc());
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002076
2077 CGF.EmitStoreOfScalar(PrevLBVal, LB);
2078 CGF.EmitStoreOfScalar(PrevUBVal, UB);
2079
2080 return {LB, UB};
2081}
2082
2083/// if the 'for' loop has a dispatch schedule (e.g. dynamic, guided) then
2084/// we need to use the LB and UB expressions generated by the worksharing
2085/// code generation support, whereas in non combined situations we would
2086/// just emit 0 and the LastIteration expression
2087/// This function is necessary due to the difference of the LB and UB
2088/// types for the RT emission routines for 'for_static_init' and
2089/// 'for_dispatch_init'
2090static std::pair<llvm::Value *, llvm::Value *>
2091emitDistributeParallelForDispatchBounds(CodeGenFunction &CGF,
2092 const OMPExecutableDirective &S,
2093 Address LB, Address UB) {
2094 const OMPLoopDirective &LS = cast<OMPLoopDirective>(S);
2095 const Expr *IVExpr = LS.getIterationVariable();
2096 // when implementing a dynamic schedule for a 'for' combined with a
2097 // 'distribute' (e.g. 'distribute parallel for'), the 'for' loop
2098 // is not normalized as each team only executes its own assigned
2099 // distribute chunk
2100 QualType IteratorTy = IVExpr->getType();
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00002101 llvm::Value *LBVal =
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002102 CGF.EmitLoadOfScalar(LB, /*Volatile=*/false, IteratorTy, S.getBeginLoc());
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00002103 llvm::Value *UBVal =
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002104 CGF.EmitLoadOfScalar(UB, /*Volatile=*/false, IteratorTy, S.getBeginLoc());
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002105 return {LBVal, UBVal};
Hans Wennborged129ae2017-04-27 17:02:25 +00002106}
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002107
2108static void emitDistributeParallelForDistributeInnerBoundParams(
2109 CodeGenFunction &CGF, const OMPExecutableDirective &S,
2110 llvm::SmallVectorImpl<llvm::Value *> &CapturedVars) {
2111 const auto &Dir = cast<OMPLoopDirective>(S);
2112 LValue LB =
2113 CGF.EmitLValue(cast<DeclRefExpr>(Dir.getCombinedLowerBoundVariable()));
Alexey Bataevddf3db92018-04-13 17:31:06 +00002114 llvm::Value *LBCast = CGF.Builder.CreateIntCast(
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002115 CGF.Builder.CreateLoad(LB.getAddress()), CGF.SizeTy, /*isSigned=*/false);
2116 CapturedVars.push_back(LBCast);
2117 LValue UB =
2118 CGF.EmitLValue(cast<DeclRefExpr>(Dir.getCombinedUpperBoundVariable()));
2119
Alexey Bataevddf3db92018-04-13 17:31:06 +00002120 llvm::Value *UBCast = CGF.Builder.CreateIntCast(
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002121 CGF.Builder.CreateLoad(UB.getAddress()), CGF.SizeTy, /*isSigned=*/false);
2122 CapturedVars.push_back(UBCast);
Hans Wennborged129ae2017-04-27 17:02:25 +00002123}
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002124
2125static void
2126emitInnerParallelForWhenCombined(CodeGenFunction &CGF,
2127 const OMPLoopDirective &S,
2128 CodeGenFunction::JumpDest LoopExit) {
2129 auto &&CGInlinedWorksharingLoop = [&S](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00002130 PrePostActionTy &Action) {
2131 Action.Enter(CGF);
Alexey Bataevdcb4b8fb2017-11-22 20:19:50 +00002132 bool HasCancel = false;
2133 if (!isOpenMPSimdDirective(S.getDirectiveKind())) {
2134 if (const auto *D = dyn_cast<OMPTeamsDistributeParallelForDirective>(&S))
2135 HasCancel = D->hasCancel();
2136 else if (const auto *D = dyn_cast<OMPDistributeParallelForDirective>(&S))
2137 HasCancel = D->hasCancel();
Alexey Bataev16e79882017-11-22 21:12:03 +00002138 else if (const auto *D =
2139 dyn_cast<OMPTargetTeamsDistributeParallelForDirective>(&S))
2140 HasCancel = D->hasCancel();
Alexey Bataevdcb4b8fb2017-11-22 20:19:50 +00002141 }
2142 CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, S.getDirectiveKind(),
2143 HasCancel);
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002144 CGF.EmitOMPWorksharingLoop(S, S.getPrevEnsureUpperBound(),
2145 emitDistributeParallelForInnerBounds,
2146 emitDistributeParallelForDispatchBounds);
2147 };
2148
2149 emitCommonOMPParallelDirective(
Alexey Bataevdcb4b8fb2017-11-22 20:19:50 +00002150 CGF, S,
2151 isOpenMPSimdDirective(S.getDirectiveKind()) ? OMPD_for_simd : OMPD_for,
2152 CGInlinedWorksharingLoop,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002153 emitDistributeParallelForDistributeInnerBoundParams);
Alexander Musmandf7a8e22015-01-22 08:49:35 +00002154}
2155
Carlo Bertolli9925f152016-06-27 14:55:37 +00002156void CodeGenFunction::EmitOMPDistributeParallelForDirective(
2157 const OMPDistributeParallelForDirective &S) {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002158 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2159 CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
2160 S.getDistInc());
2161 };
Alexey Bataev475a7442018-01-12 19:39:11 +00002162 OMPLexicalScope Scope(*this, S, OMPD_parallel);
Alexey Bataev10a54312017-11-27 16:54:08 +00002163 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen);
Carlo Bertolli9925f152016-06-27 14:55:37 +00002164}
2165
Kelvin Li4a39add2016-07-05 05:00:15 +00002166void CodeGenFunction::EmitOMPDistributeParallelForSimdDirective(
2167 const OMPDistributeParallelForSimdDirective &S) {
Alexey Bataev0b49f9e2017-11-27 19:38:58 +00002168 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2169 CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
2170 S.getDistInc());
2171 };
Alexey Bataev475a7442018-01-12 19:39:11 +00002172 OMPLexicalScope Scope(*this, S, OMPD_parallel);
Alexey Bataev0b49f9e2017-11-27 19:38:58 +00002173 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen);
Kelvin Li4a39add2016-07-05 05:00:15 +00002174}
Kelvin Li787f3fc2016-07-06 04:45:38 +00002175
2176void CodeGenFunction::EmitOMPDistributeSimdDirective(
2177 const OMPDistributeSimdDirective &S) {
Alexey Bataev617db5f2017-12-04 15:38:33 +00002178 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2179 CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
2180 };
Alexey Bataev475a7442018-01-12 19:39:11 +00002181 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev617db5f2017-12-04 15:38:33 +00002182 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
Kelvin Li787f3fc2016-07-06 04:45:38 +00002183}
2184
Alexey Bataevf8365372017-11-17 17:57:25 +00002185void CodeGenFunction::EmitOMPTargetSimdDeviceFunction(
2186 CodeGenModule &CGM, StringRef ParentName, const OMPTargetSimdDirective &S) {
2187 // Emit SPMD target parallel for region as a standalone region.
2188 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2189 emitOMPSimdRegion(CGF, S, Action);
2190 };
2191 llvm::Function *Fn;
2192 llvm::Constant *Addr;
2193 // Emit target region as a standalone region.
2194 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
2195 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
2196 assert(Fn && Addr && "Target device function emission failed.");
2197}
2198
Kelvin Li986330c2016-07-20 22:57:10 +00002199void CodeGenFunction::EmitOMPTargetSimdDirective(
2200 const OMPTargetSimdDirective &S) {
Alexey Bataevf8365372017-11-17 17:57:25 +00002201 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2202 emitOMPSimdRegion(CGF, S, Action);
2203 };
2204 emitCommonOMPTargetDirective(*this, S, CodeGen);
Kelvin Li986330c2016-07-20 22:57:10 +00002205}
2206
Alexey Bataeva6f2a142015-12-31 06:52:34 +00002207namespace {
2208 struct ScheduleKindModifiersTy {
2209 OpenMPScheduleClauseKind Kind;
2210 OpenMPScheduleClauseModifier M1;
2211 OpenMPScheduleClauseModifier M2;
2212 ScheduleKindModifiersTy(OpenMPScheduleClauseKind Kind,
2213 OpenMPScheduleClauseModifier M1,
2214 OpenMPScheduleClauseModifier M2)
2215 : Kind(Kind), M1(M1), M2(M2) {}
2216 };
2217} // namespace
2218
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002219bool CodeGenFunction::EmitOMPWorksharingLoop(
2220 const OMPLoopDirective &S, Expr *EUB,
2221 const CodeGenLoopBoundsTy &CodeGenLoopBounds,
2222 const CodeGenDispatchBoundsTy &CGDispatchBounds) {
Alexander Musmanc6388682014-12-15 07:07:06 +00002223 // Emit the loop iteration variable.
Alexey Bataevddf3db92018-04-13 17:31:06 +00002224 const auto *IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
2225 const auto *IVDecl = cast<VarDecl>(IVExpr->getDecl());
Alexander Musmanc6388682014-12-15 07:07:06 +00002226 EmitVarDecl(*IVDecl);
2227
2228 // Emit the iterations count variable.
2229 // If it is not a variable, Sema decided to calculate iterations count on each
2230 // iteration (e.g., it is foldable into a constant).
Alexey Bataevddf3db92018-04-13 17:31:06 +00002231 if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
Alexander Musmanc6388682014-12-15 07:07:06 +00002232 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
2233 // Emit calculation of the iterations count.
2234 EmitIgnoredExpr(S.getCalcLastIteration());
2235 }
2236
Alexey Bataevddf3db92018-04-13 17:31:06 +00002237 CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
Alexander Musmanc6388682014-12-15 07:07:06 +00002238
Alexey Bataev38e89532015-04-16 04:54:05 +00002239 bool HasLastprivateClause;
Alexander Musmanc6388682014-12-15 07:07:06 +00002240 // Check pre-condition.
2241 {
Alexey Bataev5a3af132016-03-29 08:58:54 +00002242 OMPLoopScope PreInitScope(*this, S);
Alexander Musmanc6388682014-12-15 07:07:06 +00002243 // Skip the entire loop if we don't meet the precondition.
Alexey Bataev62dbb972015-04-22 11:59:37 +00002244 // If the condition constant folds and can be elided, avoid emitting the
2245 // whole loop.
2246 bool CondConstant;
2247 llvm::BasicBlock *ContBlock = nullptr;
2248 if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
2249 if (!CondConstant)
2250 return false;
2251 } else {
Alexey Bataevddf3db92018-04-13 17:31:06 +00002252 llvm::BasicBlock *ThenBlock = createBasicBlock("omp.precond.then");
Alexey Bataev62dbb972015-04-22 11:59:37 +00002253 ContBlock = createBasicBlock("omp.precond.end");
2254 emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock,
Justin Bogner66242d62015-04-23 23:06:47 +00002255 getProfileCount(&S));
Alexey Bataev62dbb972015-04-22 11:59:37 +00002256 EmitBlock(ThenBlock);
Justin Bogner66242d62015-04-23 23:06:47 +00002257 incrementProfileCounter(&S);
Alexey Bataev62dbb972015-04-22 11:59:37 +00002258 }
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00002259
Alexey Bataevea33dee2018-02-15 23:39:43 +00002260 RunCleanupsScope DoacrossCleanupScope(*this);
Alexey Bataev8b427062016-05-25 12:36:08 +00002261 bool Ordered = false;
Alexey Bataevddf3db92018-04-13 17:31:06 +00002262 if (const auto *OrderedClause = S.getSingleClause<OMPOrderedClause>()) {
Alexey Bataev8b427062016-05-25 12:36:08 +00002263 if (OrderedClause->getNumForLoops())
Alexey Bataevf138fda2018-08-13 19:04:24 +00002264 RT.emitDoacrossInit(*this, S, OrderedClause->getLoopNumIterations());
Alexey Bataev8b427062016-05-25 12:36:08 +00002265 else
2266 Ordered = true;
2267 }
2268
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002269 llvm::DenseSet<const Expr *> EmittedFinals;
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00002270 emitAlignedClause(*this, S);
Alexey Bataev8c3edfe2017-08-16 15:58:46 +00002271 bool HasLinears = EmitOMPLinearClauseInit(S);
Alexey Bataevef549a82016-03-09 09:49:09 +00002272 // Emit helper vars inits.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002273
2274 std::pair<LValue, LValue> Bounds = CodeGenLoopBounds(*this, S);
2275 LValue LB = Bounds.first;
2276 LValue UB = Bounds.second;
Alexey Bataevef549a82016-03-09 09:49:09 +00002277 LValue ST =
2278 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable()));
2279 LValue IL =
2280 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
2281
Alexander Musmanc6388682014-12-15 07:07:06 +00002282 // Emit 'then' code.
2283 {
Alexander Musmanc6388682014-12-15 07:07:06 +00002284 OMPPrivateScope LoopScope(*this);
Alexey Bataev8c3edfe2017-08-16 15:58:46 +00002285 if (EmitOMPFirstprivateClause(S, LoopScope) || HasLinears) {
Alexey Bataev69c62a92015-04-15 04:52:20 +00002286 // Emit implicit barrier to synchronize threads and avoid data races on
Alexey Bataevcd8b6a22016-02-15 08:07:17 +00002287 // initialization of firstprivate variables and post-update of
2288 // lastprivate variables.
Alexey Bataev25e5b442015-09-15 12:52:43 +00002289 CGM.getOpenMPRuntime().emitBarrierCall(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002290 *this, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
Alexey Bataev25e5b442015-09-15 12:52:43 +00002291 /*ForceSimpleCall=*/true);
Alexey Bataev69c62a92015-04-15 04:52:20 +00002292 }
Alexey Bataev50a64582015-04-22 12:24:45 +00002293 EmitOMPPrivateClause(S, LoopScope);
Alexey Bataev38e89532015-04-16 04:54:05 +00002294 HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +00002295 EmitOMPReductionClauseInit(S, LoopScope);
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002296 EmitOMPPrivateLoopCounters(S, LoopScope);
2297 EmitOMPLinearClause(S, LoopScope);
Alexander Musman7931b982015-03-16 07:14:41 +00002298 (void)LoopScope.Privatize();
Alexey Bataev60705422018-10-30 15:50:12 +00002299 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
2300 CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(*this, S);
Alexander Musmanc6388682014-12-15 07:07:06 +00002301
2302 // Detect the loop schedule kind and chunk.
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002303 const Expr *ChunkExpr = nullptr;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00002304 OpenMPScheduleTy ScheduleKind;
Alexey Bataevddf3db92018-04-13 17:31:06 +00002305 if (const auto *C = S.getSingleClause<OMPScheduleClause>()) {
Alexey Bataev9ebd7422016-05-10 09:57:36 +00002306 ScheduleKind.Schedule = C->getScheduleKind();
2307 ScheduleKind.M1 = C->getFirstScheduleModifier();
2308 ScheduleKind.M2 = C->getSecondScheduleModifier();
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002309 ChunkExpr = C->getChunkSize();
Gheorghe-Teodor Bercea8233af92018-09-27 20:29:00 +00002310 } else {
2311 // Default behaviour for schedule clause.
2312 CGM.getOpenMPRuntime().getDefaultScheduleAndChunk(
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002313 *this, S, ScheduleKind.Schedule, ChunkExpr);
2314 }
2315 bool HasChunkSizeOne = false;
2316 llvm::Value *Chunk = nullptr;
2317 if (ChunkExpr) {
2318 Chunk = EmitScalarExpr(ChunkExpr);
2319 Chunk = EmitScalarConversion(Chunk, ChunkExpr->getType(),
2320 S.getIterationVariable()->getType(),
2321 S.getBeginLoc());
Fangrui Song407659a2018-11-30 23:41:18 +00002322 Expr::EvalResult Result;
2323 if (ChunkExpr->EvaluateAsInt(Result, getContext())) {
2324 llvm::APSInt EvaluatedChunk = Result.Val.getInt();
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002325 HasChunkSizeOne = (EvaluatedChunk.getLimitedValue() == 1);
Fangrui Song407659a2018-11-30 23:41:18 +00002326 }
Alexey Bataev3392d762016-02-16 11:18:12 +00002327 }
Alexander Musmanc6388682014-12-15 07:07:06 +00002328 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
2329 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
Alexey Bataeva6f2a142015-12-31 06:52:34 +00002330 // OpenMP 4.5, 2.7.1 Loop Construct, Description.
2331 // If the static schedule kind is specified or if the ordered clause is
2332 // specified, and if no monotonic modifier is specified, the effect will
2333 // be as if the monotonic modifier was specified.
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002334 bool StaticChunkedOne = RT.isStaticChunked(ScheduleKind.Schedule,
2335 /* Chunked */ Chunk != nullptr) && HasChunkSizeOne &&
2336 isOpenMPLoopBoundSharingDirective(S.getDirectiveKind());
2337 if ((RT.isStaticNonchunked(ScheduleKind.Schedule,
2338 /* Chunked */ Chunk != nullptr) ||
2339 StaticChunkedOne) &&
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00002340 !Ordered) {
Alexey Bataeva6f2a142015-12-31 06:52:34 +00002341 if (isOpenMPSimdDirective(S.getDirectiveKind()))
2342 EmitOMPSimdInit(S, /*IsMonotonic=*/true);
Alexander Musmanc6388682014-12-15 07:07:06 +00002343 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
2344 // When no chunk_size is specified, the iteration space is divided into
2345 // chunks that are approximately equal in size, and at most one chunk is
2346 // distributed to each thread. Note that the size of the chunks is
2347 // unspecified in this case.
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00002348 CGOpenMPRuntime::StaticRTInput StaticInit(
2349 IVSize, IVSigned, Ordered, IL.getAddress(), LB.getAddress(),
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002350 UB.getAddress(), ST.getAddress(),
2351 StaticChunkedOne ? Chunk : nullptr);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002352 RT.emitForStaticInit(*this, S.getBeginLoc(), S.getDirectiveKind(),
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00002353 ScheduleKind, StaticInit);
Alexey Bataevddf3db92018-04-13 17:31:06 +00002354 JumpDest LoopExit =
Alexey Bataeva6f2a142015-12-31 06:52:34 +00002355 getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit"));
Alexander Musmanc6388682014-12-15 07:07:06 +00002356 // UB = min(UB, GlobalUB);
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002357 if (!StaticChunkedOne)
2358 EmitIgnoredExpr(S.getEnsureUpperBound());
Alexander Musmanc6388682014-12-15 07:07:06 +00002359 // IV = LB;
2360 EmitIgnoredExpr(S.getInit());
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002361 // For unchunked static schedule generate:
2362 //
2363 // while (idx <= UB) {
2364 // BODY;
2365 // ++idx;
2366 // }
2367 //
2368 // For static schedule with chunk one:
2369 //
2370 // while (IV <= PrevUB) {
2371 // BODY;
2372 // IV += ST;
2373 // }
2374 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(),
2375 StaticChunkedOne ? S.getCombinedParForInDistCond() : S.getCond(),
2376 StaticChunkedOne ? S.getDistInc() : S.getInc(),
2377 [&S, LoopExit](CodeGenFunction &CGF) {
2378 CGF.EmitOMPLoopBody(S, LoopExit);
2379 CGF.EmitStopPoint(&S);
2380 },
2381 [](CodeGenFunction &) {});
Alexey Bataev0f34da12015-07-02 04:17:07 +00002382 EmitBlock(LoopExit.getBlock());
Alexander Musmanc6388682014-12-15 07:07:06 +00002383 // Tell the runtime we are done.
Alexey Bataev957d8562016-11-17 15:12:05 +00002384 auto &&CodeGen = [&S](CodeGenFunction &CGF) {
Stephen Kelly1c301dc2018-08-09 21:09:38 +00002385 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),
Alexey Bataevf43f7142017-09-06 16:17:35 +00002386 S.getDirectiveKind());
Alexey Bataev957d8562016-11-17 15:12:05 +00002387 };
2388 OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen);
Alexander Musmandf7a8e22015-01-22 08:49:35 +00002389 } else {
Alexey Bataev9ebd7422016-05-10 09:57:36 +00002390 const bool IsMonotonic =
2391 Ordered || ScheduleKind.Schedule == OMPC_SCHEDULE_static ||
2392 ScheduleKind.Schedule == OMPC_SCHEDULE_unknown ||
2393 ScheduleKind.M1 == OMPC_SCHEDULE_MODIFIER_monotonic ||
2394 ScheduleKind.M2 == OMPC_SCHEDULE_MODIFIER_monotonic;
Alexander Musmandf7a8e22015-01-22 08:49:35 +00002395 // Emit the outer loop, which requests its work chunk [LB..UB] from
2396 // runtime and runs the inner loop to process it.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002397 const OMPLoopArguments LoopArguments(LB.getAddress(), UB.getAddress(),
2398 ST.getAddress(), IL.getAddress(),
2399 Chunk, EUB);
Alexey Bataeva6f2a142015-12-31 06:52:34 +00002400 EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002401 LoopArguments, CGDispatchBounds);
Alexander Musmandf7a8e22015-01-22 08:49:35 +00002402 }
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002403 if (isOpenMPSimdDirective(S.getDirectiveKind())) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002404 EmitOMPSimdFinal(S, [IL, &S](CodeGenFunction &CGF) {
2405 return CGF.Builder.CreateIsNotNull(
2406 CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
2407 });
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002408 }
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00002409 EmitOMPReductionClauseFinal(
2410 S, /*ReductionKind=*/isOpenMPSimdDirective(S.getDirectiveKind())
2411 ? /*Parallel and Simd*/ OMPD_parallel_for_simd
2412 : /*Parallel only*/ OMPD_parallel);
Alexey Bataev61205072016-03-02 04:57:40 +00002413 // Emit post-update of the reduction variables if IsLastIter != 0.
2414 emitPostUpdateForReductionClause(
Alexey Bataevddf3db92018-04-13 17:31:06 +00002415 *this, S, [IL, &S](CodeGenFunction &CGF) {
Alexey Bataev61205072016-03-02 04:57:40 +00002416 return CGF.Builder.CreateIsNotNull(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002417 CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
Alexey Bataev61205072016-03-02 04:57:40 +00002418 });
Alexey Bataev38e89532015-04-16 04:54:05 +00002419 // Emit final copy of the lastprivate variables if IsLastIter != 0.
2420 if (HasLastprivateClause)
2421 EmitOMPLastprivateClauseFinal(
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002422 S, isOpenMPSimdDirective(S.getDirectiveKind()),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002423 Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getBeginLoc())));
Alexander Musmanc6388682014-12-15 07:07:06 +00002424 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00002425 EmitOMPLinearClauseFinal(S, [IL, &S](CodeGenFunction &CGF) {
Alexey Bataevef549a82016-03-09 09:49:09 +00002426 return CGF.Builder.CreateIsNotNull(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002427 CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
Alexey Bataevef549a82016-03-09 09:49:09 +00002428 });
Alexey Bataevea33dee2018-02-15 23:39:43 +00002429 DoacrossCleanupScope.ForceCleanup();
Alexander Musmanc6388682014-12-15 07:07:06 +00002430 // We're now done with the loop, so jump to the continuation block.
Alexey Bataev62dbb972015-04-22 11:59:37 +00002431 if (ContBlock) {
2432 EmitBranch(ContBlock);
Alexey Bataevddf3db92018-04-13 17:31:06 +00002433 EmitBlock(ContBlock, /*IsFinished=*/true);
Alexey Bataev62dbb972015-04-22 11:59:37 +00002434 }
Alexander Musmanc6388682014-12-15 07:07:06 +00002435 }
Alexey Bataev38e89532015-04-16 04:54:05 +00002436 return HasLastprivateClause;
Alexander Musmanc6388682014-12-15 07:07:06 +00002437}
2438
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002439/// The following two functions generate expressions for the loop lower
2440/// and upper bounds in case of static and dynamic (dispatch) schedule
2441/// of the associated 'for' or 'distribute' loop.
2442static std::pair<LValue, LValue>
2443emitForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00002444 const auto &LS = cast<OMPLoopDirective>(S);
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002445 LValue LB =
2446 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getLowerBoundVariable()));
2447 LValue UB =
2448 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getUpperBoundVariable()));
2449 return {LB, UB};
2450}
2451
2452/// When dealing with dispatch schedules (e.g. dynamic, guided) we do not
2453/// consider the lower and upper bound expressions generated by the
2454/// worksharing loop support, but we use 0 and the iteration space size as
2455/// constants
2456static std::pair<llvm::Value *, llvm::Value *>
2457emitDispatchForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S,
2458 Address LB, Address UB) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00002459 const auto &LS = cast<OMPLoopDirective>(S);
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002460 const Expr *IVExpr = LS.getIterationVariable();
2461 const unsigned IVSize = CGF.getContext().getTypeSize(IVExpr->getType());
2462 llvm::Value *LBVal = CGF.Builder.getIntN(IVSize, 0);
2463 llvm::Value *UBVal = CGF.EmitScalarExpr(LS.getLastIteration());
2464 return {LBVal, UBVal};
2465}
2466
Alexander Musmanc6388682014-12-15 07:07:06 +00002467void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {
Alexey Bataev38e89532015-04-16 04:54:05 +00002468 bool HasLastprivates = false;
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002469 auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF,
2470 PrePostActionTy &) {
Alexey Bataev957d8562016-11-17 15:12:05 +00002471 OMPCancelStackRAII CancelRegion(CGF, OMPD_for, S.hasCancel());
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002472 HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(),
2473 emitForLoopBounds,
2474 emitDispatchForLoopBounds);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002475 };
Alexey Bataev3392d762016-02-16 11:18:12 +00002476 {
Alexey Bataev475a7442018-01-12 19:39:11 +00002477 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev3392d762016-02-16 11:18:12 +00002478 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen,
2479 S.hasCancel());
2480 }
Alexander Musmanc6388682014-12-15 07:07:06 +00002481
2482 // Emit an implicit barrier at the end.
Alexey Bataevddf3db92018-04-13 17:31:06 +00002483 if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates)
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002484 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_for);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002485}
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002486
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00002487void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) {
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00002488 bool HasLastprivates = false;
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002489 auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF,
2490 PrePostActionTy &) {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002491 HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(),
2492 emitForLoopBounds,
2493 emitDispatchForLoopBounds);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002494 };
Alexey Bataev3392d762016-02-16 11:18:12 +00002495 {
Alexey Bataev475a7442018-01-12 19:39:11 +00002496 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev3392d762016-02-16 11:18:12 +00002497 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
2498 }
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00002499
2500 // Emit an implicit barrier at the end.
Alexey Bataevddf3db92018-04-13 17:31:06 +00002501 if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates)
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002502 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_for);
Alexander Musmanf82886e2014-09-18 05:12:34 +00002503}
2504
Alexey Bataev2df54a02015-03-12 08:53:29 +00002505static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty,
2506 const Twine &Name,
2507 llvm::Value *Init = nullptr) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00002508 LValue LVal = CGF.MakeAddrLValue(CGF.CreateMemTemp(Ty, Name), Ty);
Alexey Bataev2df54a02015-03-12 08:53:29 +00002509 if (Init)
Akira Hatanaka642f7992016-10-18 19:05:41 +00002510 CGF.EmitStoreThroughLValue(RValue::get(Init), LVal, /*isInit*/ true);
Alexey Bataev2df54a02015-03-12 08:53:29 +00002511 return LVal;
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002512}
2513
Alexey Bataev3392d762016-02-16 11:18:12 +00002514void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00002515 const Stmt *CapturedStmt = S.getInnermostCapturedStmt()->getCapturedStmt();
2516 const auto *CS = dyn_cast<CompoundStmt>(CapturedStmt);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002517 bool HasLastprivates = false;
Alexey Bataevddf3db92018-04-13 17:31:06 +00002518 auto &&CodeGen = [&S, CapturedStmt, CS,
2519 &HasLastprivates](CodeGenFunction &CGF, PrePostActionTy &) {
2520 ASTContext &C = CGF.getContext();
2521 QualType KmpInt32Ty =
2522 C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002523 // Emit helper vars inits.
2524 LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.",
2525 CGF.Builder.getInt32(0));
Alexey Bataevddf3db92018-04-13 17:31:06 +00002526 llvm::ConstantInt *GlobalUBVal = CS != nullptr
2527 ? CGF.Builder.getInt32(CS->size() - 1)
2528 : CGF.Builder.getInt32(0);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002529 LValue UB =
2530 createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal);
2531 LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.",
2532 CGF.Builder.getInt32(1));
2533 LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.",
2534 CGF.Builder.getInt32(0));
2535 // Loop counter.
2536 LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv.");
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002537 OpaqueValueExpr IVRefExpr(S.getBeginLoc(), KmpInt32Ty, VK_LValue);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002538 CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002539 OpaqueValueExpr UBRefExpr(S.getBeginLoc(), KmpInt32Ty, VK_LValue);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002540 CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
2541 // Generate condition for loop.
2542 BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue,
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002543 OK_Ordinary, S.getBeginLoc(), FPOptions());
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002544 // Increment for loop counter.
2545 UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary,
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002546 S.getBeginLoc(), true);
Alexey Bataevddf3db92018-04-13 17:31:06 +00002547 auto &&BodyGen = [CapturedStmt, CS, &S, &IV](CodeGenFunction &CGF) {
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002548 // Iterate through all sections and emit a switch construct:
2549 // switch (IV) {
2550 // case 0:
2551 // <SectionStmt[0]>;
2552 // break;
2553 // ...
2554 // case <NumSection> - 1:
2555 // <SectionStmt[<NumSection> - 1]>;
2556 // break;
2557 // }
2558 // .omp.sections.exit:
Alexey Bataevddf3db92018-04-13 17:31:06 +00002559 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".omp.sections.exit");
2560 llvm::SwitchInst *SwitchStmt =
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002561 CGF.Builder.CreateSwitch(CGF.EmitLoadOfScalar(IV, S.getBeginLoc()),
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00002562 ExitBB, CS == nullptr ? 1 : CS->size());
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002563 if (CS) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002564 unsigned CaseNumber = 0;
Alexey Bataevddf3db92018-04-13 17:31:06 +00002565 for (const Stmt *SubStmt : CS->children()) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002566 auto CaseBB = CGF.createBasicBlock(".omp.sections.case");
2567 CGF.EmitBlock(CaseBB);
2568 SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB);
Benjamin Kramer642f1732015-07-02 21:03:14 +00002569 CGF.EmitStmt(SubStmt);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002570 CGF.EmitBranch(ExitBB);
Benjamin Kramer642f1732015-07-02 21:03:14 +00002571 ++CaseNumber;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002572 }
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002573 } else {
Alexey Bataevddf3db92018-04-13 17:31:06 +00002574 llvm::BasicBlock *CaseBB = CGF.createBasicBlock(".omp.sections.case");
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002575 CGF.EmitBlock(CaseBB);
2576 SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB);
Alexey Bataevddf3db92018-04-13 17:31:06 +00002577 CGF.EmitStmt(CapturedStmt);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002578 CGF.EmitBranch(ExitBB);
Alexey Bataev2cb9b952015-04-24 03:37:03 +00002579 }
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002580 CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
Alexey Bataev2df54a02015-03-12 08:53:29 +00002581 };
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002582
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002583 CodeGenFunction::OMPPrivateScope LoopScope(CGF);
2584 if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
Alexey Bataev9efc03b2015-04-27 04:34:03 +00002585 // Emit implicit barrier to synchronize threads and avoid data races on
Alexey Bataevcd8b6a22016-02-15 08:07:17 +00002586 // initialization of firstprivate variables and post-update of lastprivate
2587 // variables.
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002588 CGF.CGM.getOpenMPRuntime().emitBarrierCall(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002589 CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002590 /*ForceSimpleCall=*/true);
Alexey Bataev9efc03b2015-04-27 04:34:03 +00002591 }
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002592 CGF.EmitOMPPrivateClause(S, LoopScope);
2593 HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
2594 CGF.EmitOMPReductionClauseInit(S, LoopScope);
2595 (void)LoopScope.Privatize();
Alexey Bataev60705422018-10-30 15:50:12 +00002596 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
2597 CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
Alexey Bataev2cb9b952015-04-24 03:37:03 +00002598
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002599 // Emit static non-chunked loop.
Alexey Bataev9ebd7422016-05-10 09:57:36 +00002600 OpenMPScheduleTy ScheduleKind;
2601 ScheduleKind.Schedule = OMPC_SCHEDULE_static;
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00002602 CGOpenMPRuntime::StaticRTInput StaticInit(
2603 /*IVSize=*/32, /*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(),
2604 LB.getAddress(), UB.getAddress(), ST.getAddress());
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002605 CGF.CGM.getOpenMPRuntime().emitForStaticInit(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002606 CGF, S.getBeginLoc(), S.getDirectiveKind(), ScheduleKind, StaticInit);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002607 // UB = min(UB, GlobalUB);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002608 llvm::Value *UBVal = CGF.EmitLoadOfScalar(UB, S.getBeginLoc());
Alexey Bataevddf3db92018-04-13 17:31:06 +00002609 llvm::Value *MinUBGlobalUB = CGF.Builder.CreateSelect(
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002610 CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
2611 CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
2612 // IV = LB;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002613 CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getBeginLoc()), IV);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002614 // while (idx <= UB) { BODY; ++idx; }
2615 CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen,
2616 [](CodeGenFunction &) {});
2617 // Tell the runtime we are done.
Alexey Bataev957d8562016-11-17 15:12:05 +00002618 auto &&CodeGen = [&S](CodeGenFunction &CGF) {
Stephen Kelly1c301dc2018-08-09 21:09:38 +00002619 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),
Alexey Bataevf43f7142017-09-06 16:17:35 +00002620 S.getDirectiveKind());
Alexey Bataev957d8562016-11-17 15:12:05 +00002621 };
2622 CGF.OMPCancelStack.emitExit(CGF, S.getDirectiveKind(), CodeGen);
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00002623 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
Alexey Bataev61205072016-03-02 04:57:40 +00002624 // Emit post-update of the reduction variables if IsLastIter != 0.
Alexey Bataevddf3db92018-04-13 17:31:06 +00002625 emitPostUpdateForReductionClause(CGF, S, [IL, &S](CodeGenFunction &CGF) {
2626 return CGF.Builder.CreateIsNotNull(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002627 CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
Alexey Bataevddf3db92018-04-13 17:31:06 +00002628 });
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002629
2630 // Emit final copy of the lastprivate variables if IsLastIter != 0.
2631 if (HasLastprivates)
2632 CGF.EmitOMPLastprivateClauseFinal(
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002633 S, /*NoFinals=*/false,
2634 CGF.Builder.CreateIsNotNull(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002635 CGF.EmitLoadOfScalar(IL, S.getBeginLoc())));
Alexey Bataev68adb7d2015-04-14 03:29:22 +00002636 };
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002637
2638 bool HasCancel = false;
2639 if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
2640 HasCancel = OSD->hasCancel();
2641 else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
2642 HasCancel = OPSD->hasCancel();
Alexey Bataev957d8562016-11-17 15:12:05 +00002643 OMPCancelStackRAII CancelRegion(*this, S.getDirectiveKind(), HasCancel);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002644 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen,
2645 HasCancel);
2646 // Emit barrier for lastprivates only if 'sections' directive has 'nowait'
2647 // clause. Otherwise the barrier will be generated by the codegen for the
2648 // directive.
2649 if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) {
Alexey Bataev2cb9b952015-04-24 03:37:03 +00002650 // Emit implicit barrier to synchronize threads and avoid data races on
2651 // initialization of firstprivate variables.
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002652 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(),
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002653 OMPD_unknown);
Alexey Bataev2cb9b952015-04-24 03:37:03 +00002654 }
Alexey Bataev68adb7d2015-04-14 03:29:22 +00002655}
Alexey Bataev2df54a02015-03-12 08:53:29 +00002656
Alexey Bataev68adb7d2015-04-14 03:29:22 +00002657void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002658 {
Alexey Bataev475a7442018-01-12 19:39:11 +00002659 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev3392d762016-02-16 11:18:12 +00002660 EmitSections(S);
2661 }
Alexey Bataev2df54a02015-03-12 08:53:29 +00002662 // Emit an implicit barrier at the end.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002663 if (!S.getSingleClause<OMPNowaitClause>()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002664 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(),
Alexey Bataev3392d762016-02-16 11:18:12 +00002665 OMPD_sections);
Alexey Bataevf2685682015-03-30 04:30:22 +00002666 }
Alexey Bataev2df54a02015-03-12 08:53:29 +00002667}
2668
2669void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002670 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataev475a7442018-01-12 19:39:11 +00002671 CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002672 };
Alexey Bataev475a7442018-01-12 19:39:11 +00002673 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev25e5b442015-09-15 12:52:43 +00002674 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen,
2675 S.hasCancel());
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002676}
2677
Alexey Bataev6956e2e2015-02-05 06:35:41 +00002678void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {
Alexey Bataeva63048e2015-03-23 06:18:07 +00002679 llvm::SmallVector<const Expr *, 8> CopyprivateVars;
Alexey Bataev420d45b2015-04-14 05:11:24 +00002680 llvm::SmallVector<const Expr *, 8> DestExprs;
Alexey Bataeva63048e2015-03-23 06:18:07 +00002681 llvm::SmallVector<const Expr *, 8> SrcExprs;
Alexey Bataeva63048e2015-03-23 06:18:07 +00002682 llvm::SmallVector<const Expr *, 8> AssignmentOps;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002683 // Check if there are any 'copyprivate' clauses associated with this
Alexey Bataevcd8b6a22016-02-15 08:07:17 +00002684 // 'single' construct.
Alexey Bataeva63048e2015-03-23 06:18:07 +00002685 // Build a list of copyprivate variables along with helper expressions
2686 // (<source>, <destination>, <destination>=<source> expressions)
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002687 for (const auto *C : S.getClausesOfKind<OMPCopyprivateClause>()) {
Alexey Bataeva63048e2015-03-23 06:18:07 +00002688 CopyprivateVars.append(C->varlists().begin(), C->varlists().end());
Alexey Bataev420d45b2015-04-14 05:11:24 +00002689 DestExprs.append(C->destination_exprs().begin(),
2690 C->destination_exprs().end());
Alexey Bataeva63048e2015-03-23 06:18:07 +00002691 SrcExprs.append(C->source_exprs().begin(), C->source_exprs().end());
Alexey Bataeva63048e2015-03-23 06:18:07 +00002692 AssignmentOps.append(C->assignment_ops().begin(),
2693 C->assignment_ops().end());
2694 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002695 // Emit code for 'single' region along with 'copyprivate' clauses
2696 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2697 Action.Enter(CGF);
2698 OMPPrivateScope SingleScope(CGF);
2699 (void)CGF.EmitOMPFirstprivateClause(S, SingleScope);
2700 CGF.EmitOMPPrivateClause(S, SingleScope);
2701 (void)SingleScope.Privatize();
Alexey Bataev475a7442018-01-12 19:39:11 +00002702 CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002703 };
Alexey Bataev3392d762016-02-16 11:18:12 +00002704 {
Alexey Bataev475a7442018-01-12 19:39:11 +00002705 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002706 CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getBeginLoc(),
Alexey Bataev3392d762016-02-16 11:18:12 +00002707 CopyprivateVars, DestExprs,
2708 SrcExprs, AssignmentOps);
2709 }
2710 // Emit an implicit barrier at the end (to avoid data race on firstprivate
2711 // init or if no 'nowait' clause was specified and no 'copyprivate' clause).
Alexey Bataev417089f2016-02-17 13:19:37 +00002712 if (!S.getSingleClause<OMPNowaitClause>() && CopyprivateVars.empty()) {
Alexey Bataev5521d782015-04-24 04:21:15 +00002713 CGM.getOpenMPRuntime().emitBarrierCall(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002714 *this, S.getBeginLoc(),
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002715 S.getSingleClause<OMPNowaitClause>() ? OMPD_unknown : OMPD_single);
Alexey Bataevf2685682015-03-30 04:30:22 +00002716 }
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002717}
2718
Alexey Bataev8d690652014-12-04 07:23:53 +00002719void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002720 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2721 Action.Enter(CGF);
Alexey Bataev475a7442018-01-12 19:39:11 +00002722 CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002723 };
Alexey Bataev475a7442018-01-12 19:39:11 +00002724 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002725 CGM.getOpenMPRuntime().emitMasterRegion(*this, CodeGen, S.getBeginLoc());
Alexander Musman80c22892014-07-17 08:54:58 +00002726}
2727
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00002728void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002729 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2730 Action.Enter(CGF);
Alexey Bataev475a7442018-01-12 19:39:11 +00002731 CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002732 };
Alexey Bataevddf3db92018-04-13 17:31:06 +00002733 const Expr *Hint = nullptr;
2734 if (const auto *HintClause = S.getSingleClause<OMPHintClause>())
Alexey Bataevfc57d162015-12-15 10:55:09 +00002735 Hint = HintClause->getHint();
Alexey Bataev475a7442018-01-12 19:39:11 +00002736 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataevfc57d162015-12-15 10:55:09 +00002737 CGM.getOpenMPRuntime().emitCriticalRegion(*this,
2738 S.getDirectiveName().getAsString(),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002739 CodeGen, S.getBeginLoc(), Hint);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002740}
2741
Alexey Bataev671605e2015-04-13 05:28:11 +00002742void CodeGenFunction::EmitOMPParallelForDirective(
2743 const OMPParallelForDirective &S) {
2744 // Emit directive as a combined directive that consists of two implicit
2745 // directives: 'parallel' with 'for' directive.
Alexey Bataevc99042b2018-03-15 18:10:54 +00002746 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2747 Action.Enter(CGF);
Alexey Bataev957d8562016-11-17 15:12:05 +00002748 OMPCancelStackRAII CancelRegion(CGF, OMPD_parallel_for, S.hasCancel());
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002749 CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds,
2750 emitDispatchForLoopBounds);
Alexey Bataev671605e2015-04-13 05:28:11 +00002751 };
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002752 emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen,
2753 emitEmptyBoundParameters);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002754}
2755
Alexander Musmane4e893b2014-09-23 09:33:00 +00002756void CodeGenFunction::EmitOMPParallelForSimdDirective(
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00002757 const OMPParallelForSimdDirective &S) {
2758 // Emit directive as a combined directive that consists of two implicit
2759 // directives: 'parallel' with 'for' directive.
Alexey Bataevc99042b2018-03-15 18:10:54 +00002760 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2761 Action.Enter(CGF);
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002762 CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds,
2763 emitDispatchForLoopBounds);
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00002764 };
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002765 emitCommonOMPParallelDirective(*this, S, OMPD_simd, CodeGen,
2766 emitEmptyBoundParameters);
Alexander Musmane4e893b2014-09-23 09:33:00 +00002767}
2768
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002769void CodeGenFunction::EmitOMPParallelSectionsDirective(
Alexey Bataev68adb7d2015-04-14 03:29:22 +00002770 const OMPParallelSectionsDirective &S) {
2771 // Emit directive as a combined directive that consists of two implicit
2772 // directives: 'parallel' with 'sections' directive.
Alexey Bataevc99042b2018-03-15 18:10:54 +00002773 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2774 Action.Enter(CGF);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002775 CGF.EmitSections(S);
2776 };
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002777 emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen,
2778 emitEmptyBoundParameters);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002779}
2780
Alexey Bataev475a7442018-01-12 19:39:11 +00002781void CodeGenFunction::EmitOMPTaskBasedDirective(
2782 const OMPExecutableDirective &S, const OpenMPDirectiveKind CapturedRegion,
2783 const RegionCodeGenTy &BodyGen, const TaskGenTy &TaskGen,
2784 OMPTaskDataTy &Data) {
Alexey Bataev62b63b12015-03-10 07:28:44 +00002785 // Emit outlined function for task construct.
Alexey Bataev475a7442018-01-12 19:39:11 +00002786 const CapturedStmt *CS = S.getCapturedStmt(CapturedRegion);
Alexey Bataevddf3db92018-04-13 17:31:06 +00002787 auto I = CS->getCapturedDecl()->param_begin();
2788 auto PartId = std::next(I);
2789 auto TaskT = std::next(I, 4);
Alexey Bataev24b5bae2016-04-28 09:23:51 +00002790 // Check if the task is final
2791 if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) {
2792 // If the condition constant folds and can be elided, try to avoid emitting
2793 // the condition and the dead arm of the if/else.
Alexey Bataevddf3db92018-04-13 17:31:06 +00002794 const Expr *Cond = Clause->getCondition();
Alexey Bataev24b5bae2016-04-28 09:23:51 +00002795 bool CondConstant;
2796 if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
2797 Data.Final.setInt(CondConstant);
2798 else
2799 Data.Final.setPointer(EvaluateExprAsBool(Cond));
2800 } else {
2801 // By default the task is not final.
2802 Data.Final.setInt(/*IntVal=*/false);
2803 }
Alexey Bataev1e1e2862016-05-10 12:21:02 +00002804 // Check if the task has 'priority' clause.
2805 if (const auto *Clause = S.getSingleClause<OMPPriorityClause>()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00002806 const Expr *Prio = Clause->getPriority();
Alexey Bataev5140e742016-07-19 04:21:09 +00002807 Data.Priority.setInt(/*IntVal=*/true);
Alexey Bataevad537bb2016-05-30 09:06:50 +00002808 Data.Priority.setPointer(EmitScalarConversion(
2809 EmitScalarExpr(Prio), Prio->getType(),
2810 getContext().getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1),
2811 Prio->getExprLoc()));
Alexey Bataev1e1e2862016-05-10 12:21:02 +00002812 }
Alexey Bataev62b63b12015-03-10 07:28:44 +00002813 // The first function argument for tasks is a thread id, the second one is a
2814 // part id (0 for tied tasks, >=0 for untied task).
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002815 llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
2816 // Get list of private variables.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002817 for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) {
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002818 auto IRef = C->varlist_begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00002819 for (const Expr *IInit : C->private_copies()) {
2820 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002821 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
Alexey Bataev7292c292016-04-25 12:22:29 +00002822 Data.PrivateVars.push_back(*IRef);
2823 Data.PrivateCopies.push_back(IInit);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002824 }
2825 ++IRef;
2826 }
2827 }
2828 EmittedAsPrivate.clear();
2829 // Get list of firstprivate variables.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002830 for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) {
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002831 auto IRef = C->varlist_begin();
2832 auto IElemInitRef = C->inits().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00002833 for (const Expr *IInit : C->private_copies()) {
2834 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002835 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
Alexey Bataev7292c292016-04-25 12:22:29 +00002836 Data.FirstprivateVars.push_back(*IRef);
2837 Data.FirstprivateCopies.push_back(IInit);
2838 Data.FirstprivateInits.push_back(*IElemInitRef);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002839 }
Richard Trieucc3949d2016-02-18 22:34:54 +00002840 ++IRef;
2841 ++IElemInitRef;
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002842 }
2843 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00002844 // Get list of lastprivate variables (for taskloops).
2845 llvm::DenseMap<const VarDecl *, const DeclRefExpr *> LastprivateDstsOrigs;
2846 for (const auto *C : S.getClausesOfKind<OMPLastprivateClause>()) {
2847 auto IRef = C->varlist_begin();
2848 auto ID = C->destination_exprs().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00002849 for (const Expr *IInit : C->private_copies()) {
2850 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataevf93095a2016-05-05 08:46:22 +00002851 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
2852 Data.LastprivateVars.push_back(*IRef);
2853 Data.LastprivateCopies.push_back(IInit);
2854 }
2855 LastprivateDstsOrigs.insert(
2856 {cast<VarDecl>(cast<DeclRefExpr>(*ID)->getDecl()),
2857 cast<DeclRefExpr>(*IRef)});
2858 ++IRef;
2859 ++ID;
2860 }
2861 }
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002862 SmallVector<const Expr *, 4> LHSs;
2863 SmallVector<const Expr *, 4> RHSs;
2864 for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) {
2865 auto IPriv = C->privates().begin();
2866 auto IRed = C->reduction_ops().begin();
2867 auto ILHS = C->lhs_exprs().begin();
2868 auto IRHS = C->rhs_exprs().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00002869 for (const Expr *Ref : C->varlists()) {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002870 Data.ReductionVars.emplace_back(Ref);
2871 Data.ReductionCopies.emplace_back(*IPriv);
2872 Data.ReductionOps.emplace_back(*IRed);
2873 LHSs.emplace_back(*ILHS);
2874 RHSs.emplace_back(*IRHS);
2875 std::advance(IPriv, 1);
2876 std::advance(IRed, 1);
2877 std::advance(ILHS, 1);
2878 std::advance(IRHS, 1);
2879 }
2880 }
2881 Data.Reductions = CGM.getOpenMPRuntime().emitTaskReductionInit(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002882 *this, S.getBeginLoc(), LHSs, RHSs, Data);
Alexey Bataev1d2353d2015-06-24 11:01:36 +00002883 // Build list of dependences.
Alexey Bataev7292c292016-04-25 12:22:29 +00002884 for (const auto *C : S.getClausesOfKind<OMPDependClause>())
Alexey Bataevddf3db92018-04-13 17:31:06 +00002885 for (const Expr *IRef : C->varlists())
Alexey Bataev43a919f2018-04-13 17:48:43 +00002886 Data.Dependences.emplace_back(C->getDependencyKind(), IRef);
Alexey Bataev475a7442018-01-12 19:39:11 +00002887 auto &&CodeGen = [&Data, &S, CS, &BodyGen, &LastprivateDstsOrigs,
2888 CapturedRegion](CodeGenFunction &CGF,
2889 PrePostActionTy &Action) {
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002890 // Set proper addresses for generated private copies.
Alexey Bataev7292c292016-04-25 12:22:29 +00002891 OMPPrivateScope Scope(CGF);
Alexey Bataevf93095a2016-05-05 08:46:22 +00002892 if (!Data.PrivateVars.empty() || !Data.FirstprivateVars.empty() ||
2893 !Data.LastprivateVars.empty()) {
James Y Knight9871db02019-02-05 16:42:33 +00002894 llvm::FunctionType *CopyFnTy = llvm::FunctionType::get(
2895 CGF.Builder.getVoidTy(), {CGF.Builder.getInt8PtrTy()}, true);
Alexey Bataev3c595a62017-08-14 15:01:03 +00002896 enum { PrivatesParam = 2, CopyFnParam = 3 };
Alexey Bataevddf3db92018-04-13 17:31:06 +00002897 llvm::Value *CopyFn = CGF.Builder.CreateLoad(
2898 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));
2899 llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(
2900 CS->getCapturedDecl()->getParam(PrivatesParam)));
Alexey Bataev48591dd2016-04-20 04:01:36 +00002901 // Map privates.
2902 llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> PrivatePtrs;
2903 llvm::SmallVector<llvm::Value *, 16> CallArgs;
2904 CallArgs.push_back(PrivatesPtr);
Alexey Bataevddf3db92018-04-13 17:31:06 +00002905 for (const Expr *E : Data.PrivateVars) {
2906 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataev48591dd2016-04-20 04:01:36 +00002907 Address PrivatePtr = CGF.CreateMemTemp(
2908 CGF.getContext().getPointerType(E->getType()), ".priv.ptr.addr");
Alexey Bataevddf3db92018-04-13 17:31:06 +00002909 PrivatePtrs.emplace_back(VD, PrivatePtr);
Alexey Bataev48591dd2016-04-20 04:01:36 +00002910 CallArgs.push_back(PrivatePtr.getPointer());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002911 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00002912 for (const Expr *E : Data.FirstprivateVars) {
2913 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataev48591dd2016-04-20 04:01:36 +00002914 Address PrivatePtr =
2915 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
2916 ".firstpriv.ptr.addr");
Alexey Bataevddf3db92018-04-13 17:31:06 +00002917 PrivatePtrs.emplace_back(VD, PrivatePtr);
Alexey Bataev48591dd2016-04-20 04:01:36 +00002918 CallArgs.push_back(PrivatePtr.getPointer());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002919 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00002920 for (const Expr *E : Data.LastprivateVars) {
2921 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataevf93095a2016-05-05 08:46:22 +00002922 Address PrivatePtr =
2923 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
2924 ".lastpriv.ptr.addr");
Alexey Bataevddf3db92018-04-13 17:31:06 +00002925 PrivatePtrs.emplace_back(VD, PrivatePtr);
Alexey Bataevf93095a2016-05-05 08:46:22 +00002926 CallArgs.push_back(PrivatePtr.getPointer());
2927 }
James Y Knight9871db02019-02-05 16:42:33 +00002928 CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
2929 CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);
Alexey Bataevddf3db92018-04-13 17:31:06 +00002930 for (const auto &Pair : LastprivateDstsOrigs) {
2931 const auto *OrigVD = cast<VarDecl>(Pair.second->getDecl());
Bruno Ricci5fc4db72018-12-21 14:10:18 +00002932 DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(OrigVD),
2933 /*RefersToEnclosingVariableOrCapture=*/
2934 CGF.CapturedStmtInfo->lookup(OrigVD) != nullptr,
2935 Pair.second->getType(), VK_LValue,
2936 Pair.second->getExprLoc());
Alexey Bataevf93095a2016-05-05 08:46:22 +00002937 Scope.addPrivate(Pair.first, [&CGF, &DRE]() {
2938 return CGF.EmitLValue(&DRE).getAddress();
2939 });
2940 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00002941 for (const auto &Pair : PrivatePtrs) {
Alexey Bataev48591dd2016-04-20 04:01:36 +00002942 Address Replacement(CGF.Builder.CreateLoad(Pair.second),
2943 CGF.getContext().getDeclAlign(Pair.first));
2944 Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; });
2945 }
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002946 }
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002947 if (Data.Reductions) {
Alexey Bataev475a7442018-01-12 19:39:11 +00002948 OMPLexicalScope LexScope(CGF, S, CapturedRegion);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002949 ReductionCodeGen RedCG(Data.ReductionVars, Data.ReductionCopies,
2950 Data.ReductionOps);
2951 llvm::Value *ReductionsPtr = CGF.Builder.CreateLoad(
2952 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(9)));
2953 for (unsigned Cnt = 0, E = Data.ReductionVars.size(); Cnt < E; ++Cnt) {
2954 RedCG.emitSharedLValue(CGF, Cnt);
2955 RedCG.emitAggregateType(CGF, Cnt);
Alexey Bataev2e0cbe502018-03-08 15:24:08 +00002956 // FIXME: This must removed once the runtime library is fixed.
2957 // Emit required threadprivate variables for
Raphael Isemannb23ccec2018-12-10 12:37:46 +00002958 // initializer/combiner/finalizer.
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002959 CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(),
Alexey Bataev2e0cbe502018-03-08 15:24:08 +00002960 RedCG, Cnt);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002961 Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002962 CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002963 Replacement =
2964 Address(CGF.EmitScalarConversion(
2965 Replacement.getPointer(), CGF.getContext().VoidPtrTy,
2966 CGF.getContext().getPointerType(
2967 Data.ReductionCopies[Cnt]->getType()),
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00002968 Data.ReductionCopies[Cnt]->getExprLoc()),
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002969 Replacement.getAlignment());
2970 Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);
2971 Scope.addPrivate(RedCG.getBaseDecl(Cnt),
2972 [Replacement]() { return Replacement; });
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002973 }
2974 }
Alexey Bataev88202be2017-07-27 13:20:36 +00002975 // Privatize all private variables except for in_reduction items.
Alexey Bataev48591dd2016-04-20 04:01:36 +00002976 (void)Scope.Privatize();
Alexey Bataev88202be2017-07-27 13:20:36 +00002977 SmallVector<const Expr *, 4> InRedVars;
2978 SmallVector<const Expr *, 4> InRedPrivs;
2979 SmallVector<const Expr *, 4> InRedOps;
2980 SmallVector<const Expr *, 4> TaskgroupDescriptors;
2981 for (const auto *C : S.getClausesOfKind<OMPInReductionClause>()) {
2982 auto IPriv = C->privates().begin();
2983 auto IRed = C->reduction_ops().begin();
2984 auto ITD = C->taskgroup_descriptors().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00002985 for (const Expr *Ref : C->varlists()) {
Alexey Bataev88202be2017-07-27 13:20:36 +00002986 InRedVars.emplace_back(Ref);
2987 InRedPrivs.emplace_back(*IPriv);
2988 InRedOps.emplace_back(*IRed);
2989 TaskgroupDescriptors.emplace_back(*ITD);
2990 std::advance(IPriv, 1);
2991 std::advance(IRed, 1);
2992 std::advance(ITD, 1);
2993 }
2994 }
2995 // Privatize in_reduction items here, because taskgroup descriptors must be
2996 // privatized earlier.
2997 OMPPrivateScope InRedScope(CGF);
2998 if (!InRedVars.empty()) {
2999 ReductionCodeGen RedCG(InRedVars, InRedPrivs, InRedOps);
3000 for (unsigned Cnt = 0, E = InRedVars.size(); Cnt < E; ++Cnt) {
3001 RedCG.emitSharedLValue(CGF, Cnt);
3002 RedCG.emitAggregateType(CGF, Cnt);
3003 // The taskgroup descriptor variable is always implicit firstprivate and
Raphael Isemannb23ccec2018-12-10 12:37:46 +00003004 // privatized already during processing of the firstprivates.
Alexey Bataev2e0cbe502018-03-08 15:24:08 +00003005 // FIXME: This must removed once the runtime library is fixed.
3006 // Emit required threadprivate variables for
Raphael Isemannb23ccec2018-12-10 12:37:46 +00003007 // initializer/combiner/finalizer.
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003008 CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(),
Alexey Bataev2e0cbe502018-03-08 15:24:08 +00003009 RedCG, Cnt);
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003010 llvm::Value *ReductionsPtr =
3011 CGF.EmitLoadOfScalar(CGF.EmitLValue(TaskgroupDescriptors[Cnt]),
3012 TaskgroupDescriptors[Cnt]->getExprLoc());
Alexey Bataev88202be2017-07-27 13:20:36 +00003013 Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003014 CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));
Alexey Bataev88202be2017-07-27 13:20:36 +00003015 Replacement = Address(
3016 CGF.EmitScalarConversion(
3017 Replacement.getPointer(), CGF.getContext().VoidPtrTy,
3018 CGF.getContext().getPointerType(InRedPrivs[Cnt]->getType()),
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003019 InRedPrivs[Cnt]->getExprLoc()),
Alexey Bataev88202be2017-07-27 13:20:36 +00003020 Replacement.getAlignment());
3021 Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);
3022 InRedScope.addPrivate(RedCG.getBaseDecl(Cnt),
3023 [Replacement]() { return Replacement; });
Alexey Bataev88202be2017-07-27 13:20:36 +00003024 }
3025 }
3026 (void)InRedScope.Privatize();
Alexey Bataev48591dd2016-04-20 04:01:36 +00003027
3028 Action.Enter(CGF);
Alexey Bataev7292c292016-04-25 12:22:29 +00003029 BodyGen(CGF);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003030 };
James Y Knight9871db02019-02-05 16:42:33 +00003031 llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
Alexey Bataev7292c292016-04-25 12:22:29 +00003032 S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, Data.Tied,
3033 Data.NumberOfParts);
3034 OMPLexicalScope Scope(*this, S);
3035 TaskGen(*this, OutlinedFn, Data);
3036}
3037
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003038static ImplicitParamDecl *
3039createImplicitFirstprivateForType(ASTContext &C, OMPTaskDataTy &Data,
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003040 QualType Ty, CapturedDecl *CD,
3041 SourceLocation Loc) {
3042 auto *OrigVD = ImplicitParamDecl::Create(C, CD, Loc, /*Id=*/nullptr, Ty,
3043 ImplicitParamDecl::Other);
3044 auto *OrigRef = DeclRefExpr::Create(
3045 C, NestedNameSpecifierLoc(), SourceLocation(), OrigVD,
3046 /*RefersToEnclosingVariableOrCapture=*/false, Loc, Ty, VK_LValue);
3047 auto *PrivateVD = ImplicitParamDecl::Create(C, CD, Loc, /*Id=*/nullptr, Ty,
3048 ImplicitParamDecl::Other);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003049 auto *PrivateRef = DeclRefExpr::Create(
3050 C, NestedNameSpecifierLoc(), SourceLocation(), PrivateVD,
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003051 /*RefersToEnclosingVariableOrCapture=*/false, Loc, Ty, VK_LValue);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003052 QualType ElemType = C.getBaseElementType(Ty);
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003053 auto *InitVD = ImplicitParamDecl::Create(C, CD, Loc, /*Id=*/nullptr, ElemType,
3054 ImplicitParamDecl::Other);
3055 auto *InitRef = DeclRefExpr::Create(
3056 C, NestedNameSpecifierLoc(), SourceLocation(), InitVD,
3057 /*RefersToEnclosingVariableOrCapture=*/false, Loc, ElemType, VK_LValue);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003058 PrivateVD->setInitStyle(VarDecl::CInit);
3059 PrivateVD->setInit(ImplicitCastExpr::Create(C, ElemType, CK_LValueToRValue,
3060 InitRef, /*BasePath=*/nullptr,
3061 VK_RValue));
3062 Data.FirstprivateVars.emplace_back(OrigRef);
3063 Data.FirstprivateCopies.emplace_back(PrivateRef);
3064 Data.FirstprivateInits.emplace_back(InitRef);
3065 return OrigVD;
3066}
3067
3068void CodeGenFunction::EmitOMPTargetTaskBasedDirective(
3069 const OMPExecutableDirective &S, const RegionCodeGenTy &BodyGen,
3070 OMPTargetDataInfo &InputInfo) {
3071 // Emit outlined function for task construct.
Alexey Bataevddf3db92018-04-13 17:31:06 +00003072 const CapturedStmt *CS = S.getCapturedStmt(OMPD_task);
3073 Address CapturedStruct = GenerateCapturedStmtArgument(*CS);
3074 QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
3075 auto I = CS->getCapturedDecl()->param_begin();
3076 auto PartId = std::next(I);
3077 auto TaskT = std::next(I, 4);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003078 OMPTaskDataTy Data;
3079 // The task is not final.
3080 Data.Final.setInt(/*IntVal=*/false);
3081 // Get list of firstprivate variables.
3082 for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) {
3083 auto IRef = C->varlist_begin();
3084 auto IElemInitRef = C->inits().begin();
3085 for (auto *IInit : C->private_copies()) {
3086 Data.FirstprivateVars.push_back(*IRef);
3087 Data.FirstprivateCopies.push_back(IInit);
3088 Data.FirstprivateInits.push_back(*IElemInitRef);
3089 ++IRef;
3090 ++IElemInitRef;
3091 }
3092 }
3093 OMPPrivateScope TargetScope(*this);
3094 VarDecl *BPVD = nullptr;
3095 VarDecl *PVD = nullptr;
3096 VarDecl *SVD = nullptr;
3097 if (InputInfo.NumberOfTargetItems > 0) {
3098 auto *CD = CapturedDecl::Create(
3099 getContext(), getContext().getTranslationUnitDecl(), /*NumParams=*/0);
3100 llvm::APInt ArrSize(/*numBits=*/32, InputInfo.NumberOfTargetItems);
3101 QualType BaseAndPointersType = getContext().getConstantArrayType(
3102 getContext().VoidPtrTy, ArrSize, ArrayType::Normal,
3103 /*IndexTypeQuals=*/0);
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003104 BPVD = createImplicitFirstprivateForType(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003105 getContext(), Data, BaseAndPointersType, CD, S.getBeginLoc());
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003106 PVD = createImplicitFirstprivateForType(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003107 getContext(), Data, BaseAndPointersType, CD, S.getBeginLoc());
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003108 QualType SizesType = getContext().getConstantArrayType(
3109 getContext().getSizeType(), ArrSize, ArrayType::Normal,
3110 /*IndexTypeQuals=*/0);
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003111 SVD = createImplicitFirstprivateForType(getContext(), Data, SizesType, CD,
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003112 S.getBeginLoc());
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003113 TargetScope.addPrivate(
3114 BPVD, [&InputInfo]() { return InputInfo.BasePointersArray; });
3115 TargetScope.addPrivate(PVD,
3116 [&InputInfo]() { return InputInfo.PointersArray; });
3117 TargetScope.addPrivate(SVD,
3118 [&InputInfo]() { return InputInfo.SizesArray; });
3119 }
3120 (void)TargetScope.Privatize();
3121 // Build list of dependences.
3122 for (const auto *C : S.getClausesOfKind<OMPDependClause>())
Alexey Bataevddf3db92018-04-13 17:31:06 +00003123 for (const Expr *IRef : C->varlists())
Alexey Bataev43a919f2018-04-13 17:48:43 +00003124 Data.Dependences.emplace_back(C->getDependencyKind(), IRef);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003125 auto &&CodeGen = [&Data, &S, CS, &BodyGen, BPVD, PVD, SVD,
3126 &InputInfo](CodeGenFunction &CGF, PrePostActionTy &Action) {
3127 // Set proper addresses for generated private copies.
3128 OMPPrivateScope Scope(CGF);
3129 if (!Data.FirstprivateVars.empty()) {
James Y Knight9871db02019-02-05 16:42:33 +00003130 llvm::FunctionType *CopyFnTy = llvm::FunctionType::get(
3131 CGF.Builder.getVoidTy(), {CGF.Builder.getInt8PtrTy()}, true);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003132 enum { PrivatesParam = 2, CopyFnParam = 3 };
Alexey Bataevddf3db92018-04-13 17:31:06 +00003133 llvm::Value *CopyFn = CGF.Builder.CreateLoad(
3134 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));
3135 llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(
3136 CS->getCapturedDecl()->getParam(PrivatesParam)));
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003137 // Map privates.
3138 llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> PrivatePtrs;
3139 llvm::SmallVector<llvm::Value *, 16> CallArgs;
3140 CallArgs.push_back(PrivatesPtr);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003141 for (const Expr *E : Data.FirstprivateVars) {
3142 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003143 Address PrivatePtr =
3144 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
3145 ".firstpriv.ptr.addr");
Alexey Bataevddf3db92018-04-13 17:31:06 +00003146 PrivatePtrs.emplace_back(VD, PrivatePtr);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003147 CallArgs.push_back(PrivatePtr.getPointer());
3148 }
James Y Knight9871db02019-02-05 16:42:33 +00003149 CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
3150 CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003151 for (const auto &Pair : PrivatePtrs) {
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003152 Address Replacement(CGF.Builder.CreateLoad(Pair.second),
3153 CGF.getContext().getDeclAlign(Pair.first));
3154 Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; });
3155 }
3156 }
3157 // Privatize all private variables except for in_reduction items.
3158 (void)Scope.Privatize();
Alexey Bataev8451efa2018-01-15 19:06:12 +00003159 if (InputInfo.NumberOfTargetItems > 0) {
3160 InputInfo.BasePointersArray = CGF.Builder.CreateConstArrayGEP(
3161 CGF.GetAddrOfLocalVar(BPVD), /*Index=*/0, CGF.getPointerSize());
3162 InputInfo.PointersArray = CGF.Builder.CreateConstArrayGEP(
3163 CGF.GetAddrOfLocalVar(PVD), /*Index=*/0, CGF.getPointerSize());
3164 InputInfo.SizesArray = CGF.Builder.CreateConstArrayGEP(
3165 CGF.GetAddrOfLocalVar(SVD), /*Index=*/0, CGF.getSizeSize());
3166 }
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003167
3168 Action.Enter(CGF);
Alexey Bataev475a7442018-01-12 19:39:11 +00003169 OMPLexicalScope LexScope(CGF, S, OMPD_task, /*EmitPreInitStmt=*/false);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003170 BodyGen(CGF);
3171 };
James Y Knight9871db02019-02-05 16:42:33 +00003172 llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003173 S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, /*Tied=*/true,
3174 Data.NumberOfParts);
3175 llvm::APInt TrueOrFalse(32, S.hasClausesOfKind<OMPNowaitClause>() ? 1 : 0);
3176 IntegerLiteral IfCond(getContext(), TrueOrFalse,
3177 getContext().getIntTypeForBitwidth(32, /*Signed=*/0),
3178 SourceLocation());
3179
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003180 CGM.getOpenMPRuntime().emitTaskCall(*this, S.getBeginLoc(), S, OutlinedFn,
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003181 SharedsTy, CapturedStruct, &IfCond, Data);
3182}
3183
Alexey Bataev7292c292016-04-25 12:22:29 +00003184void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
3185 // Emit outlined function for task construct.
Alexey Bataev475a7442018-01-12 19:39:11 +00003186 const CapturedStmt *CS = S.getCapturedStmt(OMPD_task);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003187 Address CapturedStruct = GenerateCapturedStmtArgument(*CS);
3188 QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
Alexey Bataev1d677132015-04-22 13:57:31 +00003189 const Expr *IfCond = nullptr;
Alexey Bataev7371aa32015-09-03 08:45:56 +00003190 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
3191 if (C->getNameModifier() == OMPD_unknown ||
3192 C->getNameModifier() == OMPD_task) {
3193 IfCond = C->getCondition();
3194 break;
3195 }
Alexey Bataev1d677132015-04-22 13:57:31 +00003196 }
Alexey Bataev7292c292016-04-25 12:22:29 +00003197
Alexey Bataev24b5bae2016-04-28 09:23:51 +00003198 OMPTaskDataTy Data;
3199 // Check if we should emit tied or untied task.
3200 Data.Tied = !S.getSingleClause<OMPUntiedClause>();
Alexey Bataev7292c292016-04-25 12:22:29 +00003201 auto &&BodyGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) {
3202 CGF.EmitStmt(CS->getCapturedStmt());
3203 };
Alexey Bataev24b5bae2016-04-28 09:23:51 +00003204 auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
James Y Knight9871db02019-02-05 16:42:33 +00003205 IfCond](CodeGenFunction &CGF, llvm::Function *OutlinedFn,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00003206 const OMPTaskDataTy &Data) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003207 CGF.CGM.getOpenMPRuntime().emitTaskCall(CGF, S.getBeginLoc(), S, OutlinedFn,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00003208 SharedsTy, CapturedStruct, IfCond,
3209 Data);
Alexey Bataev7292c292016-04-25 12:22:29 +00003210 };
Alexey Bataev475a7442018-01-12 19:39:11 +00003211 EmitOMPTaskBasedDirective(S, OMPD_task, BodyGen, TaskGen, Data);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00003212}
3213
Alexey Bataev9f797f32015-02-05 05:57:51 +00003214void CodeGenFunction::EmitOMPTaskyieldDirective(
3215 const OMPTaskyieldDirective &S) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003216 CGM.getOpenMPRuntime().emitTaskyieldCall(*this, S.getBeginLoc());
Alexey Bataev68446b72014-07-18 07:47:19 +00003217}
3218
Alexey Bataev8f7c1b02014-12-05 04:09:23 +00003219void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003220 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_barrier);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00003221}
3222
Alexey Bataev8b8e2022015-04-27 05:22:09 +00003223void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003224 CGM.getOpenMPRuntime().emitTaskwaitCall(*this, S.getBeginLoc());
Alexey Bataev2df347a2014-07-18 10:17:07 +00003225}
3226
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003227void CodeGenFunction::EmitOMPTaskgroupDirective(
3228 const OMPTaskgroupDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003229 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
3230 Action.Enter(CGF);
Alexey Bataev3b1b8952017-07-25 15:53:26 +00003231 if (const Expr *E = S.getReductionRef()) {
3232 SmallVector<const Expr *, 4> LHSs;
3233 SmallVector<const Expr *, 4> RHSs;
3234 OMPTaskDataTy Data;
3235 for (const auto *C : S.getClausesOfKind<OMPTaskReductionClause>()) {
3236 auto IPriv = C->privates().begin();
3237 auto IRed = C->reduction_ops().begin();
3238 auto ILHS = C->lhs_exprs().begin();
3239 auto IRHS = C->rhs_exprs().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00003240 for (const Expr *Ref : C->varlists()) {
Alexey Bataev3b1b8952017-07-25 15:53:26 +00003241 Data.ReductionVars.emplace_back(Ref);
3242 Data.ReductionCopies.emplace_back(*IPriv);
3243 Data.ReductionOps.emplace_back(*IRed);
3244 LHSs.emplace_back(*ILHS);
3245 RHSs.emplace_back(*IRHS);
3246 std::advance(IPriv, 1);
3247 std::advance(IRed, 1);
3248 std::advance(ILHS, 1);
3249 std::advance(IRHS, 1);
3250 }
3251 }
3252 llvm::Value *ReductionDesc =
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003253 CGF.CGM.getOpenMPRuntime().emitTaskReductionInit(CGF, S.getBeginLoc(),
Alexey Bataev3b1b8952017-07-25 15:53:26 +00003254 LHSs, RHSs, Data);
3255 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
3256 CGF.EmitVarDecl(*VD);
3257 CGF.EmitStoreOfScalar(ReductionDesc, CGF.GetAddrOfLocalVar(VD),
3258 /*Volatile=*/false, E->getType());
3259 }
Alexey Bataev475a7442018-01-12 19:39:11 +00003260 CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003261 };
Alexey Bataev475a7442018-01-12 19:39:11 +00003262 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003263 CGM.getOpenMPRuntime().emitTaskgroupRegion(*this, CodeGen, S.getBeginLoc());
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003264}
3265
Alexey Bataevcc37cc12014-11-20 04:34:54 +00003266void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00003267 CGM.getOpenMPRuntime().emitFlush(
3268 *this,
3269 [&S]() -> ArrayRef<const Expr *> {
3270 if (const auto *FlushClause = S.getSingleClause<OMPFlushClause>())
3271 return llvm::makeArrayRef(FlushClause->varlist_begin(),
3272 FlushClause->varlist_end());
3273 return llvm::None;
3274 }(),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003275 S.getBeginLoc());
Alexey Bataev6125da92014-07-21 11:26:11 +00003276}
3277
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003278void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S,
3279 const CodeGenLoopTy &CodeGenLoop,
3280 Expr *IncExpr) {
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003281 // Emit the loop iteration variable.
Alexey Bataevddf3db92018-04-13 17:31:06 +00003282 const auto *IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
3283 const auto *IVDecl = cast<VarDecl>(IVExpr->getDecl());
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003284 EmitVarDecl(*IVDecl);
3285
3286 // Emit the iterations count variable.
3287 // If it is not a variable, Sema decided to calculate iterations count on each
3288 // iteration (e.g., it is foldable into a constant).
Alexey Bataevddf3db92018-04-13 17:31:06 +00003289 if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003290 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
3291 // Emit calculation of the iterations count.
3292 EmitIgnoredExpr(S.getCalcLastIteration());
3293 }
3294
Alexey Bataevddf3db92018-04-13 17:31:06 +00003295 CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003296
Carlo Bertolli962bb802017-01-03 18:24:42 +00003297 bool HasLastprivateClause = false;
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003298 // Check pre-condition.
3299 {
Alexey Bataev5a3af132016-03-29 08:58:54 +00003300 OMPLoopScope PreInitScope(*this, S);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003301 // Skip the entire loop if we don't meet the precondition.
3302 // If the condition constant folds and can be elided, avoid emitting the
3303 // whole loop.
3304 bool CondConstant;
3305 llvm::BasicBlock *ContBlock = nullptr;
3306 if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
3307 if (!CondConstant)
3308 return;
3309 } else {
Alexey Bataevddf3db92018-04-13 17:31:06 +00003310 llvm::BasicBlock *ThenBlock = createBasicBlock("omp.precond.then");
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003311 ContBlock = createBasicBlock("omp.precond.end");
3312 emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock,
3313 getProfileCount(&S));
3314 EmitBlock(ThenBlock);
3315 incrementProfileCounter(&S);
3316 }
3317
Alexey Bataev617db5f2017-12-04 15:38:33 +00003318 emitAlignedClause(*this, S);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003319 // Emit 'then' code.
3320 {
3321 // Emit helper vars inits.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003322
3323 LValue LB = EmitOMPHelperVar(
3324 *this, cast<DeclRefExpr>(
3325 (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
3326 ? S.getCombinedLowerBoundVariable()
3327 : S.getLowerBoundVariable())));
3328 LValue UB = EmitOMPHelperVar(
3329 *this, cast<DeclRefExpr>(
3330 (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
3331 ? S.getCombinedUpperBoundVariable()
3332 : S.getUpperBoundVariable())));
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003333 LValue ST =
3334 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable()));
3335 LValue IL =
3336 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
3337
3338 OMPPrivateScope LoopScope(*this);
Carlo Bertolli962bb802017-01-03 18:24:42 +00003339 if (EmitOMPFirstprivateClause(S, LoopScope)) {
Alexey Bataev617db5f2017-12-04 15:38:33 +00003340 // Emit implicit barrier to synchronize threads and avoid data races
3341 // on initialization of firstprivate variables and post-update of
Carlo Bertolli962bb802017-01-03 18:24:42 +00003342 // lastprivate variables.
3343 CGM.getOpenMPRuntime().emitBarrierCall(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003344 *this, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
Alexey Bataev617db5f2017-12-04 15:38:33 +00003345 /*ForceSimpleCall=*/true);
Carlo Bertolli962bb802017-01-03 18:24:42 +00003346 }
3347 EmitOMPPrivateClause(S, LoopScope);
Alexey Bataev617db5f2017-12-04 15:38:33 +00003348 if (isOpenMPSimdDirective(S.getDirectiveKind()) &&
Alexey Bataev999277a2017-12-06 14:31:09 +00003349 !isOpenMPParallelDirective(S.getDirectiveKind()) &&
3350 !isOpenMPTeamsDirective(S.getDirectiveKind()))
Alexey Bataev617db5f2017-12-04 15:38:33 +00003351 EmitOMPReductionClauseInit(S, LoopScope);
Carlo Bertolli962bb802017-01-03 18:24:42 +00003352 HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
Alexey Bataev5dff95c2016-04-22 03:56:56 +00003353 EmitOMPPrivateLoopCounters(S, LoopScope);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003354 (void)LoopScope.Privatize();
Alexey Bataev60705422018-10-30 15:50:12 +00003355 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
3356 CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(*this, S);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003357
3358 // Detect the distribute schedule kind and chunk.
3359 llvm::Value *Chunk = nullptr;
3360 OpenMPDistScheduleClauseKind ScheduleKind = OMPC_DIST_SCHEDULE_unknown;
Alexey Bataevddf3db92018-04-13 17:31:06 +00003361 if (const auto *C = S.getSingleClause<OMPDistScheduleClause>()) {
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003362 ScheduleKind = C->getDistScheduleKind();
Alexey Bataevddf3db92018-04-13 17:31:06 +00003363 if (const Expr *Ch = C->getChunkSize()) {
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003364 Chunk = EmitScalarExpr(Ch);
3365 Chunk = EmitScalarConversion(Chunk, Ch->getType(),
Alexey Bataev617db5f2017-12-04 15:38:33 +00003366 S.getIterationVariable()->getType(),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003367 S.getBeginLoc());
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003368 }
Gheorghe-Teodor Bercea02650d42018-09-27 19:22:56 +00003369 } else {
3370 // Default behaviour for dist_schedule clause.
3371 CGM.getOpenMPRuntime().getDefaultDistScheduleAndChunk(
3372 *this, S, ScheduleKind, Chunk);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003373 }
3374 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
3375 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
3376
3377 // OpenMP [2.10.8, distribute Construct, Description]
3378 // If dist_schedule is specified, kind must be static. If specified,
3379 // iterations are divided into chunks of size chunk_size, chunks are
3380 // assigned to the teams of the league in a round-robin fashion in the
3381 // order of the team number. When no chunk_size is specified, the
3382 // iteration space is divided into chunks that are approximately equal
3383 // in size, and at most one chunk is distributed to each team of the
3384 // league. The size of the chunks is unspecified in this case.
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00003385 bool StaticChunked = RT.isStaticChunked(
3386 ScheduleKind, /* Chunked */ Chunk != nullptr) &&
3387 isOpenMPLoopBoundSharingDirective(S.getDirectiveKind());
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003388 if (RT.isStaticNonchunked(ScheduleKind,
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00003389 /* Chunked */ Chunk != nullptr) ||
3390 StaticChunked) {
Alexey Bataev617db5f2017-12-04 15:38:33 +00003391 if (isOpenMPSimdDirective(S.getDirectiveKind()))
3392 EmitOMPSimdInit(S, /*IsMonotonic=*/true);
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003393 CGOpenMPRuntime::StaticRTInput StaticInit(
3394 IVSize, IVSigned, /* Ordered = */ false, IL.getAddress(),
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00003395 LB.getAddress(), UB.getAddress(), ST.getAddress(),
3396 StaticChunked ? Chunk : nullptr);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003397 RT.emitDistributeStaticInit(*this, S.getBeginLoc(), ScheduleKind,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003398 StaticInit);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003399 JumpDest LoopExit =
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003400 getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit"));
3401 // UB = min(UB, GlobalUB);
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003402 EmitIgnoredExpr(isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
3403 ? S.getCombinedEnsureUpperBound()
3404 : S.getEnsureUpperBound());
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003405 // IV = LB;
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003406 EmitIgnoredExpr(isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
3407 ? S.getCombinedInit()
3408 : S.getInit());
3409
Alexey Bataevddf3db92018-04-13 17:31:06 +00003410 const Expr *Cond =
3411 isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
3412 ? S.getCombinedCond()
3413 : S.getCond();
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003414
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00003415 if (StaticChunked)
3416 Cond = S.getCombinedDistCond();
3417
3418 // For static unchunked schedules generate:
3419 //
3420 // 1. For distribute alone, codegen
3421 // while (idx <= UB) {
3422 // BODY;
3423 // ++idx;
3424 // }
3425 //
3426 // 2. When combined with 'for' (e.g. as in 'distribute parallel for')
3427 // while (idx <= UB) {
3428 // <CodeGen rest of pragma>(LB, UB);
3429 // idx += ST;
3430 // }
3431 //
3432 // For static chunk one schedule generate:
3433 //
3434 // while (IV <= GlobalUB) {
3435 // <CodeGen rest of pragma>(LB, UB);
3436 // LB += ST;
3437 // UB += ST;
3438 // UB = min(UB, GlobalUB);
3439 // IV = LB;
3440 // }
3441 //
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003442 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), Cond, IncExpr,
3443 [&S, LoopExit, &CodeGenLoop](CodeGenFunction &CGF) {
3444 CodeGenLoop(CGF, S, LoopExit);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003445 },
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00003446 [&S, StaticChunked](CodeGenFunction &CGF) {
3447 if (StaticChunked) {
3448 CGF.EmitIgnoredExpr(S.getCombinedNextLowerBound());
3449 CGF.EmitIgnoredExpr(S.getCombinedNextUpperBound());
3450 CGF.EmitIgnoredExpr(S.getCombinedEnsureUpperBound());
3451 CGF.EmitIgnoredExpr(S.getCombinedInit());
3452 }
3453 });
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003454 EmitBlock(LoopExit.getBlock());
3455 // Tell the runtime we are done.
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003456 RT.emitForStaticFinish(*this, S.getBeginLoc(), S.getDirectiveKind());
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003457 } else {
3458 // Emit the outer loop, which requests its work chunk [LB..UB] from
3459 // runtime and runs the inner loop to process it.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003460 const OMPLoopArguments LoopArguments = {
3461 LB.getAddress(), UB.getAddress(), ST.getAddress(), IL.getAddress(),
3462 Chunk};
3463 EmitOMPDistributeOuterLoop(ScheduleKind, S, LoopScope, LoopArguments,
3464 CodeGenLoop);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003465 }
Alexey Bataev617db5f2017-12-04 15:38:33 +00003466 if (isOpenMPSimdDirective(S.getDirectiveKind())) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00003467 EmitOMPSimdFinal(S, [IL, &S](CodeGenFunction &CGF) {
Alexey Bataev617db5f2017-12-04 15:38:33 +00003468 return CGF.Builder.CreateIsNotNull(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003469 CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
Alexey Bataev617db5f2017-12-04 15:38:33 +00003470 });
3471 }
Carlo Bertollibeda2142018-02-22 19:38:14 +00003472 if (isOpenMPSimdDirective(S.getDirectiveKind()) &&
3473 !isOpenMPParallelDirective(S.getDirectiveKind()) &&
3474 !isOpenMPTeamsDirective(S.getDirectiveKind())) {
Jonas Hahnfeld5aaaece2018-10-02 19:12:47 +00003475 EmitOMPReductionClauseFinal(S, OMPD_simd);
Carlo Bertollibeda2142018-02-22 19:38:14 +00003476 // Emit post-update of the reduction variables if IsLastIter != 0.
3477 emitPostUpdateForReductionClause(
Alexey Bataevddf3db92018-04-13 17:31:06 +00003478 *this, S, [IL, &S](CodeGenFunction &CGF) {
Carlo Bertollibeda2142018-02-22 19:38:14 +00003479 return CGF.Builder.CreateIsNotNull(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003480 CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
Carlo Bertollibeda2142018-02-22 19:38:14 +00003481 });
Alexey Bataev617db5f2017-12-04 15:38:33 +00003482 }
Carlo Bertolli962bb802017-01-03 18:24:42 +00003483 // Emit final copy of the lastprivate variables if IsLastIter != 0.
Alexey Bataev617db5f2017-12-04 15:38:33 +00003484 if (HasLastprivateClause) {
Carlo Bertolli962bb802017-01-03 18:24:42 +00003485 EmitOMPLastprivateClauseFinal(
3486 S, /*NoFinals=*/false,
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003487 Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getBeginLoc())));
Alexey Bataev617db5f2017-12-04 15:38:33 +00003488 }
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003489 }
3490
3491 // We're now done with the loop, so jump to the continuation block.
3492 if (ContBlock) {
3493 EmitBranch(ContBlock);
3494 EmitBlock(ContBlock, true);
3495 }
3496 }
3497}
3498
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003499void CodeGenFunction::EmitOMPDistributeDirective(
3500 const OMPDistributeDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003501 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003502 CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003503 };
Alexey Bataev475a7442018-01-12 19:39:11 +00003504 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev10a54312017-11-27 16:54:08 +00003505 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003506}
3507
Alexey Bataev5f600d62015-09-29 03:48:57 +00003508static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM,
3509 const CapturedStmt *S) {
3510 CodeGenFunction CGF(CGM, /*suppressNewContext=*/true);
3511 CodeGenFunction::CGCapturedStmtInfo CapStmtInfo;
3512 CGF.CapturedStmtInfo = &CapStmtInfo;
Alexey Bataevddf3db92018-04-13 17:31:06 +00003513 llvm::Function *Fn = CGF.GenerateOpenMPCapturedStmtFunction(*S);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003514 Fn->setDoesNotRecurse();
Alexey Bataev5f600d62015-09-29 03:48:57 +00003515 return Fn;
3516}
3517
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003518void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) {
Alexey Bataev475a7442018-01-12 19:39:11 +00003519 if (S.hasClausesOfKind<OMPDependClause>()) {
3520 assert(!S.getAssociatedStmt() &&
3521 "No associated statement must be in ordered depend construct.");
Alexey Bataev8b427062016-05-25 12:36:08 +00003522 for (const auto *DC : S.getClausesOfKind<OMPDependClause>())
3523 CGM.getOpenMPRuntime().emitDoacrossOrdered(*this, DC);
Alexey Bataev8ef31412015-12-18 07:58:25 +00003524 return;
Alexey Bataev8b427062016-05-25 12:36:08 +00003525 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00003526 const auto *C = S.getSingleClause<OMPSIMDClause>();
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003527 auto &&CodeGen = [&S, C, this](CodeGenFunction &CGF,
3528 PrePostActionTy &Action) {
Alexey Bataev475a7442018-01-12 19:39:11 +00003529 const CapturedStmt *CS = S.getInnermostCapturedStmt();
Alexey Bataev5f600d62015-09-29 03:48:57 +00003530 if (C) {
Alexey Bataev5f600d62015-09-29 03:48:57 +00003531 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
3532 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003533 llvm::Function *OutlinedFn = emitOutlinedOrderedFunction(CGM, CS);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003534 CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, S.getBeginLoc(),
Alexey Bataev3c595a62017-08-14 15:01:03 +00003535 OutlinedFn, CapturedVars);
Alexey Bataev5f600d62015-09-29 03:48:57 +00003536 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003537 Action.Enter(CGF);
Alexey Bataev475a7442018-01-12 19:39:11 +00003538 CGF.EmitStmt(CS->getCapturedStmt());
Alexey Bataev5f600d62015-09-29 03:48:57 +00003539 }
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003540 };
Alexey Bataev475a7442018-01-12 19:39:11 +00003541 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003542 CGM.getOpenMPRuntime().emitOrderedRegion(*this, CodeGen, S.getBeginLoc(), !C);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003543}
3544
Alexey Bataevb57056f2015-01-22 06:17:56 +00003545static llvm::Value *convertToScalarValue(CodeGenFunction &CGF, RValue Val,
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003546 QualType SrcType, QualType DestType,
3547 SourceLocation Loc) {
Alexey Bataevb57056f2015-01-22 06:17:56 +00003548 assert(CGF.hasScalarEvaluationKind(DestType) &&
3549 "DestType must have scalar evaluation kind.");
3550 assert(!Val.isAggregate() && "Must be a scalar or complex.");
Alexey Bataevddf3db92018-04-13 17:31:06 +00003551 return Val.isScalar() ? CGF.EmitScalarConversion(Val.getScalarVal(), SrcType,
3552 DestType, Loc)
3553 : CGF.EmitComplexToScalarConversion(
3554 Val.getComplexVal(), SrcType, DestType, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003555}
3556
3557static CodeGenFunction::ComplexPairTy
3558convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType,
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003559 QualType DestType, SourceLocation Loc) {
Alexey Bataevb57056f2015-01-22 06:17:56 +00003560 assert(CGF.getEvaluationKind(DestType) == TEK_Complex &&
3561 "DestType must have complex evaluation kind.");
3562 CodeGenFunction::ComplexPairTy ComplexVal;
3563 if (Val.isScalar()) {
3564 // Convert the input element to the element type of the complex.
Alexey Bataevddf3db92018-04-13 17:31:06 +00003565 QualType DestElementType =
3566 DestType->castAs<ComplexType>()->getElementType();
3567 llvm::Value *ScalarVal = CGF.EmitScalarConversion(
3568 Val.getScalarVal(), SrcType, DestElementType, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003569 ComplexVal = CodeGenFunction::ComplexPairTy(
3570 ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType()));
3571 } else {
3572 assert(Val.isComplex() && "Must be a scalar or complex.");
Alexey Bataevddf3db92018-04-13 17:31:06 +00003573 QualType SrcElementType = SrcType->castAs<ComplexType>()->getElementType();
3574 QualType DestElementType =
3575 DestType->castAs<ComplexType>()->getElementType();
Alexey Bataevb57056f2015-01-22 06:17:56 +00003576 ComplexVal.first = CGF.EmitScalarConversion(
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003577 Val.getComplexVal().first, SrcElementType, DestElementType, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003578 ComplexVal.second = CGF.EmitScalarConversion(
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003579 Val.getComplexVal().second, SrcElementType, DestElementType, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003580 }
3581 return ComplexVal;
3582}
3583
Alexey Bataev5e018f92015-04-23 06:35:10 +00003584static void emitSimpleAtomicStore(CodeGenFunction &CGF, bool IsSeqCst,
3585 LValue LVal, RValue RVal) {
3586 if (LVal.isGlobalReg()) {
3587 CGF.EmitStoreThroughGlobalRegLValue(RVal, LVal);
3588 } else {
JF Bastien92f4ef12016-04-06 17:26:42 +00003589 CGF.EmitAtomicStore(RVal, LVal,
3590 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3591 : llvm::AtomicOrdering::Monotonic,
Alexey Bataev5e018f92015-04-23 06:35:10 +00003592 LVal.isVolatile(), /*IsInit=*/false);
3593 }
3594}
3595
Alexey Bataev8524d152016-01-21 12:35:58 +00003596void CodeGenFunction::emitOMPSimpleStore(LValue LVal, RValue RVal,
3597 QualType RValTy, SourceLocation Loc) {
3598 switch (getEvaluationKind(LVal.getType())) {
Alexey Bataev5e018f92015-04-23 06:35:10 +00003599 case TEK_Scalar:
Alexey Bataev8524d152016-01-21 12:35:58 +00003600 EmitStoreThroughLValue(RValue::get(convertToScalarValue(
3601 *this, RVal, RValTy, LVal.getType(), Loc)),
3602 LVal);
Alexey Bataev5e018f92015-04-23 06:35:10 +00003603 break;
3604 case TEK_Complex:
Alexey Bataev8524d152016-01-21 12:35:58 +00003605 EmitStoreOfComplex(
3606 convertToComplexValue(*this, RVal, RValTy, LVal.getType(), Loc), LVal,
Alexey Bataev5e018f92015-04-23 06:35:10 +00003607 /*isInit=*/false);
3608 break;
3609 case TEK_Aggregate:
3610 llvm_unreachable("Must be a scalar or complex.");
3611 }
3612}
3613
Alexey Bataevddf3db92018-04-13 17:31:06 +00003614static void emitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst,
Alexey Bataevb57056f2015-01-22 06:17:56 +00003615 const Expr *X, const Expr *V,
3616 SourceLocation Loc) {
3617 // v = x;
3618 assert(V->isLValue() && "V of 'omp atomic read' is not lvalue");
3619 assert(X->isLValue() && "X of 'omp atomic read' is not lvalue");
3620 LValue XLValue = CGF.EmitLValue(X);
3621 LValue VLValue = CGF.EmitLValue(V);
David Majnemera5b195a2015-02-14 01:35:12 +00003622 RValue Res = XLValue.isGlobalReg()
3623 ? CGF.EmitLoadOfLValue(XLValue, Loc)
JF Bastien92f4ef12016-04-06 17:26:42 +00003624 : CGF.EmitAtomicLoad(
3625 XLValue, Loc,
3626 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3627 : llvm::AtomicOrdering::Monotonic,
3628 XLValue.isVolatile());
Alexey Bataevb57056f2015-01-22 06:17:56 +00003629 // OpenMP, 2.12.6, atomic Construct
3630 // Any atomic construct with a seq_cst clause forces the atomically
3631 // performed operation to include an implicit flush operation without a
3632 // list.
3633 if (IsSeqCst)
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003634 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
Alexey Bataev8524d152016-01-21 12:35:58 +00003635 CGF.emitOMPSimpleStore(VLValue, Res, X->getType().getNonReferenceType(), Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003636}
3637
Alexey Bataevddf3db92018-04-13 17:31:06 +00003638static void emitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst,
Alexey Bataevb8329262015-02-27 06:33:30 +00003639 const Expr *X, const Expr *E,
3640 SourceLocation Loc) {
3641 // x = expr;
3642 assert(X->isLValue() && "X of 'omp atomic write' is not lvalue");
Alexey Bataev5e018f92015-04-23 06:35:10 +00003643 emitSimpleAtomicStore(CGF, IsSeqCst, CGF.EmitLValue(X), CGF.EmitAnyExpr(E));
Alexey Bataevb8329262015-02-27 06:33:30 +00003644 // OpenMP, 2.12.6, atomic Construct
3645 // Any atomic construct with a seq_cst clause forces the atomically
3646 // performed operation to include an implicit flush operation without a
3647 // list.
3648 if (IsSeqCst)
3649 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
3650}
3651
Benjamin Kramer439ee9d2015-05-01 13:59:53 +00003652static std::pair<bool, RValue> emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X,
3653 RValue Update,
3654 BinaryOperatorKind BO,
3655 llvm::AtomicOrdering AO,
3656 bool IsXLHSInRHSPart) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00003657 ASTContext &Context = CGF.getContext();
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003658 // Allow atomicrmw only if 'x' and 'update' are integer values, lvalue for 'x'
Alexey Bataevb4505a72015-03-30 05:20:59 +00003659 // expression is simple and atomic is allowed for the given type for the
3660 // target platform.
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003661 if (BO == BO_Comma || !Update.isScalar() ||
Alexey Bataev9d541a72015-05-08 11:47:16 +00003662 !Update.getScalarVal()->getType()->isIntegerTy() ||
3663 !X.isSimple() || (!isa<llvm::ConstantInt>(Update.getScalarVal()) &&
3664 (Update.getScalarVal()->getType() !=
John McCall7f416cc2015-09-08 08:05:57 +00003665 X.getAddress().getElementType())) ||
3666 !X.getAddress().getElementType()->isIntegerTy() ||
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003667 !Context.getTargetInfo().hasBuiltinAtomic(
3668 Context.getTypeSize(X.getType()), Context.toBits(X.getAlignment())))
Alexey Bataev5e018f92015-04-23 06:35:10 +00003669 return std::make_pair(false, RValue::get(nullptr));
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003670
3671 llvm::AtomicRMWInst::BinOp RMWOp;
3672 switch (BO) {
3673 case BO_Add:
3674 RMWOp = llvm::AtomicRMWInst::Add;
3675 break;
3676 case BO_Sub:
3677 if (!IsXLHSInRHSPart)
Alexey Bataev5e018f92015-04-23 06:35:10 +00003678 return std::make_pair(false, RValue::get(nullptr));
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003679 RMWOp = llvm::AtomicRMWInst::Sub;
3680 break;
3681 case BO_And:
3682 RMWOp = llvm::AtomicRMWInst::And;
3683 break;
3684 case BO_Or:
3685 RMWOp = llvm::AtomicRMWInst::Or;
3686 break;
3687 case BO_Xor:
3688 RMWOp = llvm::AtomicRMWInst::Xor;
3689 break;
3690 case BO_LT:
3691 RMWOp = X.getType()->hasSignedIntegerRepresentation()
3692 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min
3693 : llvm::AtomicRMWInst::Max)
3694 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin
3695 : llvm::AtomicRMWInst::UMax);
3696 break;
3697 case BO_GT:
3698 RMWOp = X.getType()->hasSignedIntegerRepresentation()
3699 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max
3700 : llvm::AtomicRMWInst::Min)
3701 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax
3702 : llvm::AtomicRMWInst::UMin);
3703 break;
Alexey Bataev5e018f92015-04-23 06:35:10 +00003704 case BO_Assign:
3705 RMWOp = llvm::AtomicRMWInst::Xchg;
3706 break;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003707 case BO_Mul:
3708 case BO_Div:
3709 case BO_Rem:
3710 case BO_Shl:
3711 case BO_Shr:
3712 case BO_LAnd:
3713 case BO_LOr:
Alexey Bataev5e018f92015-04-23 06:35:10 +00003714 return std::make_pair(false, RValue::get(nullptr));
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003715 case BO_PtrMemD:
3716 case BO_PtrMemI:
3717 case BO_LE:
3718 case BO_GE:
3719 case BO_EQ:
3720 case BO_NE:
Richard Smithc70f1d62017-12-14 15:16:18 +00003721 case BO_Cmp:
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003722 case BO_AddAssign:
3723 case BO_SubAssign:
3724 case BO_AndAssign:
3725 case BO_OrAssign:
3726 case BO_XorAssign:
3727 case BO_MulAssign:
3728 case BO_DivAssign:
3729 case BO_RemAssign:
3730 case BO_ShlAssign:
3731 case BO_ShrAssign:
3732 case BO_Comma:
3733 llvm_unreachable("Unsupported atomic update operation");
3734 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00003735 llvm::Value *UpdateVal = Update.getScalarVal();
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003736 if (auto *IC = dyn_cast<llvm::ConstantInt>(UpdateVal)) {
3737 UpdateVal = CGF.Builder.CreateIntCast(
John McCall7f416cc2015-09-08 08:05:57 +00003738 IC, X.getAddress().getElementType(),
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003739 X.getType()->hasSignedIntegerRepresentation());
3740 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00003741 llvm::Value *Res =
3742 CGF.Builder.CreateAtomicRMW(RMWOp, X.getPointer(), UpdateVal, AO);
Alexey Bataev5e018f92015-04-23 06:35:10 +00003743 return std::make_pair(true, RValue::get(Res));
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003744}
3745
Alexey Bataev5e018f92015-04-23 06:35:10 +00003746std::pair<bool, RValue> CodeGenFunction::EmitOMPAtomicSimpleUpdateExpr(
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003747 LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart,
3748 llvm::AtomicOrdering AO, SourceLocation Loc,
Alexey Bataevddf3db92018-04-13 17:31:06 +00003749 const llvm::function_ref<RValue(RValue)> CommonGen) {
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003750 // Update expressions are allowed to have the following forms:
3751 // x binop= expr; -> xrval + expr;
3752 // x++, ++x -> xrval + 1;
3753 // x--, --x -> xrval - 1;
3754 // x = x binop expr; -> xrval binop expr
3755 // x = expr Op x; - > expr binop xrval;
Alexey Bataev5e018f92015-04-23 06:35:10 +00003756 auto Res = emitOMPAtomicRMW(*this, X, E, BO, AO, IsXLHSInRHSPart);
3757 if (!Res.first) {
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003758 if (X.isGlobalReg()) {
3759 // Emit an update expression: 'xrval' binop 'expr' or 'expr' binop
3760 // 'xrval'.
3761 EmitStoreThroughLValue(CommonGen(EmitLoadOfLValue(X, Loc)), X);
3762 } else {
3763 // Perform compare-and-swap procedure.
3764 EmitAtomicUpdate(X, AO, CommonGen, X.getType().isVolatileQualified());
Alexey Bataevb4505a72015-03-30 05:20:59 +00003765 }
3766 }
Alexey Bataev5e018f92015-04-23 06:35:10 +00003767 return Res;
Alexey Bataevb4505a72015-03-30 05:20:59 +00003768}
3769
Alexey Bataevddf3db92018-04-13 17:31:06 +00003770static void emitOMPAtomicUpdateExpr(CodeGenFunction &CGF, bool IsSeqCst,
Alexey Bataevb4505a72015-03-30 05:20:59 +00003771 const Expr *X, const Expr *E,
3772 const Expr *UE, bool IsXLHSInRHSPart,
3773 SourceLocation Loc) {
3774 assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) &&
3775 "Update expr in 'atomic update' must be a binary operator.");
Alexey Bataevddf3db92018-04-13 17:31:06 +00003776 const auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts());
Alexey Bataevb4505a72015-03-30 05:20:59 +00003777 // Update expressions are allowed to have the following forms:
3778 // x binop= expr; -> xrval + expr;
3779 // x++, ++x -> xrval + 1;
3780 // x--, --x -> xrval - 1;
3781 // x = x binop expr; -> xrval binop expr
3782 // x = expr Op x; - > expr binop xrval;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003783 assert(X->isLValue() && "X of 'omp atomic update' is not lvalue");
Alexey Bataevb4505a72015-03-30 05:20:59 +00003784 LValue XLValue = CGF.EmitLValue(X);
3785 RValue ExprRValue = CGF.EmitAnyExpr(E);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003786 llvm::AtomicOrdering AO = IsSeqCst
3787 ? llvm::AtomicOrdering::SequentiallyConsistent
3788 : llvm::AtomicOrdering::Monotonic;
3789 const auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
3790 const auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
3791 const OpaqueValueExpr *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
3792 const OpaqueValueExpr *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
3793 auto &&Gen = [&CGF, UE, ExprRValue, XRValExpr, ERValExpr](RValue XRValue) {
3794 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
3795 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);
3796 return CGF.EmitAnyExpr(UE);
3797 };
Alexey Bataev5e018f92015-04-23 06:35:10 +00003798 (void)CGF.EmitOMPAtomicSimpleUpdateExpr(
3799 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
3800 // OpenMP, 2.12.6, atomic Construct
3801 // Any atomic construct with a seq_cst clause forces the atomically
3802 // performed operation to include an implicit flush operation without a
3803 // list.
3804 if (IsSeqCst)
3805 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
3806}
3807
3808static RValue convertToType(CodeGenFunction &CGF, RValue Value,
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003809 QualType SourceType, QualType ResType,
3810 SourceLocation Loc) {
Alexey Bataev5e018f92015-04-23 06:35:10 +00003811 switch (CGF.getEvaluationKind(ResType)) {
3812 case TEK_Scalar:
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003813 return RValue::get(
3814 convertToScalarValue(CGF, Value, SourceType, ResType, Loc));
Alexey Bataev5e018f92015-04-23 06:35:10 +00003815 case TEK_Complex: {
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003816 auto Res = convertToComplexValue(CGF, Value, SourceType, ResType, Loc);
Alexey Bataev5e018f92015-04-23 06:35:10 +00003817 return RValue::getComplex(Res.first, Res.second);
3818 }
3819 case TEK_Aggregate:
3820 break;
3821 }
3822 llvm_unreachable("Must be a scalar or complex.");
3823}
3824
Alexey Bataevddf3db92018-04-13 17:31:06 +00003825static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF, bool IsSeqCst,
Alexey Bataev5e018f92015-04-23 06:35:10 +00003826 bool IsPostfixUpdate, const Expr *V,
3827 const Expr *X, const Expr *E,
3828 const Expr *UE, bool IsXLHSInRHSPart,
3829 SourceLocation Loc) {
3830 assert(X->isLValue() && "X of 'omp atomic capture' is not lvalue");
3831 assert(V->isLValue() && "V of 'omp atomic capture' is not lvalue");
3832 RValue NewVVal;
3833 LValue VLValue = CGF.EmitLValue(V);
3834 LValue XLValue = CGF.EmitLValue(X);
3835 RValue ExprRValue = CGF.EmitAnyExpr(E);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003836 llvm::AtomicOrdering AO = IsSeqCst
3837 ? llvm::AtomicOrdering::SequentiallyConsistent
3838 : llvm::AtomicOrdering::Monotonic;
Alexey Bataev5e018f92015-04-23 06:35:10 +00003839 QualType NewVValType;
3840 if (UE) {
3841 // 'x' is updated with some additional value.
3842 assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) &&
3843 "Update expr in 'atomic capture' must be a binary operator.");
Alexey Bataevddf3db92018-04-13 17:31:06 +00003844 const auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts());
Alexey Bataev5e018f92015-04-23 06:35:10 +00003845 // Update expressions are allowed to have the following forms:
3846 // x binop= expr; -> xrval + expr;
3847 // x++, ++x -> xrval + 1;
3848 // x--, --x -> xrval - 1;
3849 // x = x binop expr; -> xrval binop expr
3850 // x = expr Op x; - > expr binop xrval;
Alexey Bataevddf3db92018-04-13 17:31:06 +00003851 const auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
3852 const auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
3853 const OpaqueValueExpr *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
Alexey Bataev5e018f92015-04-23 06:35:10 +00003854 NewVValType = XRValExpr->getType();
Alexey Bataevddf3db92018-04-13 17:31:06 +00003855 const OpaqueValueExpr *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
Alexey Bataev5e018f92015-04-23 06:35:10 +00003856 auto &&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr,
Alexey Bataevddf3db92018-04-13 17:31:06 +00003857 IsPostfixUpdate](RValue XRValue) {
Alexey Bataev5e018f92015-04-23 06:35:10 +00003858 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
3859 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);
3860 RValue Res = CGF.EmitAnyExpr(UE);
3861 NewVVal = IsPostfixUpdate ? XRValue : Res;
3862 return Res;
3863 };
3864 auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr(
3865 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
3866 if (Res.first) {
3867 // 'atomicrmw' instruction was generated.
3868 if (IsPostfixUpdate) {
3869 // Use old value from 'atomicrmw'.
3870 NewVVal = Res.second;
3871 } else {
3872 // 'atomicrmw' does not provide new value, so evaluate it using old
3873 // value of 'x'.
3874 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
3875 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, Res.second);
3876 NewVVal = CGF.EmitAnyExpr(UE);
3877 }
3878 }
3879 } else {
3880 // 'x' is simply rewritten with some 'expr'.
3881 NewVValType = X->getType().getNonReferenceType();
3882 ExprRValue = convertToType(CGF, ExprRValue, E->getType(),
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003883 X->getType().getNonReferenceType(), Loc);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003884 auto &&Gen = [&NewVVal, ExprRValue](RValue XRValue) {
Alexey Bataev5e018f92015-04-23 06:35:10 +00003885 NewVVal = XRValue;
3886 return ExprRValue;
3887 };
3888 // Try to perform atomicrmw xchg, otherwise simple exchange.
3889 auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr(
3890 XLValue, ExprRValue, /*BO=*/BO_Assign, /*IsXLHSInRHSPart=*/false, AO,
3891 Loc, Gen);
3892 if (Res.first) {
3893 // 'atomicrmw' instruction was generated.
3894 NewVVal = IsPostfixUpdate ? Res.second : ExprRValue;
3895 }
3896 }
3897 // Emit post-update store to 'v' of old/new 'x' value.
Alexey Bataev8524d152016-01-21 12:35:58 +00003898 CGF.emitOMPSimpleStore(VLValue, NewVVal, NewVValType, Loc);
Alexey Bataevb4505a72015-03-30 05:20:59 +00003899 // OpenMP, 2.12.6, atomic Construct
3900 // Any atomic construct with a seq_cst clause forces the atomically
3901 // performed operation to include an implicit flush operation without a
3902 // list.
3903 if (IsSeqCst)
3904 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
3905}
3906
Alexey Bataevddf3db92018-04-13 17:31:06 +00003907static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
Alexey Bataev5e018f92015-04-23 06:35:10 +00003908 bool IsSeqCst, bool IsPostfixUpdate,
3909 const Expr *X, const Expr *V, const Expr *E,
3910 const Expr *UE, bool IsXLHSInRHSPart,
3911 SourceLocation Loc) {
Alexey Bataevb57056f2015-01-22 06:17:56 +00003912 switch (Kind) {
3913 case OMPC_read:
Alexey Bataevddf3db92018-04-13 17:31:06 +00003914 emitOMPAtomicReadExpr(CGF, IsSeqCst, X, V, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003915 break;
3916 case OMPC_write:
Alexey Bataevddf3db92018-04-13 17:31:06 +00003917 emitOMPAtomicWriteExpr(CGF, IsSeqCst, X, E, Loc);
Alexey Bataevb8329262015-02-27 06:33:30 +00003918 break;
Alexey Bataevb4505a72015-03-30 05:20:59 +00003919 case OMPC_unknown:
Alexey Bataevb57056f2015-01-22 06:17:56 +00003920 case OMPC_update:
Alexey Bataevddf3db92018-04-13 17:31:06 +00003921 emitOMPAtomicUpdateExpr(CGF, IsSeqCst, X, E, UE, IsXLHSInRHSPart, Loc);
Alexey Bataevb4505a72015-03-30 05:20:59 +00003922 break;
Alexey Bataevb57056f2015-01-22 06:17:56 +00003923 case OMPC_capture:
Alexey Bataevddf3db92018-04-13 17:31:06 +00003924 emitOMPAtomicCaptureExpr(CGF, IsSeqCst, IsPostfixUpdate, V, X, E, UE,
Alexey Bataev5e018f92015-04-23 06:35:10 +00003925 IsXLHSInRHSPart, Loc);
3926 break;
Alexey Bataevb57056f2015-01-22 06:17:56 +00003927 case OMPC_if:
3928 case OMPC_final:
3929 case OMPC_num_threads:
3930 case OMPC_private:
3931 case OMPC_firstprivate:
3932 case OMPC_lastprivate:
3933 case OMPC_reduction:
Alexey Bataev169d96a2017-07-18 20:17:46 +00003934 case OMPC_task_reduction:
Alexey Bataevfa312f32017-07-21 18:48:21 +00003935 case OMPC_in_reduction:
Alexey Bataevb57056f2015-01-22 06:17:56 +00003936 case OMPC_safelen:
Alexey Bataev66b15b52015-08-21 11:14:16 +00003937 case OMPC_simdlen:
Alexey Bataevb57056f2015-01-22 06:17:56 +00003938 case OMPC_collapse:
3939 case OMPC_default:
3940 case OMPC_seq_cst:
3941 case OMPC_shared:
3942 case OMPC_linear:
3943 case OMPC_aligned:
3944 case OMPC_copyin:
3945 case OMPC_copyprivate:
3946 case OMPC_flush:
3947 case OMPC_proc_bind:
3948 case OMPC_schedule:
3949 case OMPC_ordered:
3950 case OMPC_nowait:
3951 case OMPC_untied:
3952 case OMPC_threadprivate:
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00003953 case OMPC_depend:
Alexey Bataevb57056f2015-01-22 06:17:56 +00003954 case OMPC_mergeable:
Michael Wonge710d542015-08-07 16:16:36 +00003955 case OMPC_device:
Alexey Bataev346265e2015-09-25 10:37:12 +00003956 case OMPC_threads:
Alexey Bataevd14d1e62015-09-28 06:39:35 +00003957 case OMPC_simd:
Kelvin Li0bff7af2015-11-23 05:32:03 +00003958 case OMPC_map:
Kelvin Li099bb8c2015-11-24 20:50:12 +00003959 case OMPC_num_teams:
Kelvin Lia15fb1a2015-11-27 18:47:36 +00003960 case OMPC_thread_limit:
Alexey Bataeva0569352015-12-01 10:17:31 +00003961 case OMPC_priority:
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00003962 case OMPC_grainsize:
Alexey Bataevb825de12015-12-07 10:51:44 +00003963 case OMPC_nogroup:
Alexey Bataev382967a2015-12-08 12:06:20 +00003964 case OMPC_num_tasks:
Alexey Bataev28c75412015-12-15 08:19:24 +00003965 case OMPC_hint:
Carlo Bertollib4adf552016-01-15 18:50:31 +00003966 case OMPC_dist_schedule:
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00003967 case OMPC_defaultmap:
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003968 case OMPC_uniform:
Samuel Antao661c0902016-05-26 17:39:58 +00003969 case OMPC_to:
Samuel Antaoec172c62016-05-26 17:49:04 +00003970 case OMPC_from:
Carlo Bertolli2404b172016-07-13 15:37:16 +00003971 case OMPC_use_device_ptr:
Carlo Bertolli70594e92016-07-13 17:16:49 +00003972 case OMPC_is_device_ptr:
Kelvin Li1408f912018-09-26 04:28:39 +00003973 case OMPC_unified_address:
Alexey Bataev94c50642018-10-01 14:26:31 +00003974 case OMPC_unified_shared_memory:
Patrick Lyster6bdf63b2018-10-03 20:07:58 +00003975 case OMPC_reverse_offload:
Patrick Lyster3fe9e392018-10-11 14:41:10 +00003976 case OMPC_dynamic_allocators:
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00003977 case OMPC_atomic_default_mem_order:
Alexey Bataevb57056f2015-01-22 06:17:56 +00003978 llvm_unreachable("Clause is not allowed in 'omp atomic'.");
3979 }
3980}
3981
3982void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00003983 bool IsSeqCst = S.getSingleClause<OMPSeqCstClause>();
Alexey Bataevb57056f2015-01-22 06:17:56 +00003984 OpenMPClauseKind Kind = OMPC_unknown;
Alexey Bataevddf3db92018-04-13 17:31:06 +00003985 for (const OMPClause *C : S.clauses()) {
Alexey Bataevb57056f2015-01-22 06:17:56 +00003986 // Find first clause (skip seq_cst clause, if it is first).
3987 if (C->getClauseKind() != OMPC_seq_cst) {
3988 Kind = C->getClauseKind();
3989 break;
3990 }
3991 }
Alexey Bataev10fec572015-03-11 04:48:56 +00003992
Alexey Bataevddf3db92018-04-13 17:31:06 +00003993 const Stmt *CS = S.getInnermostCapturedStmt()->IgnoreContainers();
Bill Wendling7c44da22018-10-31 03:48:47 +00003994 if (const auto *FE = dyn_cast<FullExpr>(CS))
3995 enterFullExpression(FE);
Alexey Bataev5e018f92015-04-23 06:35:10 +00003996 // Processing for statements under 'atomic capture'.
3997 if (const auto *Compound = dyn_cast<CompoundStmt>(CS)) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00003998 for (const Stmt *C : Compound->body()) {
Bill Wendling7c44da22018-10-31 03:48:47 +00003999 if (const auto *FE = dyn_cast<FullExpr>(C))
4000 enterFullExpression(FE);
Alexey Bataev5e018f92015-04-23 06:35:10 +00004001 }
4002 }
Alexey Bataev10fec572015-03-11 04:48:56 +00004003
Alexey Bataev14fa1c62016-03-29 05:34:15 +00004004 auto &&CodeGen = [&S, Kind, IsSeqCst, CS](CodeGenFunction &CGF,
4005 PrePostActionTy &) {
Alexey Bataev33c56402015-12-14 09:26:19 +00004006 CGF.EmitStopPoint(CS);
Alexey Bataevddf3db92018-04-13 17:31:06 +00004007 emitOMPAtomicExpr(CGF, Kind, IsSeqCst, S.isPostfixUpdate(), S.getX(),
Alexey Bataev5e018f92015-04-23 06:35:10 +00004008 S.getV(), S.getExpr(), S.getUpdateExpr(),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004009 S.isXLHSInRHSPart(), S.getBeginLoc());
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00004010 };
Alexey Bataev475a7442018-01-12 19:39:11 +00004011 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00004012 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_atomic, CodeGen);
Alexey Bataev0162e452014-07-22 10:10:35 +00004013}
4014
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004015static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
4016 const OMPExecutableDirective &S,
4017 const RegionCodeGenTy &CodeGen) {
4018 assert(isOpenMPTargetExecutionDirective(S.getDirectiveKind()));
4019 CodeGenModule &CGM = CGF.CGM;
Samuel Antaobed3c462015-10-02 16:14:20 +00004020
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00004021 // On device emit this construct as inlined code.
4022 if (CGM.getLangOpts().OpenMPIsDevice) {
4023 OMPLexicalScope Scope(CGF, S, OMPD_target);
4024 CGM.getOpenMPRuntime().emitInlinedDirective(
4025 CGF, OMPD_target, [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataev4ac68a22018-05-16 15:08:32 +00004026 CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00004027 });
4028 return;
4029 }
4030
Samuel Antaoee8fb302016-01-06 13:42:12 +00004031 llvm::Function *Fn = nullptr;
4032 llvm::Constant *FnID = nullptr;
Samuel Antaobed3c462015-10-02 16:14:20 +00004033
Samuel Antaobed3c462015-10-02 16:14:20 +00004034 const Expr *IfCond = nullptr;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00004035 // Check for the at most one if clause associated with the target region.
4036 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
4037 if (C->getNameModifier() == OMPD_unknown ||
4038 C->getNameModifier() == OMPD_target) {
4039 IfCond = C->getCondition();
4040 break;
4041 }
Samuel Antaobed3c462015-10-02 16:14:20 +00004042 }
4043
4044 // Check if we have any device clause associated with the directive.
4045 const Expr *Device = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004046 if (auto *C = S.getSingleClause<OMPDeviceClause>())
Samuel Antaobed3c462015-10-02 16:14:20 +00004047 Device = C->getDevice();
Samuel Antaobed3c462015-10-02 16:14:20 +00004048
Samuel Antaoee8fb302016-01-06 13:42:12 +00004049 // Check if we have an if clause whose conditional always evaluates to false
4050 // or if we do not have any targets specified. If so the target region is not
4051 // an offload entry point.
4052 bool IsOffloadEntry = true;
4053 if (IfCond) {
4054 bool Val;
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004055 if (CGF.ConstantFoldsToSimpleInteger(IfCond, Val) && !Val)
Samuel Antaoee8fb302016-01-06 13:42:12 +00004056 IsOffloadEntry = false;
4057 }
4058 if (CGM.getLangOpts().OMPTargetTriples.empty())
4059 IsOffloadEntry = false;
4060
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004061 assert(CGF.CurFuncDecl && "No parent declaration for target region!");
Samuel Antaoee8fb302016-01-06 13:42:12 +00004062 StringRef ParentName;
4063 // In case we have Ctors/Dtors we use the complete type variant to produce
4064 // the mangling of the device outlined kernel.
Alexey Bataevddf3db92018-04-13 17:31:06 +00004065 if (const auto *D = dyn_cast<CXXConstructorDecl>(CGF.CurFuncDecl))
Samuel Antaoee8fb302016-01-06 13:42:12 +00004066 ParentName = CGM.getMangledName(GlobalDecl(D, Ctor_Complete));
Alexey Bataevddf3db92018-04-13 17:31:06 +00004067 else if (const auto *D = dyn_cast<CXXDestructorDecl>(CGF.CurFuncDecl))
Samuel Antaoee8fb302016-01-06 13:42:12 +00004068 ParentName = CGM.getMangledName(GlobalDecl(D, Dtor_Complete));
4069 else
4070 ParentName =
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004071 CGM.getMangledName(GlobalDecl(cast<FunctionDecl>(CGF.CurFuncDecl)));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004072
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004073 // Emit target region as a standalone region.
4074 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(S, ParentName, Fn, FnID,
4075 IsOffloadEntry, CodeGen);
Alexey Bataev8451efa2018-01-15 19:06:12 +00004076 OMPLexicalScope Scope(CGF, S, OMPD_task);
Alexey Bataev7bb33532019-01-07 21:30:43 +00004077 auto &&SizeEmitter = [](CodeGenFunction &CGF, const OMPLoopDirective &D) {
4078 OMPLoopScope(CGF, D);
4079 // Emit calculation of the iterations count.
4080 llvm::Value *NumIterations = CGF.EmitScalarExpr(D.getNumIterations());
4081 NumIterations = CGF.Builder.CreateIntCast(NumIterations, CGF.Int64Ty,
4082 /*IsSigned=*/false);
4083 return NumIterations;
4084 };
Alexey Bataev4920e1a2019-01-30 20:49:52 +00004085 if (IsOffloadEntry)
4086 CGM.getOpenMPRuntime().emitTargetNumIterationsCall(CGF, S, Device,
4087 SizeEmitter);
Alexey Bataev8451efa2018-01-15 19:06:12 +00004088 CGM.getOpenMPRuntime().emitTargetCall(CGF, S, Fn, FnID, IfCond, Device);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004089}
4090
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004091static void emitTargetRegion(CodeGenFunction &CGF, const OMPTargetDirective &S,
4092 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004093 Action.Enter(CGF);
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004094 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
4095 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
4096 CGF.EmitOMPPrivateClause(S, PrivateScope);
4097 (void)PrivateScope.Privatize();
Alexey Bataev60705422018-10-30 15:50:12 +00004098 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
4099 CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004100
Alexey Bataev475a7442018-01-12 19:39:11 +00004101 CGF.EmitStmt(S.getCapturedStmt(OMPD_target)->getCapturedStmt());
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004102}
4103
4104void CodeGenFunction::EmitOMPTargetDeviceFunction(CodeGenModule &CGM,
4105 StringRef ParentName,
4106 const OMPTargetDirective &S) {
4107 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4108 emitTargetRegion(CGF, S, Action);
4109 };
4110 llvm::Function *Fn;
4111 llvm::Constant *Addr;
4112 // Emit target region as a standalone region.
4113 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4114 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4115 assert(Fn && Addr && "Target device function emission failed.");
4116}
4117
4118void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) {
4119 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4120 emitTargetRegion(CGF, S, Action);
4121 };
4122 emitCommonOMPTargetDirective(*this, S, CodeGen);
4123}
4124
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004125static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF,
4126 const OMPExecutableDirective &S,
4127 OpenMPDirectiveKind InnermostKind,
4128 const RegionCodeGenTy &CodeGen) {
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004129 const CapturedStmt *CS = S.getCapturedStmt(OMPD_teams);
James Y Knight9871db02019-02-05 16:42:33 +00004130 llvm::Function *OutlinedFn =
Alexey Bataevddf3db92018-04-13 17:31:06 +00004131 CGF.CGM.getOpenMPRuntime().emitTeamsOutlinedFunction(
4132 S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
Samuel Antaob68e2db2016-03-03 16:20:23 +00004133
Alexey Bataevddf3db92018-04-13 17:31:06 +00004134 const auto *NT = S.getSingleClause<OMPNumTeamsClause>();
4135 const auto *TL = S.getSingleClause<OMPThreadLimitClause>();
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004136 if (NT || TL) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00004137 const Expr *NumTeams = NT ? NT->getNumTeams() : nullptr;
4138 const Expr *ThreadLimit = TL ? TL->getThreadLimit() : nullptr;
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004139
Carlo Bertollic6872252016-04-04 15:55:02 +00004140 CGF.CGM.getOpenMPRuntime().emitNumTeamsClause(CGF, NumTeams, ThreadLimit,
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004141 S.getBeginLoc());
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004142 }
4143
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00004144 OMPTeamsScope Scope(CGF, S);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00004145 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
4146 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004147 CGF.CGM.getOpenMPRuntime().emitTeamsCall(CGF, S, S.getBeginLoc(), OutlinedFn,
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004148 CapturedVars);
4149}
4150
4151void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &S) {
Kelvin Li51336dd2016-12-15 17:55:32 +00004152 // Emit teams region as a standalone region.
Alexey Bataevc99042b2018-03-15 18:10:54 +00004153 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004154 Action.Enter(CGF);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004155 OMPPrivateScope PrivateScope(CGF);
Carlo Bertolli6ad7b5a2016-03-03 22:09:40 +00004156 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
4157 CGF.EmitOMPPrivateClause(S, PrivateScope);
Arpith Chacko Jacobfc711b12017-02-16 16:48:49 +00004158 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004159 (void)PrivateScope.Privatize();
Alexey Bataev475a7442018-01-12 19:39:11 +00004160 CGF.EmitStmt(S.getCapturedStmt(OMPD_teams)->getCapturedStmt());
Arpith Chacko Jacobfc711b12017-02-16 16:48:49 +00004161 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004162 };
Alexey Bataev2139ed62017-11-16 18:20:21 +00004163 emitCommonOMPTeamsDirective(*this, S, OMPD_distribute, CodeGen);
Alexey Bataevddf3db92018-04-13 17:31:06 +00004164 emitPostUpdateForReductionClause(*this, S,
4165 [](CodeGenFunction &) { return nullptr; });
Alexey Bataev13314bf2014-10-09 04:18:56 +00004166}
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004167
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00004168static void emitTargetTeamsRegion(CodeGenFunction &CGF, PrePostActionTy &Action,
4169 const OMPTargetTeamsDirective &S) {
4170 auto *CS = S.getCapturedStmt(OMPD_teams);
4171 Action.Enter(CGF);
Alexey Bataevf9fc42e2017-11-22 14:25:55 +00004172 // Emit teams region as a standalone region.
4173 auto &&CodeGen = [&S, CS](CodeGenFunction &CGF, PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004174 Action.Enter(CGF);
Alexey Bataevf9fc42e2017-11-22 14:25:55 +00004175 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
4176 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
4177 CGF.EmitOMPPrivateClause(S, PrivateScope);
4178 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4179 (void)PrivateScope.Privatize();
Alexey Bataev60705422018-10-30 15:50:12 +00004180 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
4181 CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00004182 CGF.EmitStmt(CS->getCapturedStmt());
Alexey Bataevf9fc42e2017-11-22 14:25:55 +00004183 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00004184 };
4185 emitCommonOMPTeamsDirective(CGF, S, OMPD_teams, CodeGen);
Alexey Bataevddf3db92018-04-13 17:31:06 +00004186 emitPostUpdateForReductionClause(CGF, S,
4187 [](CodeGenFunction &) { return nullptr; });
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00004188}
4189
4190void CodeGenFunction::EmitOMPTargetTeamsDeviceFunction(
4191 CodeGenModule &CGM, StringRef ParentName,
4192 const OMPTargetTeamsDirective &S) {
4193 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4194 emitTargetTeamsRegion(CGF, Action, S);
4195 };
4196 llvm::Function *Fn;
4197 llvm::Constant *Addr;
4198 // Emit target region as a standalone region.
4199 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4200 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4201 assert(Fn && Addr && "Target device function emission failed.");
4202}
4203
4204void CodeGenFunction::EmitOMPTargetTeamsDirective(
4205 const OMPTargetTeamsDirective &S) {
4206 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4207 emitTargetTeamsRegion(CGF, Action, S);
4208 };
4209 emitCommonOMPTargetDirective(*this, S, CodeGen);
4210}
4211
Alexey Bataevdfa430f2017-12-08 15:03:50 +00004212static void
4213emitTargetTeamsDistributeRegion(CodeGenFunction &CGF, PrePostActionTy &Action,
4214 const OMPTargetTeamsDistributeDirective &S) {
4215 Action.Enter(CGF);
4216 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4217 CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
4218 };
4219
4220 // Emit teams region as a standalone region.
4221 auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00004222 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004223 Action.Enter(CGF);
Alexey Bataevdfa430f2017-12-08 15:03:50 +00004224 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
4225 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4226 (void)PrivateScope.Privatize();
4227 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
4228 CodeGenDistribute);
4229 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4230 };
4231 emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute, CodeGen);
4232 emitPostUpdateForReductionClause(CGF, S,
4233 [](CodeGenFunction &) { return nullptr; });
4234}
4235
4236void CodeGenFunction::EmitOMPTargetTeamsDistributeDeviceFunction(
4237 CodeGenModule &CGM, StringRef ParentName,
4238 const OMPTargetTeamsDistributeDirective &S) {
4239 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4240 emitTargetTeamsDistributeRegion(CGF, Action, S);
4241 };
4242 llvm::Function *Fn;
4243 llvm::Constant *Addr;
4244 // Emit target region as a standalone region.
4245 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4246 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4247 assert(Fn && Addr && "Target device function emission failed.");
4248}
4249
4250void CodeGenFunction::EmitOMPTargetTeamsDistributeDirective(
4251 const OMPTargetTeamsDistributeDirective &S) {
4252 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4253 emitTargetTeamsDistributeRegion(CGF, Action, S);
4254 };
4255 emitCommonOMPTargetDirective(*this, S, CodeGen);
4256}
4257
Alexey Bataevfbe17fb2017-12-13 19:45:06 +00004258static void emitTargetTeamsDistributeSimdRegion(
4259 CodeGenFunction &CGF, PrePostActionTy &Action,
4260 const OMPTargetTeamsDistributeSimdDirective &S) {
4261 Action.Enter(CGF);
4262 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4263 CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
4264 };
4265
4266 // Emit teams region as a standalone region.
4267 auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00004268 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004269 Action.Enter(CGF);
Alexey Bataevfbe17fb2017-12-13 19:45:06 +00004270 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
4271 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4272 (void)PrivateScope.Privatize();
4273 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
4274 CodeGenDistribute);
4275 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4276 };
4277 emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute_simd, CodeGen);
4278 emitPostUpdateForReductionClause(CGF, S,
4279 [](CodeGenFunction &) { return nullptr; });
4280}
4281
4282void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDeviceFunction(
4283 CodeGenModule &CGM, StringRef ParentName,
4284 const OMPTargetTeamsDistributeSimdDirective &S) {
4285 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4286 emitTargetTeamsDistributeSimdRegion(CGF, Action, S);
4287 };
4288 llvm::Function *Fn;
4289 llvm::Constant *Addr;
4290 // Emit target region as a standalone region.
4291 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4292 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4293 assert(Fn && Addr && "Target device function emission failed.");
4294}
4295
4296void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDirective(
4297 const OMPTargetTeamsDistributeSimdDirective &S) {
4298 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4299 emitTargetTeamsDistributeSimdRegion(CGF, Action, S);
4300 };
4301 emitCommonOMPTargetDirective(*this, S, CodeGen);
4302}
4303
Carlo Bertolliba1487b2017-10-04 14:12:09 +00004304void CodeGenFunction::EmitOMPTeamsDistributeDirective(
4305 const OMPTeamsDistributeDirective &S) {
4306
4307 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4308 CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
4309 };
4310
4311 // Emit teams region as a standalone region.
4312 auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00004313 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004314 Action.Enter(CGF);
Carlo Bertolliba1487b2017-10-04 14:12:09 +00004315 OMPPrivateScope PrivateScope(CGF);
4316 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4317 (void)PrivateScope.Privatize();
4318 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
4319 CodeGenDistribute);
4320 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4321 };
Alexey Bataev95c6dd42017-11-29 15:14:16 +00004322 emitCommonOMPTeamsDirective(*this, S, OMPD_distribute, CodeGen);
Carlo Bertolliba1487b2017-10-04 14:12:09 +00004323 emitPostUpdateForReductionClause(*this, S,
4324 [](CodeGenFunction &) { return nullptr; });
4325}
4326
Alexey Bataev999277a2017-12-06 14:31:09 +00004327void CodeGenFunction::EmitOMPTeamsDistributeSimdDirective(
4328 const OMPTeamsDistributeSimdDirective &S) {
4329 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4330 CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
4331 };
4332
4333 // Emit teams region as a standalone region.
4334 auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00004335 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004336 Action.Enter(CGF);
Alexey Bataev999277a2017-12-06 14:31:09 +00004337 OMPPrivateScope PrivateScope(CGF);
4338 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4339 (void)PrivateScope.Privatize();
4340 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_simd,
4341 CodeGenDistribute);
4342 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4343 };
4344 emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_simd, CodeGen);
4345 emitPostUpdateForReductionClause(*this, S,
4346 [](CodeGenFunction &) { return nullptr; });
4347}
4348
Carlo Bertolli62fae152017-11-20 20:46:39 +00004349void CodeGenFunction::EmitOMPTeamsDistributeParallelForDirective(
4350 const OMPTeamsDistributeParallelForDirective &S) {
4351 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4352 CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
4353 S.getDistInc());
4354 };
4355
4356 // Emit teams region as a standalone region.
4357 auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00004358 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004359 Action.Enter(CGF);
Carlo Bertolli62fae152017-11-20 20:46:39 +00004360 OMPPrivateScope PrivateScope(CGF);
4361 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4362 (void)PrivateScope.Privatize();
Alexey Bataev10a54312017-11-27 16:54:08 +00004363 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
4364 CodeGenDistribute);
Carlo Bertolli62fae152017-11-20 20:46:39 +00004365 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4366 };
4367 emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_parallel_for, CodeGen);
4368 emitPostUpdateForReductionClause(*this, S,
4369 [](CodeGenFunction &) { return nullptr; });
4370}
4371
Carlo Bertolli56a2aa42017-12-04 20:57:19 +00004372void CodeGenFunction::EmitOMPTeamsDistributeParallelForSimdDirective(
4373 const OMPTeamsDistributeParallelForSimdDirective &S) {
4374 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4375 CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
4376 S.getDistInc());
4377 };
4378
4379 // Emit teams region as a standalone region.
4380 auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00004381 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004382 Action.Enter(CGF);
Carlo Bertolli56a2aa42017-12-04 20:57:19 +00004383 OMPPrivateScope PrivateScope(CGF);
4384 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4385 (void)PrivateScope.Privatize();
4386 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
4387 CGF, OMPD_distribute, CodeGenDistribute, /*HasCancel=*/false);
4388 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4389 };
4390 emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_parallel_for, CodeGen);
4391 emitPostUpdateForReductionClause(*this, S,
4392 [](CodeGenFunction &) { return nullptr; });
4393}
4394
Carlo Bertolli52978c32018-01-03 21:12:44 +00004395static void emitTargetTeamsDistributeParallelForRegion(
4396 CodeGenFunction &CGF, const OMPTargetTeamsDistributeParallelForDirective &S,
4397 PrePostActionTy &Action) {
Carlo Bertolli79712092018-02-28 20:48:35 +00004398 Action.Enter(CGF);
Carlo Bertolli52978c32018-01-03 21:12:44 +00004399 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4400 CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
4401 S.getDistInc());
4402 };
4403
4404 // Emit teams region as a standalone region.
4405 auto &&CodeGenTeams = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00004406 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004407 Action.Enter(CGF);
Carlo Bertolli52978c32018-01-03 21:12:44 +00004408 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
4409 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4410 (void)PrivateScope.Privatize();
4411 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
4412 CGF, OMPD_distribute, CodeGenDistribute, /*HasCancel=*/false);
4413 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4414 };
4415
4416 emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute_parallel_for,
4417 CodeGenTeams);
4418 emitPostUpdateForReductionClause(CGF, S,
4419 [](CodeGenFunction &) { return nullptr; });
4420}
4421
4422void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDeviceFunction(
4423 CodeGenModule &CGM, StringRef ParentName,
4424 const OMPTargetTeamsDistributeParallelForDirective &S) {
4425 // Emit SPMD target teams distribute parallel for region as a standalone
4426 // region.
4427 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4428 emitTargetTeamsDistributeParallelForRegion(CGF, S, Action);
4429 };
4430 llvm::Function *Fn;
4431 llvm::Constant *Addr;
4432 // Emit target region as a standalone region.
4433 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4434 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4435 assert(Fn && Addr && "Target device function emission failed.");
4436}
4437
4438void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDirective(
4439 const OMPTargetTeamsDistributeParallelForDirective &S) {
4440 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4441 emitTargetTeamsDistributeParallelForRegion(CGF, S, Action);
4442 };
4443 emitCommonOMPTargetDirective(*this, S, CodeGen);
4444}
4445
Alexey Bataev647dd842018-01-15 20:59:40 +00004446static void emitTargetTeamsDistributeParallelForSimdRegion(
4447 CodeGenFunction &CGF,
4448 const OMPTargetTeamsDistributeParallelForSimdDirective &S,
4449 PrePostActionTy &Action) {
Carlo Bertolli79712092018-02-28 20:48:35 +00004450 Action.Enter(CGF);
Alexey Bataev647dd842018-01-15 20:59:40 +00004451 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4452 CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
4453 S.getDistInc());
4454 };
4455
4456 // Emit teams region as a standalone region.
4457 auto &&CodeGenTeams = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00004458 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004459 Action.Enter(CGF);
Alexey Bataev647dd842018-01-15 20:59:40 +00004460 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
4461 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4462 (void)PrivateScope.Privatize();
4463 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
4464 CGF, OMPD_distribute, CodeGenDistribute, /*HasCancel=*/false);
4465 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4466 };
4467
4468 emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute_parallel_for_simd,
4469 CodeGenTeams);
4470 emitPostUpdateForReductionClause(CGF, S,
4471 [](CodeGenFunction &) { return nullptr; });
4472}
4473
4474void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(
4475 CodeGenModule &CGM, StringRef ParentName,
4476 const OMPTargetTeamsDistributeParallelForSimdDirective &S) {
4477 // Emit SPMD target teams distribute parallel for simd region as a standalone
4478 // region.
4479 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4480 emitTargetTeamsDistributeParallelForSimdRegion(CGF, S, Action);
4481 };
4482 llvm::Function *Fn;
4483 llvm::Constant *Addr;
4484 // Emit target region as a standalone region.
4485 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4486 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4487 assert(Fn && Addr && "Target device function emission failed.");
4488}
4489
4490void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDirective(
4491 const OMPTargetTeamsDistributeParallelForSimdDirective &S) {
4492 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4493 emitTargetTeamsDistributeParallelForSimdRegion(CGF, S, Action);
4494 };
4495 emitCommonOMPTargetDirective(*this, S, CodeGen);
4496}
4497
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004498void CodeGenFunction::EmitOMPCancellationPointDirective(
4499 const OMPCancellationPointDirective &S) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004500 CGM.getOpenMPRuntime().emitCancellationPointCall(*this, S.getBeginLoc(),
Alexey Bataev0f34da12015-07-02 04:17:07 +00004501 S.getCancelRegion());
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004502}
4503
Alexey Bataev80909872015-07-02 11:25:17 +00004504void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) {
Alexey Bataev87933c72015-09-18 08:07:34 +00004505 const Expr *IfCond = nullptr;
4506 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
4507 if (C->getNameModifier() == OMPD_unknown ||
4508 C->getNameModifier() == OMPD_cancel) {
4509 IfCond = C->getCondition();
4510 break;
4511 }
4512 }
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004513 CGM.getOpenMPRuntime().emitCancelCall(*this, S.getBeginLoc(), IfCond,
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00004514 S.getCancelRegion());
Alexey Bataev80909872015-07-02 11:25:17 +00004515}
4516
Alexey Bataev81c7ea02015-07-03 09:56:58 +00004517CodeGenFunction::JumpDest
4518CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) {
Alexey Bataev957d8562016-11-17 15:12:05 +00004519 if (Kind == OMPD_parallel || Kind == OMPD_task ||
4520 Kind == OMPD_target_parallel)
Alexey Bataev81c7ea02015-07-03 09:56:58 +00004521 return ReturnBlock;
Alexey Bataev25e5b442015-09-15 12:52:43 +00004522 assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
Alexey Bataev957d8562016-11-17 15:12:05 +00004523 Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for ||
4524 Kind == OMPD_distribute_parallel_for ||
Alexey Bataevdcb4b8fb2017-11-22 20:19:50 +00004525 Kind == OMPD_target_parallel_for ||
Alexey Bataev16e79882017-11-22 21:12:03 +00004526 Kind == OMPD_teams_distribute_parallel_for ||
4527 Kind == OMPD_target_teams_distribute_parallel_for);
Alexey Bataev957d8562016-11-17 15:12:05 +00004528 return OMPCancelStack.getExitBlock();
Alexey Bataev81c7ea02015-07-03 09:56:58 +00004529}
Michael Wong65f367f2015-07-21 13:44:28 +00004530
Samuel Antaocc10b852016-07-28 14:23:26 +00004531void CodeGenFunction::EmitOMPUseDevicePtrClause(
4532 const OMPClause &NC, OMPPrivateScope &PrivateScope,
4533 const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap) {
4534 const auto &C = cast<OMPUseDevicePtrClause>(NC);
4535 auto OrigVarIt = C.varlist_begin();
4536 auto InitIt = C.inits().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00004537 for (const Expr *PvtVarIt : C.private_copies()) {
4538 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*OrigVarIt)->getDecl());
4539 const auto *InitVD = cast<VarDecl>(cast<DeclRefExpr>(*InitIt)->getDecl());
4540 const auto *PvtVD = cast<VarDecl>(cast<DeclRefExpr>(PvtVarIt)->getDecl());
Samuel Antaocc10b852016-07-28 14:23:26 +00004541
4542 // In order to identify the right initializer we need to match the
4543 // declaration used by the mapping logic. In some cases we may get
4544 // OMPCapturedExprDecl that refers to the original declaration.
4545 const ValueDecl *MatchingVD = OrigVD;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004546 if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) {
Samuel Antaocc10b852016-07-28 14:23:26 +00004547 // OMPCapturedExprDecl are used to privative fields of the current
4548 // structure.
Alexey Bataevddf3db92018-04-13 17:31:06 +00004549 const auto *ME = cast<MemberExpr>(OED->getInit());
Samuel Antaocc10b852016-07-28 14:23:26 +00004550 assert(isa<CXXThisExpr>(ME->getBase()) &&
4551 "Base should be the current struct!");
4552 MatchingVD = ME->getMemberDecl();
4553 }
4554
4555 // If we don't have information about the current list item, move on to
4556 // the next one.
4557 auto InitAddrIt = CaptureDeviceAddrMap.find(MatchingVD);
4558 if (InitAddrIt == CaptureDeviceAddrMap.end())
4559 continue;
4560
Alexey Bataevddf3db92018-04-13 17:31:06 +00004561 bool IsRegistered = PrivateScope.addPrivate(OrigVD, [this, OrigVD,
4562 InitAddrIt, InitVD,
4563 PvtVD]() {
Samuel Antaocc10b852016-07-28 14:23:26 +00004564 // Initialize the temporary initialization variable with the address we
4565 // get from the runtime library. We have to cast the source address
4566 // because it is always a void *. References are materialized in the
4567 // privatization scope, so the initialization here disregards the fact
4568 // the original variable is a reference.
4569 QualType AddrQTy =
4570 getContext().getPointerType(OrigVD->getType().getNonReferenceType());
4571 llvm::Type *AddrTy = ConvertTypeForMem(AddrQTy);
4572 Address InitAddr = Builder.CreateBitCast(InitAddrIt->second, AddrTy);
4573 setAddrOfLocalVar(InitVD, InitAddr);
4574
4575 // Emit private declaration, it will be initialized by the value we
4576 // declaration we just added to the local declarations map.
4577 EmitDecl(*PvtVD);
4578
4579 // The initialization variables reached its purpose in the emission
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00004580 // of the previous declaration, so we don't need it anymore.
Samuel Antaocc10b852016-07-28 14:23:26 +00004581 LocalDeclMap.erase(InitVD);
4582
4583 // Return the address of the private variable.
4584 return GetAddrOfLocalVar(PvtVD);
4585 });
4586 assert(IsRegistered && "firstprivate var already registered as private");
4587 // Silence the warning about unused variable.
4588 (void)IsRegistered;
4589
4590 ++OrigVarIt;
4591 ++InitIt;
4592 }
4593}
4594
Michael Wong65f367f2015-07-21 13:44:28 +00004595// Generate the instructions for '#pragma omp target data' directive.
4596void CodeGenFunction::EmitOMPTargetDataDirective(
4597 const OMPTargetDataDirective &S) {
Samuel Antaocc10b852016-07-28 14:23:26 +00004598 CGOpenMPRuntime::TargetDataInfo Info(/*RequiresDevicePointerInfo=*/true);
4599
4600 // Create a pre/post action to signal the privatization of the device pointer.
4601 // This action can be replaced by the OpenMP runtime code generation to
4602 // deactivate privatization.
4603 bool PrivatizeDevicePointers = false;
4604 class DevicePointerPrivActionTy : public PrePostActionTy {
4605 bool &PrivatizeDevicePointers;
4606
4607 public:
4608 explicit DevicePointerPrivActionTy(bool &PrivatizeDevicePointers)
4609 : PrePostActionTy(), PrivatizeDevicePointers(PrivatizeDevicePointers) {}
4610 void Enter(CodeGenFunction &CGF) override {
4611 PrivatizeDevicePointers = true;
4612 }
Samuel Antaodf158d52016-04-27 22:58:19 +00004613 };
Samuel Antaocc10b852016-07-28 14:23:26 +00004614 DevicePointerPrivActionTy PrivAction(PrivatizeDevicePointers);
4615
4616 auto &&CodeGen = [&S, &Info, &PrivatizeDevicePointers](
Alexey Bataev475a7442018-01-12 19:39:11 +00004617 CodeGenFunction &CGF, PrePostActionTy &Action) {
Samuel Antaocc10b852016-07-28 14:23:26 +00004618 auto &&InnermostCodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataev475a7442018-01-12 19:39:11 +00004619 CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
Samuel Antaocc10b852016-07-28 14:23:26 +00004620 };
4621
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00004622 // Codegen that selects whether to generate the privatization code or not.
Samuel Antaocc10b852016-07-28 14:23:26 +00004623 auto &&PrivCodeGen = [&S, &Info, &PrivatizeDevicePointers,
4624 &InnermostCodeGen](CodeGenFunction &CGF,
4625 PrePostActionTy &Action) {
4626 RegionCodeGenTy RCG(InnermostCodeGen);
4627 PrivatizeDevicePointers = false;
4628
4629 // Call the pre-action to change the status of PrivatizeDevicePointers if
4630 // needed.
4631 Action.Enter(CGF);
4632
4633 if (PrivatizeDevicePointers) {
4634 OMPPrivateScope PrivateScope(CGF);
4635 // Emit all instances of the use_device_ptr clause.
4636 for (const auto *C : S.getClausesOfKind<OMPUseDevicePtrClause>())
4637 CGF.EmitOMPUseDevicePtrClause(*C, PrivateScope,
4638 Info.CaptureDeviceAddrMap);
4639 (void)PrivateScope.Privatize();
4640 RCG(CGF);
Alexey Bataevddf3db92018-04-13 17:31:06 +00004641 } else {
Samuel Antaocc10b852016-07-28 14:23:26 +00004642 RCG(CGF);
Alexey Bataevddf3db92018-04-13 17:31:06 +00004643 }
Samuel Antaocc10b852016-07-28 14:23:26 +00004644 };
4645
4646 // Forward the provided action to the privatization codegen.
4647 RegionCodeGenTy PrivRCG(PrivCodeGen);
4648 PrivRCG.setAction(Action);
4649
4650 // Notwithstanding the body of the region is emitted as inlined directive,
4651 // we don't use an inline scope as changes in the references inside the
4652 // region are expected to be visible outside, so we do not privative them.
4653 OMPLexicalScope Scope(CGF, S);
4654 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_target_data,
4655 PrivRCG);
4656 };
4657
4658 RegionCodeGenTy RCG(CodeGen);
Samuel Antaodf158d52016-04-27 22:58:19 +00004659
4660 // If we don't have target devices, don't bother emitting the data mapping
4661 // code.
4662 if (CGM.getLangOpts().OMPTargetTriples.empty()) {
Samuel Antaocc10b852016-07-28 14:23:26 +00004663 RCG(*this);
Samuel Antaodf158d52016-04-27 22:58:19 +00004664 return;
4665 }
4666
4667 // Check if we have any if clause associated with the directive.
4668 const Expr *IfCond = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004669 if (const auto *C = S.getSingleClause<OMPIfClause>())
Samuel Antaodf158d52016-04-27 22:58:19 +00004670 IfCond = C->getCondition();
4671
4672 // Check if we have any device clause associated with the directive.
4673 const Expr *Device = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004674 if (const auto *C = S.getSingleClause<OMPDeviceClause>())
Samuel Antaodf158d52016-04-27 22:58:19 +00004675 Device = C->getDevice();
4676
Samuel Antaocc10b852016-07-28 14:23:26 +00004677 // Set the action to signal privatization of device pointers.
4678 RCG.setAction(PrivAction);
4679
4680 // Emit region code.
4681 CGM.getOpenMPRuntime().emitTargetDataCalls(*this, S, IfCond, Device, RCG,
4682 Info);
Michael Wong65f367f2015-07-21 13:44:28 +00004683}
Alexey Bataev49f6e782015-12-01 04:18:41 +00004684
Samuel Antaodf67fc42016-01-19 19:15:56 +00004685void CodeGenFunction::EmitOMPTargetEnterDataDirective(
4686 const OMPTargetEnterDataDirective &S) {
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00004687 // If we don't have target devices, don't bother emitting the data mapping
4688 // code.
4689 if (CGM.getLangOpts().OMPTargetTriples.empty())
4690 return;
4691
4692 // Check if we have any if clause associated with the directive.
4693 const Expr *IfCond = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004694 if (const auto *C = S.getSingleClause<OMPIfClause>())
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00004695 IfCond = C->getCondition();
4696
4697 // Check if we have any device clause associated with the directive.
4698 const Expr *Device = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004699 if (const auto *C = S.getSingleClause<OMPDeviceClause>())
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00004700 Device = C->getDevice();
4701
Alexey Bataev475a7442018-01-12 19:39:11 +00004702 OMPLexicalScope Scope(*this, S, OMPD_task);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00004703 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
Samuel Antaodf67fc42016-01-19 19:15:56 +00004704}
4705
Samuel Antao72590762016-01-19 20:04:50 +00004706void CodeGenFunction::EmitOMPTargetExitDataDirective(
4707 const OMPTargetExitDataDirective &S) {
Samuel Antao8dd66282016-04-27 23:14:30 +00004708 // If we don't have target devices, don't bother emitting the data mapping
4709 // code.
4710 if (CGM.getLangOpts().OMPTargetTriples.empty())
4711 return;
4712
4713 // Check if we have any if clause associated with the directive.
4714 const Expr *IfCond = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004715 if (const auto *C = S.getSingleClause<OMPIfClause>())
Samuel Antao8dd66282016-04-27 23:14:30 +00004716 IfCond = C->getCondition();
4717
4718 // Check if we have any device clause associated with the directive.
4719 const Expr *Device = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004720 if (const auto *C = S.getSingleClause<OMPDeviceClause>())
Samuel Antao8dd66282016-04-27 23:14:30 +00004721 Device = C->getDevice();
4722
Alexey Bataev475a7442018-01-12 19:39:11 +00004723 OMPLexicalScope Scope(*this, S, OMPD_task);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00004724 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
Samuel Antao72590762016-01-19 20:04:50 +00004725}
4726
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004727static void emitTargetParallelRegion(CodeGenFunction &CGF,
4728 const OMPTargetParallelDirective &S,
4729 PrePostActionTy &Action) {
4730 // Get the captured statement associated with the 'parallel' region.
Alexey Bataevddf3db92018-04-13 17:31:06 +00004731 const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel);
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004732 Action.Enter(CGF);
Alexey Bataevc99042b2018-03-15 18:10:54 +00004733 auto &&CodeGen = [&S, CS](CodeGenFunction &CGF, PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004734 Action.Enter(CGF);
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00004735 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
4736 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
4737 CGF.EmitOMPPrivateClause(S, PrivateScope);
4738 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4739 (void)PrivateScope.Privatize();
Alexey Bataev60705422018-10-30 15:50:12 +00004740 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
4741 CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004742 // TODO: Add support for clauses.
4743 CGF.EmitStmt(CS->getCapturedStmt());
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00004744 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004745 };
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00004746 emitCommonOMPParallelDirective(CGF, S, OMPD_parallel, CodeGen,
4747 emitEmptyBoundParameters);
Alexey Bataevddf3db92018-04-13 17:31:06 +00004748 emitPostUpdateForReductionClause(CGF, S,
4749 [](CodeGenFunction &) { return nullptr; });
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004750}
4751
4752void CodeGenFunction::EmitOMPTargetParallelDeviceFunction(
4753 CodeGenModule &CGM, StringRef ParentName,
4754 const OMPTargetParallelDirective &S) {
4755 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4756 emitTargetParallelRegion(CGF, S, Action);
4757 };
4758 llvm::Function *Fn;
4759 llvm::Constant *Addr;
4760 // Emit target region as a standalone region.
4761 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4762 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4763 assert(Fn && Addr && "Target device function emission failed.");
4764}
4765
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004766void CodeGenFunction::EmitOMPTargetParallelDirective(
4767 const OMPTargetParallelDirective &S) {
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004768 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4769 emitTargetParallelRegion(CGF, S, Action);
4770 };
4771 emitCommonOMPTargetDirective(*this, S, CodeGen);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004772}
4773
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00004774static void emitTargetParallelForRegion(CodeGenFunction &CGF,
4775 const OMPTargetParallelForDirective &S,
4776 PrePostActionTy &Action) {
4777 Action.Enter(CGF);
4778 // Emit directive as a combined directive that consists of two implicit
4779 // directives: 'parallel' with 'for' directive.
Alexey Bataevc99042b2018-03-15 18:10:54 +00004780 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4781 Action.Enter(CGF);
Alexey Bataev2139ed62017-11-16 18:20:21 +00004782 CodeGenFunction::OMPCancelStackRAII CancelRegion(
4783 CGF, OMPD_target_parallel_for, S.hasCancel());
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00004784 CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds,
4785 emitDispatchForLoopBounds);
4786 };
4787 emitCommonOMPParallelDirective(CGF, S, OMPD_for, CodeGen,
4788 emitEmptyBoundParameters);
4789}
4790
4791void CodeGenFunction::EmitOMPTargetParallelForDeviceFunction(
4792 CodeGenModule &CGM, StringRef ParentName,
4793 const OMPTargetParallelForDirective &S) {
4794 // Emit SPMD target parallel for region as a standalone region.
4795 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4796 emitTargetParallelForRegion(CGF, S, Action);
4797 };
4798 llvm::Function *Fn;
4799 llvm::Constant *Addr;
4800 // Emit target region as a standalone region.
4801 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4802 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4803 assert(Fn && Addr && "Target device function emission failed.");
4804}
4805
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004806void CodeGenFunction::EmitOMPTargetParallelForDirective(
4807 const OMPTargetParallelForDirective &S) {
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00004808 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4809 emitTargetParallelForRegion(CGF, S, Action);
4810 };
4811 emitCommonOMPTargetDirective(*this, S, CodeGen);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004812}
4813
Alexey Bataev5d7edca2017-11-09 17:32:15 +00004814static void
4815emitTargetParallelForSimdRegion(CodeGenFunction &CGF,
4816 const OMPTargetParallelForSimdDirective &S,
4817 PrePostActionTy &Action) {
4818 Action.Enter(CGF);
4819 // Emit directive as a combined directive that consists of two implicit
4820 // directives: 'parallel' with 'for' directive.
Alexey Bataevc99042b2018-03-15 18:10:54 +00004821 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4822 Action.Enter(CGF);
Alexey Bataev5d7edca2017-11-09 17:32:15 +00004823 CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds,
4824 emitDispatchForLoopBounds);
4825 };
4826 emitCommonOMPParallelDirective(CGF, S, OMPD_simd, CodeGen,
4827 emitEmptyBoundParameters);
4828}
4829
4830void CodeGenFunction::EmitOMPTargetParallelForSimdDeviceFunction(
4831 CodeGenModule &CGM, StringRef ParentName,
4832 const OMPTargetParallelForSimdDirective &S) {
4833 // Emit SPMD target parallel for region as a standalone region.
4834 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4835 emitTargetParallelForSimdRegion(CGF, S, Action);
4836 };
4837 llvm::Function *Fn;
4838 llvm::Constant *Addr;
4839 // Emit target region as a standalone region.
4840 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4841 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4842 assert(Fn && Addr && "Target device function emission failed.");
4843}
4844
4845void CodeGenFunction::EmitOMPTargetParallelForSimdDirective(
4846 const OMPTargetParallelForSimdDirective &S) {
4847 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4848 emitTargetParallelForSimdRegion(CGF, S, Action);
4849 };
4850 emitCommonOMPTargetDirective(*this, S, CodeGen);
4851}
4852
Alexey Bataev7292c292016-04-25 12:22:29 +00004853/// Emit a helper variable and return corresponding lvalue.
4854static void mapParam(CodeGenFunction &CGF, const DeclRefExpr *Helper,
4855 const ImplicitParamDecl *PVD,
4856 CodeGenFunction::OMPPrivateScope &Privates) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00004857 const auto *VDecl = cast<VarDecl>(Helper->getDecl());
4858 Privates.addPrivate(VDecl,
4859 [&CGF, PVD]() { return CGF.GetAddrOfLocalVar(PVD); });
Alexey Bataev7292c292016-04-25 12:22:29 +00004860}
4861
4862void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) {
4863 assert(isOpenMPTaskLoopDirective(S.getDirectiveKind()));
4864 // Emit outlined function for task construct.
Alexey Bataev475a7442018-01-12 19:39:11 +00004865 const CapturedStmt *CS = S.getCapturedStmt(OMPD_taskloop);
Alexey Bataevddf3db92018-04-13 17:31:06 +00004866 Address CapturedStruct = GenerateCapturedStmtArgument(*CS);
4867 QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
Alexey Bataev7292c292016-04-25 12:22:29 +00004868 const Expr *IfCond = nullptr;
4869 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
4870 if (C->getNameModifier() == OMPD_unknown ||
4871 C->getNameModifier() == OMPD_taskloop) {
4872 IfCond = C->getCondition();
4873 break;
4874 }
4875 }
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004876
4877 OMPTaskDataTy Data;
4878 // Check if taskloop must be emitted without taskgroup.
4879 Data.Nogroup = S.getSingleClause<OMPNogroupClause>();
Alexey Bataev7292c292016-04-25 12:22:29 +00004880 // TODO: Check if we should emit tied or untied task.
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004881 Data.Tied = true;
4882 // Set scheduling for taskloop
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00004883 if (const auto* Clause = S.getSingleClause<OMPGrainsizeClause>()) {
4884 // grainsize clause
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004885 Data.Schedule.setInt(/*IntVal=*/false);
4886 Data.Schedule.setPointer(EmitScalarExpr(Clause->getGrainsize()));
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00004887 } else if (const auto* Clause = S.getSingleClause<OMPNumTasksClause>()) {
4888 // num_tasks clause
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004889 Data.Schedule.setInt(/*IntVal=*/true);
4890 Data.Schedule.setPointer(EmitScalarExpr(Clause->getNumTasks()));
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00004891 }
Alexey Bataev7292c292016-04-25 12:22:29 +00004892
4893 auto &&BodyGen = [CS, &S](CodeGenFunction &CGF, PrePostActionTy &) {
4894 // if (PreCond) {
4895 // for (IV in 0..LastIteration) BODY;
4896 // <Final counter/linear vars updates>;
4897 // }
4898 //
4899
4900 // Emit: if (PreCond) - begin.
4901 // If the condition constant folds and can be elided, avoid emitting the
4902 // whole loop.
4903 bool CondConstant;
4904 llvm::BasicBlock *ContBlock = nullptr;
4905 OMPLoopScope PreInitScope(CGF, S);
4906 if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
4907 if (!CondConstant)
4908 return;
4909 } else {
Alexey Bataevddf3db92018-04-13 17:31:06 +00004910 llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("taskloop.if.then");
Alexey Bataev7292c292016-04-25 12:22:29 +00004911 ContBlock = CGF.createBasicBlock("taskloop.if.end");
4912 emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
4913 CGF.getProfileCount(&S));
4914 CGF.EmitBlock(ThenBlock);
4915 CGF.incrementProfileCounter(&S);
4916 }
4917
Alexey Bataev1e73ef32016-04-28 12:14:51 +00004918 if (isOpenMPSimdDirective(S.getDirectiveKind()))
4919 CGF.EmitOMPSimdInit(S);
4920
Alexey Bataev7292c292016-04-25 12:22:29 +00004921 OMPPrivateScope LoopScope(CGF);
4922 // Emit helper vars inits.
4923 enum { LowerBound = 5, UpperBound, Stride, LastIter };
4924 auto *I = CS->getCapturedDecl()->param_begin();
4925 auto *LBP = std::next(I, LowerBound);
4926 auto *UBP = std::next(I, UpperBound);
4927 auto *STP = std::next(I, Stride);
4928 auto *LIP = std::next(I, LastIter);
4929 mapParam(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()), *LBP,
4930 LoopScope);
4931 mapParam(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()), *UBP,
4932 LoopScope);
4933 mapParam(CGF, cast<DeclRefExpr>(S.getStrideVariable()), *STP, LoopScope);
4934 mapParam(CGF, cast<DeclRefExpr>(S.getIsLastIterVariable()), *LIP,
4935 LoopScope);
4936 CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
Alexey Bataevf93095a2016-05-05 08:46:22 +00004937 bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
Alexey Bataev7292c292016-04-25 12:22:29 +00004938 (void)LoopScope.Privatize();
4939 // Emit the loop iteration variable.
4940 const Expr *IVExpr = S.getIterationVariable();
Alexey Bataevddf3db92018-04-13 17:31:06 +00004941 const auto *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
Alexey Bataev7292c292016-04-25 12:22:29 +00004942 CGF.EmitVarDecl(*IVDecl);
4943 CGF.EmitIgnoredExpr(S.getInit());
4944
4945 // Emit the iterations count variable.
4946 // If it is not a variable, Sema decided to calculate iterations count on
4947 // each iteration (e.g., it is foldable into a constant).
Alexey Bataevddf3db92018-04-13 17:31:06 +00004948 if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
Alexey Bataev7292c292016-04-25 12:22:29 +00004949 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
4950 // Emit calculation of the iterations count.
4951 CGF.EmitIgnoredExpr(S.getCalcLastIteration());
4952 }
4953
4954 CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
4955 S.getInc(),
4956 [&S](CodeGenFunction &CGF) {
4957 CGF.EmitOMPLoopBody(S, JumpDest());
4958 CGF.EmitStopPoint(&S);
4959 },
4960 [](CodeGenFunction &) {});
4961 // Emit: if (PreCond) - end.
4962 if (ContBlock) {
4963 CGF.EmitBranch(ContBlock);
4964 CGF.EmitBlock(ContBlock, true);
4965 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00004966 // Emit final copy of the lastprivate variables if IsLastIter != 0.
4967 if (HasLastprivateClause) {
4968 CGF.EmitOMPLastprivateClauseFinal(
4969 S, isOpenMPSimdDirective(S.getDirectiveKind()),
4970 CGF.Builder.CreateIsNotNull(CGF.EmitLoadOfScalar(
4971 CGF.GetAddrOfLocalVar(*LIP), /*Volatile=*/false,
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004972 (*LIP)->getType(), S.getBeginLoc())));
Alexey Bataevf93095a2016-05-05 08:46:22 +00004973 }
Alexey Bataev7292c292016-04-25 12:22:29 +00004974 };
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004975 auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
James Y Knight9871db02019-02-05 16:42:33 +00004976 IfCond](CodeGenFunction &CGF, llvm::Function *OutlinedFn,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004977 const OMPTaskDataTy &Data) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00004978 auto &&CodeGen = [&S, OutlinedFn, SharedsTy, CapturedStruct, IfCond,
4979 &Data](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataev7292c292016-04-25 12:22:29 +00004980 OMPLoopScope PreInitScope(CGF, S);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004981 CGF.CGM.getOpenMPRuntime().emitTaskLoopCall(CGF, S.getBeginLoc(), S,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004982 OutlinedFn, SharedsTy,
4983 CapturedStruct, IfCond, Data);
Alexey Bataev7292c292016-04-25 12:22:29 +00004984 };
4985 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop,
4986 CodeGen);
4987 };
Alexey Bataev475a7442018-01-12 19:39:11 +00004988 if (Data.Nogroup) {
4989 EmitOMPTaskBasedDirective(S, OMPD_taskloop, BodyGen, TaskGen, Data);
4990 } else {
Alexey Bataev33446032017-07-12 18:09:32 +00004991 CGM.getOpenMPRuntime().emitTaskgroupRegion(
4992 *this,
4993 [&S, &BodyGen, &TaskGen, &Data](CodeGenFunction &CGF,
4994 PrePostActionTy &Action) {
4995 Action.Enter(CGF);
Alexey Bataev475a7442018-01-12 19:39:11 +00004996 CGF.EmitOMPTaskBasedDirective(S, OMPD_taskloop, BodyGen, TaskGen,
4997 Data);
Alexey Bataev33446032017-07-12 18:09:32 +00004998 },
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004999 S.getBeginLoc());
Alexey Bataev33446032017-07-12 18:09:32 +00005000 }
Alexey Bataev7292c292016-04-25 12:22:29 +00005001}
5002
Alexey Bataev49f6e782015-12-01 04:18:41 +00005003void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) {
Alexey Bataev7292c292016-04-25 12:22:29 +00005004 EmitOMPTaskLoopBasedDirective(S);
Alexey Bataev49f6e782015-12-01 04:18:41 +00005005}
5006
Alexey Bataev0a6ed842015-12-03 09:40:15 +00005007void CodeGenFunction::EmitOMPTaskLoopSimdDirective(
5008 const OMPTaskLoopSimdDirective &S) {
Alexey Bataev1e73ef32016-04-28 12:14:51 +00005009 EmitOMPTaskLoopBasedDirective(S);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00005010}
Samuel Antao686c70c2016-05-26 17:30:50 +00005011
5012// Generate the instructions for '#pragma omp target update' directive.
5013void CodeGenFunction::EmitOMPTargetUpdateDirective(
5014 const OMPTargetUpdateDirective &S) {
Samuel Antao8d2d7302016-05-26 18:30:22 +00005015 // If we don't have target devices, don't bother emitting the data mapping
5016 // code.
5017 if (CGM.getLangOpts().OMPTargetTriples.empty())
5018 return;
5019
5020 // Check if we have any if clause associated with the directive.
5021 const Expr *IfCond = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00005022 if (const auto *C = S.getSingleClause<OMPIfClause>())
Samuel Antao8d2d7302016-05-26 18:30:22 +00005023 IfCond = C->getCondition();
5024
5025 // Check if we have any device clause associated with the directive.
5026 const Expr *Device = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00005027 if (const auto *C = S.getSingleClause<OMPDeviceClause>())
Samuel Antao8d2d7302016-05-26 18:30:22 +00005028 Device = C->getDevice();
5029
Alexey Bataev475a7442018-01-12 19:39:11 +00005030 OMPLexicalScope Scope(*this, S, OMPD_task);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00005031 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
Samuel Antao686c70c2016-05-26 17:30:50 +00005032}
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00005033
5034void CodeGenFunction::EmitSimpleOMPExecutableDirective(
5035 const OMPExecutableDirective &D) {
5036 if (!D.hasAssociatedStmt() || !D.getAssociatedStmt())
5037 return;
5038 auto &&CodeGen = [&D](CodeGenFunction &CGF, PrePostActionTy &Action) {
5039 if (isOpenMPSimdDirective(D.getDirectiveKind())) {
5040 emitOMPSimdRegion(CGF, cast<OMPLoopDirective>(D), Action);
5041 } else {
Alexey Bataev6ab5bb12018-10-29 15:01:58 +00005042 OMPPrivateScope LoopGlobals(CGF);
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00005043 if (const auto *LD = dyn_cast<OMPLoopDirective>(&D)) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00005044 for (const Expr *E : LD->counters()) {
Alexey Bataev6ab5bb12018-10-29 15:01:58 +00005045 const auto *VD = dyn_cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
5046 if (!VD->hasLocalStorage() && !CGF.LocalDeclMap.count(VD)) {
5047 LValue GlobLVal = CGF.EmitLValue(E);
5048 LoopGlobals.addPrivate(
5049 VD, [&GlobLVal]() { return GlobLVal.getAddress(); });
5050 }
Bjorn Pettersson6c2d83b2018-10-30 08:49:26 +00005051 if (isa<OMPCapturedExprDecl>(VD)) {
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00005052 // Emit only those that were not explicitly referenced in clauses.
5053 if (!CGF.LocalDeclMap.count(VD))
5054 CGF.EmitVarDecl(*VD);
5055 }
5056 }
Alexey Bataevf138fda2018-08-13 19:04:24 +00005057 for (const auto *C : D.getClausesOfKind<OMPOrderedClause>()) {
5058 if (!C->getNumForLoops())
5059 continue;
5060 for (unsigned I = LD->getCollapsedNumber(),
5061 E = C->getLoopNumIterations().size();
5062 I < E; ++I) {
5063 if (const auto *VD = dyn_cast<OMPCapturedExprDecl>(
Mike Rice0ed46662018-09-20 17:19:41 +00005064 cast<DeclRefExpr>(C->getLoopCounter(I))->getDecl())) {
Alexey Bataevf138fda2018-08-13 19:04:24 +00005065 // Emit only those that were not explicitly referenced in clauses.
5066 if (!CGF.LocalDeclMap.count(VD))
5067 CGF.EmitVarDecl(*VD);
5068 }
5069 }
5070 }
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00005071 }
Alexey Bataev6ab5bb12018-10-29 15:01:58 +00005072 LoopGlobals.Privatize();
Alexey Bataev475a7442018-01-12 19:39:11 +00005073 CGF.EmitStmt(D.getInnermostCapturedStmt()->getCapturedStmt());
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00005074 }
5075 };
5076 OMPSimdLexicalScope Scope(*this, D);
5077 CGM.getOpenMPRuntime().emitInlinedDirective(
5078 *this,
5079 isOpenMPSimdDirective(D.getDirectiveKind()) ? OMPD_simd
5080 : D.getDirectiveKind(),
5081 CodeGen);
5082}