blob: bb6323e118cc2ac45cc837163d3fe16c1ce3327d [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 Bataevf71939c2019-09-18 19:24:07 +0000123 llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
Alexey Bataevddf3db92018-04-13 17:31:06 +0000124 for (const auto *E : S.counters()) {
Alexey Bataeve83b3e82017-12-08 20:18:58 +0000125 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataevf71939c2019-09-18 19:24:07 +0000126 EmittedAsPrivate.insert(VD->getCanonicalDecl());
Alexey Bataevab4ea222018-03-07 18:17:06 +0000127 (void)PreCondVars.setVarAddr(
128 CGF, VD, CGF.CreateMemTemp(VD->getType().getNonReferenceType()));
Alexey Bataeve83b3e82017-12-08 20:18:58 +0000129 }
Alexey Bataevf71939c2019-09-18 19:24:07 +0000130 // Mark private vars as undefs.
131 for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) {
132 for (const Expr *IRef : C->varlists()) {
133 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl());
134 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
135 (void)PreCondVars.setVarAddr(
136 CGF, OrigVD,
137 Address(llvm::UndefValue::get(
138 CGF.ConvertTypeForMem(CGF.getContext().getPointerType(
139 OrigVD->getType().getNonReferenceType()))),
140 CGF.getContext().getDeclAlign(OrigVD)));
141 }
142 }
143 }
Alexey Bataevab4ea222018-03-07 18:17:06 +0000144 (void)PreCondVars.apply(CGF);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000145 if (const auto *PreInits = cast_or_null<DeclStmt>(S.getPreInits())) {
George Burgess IV00f70bd2018-03-01 05:43:23 +0000146 for (const auto *I : PreInits->decls())
147 CGF.EmitVarDecl(cast<VarDecl>(*I));
Alexey Bataev5a3af132016-03-29 08:58:54 +0000148 }
Alexey Bataevab4ea222018-03-07 18:17:06 +0000149 PreCondVars.restore(CGF);
Alexey Bataev5a3af132016-03-29 08:58:54 +0000150 }
151
152public:
153 OMPLoopScope(CodeGenFunction &CGF, const OMPLoopDirective &S)
154 : CodeGenFunction::RunCleanupsScope(CGF) {
155 emitPreInitStmt(CGF, S);
156 }
157};
158
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000159class OMPSimdLexicalScope : public CodeGenFunction::LexicalScope {
160 CodeGenFunction::OMPPrivateScope InlinedShareds;
161
162 static bool isCapturedVar(CodeGenFunction &CGF, const VarDecl *VD) {
163 return CGF.LambdaCaptureFields.lookup(VD) ||
164 (CGF.CapturedStmtInfo && CGF.CapturedStmtInfo->lookup(VD)) ||
165 (CGF.CurCodeDecl && isa<BlockDecl>(CGF.CurCodeDecl) &&
166 cast<BlockDecl>(CGF.CurCodeDecl)->capturesVariable(VD));
167 }
168
169public:
170 OMPSimdLexicalScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
171 : CodeGenFunction::LexicalScope(CGF, S.getSourceRange()),
172 InlinedShareds(CGF) {
173 for (const auto *C : S.clauses()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000174 if (const auto *CPI = OMPClauseWithPreInit::get(C)) {
175 if (const auto *PreInit =
176 cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000177 for (const auto *I : PreInit->decls()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000178 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000179 CGF.EmitVarDecl(cast<VarDecl>(*I));
Alexey Bataevddf3db92018-04-13 17:31:06 +0000180 } else {
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000181 CodeGenFunction::AutoVarEmission Emission =
182 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
183 CGF.EmitAutoVarCleanups(Emission);
184 }
185 }
186 }
187 } else if (const auto *UDP = dyn_cast<OMPUseDevicePtrClause>(C)) {
188 for (const Expr *E : UDP->varlists()) {
189 const Decl *D = cast<DeclRefExpr>(E)->getDecl();
190 if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(D))
191 CGF.EmitVarDecl(*OED);
192 }
193 }
194 }
195 if (!isOpenMPSimdDirective(S.getDirectiveKind()))
196 CGF.EmitOMPPrivateClause(S, InlinedShareds);
197 if (const auto *TG = dyn_cast<OMPTaskgroupDirective>(&S)) {
198 if (const Expr *E = TG->getReductionRef())
199 CGF.EmitVarDecl(*cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()));
200 }
201 const auto *CS = cast_or_null<CapturedStmt>(S.getAssociatedStmt());
202 while (CS) {
203 for (auto &C : CS->captures()) {
204 if (C.capturesVariable() || C.capturesVariableByCopy()) {
205 auto *VD = C.getCapturedVar();
206 assert(VD == VD->getCanonicalDecl() &&
207 "Canonical decl must be captured.");
Bruno Ricci5fc4db72018-12-21 14:10:18 +0000208 DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(VD),
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000209 isCapturedVar(CGF, VD) ||
210 (CGF.CapturedStmtInfo &&
211 InlinedShareds.isGlobalVarCaptured(VD)),
212 VD->getType().getNonReferenceType(), VK_LValue,
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000213 C.getLocation());
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000214 InlinedShareds.addPrivate(VD, [&CGF, &DRE]() -> Address {
215 return CGF.EmitLValue(&DRE).getAddress();
216 });
217 }
218 }
219 CS = dyn_cast<CapturedStmt>(CS->getCapturedStmt());
220 }
221 (void)InlinedShareds.Privatize();
222 }
223};
224
Alexey Bataev3392d762016-02-16 11:18:12 +0000225} // namespace
226
Alexey Bataevf8365372017-11-17 17:57:25 +0000227static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
228 const OMPExecutableDirective &S,
229 const RegionCodeGenTy &CodeGen);
230
Alexey Bataevf47c4b42017-09-26 13:47:31 +0000231LValue CodeGenFunction::EmitOMPSharedLValue(const Expr *E) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000232 if (const auto *OrigDRE = dyn_cast<DeclRefExpr>(E)) {
233 if (const auto *OrigVD = dyn_cast<VarDecl>(OrigDRE->getDecl())) {
Alexey Bataevf47c4b42017-09-26 13:47:31 +0000234 OrigVD = OrigVD->getCanonicalDecl();
235 bool IsCaptured =
236 LambdaCaptureFields.lookup(OrigVD) ||
237 (CapturedStmtInfo && CapturedStmtInfo->lookup(OrigVD)) ||
238 (CurCodeDecl && isa<BlockDecl>(CurCodeDecl));
Bruno Ricci5fc4db72018-12-21 14:10:18 +0000239 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD), IsCaptured,
Alexey Bataevf47c4b42017-09-26 13:47:31 +0000240 OrigDRE->getType(), VK_LValue, OrigDRE->getExprLoc());
241 return EmitLValue(&DRE);
242 }
243 }
244 return EmitLValue(E);
245}
246
Alexey Bataev1189bd02016-01-26 12:20:39 +0000247llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000248 ASTContext &C = getContext();
Alexey Bataev1189bd02016-01-26 12:20:39 +0000249 llvm::Value *Size = nullptr;
250 auto SizeInChars = C.getTypeSizeInChars(Ty);
251 if (SizeInChars.isZero()) {
252 // getTypeSizeInChars() returns 0 for a VLA.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000253 while (const VariableArrayType *VAT = C.getAsVariableArrayType(Ty)) {
254 VlaSizePair VlaSize = getVLASize(VAT);
Sander de Smalen891af03a2018-02-03 13:55:59 +0000255 Ty = VlaSize.Type;
256 Size = Size ? Builder.CreateNUWMul(Size, VlaSize.NumElts)
257 : VlaSize.NumElts;
Alexey Bataev1189bd02016-01-26 12:20:39 +0000258 }
259 SizeInChars = C.getTypeSizeInChars(Ty);
260 if (SizeInChars.isZero())
261 return llvm::ConstantInt::get(SizeTy, /*V=*/0);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000262 return Builder.CreateNUWMul(Size, CGM.getSize(SizeInChars));
263 }
264 return CGM.getSize(SizeInChars);
Alexey Bataev1189bd02016-01-26 12:20:39 +0000265}
266
Alexey Bataev2377fe92015-09-10 08:12:02 +0000267void CodeGenFunction::GenerateOpenMPCapturedVars(
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000268 const CapturedStmt &S, SmallVectorImpl<llvm::Value *> &CapturedVars) {
Alexey Bataev2377fe92015-09-10 08:12:02 +0000269 const RecordDecl *RD = S.getCapturedRecordDecl();
270 auto CurField = RD->field_begin();
271 auto CurCap = S.captures().begin();
272 for (CapturedStmt::const_capture_init_iterator I = S.capture_init_begin(),
273 E = S.capture_init_end();
274 I != E; ++I, ++CurField, ++CurCap) {
275 if (CurField->hasCapturedVLAType()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000276 const VariableArrayType *VAT = CurField->getCapturedVLAType();
277 llvm::Value *Val = VLASizeMap[VAT->getSizeExpr()];
Samuel Antaobed3c462015-10-02 16:14:20 +0000278 CapturedVars.push_back(Val);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000279 } else if (CurCap->capturesThis()) {
Alexey Bataev2377fe92015-09-10 08:12:02 +0000280 CapturedVars.push_back(CXXThisValue);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000281 } else if (CurCap->capturesVariableByCopy()) {
Alexey Bataev1e491372018-01-23 18:44:14 +0000282 llvm::Value *CV = EmitLoadOfScalar(EmitLValue(*I), CurCap->getLocation());
Samuel Antao6d004262016-06-16 18:39:34 +0000283
284 // If the field is not a pointer, we need to save the actual value
285 // and load it as a void pointer.
286 if (!CurField->getType()->isAnyPointerType()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000287 ASTContext &Ctx = getContext();
288 Address DstAddr = CreateMemTemp(
Samuel Antao6d004262016-06-16 18:39:34 +0000289 Ctx.getUIntPtrType(),
Alexey Bataevddf3db92018-04-13 17:31:06 +0000290 Twine(CurCap->getCapturedVar()->getName(), ".casted"));
Samuel Antao6d004262016-06-16 18:39:34 +0000291 LValue DstLV = MakeAddrLValue(DstAddr, Ctx.getUIntPtrType());
292
Alexey Bataevddf3db92018-04-13 17:31:06 +0000293 llvm::Value *SrcAddrVal = EmitScalarConversion(
Samuel Antao6d004262016-06-16 18:39:34 +0000294 DstAddr.getPointer(), Ctx.getPointerType(Ctx.getUIntPtrType()),
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000295 Ctx.getPointerType(CurField->getType()), CurCap->getLocation());
Samuel Antao6d004262016-06-16 18:39:34 +0000296 LValue SrcLV =
297 MakeNaturalAlignAddrLValue(SrcAddrVal, CurField->getType());
298
299 // Store the value using the source type pointer.
300 EmitStoreThroughLValue(RValue::get(CV), SrcLV);
301
302 // Load the value using the destination type pointer.
Alexey Bataev1e491372018-01-23 18:44:14 +0000303 CV = EmitLoadOfScalar(DstLV, CurCap->getLocation());
Samuel Antao6d004262016-06-16 18:39:34 +0000304 }
305 CapturedVars.push_back(CV);
306 } else {
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000307 assert(CurCap->capturesVariable() && "Expected capture by reference.");
Alexey Bataev2377fe92015-09-10 08:12:02 +0000308 CapturedVars.push_back(EmitLValue(*I).getAddress().getPointer());
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000309 }
Alexey Bataev2377fe92015-09-10 08:12:02 +0000310 }
311}
312
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000313static Address castValueFromUintptr(CodeGenFunction &CGF, SourceLocation Loc,
314 QualType DstType, StringRef Name,
Alexey Bataev06e80f62019-05-23 18:19:54 +0000315 LValue AddrLV) {
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000316 ASTContext &Ctx = CGF.getContext();
317
Alexey Bataevddf3db92018-04-13 17:31:06 +0000318 llvm::Value *CastedPtr = CGF.EmitScalarConversion(
319 AddrLV.getAddress().getPointer(), Ctx.getUIntPtrType(),
320 Ctx.getPointerType(DstType), Loc);
321 Address TmpAddr =
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000322 CGF.MakeNaturalAlignAddrLValue(CastedPtr, Ctx.getPointerType(DstType))
323 .getAddress();
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000324 return TmpAddr;
325}
326
Alexey Bataevf7ce1662017-04-10 19:16:45 +0000327static QualType getCanonicalParamType(ASTContext &C, QualType T) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000328 if (T->isLValueReferenceType())
Alexey Bataevf7ce1662017-04-10 19:16:45 +0000329 return C.getLValueReferenceType(
330 getCanonicalParamType(C, T.getNonReferenceType()),
331 /*SpelledAsLValue=*/false);
Alexey Bataevf7ce1662017-04-10 19:16:45 +0000332 if (T->isPointerType())
333 return C.getPointerType(getCanonicalParamType(C, T->getPointeeType()));
Alexey Bataevddf3db92018-04-13 17:31:06 +0000334 if (const ArrayType *A = T->getAsArrayTypeUnsafe()) {
335 if (const auto *VLA = dyn_cast<VariableArrayType>(A))
Alexey Bataev1b48c5e2017-10-24 19:52:31 +0000336 return getCanonicalParamType(C, VLA->getElementType());
Alexey Bataevddf3db92018-04-13 17:31:06 +0000337 if (!A->isVariablyModifiedType())
Alexey Bataev1b48c5e2017-10-24 19:52:31 +0000338 return C.getCanonicalType(T);
339 }
Alexey Bataevf7ce1662017-04-10 19:16:45 +0000340 return C.getCanonicalParamType(T);
341}
342
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000343namespace {
344 /// Contains required data for proper outlined function codegen.
345 struct FunctionOptions {
346 /// Captured statement for which the function is generated.
347 const CapturedStmt *S = nullptr;
348 /// true if cast to/from UIntPtr is required for variables captured by
349 /// value.
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000350 const bool UIntPtrCastRequired = true;
Alexey Bataeve754b182017-08-09 19:38:53 +0000351 /// true if only casted arguments must be registered as local args or VLA
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000352 /// sizes.
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000353 const bool RegisterCastedArgsOnly = false;
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000354 /// Name of the generated function.
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000355 const StringRef FunctionName;
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000356 explicit FunctionOptions(const CapturedStmt *S, bool UIntPtrCastRequired,
357 bool RegisterCastedArgsOnly,
Alexey Bataev4aa19052017-08-08 16:45:36 +0000358 StringRef FunctionName)
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000359 : S(S), UIntPtrCastRequired(UIntPtrCastRequired),
360 RegisterCastedArgsOnly(UIntPtrCastRequired && RegisterCastedArgsOnly),
Alexey Bataev4aa19052017-08-08 16:45:36 +0000361 FunctionName(FunctionName) {}
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000362 };
363}
364
Alexey Bataeve754b182017-08-09 19:38:53 +0000365static llvm::Function *emitOutlinedFunctionPrologue(
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000366 CodeGenFunction &CGF, FunctionArgList &Args,
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000367 llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>>
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000368 &LocalAddrs,
369 llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>>
370 &VLASizes,
371 llvm::Value *&CXXThisValue, const FunctionOptions &FO) {
372 const CapturedDecl *CD = FO.S->getCapturedDecl();
373 const RecordDecl *RD = FO.S->getCapturedRecordDecl();
Alexey Bataev2377fe92015-09-10 08:12:02 +0000374 assert(CD->hasBody() && "missing CapturedDecl body");
375
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000376 CXXThisValue = nullptr;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000377 // Build the argument list.
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000378 CodeGenModule &CGM = CGF.CGM;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000379 ASTContext &Ctx = CGM.getContext();
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000380 FunctionArgList TargetArgs;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000381 Args.append(CD->param_begin(),
382 std::next(CD->param_begin(), CD->getContextParamPosition()));
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000383 TargetArgs.append(
384 CD->param_begin(),
385 std::next(CD->param_begin(), CD->getContextParamPosition()));
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000386 auto I = FO.S->captures().begin();
Alexey Bataevb45d43c2017-11-22 16:02:03 +0000387 FunctionDecl *DebugFunctionDecl = nullptr;
388 if (!FO.UIntPtrCastRequired) {
389 FunctionProtoType::ExtProtoInfo EPI;
Jonas Devlieghere64a26302018-11-11 00:56:15 +0000390 QualType FunctionTy = Ctx.getFunctionType(Ctx.VoidTy, llvm::None, EPI);
Alexey Bataevb45d43c2017-11-22 16:02:03 +0000391 DebugFunctionDecl = FunctionDecl::Create(
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000392 Ctx, Ctx.getTranslationUnitDecl(), FO.S->getBeginLoc(),
Jonas Devlieghere64a26302018-11-11 00:56:15 +0000393 SourceLocation(), DeclarationName(), FunctionTy,
394 Ctx.getTrivialTypeSourceInfo(FunctionTy), SC_Static,
395 /*isInlineSpecified=*/false, /*hasWrittenPrototype=*/false);
Alexey Bataevb45d43c2017-11-22 16:02:03 +0000396 }
Alexey Bataevddf3db92018-04-13 17:31:06 +0000397 for (const FieldDecl *FD : RD->fields()) {
Alexey Bataev2377fe92015-09-10 08:12:02 +0000398 QualType ArgType = FD->getType();
399 IdentifierInfo *II = nullptr;
400 VarDecl *CapVar = nullptr;
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000401
402 // If this is a capture by copy and the type is not a pointer, the outlined
403 // function argument type should be uintptr and the value properly casted to
404 // uintptr. This is necessary given that the runtime library is only able to
405 // deal with pointers. We can pass in the same way the VLA type sizes to the
406 // outlined function.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000407 if (FO.UIntPtrCastRequired &&
408 ((I->capturesVariableByCopy() && !ArgType->isAnyPointerType()) ||
409 I->capturesVariableArrayType()))
410 ArgType = Ctx.getUIntPtrType();
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000411
412 if (I->capturesVariable() || I->capturesVariableByCopy()) {
Alexey Bataev2377fe92015-09-10 08:12:02 +0000413 CapVar = I->getCapturedVar();
414 II = CapVar->getIdentifier();
Alexey Bataevddf3db92018-04-13 17:31:06 +0000415 } else if (I->capturesThis()) {
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000416 II = &Ctx.Idents.get("this");
Alexey Bataevddf3db92018-04-13 17:31:06 +0000417 } else {
Alexey Bataev2377fe92015-09-10 08:12:02 +0000418 assert(I->capturesVariableArrayType());
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000419 II = &Ctx.Idents.get("vla");
Alexey Bataev2377fe92015-09-10 08:12:02 +0000420 }
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000421 if (ArgType->isVariablyModifiedType())
Alexey Bataev1b48c5e2017-10-24 19:52:31 +0000422 ArgType = getCanonicalParamType(Ctx, ArgType);
Alexey Bataevb45d43c2017-11-22 16:02:03 +0000423 VarDecl *Arg;
424 if (DebugFunctionDecl && (CapVar || I->capturesThis())) {
425 Arg = ParmVarDecl::Create(
426 Ctx, DebugFunctionDecl,
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000427 CapVar ? CapVar->getBeginLoc() : FD->getBeginLoc(),
Alexey Bataevb45d43c2017-11-22 16:02:03 +0000428 CapVar ? CapVar->getLocation() : FD->getLocation(), II, ArgType,
429 /*TInfo=*/nullptr, SC_None, /*DefArg=*/nullptr);
430 } else {
431 Arg = ImplicitParamDecl::Create(Ctx, /*DC=*/nullptr, FD->getLocation(),
432 II, ArgType, ImplicitParamDecl::Other);
433 }
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000434 Args.emplace_back(Arg);
435 // Do not cast arguments if we emit function with non-original types.
436 TargetArgs.emplace_back(
437 FO.UIntPtrCastRequired
438 ? Arg
439 : CGM.getOpenMPRuntime().translateParameter(FD, Arg));
Alexey Bataev2377fe92015-09-10 08:12:02 +0000440 ++I;
441 }
442 Args.append(
443 std::next(CD->param_begin(), CD->getContextParamPosition() + 1),
444 CD->param_end());
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000445 TargetArgs.append(
446 std::next(CD->param_begin(), CD->getContextParamPosition() + 1),
447 CD->param_end());
Alexey Bataev2377fe92015-09-10 08:12:02 +0000448
449 // Create the function declaration.
Alexey Bataev2377fe92015-09-10 08:12:02 +0000450 const CGFunctionInfo &FuncInfo =
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000451 CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, TargetArgs);
Alexey Bataev2377fe92015-09-10 08:12:02 +0000452 llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo);
453
Alexey Bataevddf3db92018-04-13 17:31:06 +0000454 auto *F =
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000455 llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
456 FO.FunctionName, &CGM.getModule());
Alexey Bataev2377fe92015-09-10 08:12:02 +0000457 CGM.SetInternalFunctionAttributes(CD, F, FuncInfo);
458 if (CD->isNothrow())
Alexey Bataev2c7eee52017-08-04 19:10:54 +0000459 F->setDoesNotThrow();
Alexey Bataevc0f879b2018-04-10 20:10:53 +0000460 F->setDoesNotRecurse();
Alexey Bataev2377fe92015-09-10 08:12:02 +0000461
462 // Generate the function.
Alexey Bataev6e01dc12017-08-14 16:03:47 +0000463 CGF.StartFunction(CD, Ctx.VoidTy, F, FuncInfo, TargetArgs,
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000464 FO.S->getBeginLoc(), CD->getBody()->getBeginLoc());
Alexey Bataev2377fe92015-09-10 08:12:02 +0000465 unsigned Cnt = CD->getContextParamPosition();
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000466 I = FO.S->captures().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +0000467 for (const FieldDecl *FD : RD->fields()) {
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000468 // Do not map arguments if we emit function with non-original types.
469 Address LocalAddr(Address::invalid());
470 if (!FO.UIntPtrCastRequired && Args[Cnt] != TargetArgs[Cnt]) {
471 LocalAddr = CGM.getOpenMPRuntime().getParameterAddress(CGF, Args[Cnt],
472 TargetArgs[Cnt]);
473 } else {
474 LocalAddr = CGF.GetAddrOfLocalVar(Args[Cnt]);
475 }
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000476 // If we are capturing a pointer by copy we don't need to do anything, just
477 // use the value that we get from the arguments.
478 if (I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) {
Samuel Antao403ffd42016-07-27 22:49:49 +0000479 const VarDecl *CurVD = I->getCapturedVar();
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000480 if (!FO.RegisterCastedArgsOnly)
481 LocalAddrs.insert({Args[Cnt], {CurVD, LocalAddr}});
Richard Trieucc3949d2016-02-18 22:34:54 +0000482 ++Cnt;
483 ++I;
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000484 continue;
485 }
486
Ivan A. Kosarev5f8c0ca2017-10-10 09:39:32 +0000487 LValue ArgLVal = CGF.MakeAddrLValue(LocalAddr, Args[Cnt]->getType(),
488 AlignmentSource::Decl);
Alexey Bataev2377fe92015-09-10 08:12:02 +0000489 if (FD->hasCapturedVLAType()) {
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000490 if (FO.UIntPtrCastRequired) {
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000491 ArgLVal = CGF.MakeAddrLValue(
492 castValueFromUintptr(CGF, I->getLocation(), FD->getType(),
493 Args[Cnt]->getName(), ArgLVal),
494 FD->getType(), AlignmentSource::Decl);
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000495 }
Alexey Bataevddf3db92018-04-13 17:31:06 +0000496 llvm::Value *ExprArg = CGF.EmitLoadOfScalar(ArgLVal, I->getLocation());
497 const VariableArrayType *VAT = FD->getCapturedVLAType();
498 VLASizes.try_emplace(Args[Cnt], VAT->getSizeExpr(), ExprArg);
Alexey Bataev2377fe92015-09-10 08:12:02 +0000499 } else if (I->capturesVariable()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000500 const VarDecl *Var = I->getCapturedVar();
Alexey Bataev2377fe92015-09-10 08:12:02 +0000501 QualType VarTy = Var->getType();
502 Address ArgAddr = ArgLVal.getAddress();
Alexey Bataev06e80f62019-05-23 18:19:54 +0000503 if (ArgLVal.getType()->isLValueReferenceType()) {
504 ArgAddr = CGF.EmitLoadOfReference(ArgLVal);
505 } else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) {
506 assert(ArgLVal.getType()->isPointerType());
507 ArgAddr = CGF.EmitLoadOfPointer(
508 ArgAddr, ArgLVal.getType()->castAs<PointerType>());
Alexey Bataev2377fe92015-09-10 08:12:02 +0000509 }
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000510 if (!FO.RegisterCastedArgsOnly) {
511 LocalAddrs.insert(
512 {Args[Cnt],
513 {Var, Address(ArgAddr.getPointer(), Ctx.getDeclAlign(Var))}});
514 }
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000515 } else if (I->capturesVariableByCopy()) {
516 assert(!FD->getType()->isAnyPointerType() &&
517 "Not expecting a captured pointer.");
Alexey Bataevddf3db92018-04-13 17:31:06 +0000518 const VarDecl *Var = I->getCapturedVar();
Alexey Bataev06e80f62019-05-23 18:19:54 +0000519 LocalAddrs.insert({Args[Cnt],
520 {Var, FO.UIntPtrCastRequired
521 ? castValueFromUintptr(
522 CGF, I->getLocation(), FD->getType(),
523 Args[Cnt]->getName(), ArgLVal)
524 : ArgLVal.getAddress()}});
Alexey Bataev2377fe92015-09-10 08:12:02 +0000525 } else {
526 // If 'this' is captured, load it into CXXThisValue.
527 assert(I->capturesThis());
Alexey Bataev1e491372018-01-23 18:44:14 +0000528 CXXThisValue = CGF.EmitLoadOfScalar(ArgLVal, I->getLocation());
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000529 LocalAddrs.insert({Args[Cnt], {nullptr, ArgLVal.getAddress()}});
Alexey Bataev2377fe92015-09-10 08:12:02 +0000530 }
Richard Trieucc3949d2016-02-18 22:34:54 +0000531 ++Cnt;
532 ++I;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000533 }
534
Alexey Bataeve754b182017-08-09 19:38:53 +0000535 return F;
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000536}
537
538llvm::Function *
539CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
540 assert(
541 CapturedStmtInfo &&
542 "CapturedStmtInfo should be set when generating the captured function");
543 const CapturedDecl *CD = S.getCapturedDecl();
544 // Build the argument list.
545 bool NeedWrapperFunction =
546 getDebugInfo() &&
547 CGM.getCodeGenOpts().getDebugInfo() >= codegenoptions::LimitedDebugInfo;
548 FunctionArgList Args;
Alexey Bataev3b8d5582017-08-08 18:04:06 +0000549 llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>> LocalAddrs;
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000550 llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> VLASizes;
Alexey Bataeve754b182017-08-09 19:38:53 +0000551 SmallString<256> Buffer;
552 llvm::raw_svector_ostream Out(Buffer);
553 Out << CapturedStmtInfo->getHelperName();
554 if (NeedWrapperFunction)
555 Out << "_debug__";
Alexey Bataev4aa19052017-08-08 16:45:36 +0000556 FunctionOptions FO(&S, !NeedWrapperFunction, /*RegisterCastedArgsOnly=*/false,
Alexey Bataeve754b182017-08-09 19:38:53 +0000557 Out.str());
558 llvm::Function *F = emitOutlinedFunctionPrologue(*this, Args, LocalAddrs,
559 VLASizes, CXXThisValue, FO);
Alexey Bataev06e80f62019-05-23 18:19:54 +0000560 CodeGenFunction::OMPPrivateScope LocalScope(*this);
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000561 for (const auto &LocalAddrPair : LocalAddrs) {
562 if (LocalAddrPair.second.first) {
Alexey Bataev06e80f62019-05-23 18:19:54 +0000563 LocalScope.addPrivate(LocalAddrPair.second.first, [&LocalAddrPair]() {
564 return LocalAddrPair.second.second;
565 });
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000566 }
567 }
Alexey Bataev06e80f62019-05-23 18:19:54 +0000568 (void)LocalScope.Privatize();
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000569 for (const auto &VLASizePair : VLASizes)
570 VLASizeMap[VLASizePair.second.first] = VLASizePair.second.second;
Serge Pavlov3a561452015-12-06 14:32:39 +0000571 PGO.assignRegionCounters(GlobalDecl(CD), F);
Alexey Bataev2377fe92015-09-10 08:12:02 +0000572 CapturedStmtInfo->EmitBody(*this, CD->getBody());
Alexey Bataev06e80f62019-05-23 18:19:54 +0000573 (void)LocalScope.ForceCleanup();
Alexey Bataev2377fe92015-09-10 08:12:02 +0000574 FinishFunction(CD->getBodyRBrace());
Alexey Bataeve754b182017-08-09 19:38:53 +0000575 if (!NeedWrapperFunction)
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000576 return F;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000577
Alexey Bataevefd884d2017-08-04 21:26:25 +0000578 FunctionOptions WrapperFO(&S, /*UIntPtrCastRequired=*/true,
Alexey Bataeve754b182017-08-09 19:38:53 +0000579 /*RegisterCastedArgsOnly=*/true,
580 CapturedStmtInfo->getHelperName());
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000581 CodeGenFunction WrapperCGF(CGM, /*suppressNewContext=*/true);
Gheorghe-Teodor Bercead3dcf2f2018-03-14 14:17:45 +0000582 WrapperCGF.CapturedStmtInfo = CapturedStmtInfo;
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000583 Args.clear();
584 LocalAddrs.clear();
585 VLASizes.clear();
586 llvm::Function *WrapperF =
587 emitOutlinedFunctionPrologue(WrapperCGF, Args, LocalAddrs, VLASizes,
Alexey Bataeve754b182017-08-09 19:38:53 +0000588 WrapperCGF.CXXThisValue, WrapperFO);
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000589 llvm::SmallVector<llvm::Value *, 4> CallArgs;
590 for (const auto *Arg : Args) {
591 llvm::Value *CallArg;
592 auto I = LocalAddrs.find(Arg);
593 if (I != LocalAddrs.end()) {
Alexey Bataev7ba57af2017-10-17 16:47:34 +0000594 LValue LV = WrapperCGF.MakeAddrLValue(
595 I->second.second,
596 I->second.first ? I->second.first->getType() : Arg->getType(),
597 AlignmentSource::Decl);
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000598 CallArg = WrapperCGF.EmitLoadOfScalar(LV, S.getBeginLoc());
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000599 } else {
600 auto EI = VLASizes.find(Arg);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000601 if (EI != VLASizes.end()) {
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000602 CallArg = EI->second.second;
Alexey Bataevddf3db92018-04-13 17:31:06 +0000603 } else {
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000604 LValue LV = WrapperCGF.MakeAddrLValue(WrapperCGF.GetAddrOfLocalVar(Arg),
Ivan A. Kosarev5f8c0ca2017-10-10 09:39:32 +0000605 Arg->getType(),
606 AlignmentSource::Decl);
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000607 CallArg = WrapperCGF.EmitLoadOfScalar(LV, S.getBeginLoc());
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000608 }
609 }
Alexey Bataev7ba57af2017-10-17 16:47:34 +0000610 CallArgs.emplace_back(WrapperCGF.EmitFromMemory(CallArg, Arg->getType()));
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000611 }
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000612 CGM.getOpenMPRuntime().emitOutlinedFunctionCall(WrapperCGF, S.getBeginLoc(),
Alexey Bataev3c595a62017-08-14 15:01:03 +0000613 F, CallArgs);
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000614 WrapperCGF.FinishFunction();
615 return WrapperF;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000616}
617
Alexey Bataev9959db52014-05-06 10:08:46 +0000618//===----------------------------------------------------------------------===//
619// OpenMP Directive Emission
620//===----------------------------------------------------------------------===//
Alexey Bataev420d45b2015-04-14 05:11:24 +0000621void CodeGenFunction::EmitOMPAggregateAssign(
John McCall7f416cc2015-09-08 08:05:57 +0000622 Address DestAddr, Address SrcAddr, QualType OriginalType,
Alexey Bataevddf3db92018-04-13 17:31:06 +0000623 const llvm::function_ref<void(Address, Address)> CopyGen) {
Alexey Bataev420d45b2015-04-14 05:11:24 +0000624 // Perform element-by-element initialization.
625 QualType ElementTy;
John McCall7f416cc2015-09-08 08:05:57 +0000626
627 // Drill down to the base element type on both arrays.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000628 const ArrayType *ArrayTy = OriginalType->getAsArrayTypeUnsafe();
629 llvm::Value *NumElements = emitArrayLength(ArrayTy, ElementTy, DestAddr);
John McCall7f416cc2015-09-08 08:05:57 +0000630 SrcAddr = Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());
631
Alexey Bataevddf3db92018-04-13 17:31:06 +0000632 llvm::Value *SrcBegin = SrcAddr.getPointer();
633 llvm::Value *DestBegin = DestAddr.getPointer();
Alexey Bataev420d45b2015-04-14 05:11:24 +0000634 // Cast from pointer to array type to pointer to single element.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000635 llvm::Value *DestEnd = Builder.CreateGEP(DestBegin, NumElements);
Alexey Bataev420d45b2015-04-14 05:11:24 +0000636 // The basic structure here is a while-do loop.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000637 llvm::BasicBlock *BodyBB = createBasicBlock("omp.arraycpy.body");
638 llvm::BasicBlock *DoneBB = createBasicBlock("omp.arraycpy.done");
639 llvm::Value *IsEmpty =
Alexey Bataev420d45b2015-04-14 05:11:24 +0000640 Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty");
641 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000642
Alexey Bataev420d45b2015-04-14 05:11:24 +0000643 // Enter the loop body, making that address the current address.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000644 llvm::BasicBlock *EntryBB = Builder.GetInsertBlock();
Alexey Bataev420d45b2015-04-14 05:11:24 +0000645 EmitBlock(BodyBB);
John McCall7f416cc2015-09-08 08:05:57 +0000646
647 CharUnits ElementSize = getContext().getTypeSizeInChars(ElementTy);
648
649 llvm::PHINode *SrcElementPHI =
650 Builder.CreatePHI(SrcBegin->getType(), 2, "omp.arraycpy.srcElementPast");
651 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
652 Address SrcElementCurrent =
653 Address(SrcElementPHI,
654 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
655
656 llvm::PHINode *DestElementPHI =
657 Builder.CreatePHI(DestBegin->getType(), 2, "omp.arraycpy.destElementPast");
658 DestElementPHI->addIncoming(DestBegin, EntryBB);
659 Address DestElementCurrent =
660 Address(DestElementPHI,
661 DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000662
Alexey Bataev420d45b2015-04-14 05:11:24 +0000663 // Emit copy.
664 CopyGen(DestElementCurrent, SrcElementCurrent);
665
666 // Shift the address forward by one element.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000667 llvm::Value *DestElementNext = Builder.CreateConstGEP1_32(
John McCall7f416cc2015-09-08 08:05:57 +0000668 DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
Alexey Bataevddf3db92018-04-13 17:31:06 +0000669 llvm::Value *SrcElementNext = Builder.CreateConstGEP1_32(
John McCall7f416cc2015-09-08 08:05:57 +0000670 SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.src.element");
Alexey Bataev420d45b2015-04-14 05:11:24 +0000671 // Check whether we've reached the end.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000672 llvm::Value *Done =
Alexey Bataev420d45b2015-04-14 05:11:24 +0000673 Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");
674 Builder.CreateCondBr(Done, DoneBB, BodyBB);
John McCall7f416cc2015-09-08 08:05:57 +0000675 DestElementPHI->addIncoming(DestElementNext, Builder.GetInsertBlock());
676 SrcElementPHI->addIncoming(SrcElementNext, Builder.GetInsertBlock());
Alexey Bataev420d45b2015-04-14 05:11:24 +0000677
678 // Done.
679 EmitBlock(DoneBB, /*IsFinished=*/true);
680}
681
John McCall7f416cc2015-09-08 08:05:57 +0000682void CodeGenFunction::EmitOMPCopy(QualType OriginalType, Address DestAddr,
683 Address SrcAddr, const VarDecl *DestVD,
Alexey Bataev420d45b2015-04-14 05:11:24 +0000684 const VarDecl *SrcVD, const Expr *Copy) {
685 if (OriginalType->isArrayType()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000686 const auto *BO = dyn_cast<BinaryOperator>(Copy);
Alexey Bataev420d45b2015-04-14 05:11:24 +0000687 if (BO && BO->getOpcode() == BO_Assign) {
688 // Perform simple memcpy for simple copying.
Ivan A. Kosarev1860b522018-01-25 14:21:55 +0000689 LValue Dest = MakeAddrLValue(DestAddr, OriginalType);
690 LValue Src = MakeAddrLValue(SrcAddr, OriginalType);
691 EmitAggregateAssign(Dest, Src, OriginalType);
Alexey Bataev420d45b2015-04-14 05:11:24 +0000692 } else {
693 // For arrays with complex element types perform element by element
694 // copying.
John McCall7f416cc2015-09-08 08:05:57 +0000695 EmitOMPAggregateAssign(
Alexey Bataev420d45b2015-04-14 05:11:24 +0000696 DestAddr, SrcAddr, OriginalType,
John McCall7f416cc2015-09-08 08:05:57 +0000697 [this, Copy, SrcVD, DestVD](Address DestElement, Address SrcElement) {
Alexey Bataev420d45b2015-04-14 05:11:24 +0000698 // Working with the single array element, so have to remap
699 // destination and source variables to corresponding array
700 // elements.
John McCall7f416cc2015-09-08 08:05:57 +0000701 CodeGenFunction::OMPPrivateScope Remap(*this);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000702 Remap.addPrivate(DestVD, [DestElement]() { return DestElement; });
703 Remap.addPrivate(SrcVD, [SrcElement]() { return SrcElement; });
Alexey Bataev420d45b2015-04-14 05:11:24 +0000704 (void)Remap.Privatize();
John McCall7f416cc2015-09-08 08:05:57 +0000705 EmitIgnoredExpr(Copy);
Alexey Bataev420d45b2015-04-14 05:11:24 +0000706 });
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000707 }
Alexey Bataev420d45b2015-04-14 05:11:24 +0000708 } else {
709 // Remap pseudo source variable to private copy.
John McCall7f416cc2015-09-08 08:05:57 +0000710 CodeGenFunction::OMPPrivateScope Remap(*this);
Alexey Bataevddf3db92018-04-13 17:31:06 +0000711 Remap.addPrivate(SrcVD, [SrcAddr]() { return SrcAddr; });
712 Remap.addPrivate(DestVD, [DestAddr]() { return DestAddr; });
Alexey Bataev420d45b2015-04-14 05:11:24 +0000713 (void)Remap.Privatize();
714 // Emit copying of the whole variable.
John McCall7f416cc2015-09-08 08:05:57 +0000715 EmitIgnoredExpr(Copy);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000716 }
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000717}
718
Alexey Bataev69c62a92015-04-15 04:52:20 +0000719bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
720 OMPPrivateScope &PrivateScope) {
Alexey Bataev8ef31412015-12-18 07:58:25 +0000721 if (!HaveInsertPoint())
722 return false;
Alexey Bataev1af5bd52019-03-05 17:47:18 +0000723 bool DeviceConstTarget =
724 getLangOpts().OpenMPIsDevice &&
725 isOpenMPTargetExecutionDirective(D.getDirectiveKind());
Alexey Bataevcd8b6a22016-02-15 08:07:17 +0000726 bool FirstprivateIsLastprivate = false;
727 llvm::DenseSet<const VarDecl *> Lastprivates;
728 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
729 for (const auto *D : C->varlists())
730 Lastprivates.insert(
731 cast<VarDecl>(cast<DeclRefExpr>(D)->getDecl())->getCanonicalDecl());
732 }
Alexey Bataev69c62a92015-04-15 04:52:20 +0000733 llvm::DenseSet<const VarDecl *> EmittedAsFirstprivate;
Alexey Bataev475a7442018-01-12 19:39:11 +0000734 llvm::SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
735 getOpenMPCaptureRegions(CaptureRegions, D.getDirectiveKind());
736 // Force emission of the firstprivate copy if the directive does not emit
737 // outlined function, like omp for, omp simd, omp distribute etc.
738 bool MustEmitFirstprivateCopy =
739 CaptureRegions.size() == 1 && CaptureRegions.back() == OMPD_unknown;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +0000740 for (const auto *C : D.getClausesOfKind<OMPFirstprivateClause>()) {
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000741 auto IRef = C->varlist_begin();
742 auto InitsRef = C->inits().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +0000743 for (const Expr *IInit : C->private_copies()) {
744 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000745 bool ThisFirstprivateIsLastprivate =
746 Lastprivates.count(OrigVD->getCanonicalDecl()) > 0;
Alexey Bataevddf3db92018-04-13 17:31:06 +0000747 const FieldDecl *FD = CapturedStmtInfo->lookup(OrigVD);
Alexey Bataev9c397812019-04-03 17:57:06 +0000748 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
Alexey Bataev475a7442018-01-12 19:39:11 +0000749 if (!MustEmitFirstprivateCopy && !ThisFirstprivateIsLastprivate && FD &&
Alexey Bataev9c397812019-04-03 17:57:06 +0000750 !FD->getType()->isReferenceType() &&
751 (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())) {
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000752 EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl());
753 ++IRef;
754 ++InitsRef;
755 continue;
756 }
Alexey Bataev1af5bd52019-03-05 17:47:18 +0000757 // Do not emit copy for firstprivate constant variables in target regions,
758 // captured by reference.
759 if (DeviceConstTarget && OrigVD->getType().isConstant(getContext()) &&
Alexey Bataev9c397812019-04-03 17:57:06 +0000760 FD && FD->getType()->isReferenceType() &&
761 (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())) {
Alexey Bataev1af5bd52019-03-05 17:47:18 +0000762 (void)CGM.getOpenMPRuntime().registerTargetFirstprivateCopy(*this,
763 OrigVD);
764 ++IRef;
765 ++InitsRef;
766 continue;
767 }
Alexey Bataevcd8b6a22016-02-15 08:07:17 +0000768 FirstprivateIsLastprivate =
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000769 FirstprivateIsLastprivate || ThisFirstprivateIsLastprivate;
Alexey Bataevcd8b6a22016-02-15 08:07:17 +0000770 if (EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()).second) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000771 const auto *VDInit =
772 cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
Alexey Bataev69c62a92015-04-15 04:52:20 +0000773 bool IsRegistered;
Bruno Ricci5fc4db72018-12-21 14:10:18 +0000774 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000775 /*RefersToEnclosingVariableOrCapture=*/FD != nullptr,
776 (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
Alexey Bataeve0ef04f2019-05-23 22:30:43 +0000777 LValue OriginalLVal;
778 if (!FD) {
779 // Check if the firstprivate variable is just a constant value.
780 ConstantEmission CE = tryEmitAsConstant(&DRE);
781 if (CE && !CE.isReference()) {
782 // Constant value, no need to create a copy.
783 ++IRef;
784 ++InitsRef;
785 continue;
786 }
787 if (CE && CE.isReference()) {
788 OriginalLVal = CE.getReferenceLValue(*this, &DRE);
789 } else {
790 assert(!CE && "Expected non-constant firstprivate.");
791 OriginalLVal = EmitLValue(&DRE);
792 }
793 } else {
794 OriginalLVal = EmitLValue(&DRE);
795 }
Alexey Bataevfeddd642016-04-22 09:05:03 +0000796 QualType Type = VD->getType();
Alexey Bataev1d9c15c2015-05-19 12:31:28 +0000797 if (Type->isArrayType()) {
Alexey Bataev69c62a92015-04-15 04:52:20 +0000798 // Emit VarDecl with copy init for arrays.
799 // Get the address of the original variable captured in current
800 // captured region.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000801 IsRegistered = PrivateScope.addPrivate(
802 OrigVD, [this, VD, Type, OriginalLVal, VDInit]() {
803 AutoVarEmission Emission = EmitAutoVarAlloca(*VD);
804 const Expr *Init = VD->getInit();
805 if (!isa<CXXConstructExpr>(Init) ||
806 isTrivialInitializer(Init)) {
807 // Perform simple memcpy.
808 LValue Dest =
809 MakeAddrLValue(Emission.getAllocatedAddress(), Type);
810 EmitAggregateAssign(Dest, OriginalLVal, Type);
811 } else {
812 EmitOMPAggregateAssign(
813 Emission.getAllocatedAddress(), OriginalLVal.getAddress(),
814 Type,
815 [this, VDInit, Init](Address DestElement,
816 Address SrcElement) {
817 // Clean up any temporaries needed by the
818 // initialization.
819 RunCleanupsScope InitScope(*this);
820 // Emit initialization for single element.
821 setAddrOfLocalVar(VDInit, SrcElement);
822 EmitAnyExprToMem(Init, DestElement,
823 Init->getType().getQualifiers(),
824 /*IsInitializer*/ false);
825 LocalDeclMap.erase(VDInit);
826 });
827 }
828 EmitAutoVarCleanups(Emission);
829 return Emission.getAllocatedAddress();
830 });
Alexey Bataev69c62a92015-04-15 04:52:20 +0000831 } else {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000832 Address OriginalAddr = OriginalLVal.getAddress();
833 IsRegistered = PrivateScope.addPrivate(
834 OrigVD, [this, VDInit, OriginalAddr, VD]() {
835 // Emit private VarDecl with copy init.
836 // Remap temp VDInit variable to the address of the original
837 // variable (for proper handling of captured global variables).
838 setAddrOfLocalVar(VDInit, OriginalAddr);
839 EmitDecl(*VD);
840 LocalDeclMap.erase(VDInit);
841 return GetAddrOfLocalVar(VD);
842 });
Alexey Bataev69c62a92015-04-15 04:52:20 +0000843 }
844 assert(IsRegistered &&
845 "firstprivate var already registered as private");
846 // Silence the warning about unused variable.
847 (void)IsRegistered;
848 }
Richard Trieucc3949d2016-02-18 22:34:54 +0000849 ++IRef;
850 ++InitsRef;
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000851 }
852 }
Alexey Bataevcd8b6a22016-02-15 08:07:17 +0000853 return FirstprivateIsLastprivate && !EmittedAsFirstprivate.empty();
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000854}
855
Alexey Bataev03b340a2014-10-21 03:16:40 +0000856void CodeGenFunction::EmitOMPPrivateClause(
857 const OMPExecutableDirective &D,
858 CodeGenFunction::OMPPrivateScope &PrivateScope) {
Alexey Bataev8ef31412015-12-18 07:58:25 +0000859 if (!HaveInsertPoint())
860 return;
Alexey Bataev50a64582015-04-22 12:24:45 +0000861 llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +0000862 for (const auto *C : D.getClausesOfKind<OMPPrivateClause>()) {
Alexey Bataev03b340a2014-10-21 03:16:40 +0000863 auto IRef = C->varlist_begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +0000864 for (const Expr *IInit : C->private_copies()) {
865 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataev50a64582015-04-22 12:24:45 +0000866 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000867 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
868 bool IsRegistered = PrivateScope.addPrivate(OrigVD, [this, VD]() {
869 // Emit private VarDecl with copy init.
870 EmitDecl(*VD);
871 return GetAddrOfLocalVar(VD);
872 });
Alexey Bataev50a64582015-04-22 12:24:45 +0000873 assert(IsRegistered && "private var already registered as private");
874 // Silence the warning about unused variable.
875 (void)IsRegistered;
876 }
Alexey Bataev03b340a2014-10-21 03:16:40 +0000877 ++IRef;
878 }
879 }
880}
881
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000882bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) {
Alexey Bataev8ef31412015-12-18 07:58:25 +0000883 if (!HaveInsertPoint())
884 return false;
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000885 // threadprivate_var1 = master_threadprivate_var1;
886 // operator=(threadprivate_var2, master_threadprivate_var2);
887 // ...
888 // __kmpc_barrier(&loc, global_tid);
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000889 llvm::DenseSet<const VarDecl *> CopiedVars;
890 llvm::BasicBlock *CopyBegin = nullptr, *CopyEnd = nullptr;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +0000891 for (const auto *C : D.getClausesOfKind<OMPCopyinClause>()) {
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000892 auto IRef = C->varlist_begin();
893 auto ISrcRef = C->source_exprs().begin();
894 auto IDestRef = C->destination_exprs().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +0000895 for (const Expr *AssignOp : C->assignment_ops()) {
896 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataev1d9c15c2015-05-19 12:31:28 +0000897 QualType Type = VD->getType();
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000898 if (CopiedVars.insert(VD->getCanonicalDecl()).second) {
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000899 // Get the address of the master variable. If we are emitting code with
900 // TLS support, the address is passed from the master as field in the
901 // captured declaration.
John McCall7f416cc2015-09-08 08:05:57 +0000902 Address MasterAddr = Address::invalid();
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000903 if (getLangOpts().OpenMPUseTLS &&
904 getContext().getTargetInfo().isTLSSupported()) {
905 assert(CapturedStmtInfo->lookup(VD) &&
906 "Copyin threadprivates should have been captured!");
Bruno Ricci5fc4db72018-12-21 14:10:18 +0000907 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(VD), true,
908 (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000909 MasterAddr = EmitLValue(&DRE).getAddress();
Alexey Bataev2377fe92015-09-10 08:12:02 +0000910 LocalDeclMap.erase(VD);
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000911 } else {
John McCall7f416cc2015-09-08 08:05:57 +0000912 MasterAddr =
913 Address(VD->isStaticLocal() ? CGM.getStaticLocalDeclAddress(VD)
914 : CGM.GetAddrOfGlobal(VD),
915 getContext().getDeclAlign(VD));
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000916 }
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000917 // Get the address of the threadprivate variable.
John McCall7f416cc2015-09-08 08:05:57 +0000918 Address PrivateAddr = EmitLValue(*IRef).getAddress();
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000919 if (CopiedVars.size() == 1) {
920 // At first check if current thread is a master thread. If it is, no
921 // need to copy data.
922 CopyBegin = createBasicBlock("copyin.not.master");
923 CopyEnd = createBasicBlock("copyin.not.master.end");
924 Builder.CreateCondBr(
925 Builder.CreateICmpNE(
John McCall7f416cc2015-09-08 08:05:57 +0000926 Builder.CreatePtrToInt(MasterAddr.getPointer(), CGM.IntPtrTy),
Alexey Bataevddf3db92018-04-13 17:31:06 +0000927 Builder.CreatePtrToInt(PrivateAddr.getPointer(),
928 CGM.IntPtrTy)),
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000929 CopyBegin, CopyEnd);
930 EmitBlock(CopyBegin);
931 }
Alexey Bataevddf3db92018-04-13 17:31:06 +0000932 const auto *SrcVD =
933 cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
934 const auto *DestVD =
935 cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
John McCall7f416cc2015-09-08 08:05:57 +0000936 EmitOMPCopy(Type, PrivateAddr, MasterAddr, DestVD, SrcVD, AssignOp);
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000937 }
938 ++IRef;
939 ++ISrcRef;
940 ++IDestRef;
941 }
942 }
943 if (CopyEnd) {
944 // Exit out of copying procedure for non-master thread.
945 EmitBlock(CopyEnd, /*IsFinished=*/true);
946 return true;
947 }
948 return false;
949}
950
Alexey Bataev38e89532015-04-16 04:54:05 +0000951bool CodeGenFunction::EmitOMPLastprivateClauseInit(
952 const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) {
Alexey Bataev8ef31412015-12-18 07:58:25 +0000953 if (!HaveInsertPoint())
954 return false;
Alexey Bataev38e89532015-04-16 04:54:05 +0000955 bool HasAtLeastOneLastprivate = false;
Alexey Bataev5dff95c2016-04-22 03:56:56 +0000956 llvm::DenseSet<const VarDecl *> SIMDLCVs;
957 if (isOpenMPSimdDirective(D.getDirectiveKind())) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000958 const auto *LoopDirective = cast<OMPLoopDirective>(&D);
959 for (const Expr *C : LoopDirective->counters()) {
Alexey Bataev5dff95c2016-04-22 03:56:56 +0000960 SIMDLCVs.insert(
961 cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl());
962 }
963 }
Alexey Bataev38e89532015-04-16 04:54:05 +0000964 llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +0000965 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
Alexey Bataevd130fd12015-05-13 10:23:02 +0000966 HasAtLeastOneLastprivate = true;
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000967 if (isOpenMPTaskLoopDirective(D.getDirectiveKind()) &&
968 !getLangOpts().OpenMPSimd)
Alexey Bataevf93095a2016-05-05 08:46:22 +0000969 break;
Alexey Bataev38e89532015-04-16 04:54:05 +0000970 auto IRef = C->varlist_begin();
971 auto IDestRef = C->destination_exprs().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +0000972 for (const Expr *IInit : C->private_copies()) {
Alexey Bataev38e89532015-04-16 04:54:05 +0000973 // Keep the address of the original variable for future update at the end
974 // of the loop.
Alexey Bataevddf3db92018-04-13 17:31:06 +0000975 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataevf93095a2016-05-05 08:46:22 +0000976 // Taskloops do not require additional initialization, it is done in
977 // runtime support library.
Alexey Bataev38e89532015-04-16 04:54:05 +0000978 if (AlreadyEmittedVars.insert(OrigVD->getCanonicalDecl()).second) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000979 const auto *DestVD =
980 cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
981 PrivateScope.addPrivate(DestVD, [this, OrigVD, IRef]() {
Bruno Ricci5fc4db72018-12-21 14:10:18 +0000982 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
983 /*RefersToEnclosingVariableOrCapture=*/
984 CapturedStmtInfo->lookup(OrigVD) != nullptr,
985 (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
Alexey Bataev38e89532015-04-16 04:54:05 +0000986 return EmitLValue(&DRE).getAddress();
987 });
988 // Check if the variable is also a firstprivate: in this case IInit is
989 // not generated. Initialization of this variable will happen in codegen
990 // for 'firstprivate' clause.
Alexey Bataev5dff95c2016-04-22 03:56:56 +0000991 if (IInit && !SIMDLCVs.count(OrigVD->getCanonicalDecl())) {
Alexey Bataevddf3db92018-04-13 17:31:06 +0000992 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
993 bool IsRegistered = PrivateScope.addPrivate(OrigVD, [this, VD]() {
Alexey Bataevf93095a2016-05-05 08:46:22 +0000994 // Emit private VarDecl with copy init.
995 EmitDecl(*VD);
996 return GetAddrOfLocalVar(VD);
997 });
Alexey Bataevd130fd12015-05-13 10:23:02 +0000998 assert(IsRegistered &&
999 "lastprivate var already registered as private");
1000 (void)IsRegistered;
1001 }
Alexey Bataev38e89532015-04-16 04:54:05 +00001002 }
Richard Trieucc3949d2016-02-18 22:34:54 +00001003 ++IRef;
1004 ++IDestRef;
Alexey Bataev38e89532015-04-16 04:54:05 +00001005 }
1006 }
1007 return HasAtLeastOneLastprivate;
1008}
1009
1010void CodeGenFunction::EmitOMPLastprivateClauseFinal(
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001011 const OMPExecutableDirective &D, bool NoFinals,
1012 llvm::Value *IsLastIterCond) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001013 if (!HaveInsertPoint())
1014 return;
Alexey Bataev38e89532015-04-16 04:54:05 +00001015 // Emit following code:
1016 // if (<IsLastIterCond>) {
1017 // orig_var1 = private_orig_var1;
1018 // ...
1019 // orig_varn = private_orig_varn;
1020 // }
Alexey Bataevfc087ec2015-06-16 13:14:42 +00001021 llvm::BasicBlock *ThenBB = nullptr;
1022 llvm::BasicBlock *DoneBB = nullptr;
1023 if (IsLastIterCond) {
1024 ThenBB = createBasicBlock(".omp.lastprivate.then");
1025 DoneBB = createBasicBlock(".omp.lastprivate.done");
1026 Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB);
1027 EmitBlock(ThenBB);
1028 }
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001029 llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
1030 llvm::DenseMap<const VarDecl *, const Expr *> LoopCountersAndUpdates;
Alexey Bataevddf3db92018-04-13 17:31:06 +00001031 if (const auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) {
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001032 auto IC = LoopDirective->counters().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001033 for (const Expr *F : LoopDirective->finals()) {
1034 const auto *D =
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001035 cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl())->getCanonicalDecl();
1036 if (NoFinals)
1037 AlreadyEmittedVars.insert(D);
1038 else
1039 LoopCountersAndUpdates[D] = F;
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001040 ++IC;
Alexey Bataev7a228ff2015-05-21 07:59:51 +00001041 }
1042 }
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001043 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
1044 auto IRef = C->varlist_begin();
1045 auto ISrcRef = C->source_exprs().begin();
1046 auto IDestRef = C->destination_exprs().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001047 for (const Expr *AssignOp : C->assignment_ops()) {
1048 const auto *PrivateVD =
1049 cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001050 QualType Type = PrivateVD->getType();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001051 const auto *CanonicalVD = PrivateVD->getCanonicalDecl();
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001052 if (AlreadyEmittedVars.insert(CanonicalVD).second) {
1053 // If lastprivate variable is a loop control variable for loop-based
1054 // directive, update its value before copyin back to original
1055 // variable.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001056 if (const Expr *FinalExpr = LoopCountersAndUpdates.lookup(CanonicalVD))
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001057 EmitIgnoredExpr(FinalExpr);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001058 const auto *SrcVD =
1059 cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
1060 const auto *DestVD =
1061 cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001062 // Get the address of the original variable.
1063 Address OriginalAddr = GetAddrOfLocalVar(DestVD);
1064 // Get the address of the private variable.
1065 Address PrivateAddr = GetAddrOfLocalVar(PrivateVD);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001066 if (const auto *RefTy = PrivateVD->getType()->getAs<ReferenceType>())
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001067 PrivateAddr =
John McCall7f416cc2015-09-08 08:05:57 +00001068 Address(Builder.CreateLoad(PrivateAddr),
1069 getNaturalTypeAlignment(RefTy->getPointeeType()));
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001070 EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp);
Alexey Bataev38e89532015-04-16 04:54:05 +00001071 }
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001072 ++IRef;
1073 ++ISrcRef;
1074 ++IDestRef;
Alexey Bataev38e89532015-04-16 04:54:05 +00001075 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00001076 if (const Expr *PostUpdate = C->getPostUpdateExpr())
Alexey Bataev005248a2016-02-25 05:25:57 +00001077 EmitIgnoredExpr(PostUpdate);
Alexey Bataev38e89532015-04-16 04:54:05 +00001078 }
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001079 if (IsLastIterCond)
Alexey Bataevfc087ec2015-06-16 13:14:42 +00001080 EmitBlock(DoneBB, /*IsFinished=*/true);
Alexey Bataev38e89532015-04-16 04:54:05 +00001081}
1082
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001083void CodeGenFunction::EmitOMPReductionClauseInit(
1084 const OMPExecutableDirective &D,
1085 CodeGenFunction::OMPPrivateScope &PrivateScope) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001086 if (!HaveInsertPoint())
1087 return;
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001088 SmallVector<const Expr *, 4> Shareds;
1089 SmallVector<const Expr *, 4> Privates;
1090 SmallVector<const Expr *, 4> ReductionOps;
1091 SmallVector<const Expr *, 4> LHSs;
1092 SmallVector<const Expr *, 4> RHSs;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001093 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001094 auto IPriv = C->privates().begin();
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001095 auto IRed = C->reduction_ops().begin();
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001096 auto ILHS = C->lhs_exprs().begin();
1097 auto IRHS = C->rhs_exprs().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001098 for (const Expr *Ref : C->varlists()) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001099 Shareds.emplace_back(Ref);
1100 Privates.emplace_back(*IPriv);
1101 ReductionOps.emplace_back(*IRed);
1102 LHSs.emplace_back(*ILHS);
1103 RHSs.emplace_back(*IRHS);
1104 std::advance(IPriv, 1);
1105 std::advance(IRed, 1);
1106 std::advance(ILHS, 1);
1107 std::advance(IRHS, 1);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001108 }
1109 }
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001110 ReductionCodeGen RedCG(Shareds, Privates, ReductionOps);
1111 unsigned Count = 0;
1112 auto ILHS = LHSs.begin();
1113 auto IRHS = RHSs.begin();
1114 auto IPriv = Privates.begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001115 for (const Expr *IRef : Shareds) {
1116 const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl());
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001117 // Emit private VarDecl with reduction init.
1118 RedCG.emitSharedLValue(*this, Count);
1119 RedCG.emitAggregateType(*this, Count);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001120 AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001121 RedCG.emitInitialization(*this, Count, Emission.getAllocatedAddress(),
1122 RedCG.getSharedLValue(Count),
1123 [&Emission](CodeGenFunction &CGF) {
1124 CGF.EmitAutoVarInit(Emission);
1125 return true;
1126 });
1127 EmitAutoVarCleanups(Emission);
1128 Address BaseAddr = RedCG.adjustPrivateAddress(
1129 *this, Count, Emission.getAllocatedAddress());
1130 bool IsRegistered = PrivateScope.addPrivate(
Alexey Bataevddf3db92018-04-13 17:31:06 +00001131 RedCG.getBaseDecl(Count), [BaseAddr]() { return BaseAddr; });
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001132 assert(IsRegistered && "private var already registered as private");
1133 // Silence the warning about unused variable.
1134 (void)IsRegistered;
1135
Alexey Bataevddf3db92018-04-13 17:31:06 +00001136 const auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
1137 const auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
Jonas Hahnfeld4525c822017-10-23 19:01:35 +00001138 QualType Type = PrivateVD->getType();
1139 bool isaOMPArraySectionExpr = isa<OMPArraySectionExpr>(IRef);
1140 if (isaOMPArraySectionExpr && Type->isVariablyModifiedType()) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001141 // Store the address of the original variable associated with the LHS
1142 // implicit variable.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001143 PrivateScope.addPrivate(LHSVD, [&RedCG, Count]() {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001144 return RedCG.getSharedLValue(Count).getAddress();
1145 });
Alexey Bataevddf3db92018-04-13 17:31:06 +00001146 PrivateScope.addPrivate(
1147 RHSVD, [this, PrivateVD]() { return GetAddrOfLocalVar(PrivateVD); });
Jonas Hahnfeld4525c822017-10-23 19:01:35 +00001148 } else if ((isaOMPArraySectionExpr && Type->isScalarType()) ||
1149 isa<ArraySubscriptExpr>(IRef)) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001150 // Store the address of the original variable associated with the LHS
1151 // implicit variable.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001152 PrivateScope.addPrivate(LHSVD, [&RedCG, Count]() {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001153 return RedCG.getSharedLValue(Count).getAddress();
1154 });
Alexey Bataevddf3db92018-04-13 17:31:06 +00001155 PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001156 return Builder.CreateElementBitCast(GetAddrOfLocalVar(PrivateVD),
1157 ConvertTypeForMem(RHSVD->getType()),
1158 "rhs.begin");
1159 });
1160 } else {
1161 QualType Type = PrivateVD->getType();
1162 bool IsArray = getContext().getAsArrayType(Type) != nullptr;
1163 Address OriginalAddr = RedCG.getSharedLValue(Count).getAddress();
1164 // Store the address of the original variable associated with the LHS
1165 // implicit variable.
1166 if (IsArray) {
1167 OriginalAddr = Builder.CreateElementBitCast(
1168 OriginalAddr, ConvertTypeForMem(LHSVD->getType()), "lhs.begin");
1169 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00001170 PrivateScope.addPrivate(LHSVD, [OriginalAddr]() { return OriginalAddr; });
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001171 PrivateScope.addPrivate(
Alexey Bataevddf3db92018-04-13 17:31:06 +00001172 RHSVD, [this, PrivateVD, RHSVD, IsArray]() {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001173 return IsArray
1174 ? Builder.CreateElementBitCast(
1175 GetAddrOfLocalVar(PrivateVD),
1176 ConvertTypeForMem(RHSVD->getType()), "rhs.begin")
1177 : GetAddrOfLocalVar(PrivateVD);
1178 });
1179 }
1180 ++ILHS;
1181 ++IRHS;
1182 ++IPriv;
1183 ++Count;
1184 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001185}
1186
1187void CodeGenFunction::EmitOMPReductionClauseFinal(
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001188 const OMPExecutableDirective &D, const OpenMPDirectiveKind ReductionKind) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001189 if (!HaveInsertPoint())
1190 return;
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001191 llvm::SmallVector<const Expr *, 8> Privates;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001192 llvm::SmallVector<const Expr *, 8> LHSExprs;
1193 llvm::SmallVector<const Expr *, 8> RHSExprs;
1194 llvm::SmallVector<const Expr *, 8> ReductionOps;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001195 bool HasAtLeastOneReduction = false;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001196 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001197 HasAtLeastOneReduction = true;
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001198 Privates.append(C->privates().begin(), C->privates().end());
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001199 LHSExprs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
1200 RHSExprs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
1201 ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
1202 }
1203 if (HasAtLeastOneReduction) {
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001204 bool WithNowait = D.getSingleClause<OMPNowaitClause>() ||
1205 isOpenMPParallelDirective(D.getDirectiveKind()) ||
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001206 ReductionKind == OMPD_simd;
1207 bool SimpleReduction = ReductionKind == OMPD_simd;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001208 // Emit nowait reduction if nowait clause is present or directive is a
1209 // parallel directive (it always has implicit barrier).
1210 CGM.getOpenMPRuntime().emitReduction(
Stephen Kelly1c301dc2018-08-09 21:09:38 +00001211 *this, D.getEndLoc(), Privates, LHSExprs, RHSExprs, ReductionOps,
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001212 {WithNowait, SimpleReduction, ReductionKind});
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001213 }
1214}
1215
Alexey Bataev61205072016-03-02 04:57:40 +00001216static void emitPostUpdateForReductionClause(
1217 CodeGenFunction &CGF, const OMPExecutableDirective &D,
Alexey Bataevddf3db92018-04-13 17:31:06 +00001218 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) {
Alexey Bataev61205072016-03-02 04:57:40 +00001219 if (!CGF.HaveInsertPoint())
1220 return;
1221 llvm::BasicBlock *DoneBB = nullptr;
1222 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001223 if (const Expr *PostUpdate = C->getPostUpdateExpr()) {
Alexey Bataev61205072016-03-02 04:57:40 +00001224 if (!DoneBB) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001225 if (llvm::Value *Cond = CondGen(CGF)) {
Alexey Bataev61205072016-03-02 04:57:40 +00001226 // If the first post-update expression is found, emit conditional
1227 // block if it was requested.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001228 llvm::BasicBlock *ThenBB = CGF.createBasicBlock(".omp.reduction.pu");
Alexey Bataev61205072016-03-02 04:57:40 +00001229 DoneBB = CGF.createBasicBlock(".omp.reduction.pu.done");
1230 CGF.Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1231 CGF.EmitBlock(ThenBB);
1232 }
1233 }
1234 CGF.EmitIgnoredExpr(PostUpdate);
1235 }
1236 }
1237 if (DoneBB)
1238 CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
1239}
1240
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001241namespace {
1242/// Codegen lambda for appending distribute lower and upper bounds to outlined
1243/// parallel function. This is necessary for combined constructs such as
1244/// 'distribute parallel for'
1245typedef llvm::function_ref<void(CodeGenFunction &,
1246 const OMPExecutableDirective &,
1247 llvm::SmallVectorImpl<llvm::Value *> &)>
1248 CodeGenBoundParametersTy;
1249} // anonymous namespace
1250
1251static void emitCommonOMPParallelDirective(
1252 CodeGenFunction &CGF, const OMPExecutableDirective &S,
1253 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
1254 const CodeGenBoundParametersTy &CodeGenBoundParameters) {
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00001255 const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel);
James Y Knight9871db02019-02-05 16:42:33 +00001256 llvm::Function *OutlinedFn =
Alexey Bataevddf3db92018-04-13 17:31:06 +00001257 CGF.CGM.getOpenMPRuntime().emitParallelOutlinedFunction(
1258 S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001259 if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>()) {
Alexey Bataev1d677132015-04-22 13:57:31 +00001260 CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001261 llvm::Value *NumThreads =
1262 CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(),
1263 /*IgnoreResultAssign=*/true);
Alexey Bataev1d677132015-04-22 13:57:31 +00001264 CGF.CGM.getOpenMPRuntime().emitNumThreadsClause(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001265 CGF, NumThreads, NumThreadsClause->getBeginLoc());
Alexey Bataev1d677132015-04-22 13:57:31 +00001266 }
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001267 if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>()) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001268 CodeGenFunction::RunCleanupsScope ProcBindScope(CGF);
Alexey Bataev7f210c62015-06-18 13:40:03 +00001269 CGF.CGM.getOpenMPRuntime().emitProcBindClause(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001270 CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getBeginLoc());
Alexey Bataev7f210c62015-06-18 13:40:03 +00001271 }
Alexey Bataev1d677132015-04-22 13:57:31 +00001272 const Expr *IfCond = nullptr;
Alexey Bataev7371aa32015-09-03 08:45:56 +00001273 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
1274 if (C->getNameModifier() == OMPD_unknown ||
1275 C->getNameModifier() == OMPD_parallel) {
1276 IfCond = C->getCondition();
1277 break;
1278 }
Alexey Bataev1d677132015-04-22 13:57:31 +00001279 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001280
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00001281 OMPParallelScope Scope(CGF, S);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001282 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001283 // Combining 'distribute' with 'for' requires sharing each 'distribute' chunk
1284 // lower and upper bounds with the pragma 'for' chunking mechanism.
1285 // The following lambda takes care of appending the lower and upper bound
1286 // parameters when necessary
1287 CodeGenBoundParameters(CGF, S, CapturedVars);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001288 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001289 CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getBeginLoc(), OutlinedFn,
Alexey Bataev2377fe92015-09-10 08:12:02 +00001290 CapturedVars, IfCond);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001291}
1292
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001293static void emitEmptyBoundParameters(CodeGenFunction &,
1294 const OMPExecutableDirective &,
1295 llvm::SmallVectorImpl<llvm::Value *> &) {}
1296
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001297void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001298 // Emit parallel region as a standalone region.
Alexey Bataevc99042b2018-03-15 18:10:54 +00001299 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00001300 Action.Enter(CGF);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001301 OMPPrivateScope PrivateScope(CGF);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00001302 bool Copyins = CGF.EmitOMPCopyinClause(S);
Alexey Bataevcd8b6a22016-02-15 08:07:17 +00001303 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
1304 if (Copyins) {
Alexey Bataev69c62a92015-04-15 04:52:20 +00001305 // Emit implicit barrier to synchronize threads and avoid data races on
Alexey Bataevcd8b6a22016-02-15 08:07:17 +00001306 // propagation master's thread values of threadprivate variables to local
1307 // instances of that variables of all other implicit threads.
Alexey Bataev25e5b442015-09-15 12:52:43 +00001308 CGF.CGM.getOpenMPRuntime().emitBarrierCall(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001309 CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
Alexey Bataev25e5b442015-09-15 12:52:43 +00001310 /*ForceSimpleCall=*/true);
Alexey Bataev69c62a92015-04-15 04:52:20 +00001311 }
1312 CGF.EmitOMPPrivateClause(S, PrivateScope);
1313 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
1314 (void)PrivateScope.Privatize();
Alexey Bataev475a7442018-01-12 19:39:11 +00001315 CGF.EmitStmt(S.getCapturedStmt(OMPD_parallel)->getCapturedStmt());
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001316 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001317 };
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001318 emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen,
1319 emitEmptyBoundParameters);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001320 emitPostUpdateForReductionClause(*this, S,
1321 [](CodeGenFunction &) { return nullptr; });
Alexey Bataev9959db52014-05-06 10:08:46 +00001322}
Alexander Musman515ad8c2014-05-22 08:54:05 +00001323
Alexey Bataev0f34da12015-07-02 04:17:07 +00001324void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D,
1325 JumpDest LoopExit) {
Alexander Musmana5f070a2014-10-01 06:03:56 +00001326 RunCleanupsScope BodyScope(*this);
1327 // Update counters values on current iteration.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001328 for (const Expr *UE : D.updates())
1329 EmitIgnoredExpr(UE);
Alexander Musman3276a272015-03-21 10:12:56 +00001330 // Update the linear variables.
Alexey Bataev617db5f2017-12-04 15:38:33 +00001331 // In distribute directives only loop counters may be marked as linear, no
1332 // need to generate the code for them.
1333 if (!isOpenMPDistributeDirective(D.getDirectiveKind())) {
1334 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001335 for (const Expr *UE : C->updates())
1336 EmitIgnoredExpr(UE);
Alexey Bataev617db5f2017-12-04 15:38:33 +00001337 }
Alexander Musman3276a272015-03-21 10:12:56 +00001338 }
1339
Alexander Musmana5f070a2014-10-01 06:03:56 +00001340 // On a continue in the body, jump to the end.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001341 JumpDest Continue = getJumpDestInCurrentScope("omp.body.continue");
Alexey Bataev0f34da12015-07-02 04:17:07 +00001342 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
Alexey Bataevf8be4762019-08-14 19:30:06 +00001343 for (const Expr *E : D.finals_conditions()) {
1344 if (!E)
1345 continue;
1346 // Check that loop counter in non-rectangular nest fits into the iteration
1347 // space.
1348 llvm::BasicBlock *NextBB = createBasicBlock("omp.body.next");
1349 EmitBranchOnBoolExpr(E, NextBB, Continue.getBlock(),
1350 getProfileCount(D.getBody()));
1351 EmitBlock(NextBB);
1352 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00001353 // Emit loop body.
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001354 EmitStmt(D.getBody());
Alexander Musmana5f070a2014-10-01 06:03:56 +00001355 // The end (updates/cleanups).
1356 EmitBlock(Continue.getBlock());
1357 BreakContinueStack.pop_back();
Alexander Musmana5f070a2014-10-01 06:03:56 +00001358}
1359
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001360void CodeGenFunction::EmitOMPInnerLoop(
1361 const Stmt &S, bool RequiresCleanup, const Expr *LoopCond,
1362 const Expr *IncExpr,
Alexey Bataevddf3db92018-04-13 17:31:06 +00001363 const llvm::function_ref<void(CodeGenFunction &)> BodyGen,
1364 const llvm::function_ref<void(CodeGenFunction &)> PostIncGen) {
Alexander Musmand196ef22014-10-07 08:57:09 +00001365 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
Alexander Musmana5f070a2014-10-01 06:03:56 +00001366
1367 // Start the loop with a block that tests the condition.
Alexander Musmand196ef22014-10-07 08:57:09 +00001368 auto CondBlock = createBasicBlock("omp.inner.for.cond");
Alexander Musmana5f070a2014-10-01 06:03:56 +00001369 EmitBlock(CondBlock);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001370 const SourceRange R = S.getSourceRange();
Amara Emerson652795d2016-11-10 14:44:30 +00001371 LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()),
1372 SourceLocToDebugLoc(R.getEnd()));
Alexander Musmana5f070a2014-10-01 06:03:56 +00001373
1374 // If there are any cleanups between here and the loop-exit scope,
1375 // create a block to stage a loop exit along.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001376 llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
Alexey Bataev2df54a02015-03-12 08:53:29 +00001377 if (RequiresCleanup)
Alexander Musmand196ef22014-10-07 08:57:09 +00001378 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
Alexander Musmana5f070a2014-10-01 06:03:56 +00001379
Alexey Bataevddf3db92018-04-13 17:31:06 +00001380 llvm::BasicBlock *LoopBody = createBasicBlock("omp.inner.for.body");
Alexander Musmana5f070a2014-10-01 06:03:56 +00001381
Alexey Bataev2df54a02015-03-12 08:53:29 +00001382 // Emit condition.
Justin Bogner66242d62015-04-23 23:06:47 +00001383 EmitBranchOnBoolExpr(LoopCond, LoopBody, ExitBlock, getProfileCount(&S));
Alexander Musmana5f070a2014-10-01 06:03:56 +00001384 if (ExitBlock != LoopExit.getBlock()) {
1385 EmitBlock(ExitBlock);
1386 EmitBranchThroughCleanup(LoopExit);
1387 }
1388
1389 EmitBlock(LoopBody);
Justin Bogner66242d62015-04-23 23:06:47 +00001390 incrementProfileCounter(&S);
Alexander Musmana5f070a2014-10-01 06:03:56 +00001391
1392 // Create a block for the increment.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001393 JumpDest Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
Alexander Musmana5f070a2014-10-01 06:03:56 +00001394 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1395
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001396 BodyGen(*this);
Alexander Musmana5f070a2014-10-01 06:03:56 +00001397
1398 // Emit "IV = IV + 1" and a back-edge to the condition block.
1399 EmitBlock(Continue.getBlock());
Alexey Bataev2df54a02015-03-12 08:53:29 +00001400 EmitIgnoredExpr(IncExpr);
Alexey Bataev98eb6e32015-04-22 11:15:40 +00001401 PostIncGen(*this);
Alexander Musmana5f070a2014-10-01 06:03:56 +00001402 BreakContinueStack.pop_back();
1403 EmitBranch(CondBlock);
1404 LoopStack.pop();
1405 // Emit the fall-through block.
1406 EmitBlock(LoopExit.getBlock());
1407}
1408
Alexey Bataev8c3edfe2017-08-16 15:58:46 +00001409bool CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001410 if (!HaveInsertPoint())
Alexey Bataev8c3edfe2017-08-16 15:58:46 +00001411 return false;
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001412 // Emit inits for the linear variables.
Alexey Bataev8c3edfe2017-08-16 15:58:46 +00001413 bool HasLinears = false;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001414 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001415 for (const Expr *Init : C->inits()) {
Alexey Bataev8c3edfe2017-08-16 15:58:46 +00001416 HasLinears = true;
Alexey Bataevddf3db92018-04-13 17:31:06 +00001417 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl());
1418 if (const auto *Ref =
1419 dyn_cast<DeclRefExpr>(VD->getInit()->IgnoreImpCasts())) {
Alexey Bataevef549a82016-03-09 09:49:09 +00001420 AutoVarEmission Emission = EmitAutoVarAlloca(*VD);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001421 const auto *OrigVD = cast<VarDecl>(Ref->getDecl());
Bruno Ricci5fc4db72018-12-21 14:10:18 +00001422 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
Alexey Bataevef549a82016-03-09 09:49:09 +00001423 CapturedStmtInfo->lookup(OrigVD) != nullptr,
1424 VD->getInit()->getType(), VK_LValue,
1425 VD->getInit()->getExprLoc());
1426 EmitExprAsInit(&DRE, VD, MakeAddrLValue(Emission.getAllocatedAddress(),
1427 VD->getType()),
1428 /*capturedByInit=*/false);
1429 EmitAutoVarCleanups(Emission);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001430 } else {
Alexey Bataevef549a82016-03-09 09:49:09 +00001431 EmitVarDecl(*VD);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001432 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00001433 }
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001434 // Emit the linear steps for the linear clauses.
1435 // If a step is not constant, it is pre-calculated before the loop.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001436 if (const auto *CS = cast_or_null<BinaryOperator>(C->getCalcStep()))
1437 if (const auto *SaveRef = cast<DeclRefExpr>(CS->getLHS())) {
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00001438 EmitVarDecl(*cast<VarDecl>(SaveRef->getDecl()));
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001439 // Emit calculation of the linear step.
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00001440 EmitIgnoredExpr(CS);
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001441 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00001442 }
Alexey Bataev8c3edfe2017-08-16 15:58:46 +00001443 return HasLinears;
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001444}
1445
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001446void CodeGenFunction::EmitOMPLinearClauseFinal(
1447 const OMPLoopDirective &D,
Alexey Bataevddf3db92018-04-13 17:31:06 +00001448 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) {
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001449 if (!HaveInsertPoint())
Alexey Bataev8ef31412015-12-18 07:58:25 +00001450 return;
Alexey Bataevef549a82016-03-09 09:49:09 +00001451 llvm::BasicBlock *DoneBB = nullptr;
Alexander Musman3276a272015-03-21 10:12:56 +00001452 // Emit the final values of the linear variables.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001453 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
Alexey Bataev39f915b82015-05-08 10:41:21 +00001454 auto IC = C->varlist_begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001455 for (const Expr *F : C->finals()) {
Alexey Bataevef549a82016-03-09 09:49:09 +00001456 if (!DoneBB) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001457 if (llvm::Value *Cond = CondGen(*this)) {
Alexey Bataevef549a82016-03-09 09:49:09 +00001458 // If the first post-update expression is found, emit conditional
1459 // block if it was requested.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001460 llvm::BasicBlock *ThenBB = createBasicBlock(".omp.linear.pu");
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001461 DoneBB = createBasicBlock(".omp.linear.pu.done");
1462 Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1463 EmitBlock(ThenBB);
Alexey Bataevef549a82016-03-09 09:49:09 +00001464 }
1465 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00001466 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl());
Bruno Ricci5fc4db72018-12-21 14:10:18 +00001467 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001468 CapturedStmtInfo->lookup(OrigVD) != nullptr,
Alexey Bataev39f915b82015-05-08 10:41:21 +00001469 (*IC)->getType(), VK_LValue, (*IC)->getExprLoc());
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001470 Address OrigAddr = EmitLValue(&DRE).getAddress();
1471 CodeGenFunction::OMPPrivateScope VarScope(*this);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001472 VarScope.addPrivate(OrigVD, [OrigAddr]() { return OrigAddr; });
Alexey Bataev39f915b82015-05-08 10:41:21 +00001473 (void)VarScope.Privatize();
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001474 EmitIgnoredExpr(F);
Alexey Bataev39f915b82015-05-08 10:41:21 +00001475 ++IC;
Alexander Musman3276a272015-03-21 10:12:56 +00001476 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00001477 if (const Expr *PostUpdate = C->getPostUpdateExpr())
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001478 EmitIgnoredExpr(PostUpdate);
Alexander Musman3276a272015-03-21 10:12:56 +00001479 }
Alexey Bataevef549a82016-03-09 09:49:09 +00001480 if (DoneBB)
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001481 EmitBlock(DoneBB, /*IsFinished=*/true);
Alexander Musmana5f070a2014-10-01 06:03:56 +00001482}
1483
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001484static void emitAlignedClause(CodeGenFunction &CGF,
1485 const OMPExecutableDirective &D) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001486 if (!CGF.HaveInsertPoint())
1487 return;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001488 for (const auto *Clause : D.getClausesOfKind<OMPAlignedClause>()) {
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001489 unsigned ClauseAlignment = 0;
Alexey Bataevddf3db92018-04-13 17:31:06 +00001490 if (const Expr *AlignmentExpr = Clause->getAlignment()) {
1491 auto *AlignmentCI =
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001492 cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
1493 ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue());
Alexander Musman09184fe2014-09-30 05:29:28 +00001494 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00001495 for (const Expr *E : Clause->varlists()) {
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001496 unsigned Alignment = ClauseAlignment;
1497 if (Alignment == 0) {
1498 // OpenMP [2.8.1, Description]
1499 // If no optional parameter is specified, implementation-defined default
1500 // alignments for SIMD instructions on the target platforms are assumed.
1501 Alignment =
Alexey Bataev00396512015-07-02 03:40:19 +00001502 CGF.getContext()
1503 .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign(
1504 E->getType()->getPointeeType()))
1505 .getQuantity();
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001506 }
1507 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
1508 "alignment is not power of 2");
1509 if (Alignment != 0) {
1510 llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
Roman Lebedevbd1c0872019-01-15 09:44:25 +00001511 CGF.EmitAlignmentAssumption(
1512 PtrValue, E, /*No second loc needed*/ SourceLocation(), Alignment);
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001513 }
Alexander Musman09184fe2014-09-30 05:29:28 +00001514 }
1515 }
1516}
1517
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001518void CodeGenFunction::EmitOMPPrivateLoopCounters(
1519 const OMPLoopDirective &S, CodeGenFunction::OMPPrivateScope &LoopScope) {
1520 if (!HaveInsertPoint())
Alexey Bataev8ef31412015-12-18 07:58:25 +00001521 return;
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001522 auto I = S.private_counters().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001523 for (const Expr *E : S.counters()) {
1524 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
1525 const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl());
Alexey Bataevab4ea222018-03-07 18:17:06 +00001526 // Emit var without initialization.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001527 AutoVarEmission VarEmission = EmitAutoVarAlloca(*PrivateVD);
Alexey Bataevab4ea222018-03-07 18:17:06 +00001528 EmitAutoVarCleanups(VarEmission);
1529 LocalDeclMap.erase(PrivateVD);
1530 (void)LoopScope.addPrivate(VD, [&VarEmission]() {
1531 return VarEmission.getAllocatedAddress();
Alexey Bataev435ad7b2014-10-10 09:48:26 +00001532 });
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001533 if (LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD) ||
1534 VD->hasGlobalStorage()) {
Alexey Bataevab4ea222018-03-07 18:17:06 +00001535 (void)LoopScope.addPrivate(PrivateVD, [this, VD, E]() {
Bruno Ricci5fc4db72018-12-21 14:10:18 +00001536 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(VD),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001537 LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD),
1538 E->getType(), VK_LValue, E->getExprLoc());
1539 return EmitLValue(&DRE).getAddress();
1540 });
Alexey Bataevab4ea222018-03-07 18:17:06 +00001541 } else {
1542 (void)LoopScope.addPrivate(PrivateVD, [&VarEmission]() {
1543 return VarEmission.getAllocatedAddress();
1544 });
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001545 }
Alexey Bataeva8899172015-08-06 12:30:57 +00001546 ++I;
Alexey Bataev435ad7b2014-10-10 09:48:26 +00001547 }
Alexey Bataevf138fda2018-08-13 19:04:24 +00001548 // Privatize extra loop counters used in loops for ordered(n) clauses.
1549 for (const auto *C : S.getClausesOfKind<OMPOrderedClause>()) {
1550 if (!C->getNumForLoops())
1551 continue;
1552 for (unsigned I = S.getCollapsedNumber(),
1553 E = C->getLoopNumIterations().size();
1554 I < E; ++I) {
Mike Rice0ed46662018-09-20 17:19:41 +00001555 const auto *DRE = cast<DeclRefExpr>(C->getLoopCounter(I));
Alexey Bataevf138fda2018-08-13 19:04:24 +00001556 const auto *VD = cast<VarDecl>(DRE->getDecl());
Alexey Bataev0d8fcdf2019-03-14 20:36:00 +00001557 // Override only those variables that can be captured to avoid re-emission
1558 // of the variables declared within the loops.
1559 if (DRE->refersToEnclosingVariableOrCapture()) {
Alexey Bataevf138fda2018-08-13 19:04:24 +00001560 (void)LoopScope.addPrivate(VD, [this, DRE, VD]() {
1561 return CreateMemTemp(DRE->getType(), VD->getName());
1562 });
1563 }
1564 }
1565 }
Alexey Bataev435ad7b2014-10-10 09:48:26 +00001566}
1567
Alexey Bataev62dbb972015-04-22 11:59:37 +00001568static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S,
1569 const Expr *Cond, llvm::BasicBlock *TrueBlock,
1570 llvm::BasicBlock *FalseBlock, uint64_t TrueCount) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001571 if (!CGF.HaveInsertPoint())
1572 return;
Alexey Bataev6e8248f2015-06-11 10:53:56 +00001573 {
1574 CodeGenFunction::OMPPrivateScope PreCondScope(CGF);
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001575 CGF.EmitOMPPrivateLoopCounters(S, PreCondScope);
Alexey Bataev6e8248f2015-06-11 10:53:56 +00001576 (void)PreCondScope.Privatize();
Alexey Bataev6e8248f2015-06-11 10:53:56 +00001577 // Get initial values of real counters.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001578 for (const Expr *I : S.inits()) {
Alexey Bataev6e8248f2015-06-11 10:53:56 +00001579 CGF.EmitIgnoredExpr(I);
1580 }
Alexey Bataev62dbb972015-04-22 11:59:37 +00001581 }
Alexey Bataevf8be4762019-08-14 19:30:06 +00001582 // Create temp loop control variables with their init values to support
1583 // non-rectangular loops.
1584 CodeGenFunction::OMPMapVars PreCondVars;
1585 for (const Expr * E: S.dependent_counters()) {
1586 if (!E)
1587 continue;
1588 assert(!E->getType().getNonReferenceType()->isRecordType() &&
1589 "dependent counter must not be an iterator.");
1590 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
1591 Address CounterAddr =
1592 CGF.CreateMemTemp(VD->getType().getNonReferenceType());
1593 (void)PreCondVars.setVarAddr(CGF, VD, CounterAddr);
1594 }
1595 (void)PreCondVars.apply(CGF);
1596 for (const Expr *E : S.dependent_inits()) {
1597 if (!E)
1598 continue;
1599 CGF.EmitIgnoredExpr(E);
1600 }
Alexey Bataev62dbb972015-04-22 11:59:37 +00001601 // Check that loop is executed at least one time.
1602 CGF.EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount);
Alexey Bataevf8be4762019-08-14 19:30:06 +00001603 PreCondVars.restore(CGF);
Alexey Bataev62dbb972015-04-22 11:59:37 +00001604}
1605
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001606void CodeGenFunction::EmitOMPLinearClause(
1607 const OMPLoopDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) {
1608 if (!HaveInsertPoint())
Alexey Bataev8ef31412015-12-18 07:58:25 +00001609 return;
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001610 llvm::DenseSet<const VarDecl *> SIMDLCVs;
1611 if (isOpenMPSimdDirective(D.getDirectiveKind())) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001612 const auto *LoopDirective = cast<OMPLoopDirective>(&D);
1613 for (const Expr *C : LoopDirective->counters()) {
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001614 SIMDLCVs.insert(
1615 cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl());
1616 }
1617 }
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001618 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
Alexey Bataevbd9fec12015-08-18 06:47:21 +00001619 auto CurPrivate = C->privates().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001620 for (const Expr *E : C->varlists()) {
1621 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
1622 const auto *PrivateVD =
Alexey Bataevbd9fec12015-08-18 06:47:21 +00001623 cast<VarDecl>(cast<DeclRefExpr>(*CurPrivate)->getDecl());
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001624 if (!SIMDLCVs.count(VD->getCanonicalDecl())) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001625 bool IsRegistered = PrivateScope.addPrivate(VD, [this, PrivateVD]() {
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001626 // Emit private VarDecl with copy init.
1627 EmitVarDecl(*PrivateVD);
1628 return GetAddrOfLocalVar(PrivateVD);
1629 });
1630 assert(IsRegistered && "linear var already registered as private");
1631 // Silence the warning about unused variable.
1632 (void)IsRegistered;
Alexey Bataevddf3db92018-04-13 17:31:06 +00001633 } else {
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001634 EmitVarDecl(*PrivateVD);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001635 }
Alexey Bataevbd9fec12015-08-18 06:47:21 +00001636 ++CurPrivate;
Alexander Musman3276a272015-03-21 10:12:56 +00001637 }
1638 }
1639}
1640
Alexey Bataev45bfad52015-08-21 12:19:04 +00001641static void emitSimdlenSafelenClause(CodeGenFunction &CGF,
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001642 const OMPExecutableDirective &D,
1643 bool IsMonotonic) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001644 if (!CGF.HaveInsertPoint())
1645 return;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001646 if (const auto *C = D.getSingleClause<OMPSimdlenClause>()) {
Alexey Bataev45bfad52015-08-21 12:19:04 +00001647 RValue Len = CGF.EmitAnyExpr(C->getSimdlen(), AggValueSlot::ignored(),
1648 /*ignoreResult=*/true);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001649 auto *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
Alexey Bataev45bfad52015-08-21 12:19:04 +00001650 CGF.LoopStack.setVectorizeWidth(Val->getZExtValue());
1651 // In presence of finite 'safelen', it may be unsafe to mark all
1652 // the memory instructions parallel, because loop-carried
1653 // dependences of 'safelen' iterations are possible.
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001654 if (!IsMonotonic)
1655 CGF.LoopStack.setParallel(!D.getSingleClause<OMPSafelenClause>());
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001656 } else if (const auto *C = D.getSingleClause<OMPSafelenClause>()) {
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001657 RValue Len = CGF.EmitAnyExpr(C->getSafelen(), AggValueSlot::ignored(),
1658 /*ignoreResult=*/true);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001659 auto *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
Tyler Nowickida46d0e2015-07-14 23:03:09 +00001660 CGF.LoopStack.setVectorizeWidth(Val->getZExtValue());
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001661 // In presence of finite 'safelen', it may be unsafe to mark all
1662 // the memory instructions parallel, because loop-carried
1663 // dependences of 'safelen' iterations are possible.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001664 CGF.LoopStack.setParallel(/*Enable=*/false);
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001665 }
1666}
1667
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001668void CodeGenFunction::EmitOMPSimdInit(const OMPLoopDirective &D,
1669 bool IsMonotonic) {
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001670 // Walk clauses and process safelen/lastprivate.
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001671 LoopStack.setParallel(!IsMonotonic);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001672 LoopStack.setVectorizeEnable();
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001673 emitSimdlenSafelenClause(*this, D, IsMonotonic);
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001674}
1675
Alexey Bataevef549a82016-03-09 09:49:09 +00001676void CodeGenFunction::EmitOMPSimdFinal(
1677 const OMPLoopDirective &D,
Alexey Bataevddf3db92018-04-13 17:31:06 +00001678 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001679 if (!HaveInsertPoint())
1680 return;
Alexey Bataevef549a82016-03-09 09:49:09 +00001681 llvm::BasicBlock *DoneBB = nullptr;
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001682 auto IC = D.counters().begin();
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001683 auto IPC = D.private_counters().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001684 for (const Expr *F : D.finals()) {
1685 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl());
1686 const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>((*IPC))->getDecl());
1687 const auto *CED = dyn_cast<OMPCapturedExprDecl>(OrigVD);
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001688 if (LocalDeclMap.count(OrigVD) || CapturedStmtInfo->lookup(OrigVD) ||
1689 OrigVD->hasGlobalStorage() || CED) {
Alexey Bataevef549a82016-03-09 09:49:09 +00001690 if (!DoneBB) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001691 if (llvm::Value *Cond = CondGen(*this)) {
Alexey Bataevef549a82016-03-09 09:49:09 +00001692 // If the first post-update expression is found, emit conditional
1693 // block if it was requested.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001694 llvm::BasicBlock *ThenBB = createBasicBlock(".omp.final.then");
Alexey Bataevef549a82016-03-09 09:49:09 +00001695 DoneBB = createBasicBlock(".omp.final.done");
1696 Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1697 EmitBlock(ThenBB);
1698 }
1699 }
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001700 Address OrigAddr = Address::invalid();
Alexey Bataevab4ea222018-03-07 18:17:06 +00001701 if (CED) {
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001702 OrigAddr = EmitLValue(CED->getInit()->IgnoreImpCasts()).getAddress();
Alexey Bataevab4ea222018-03-07 18:17:06 +00001703 } else {
Bruno Ricci5fc4db72018-12-21 14:10:18 +00001704 DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(PrivateVD),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001705 /*RefersToEnclosingVariableOrCapture=*/false,
1706 (*IPC)->getType(), VK_LValue, (*IPC)->getExprLoc());
1707 OrigAddr = EmitLValue(&DRE).getAddress();
1708 }
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001709 OMPPrivateScope VarScope(*this);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001710 VarScope.addPrivate(OrigVD, [OrigAddr]() { return OrigAddr; });
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001711 (void)VarScope.Privatize();
1712 EmitIgnoredExpr(F);
1713 }
1714 ++IC;
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001715 ++IPC;
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001716 }
Alexey Bataevef549a82016-03-09 09:49:09 +00001717 if (DoneBB)
1718 EmitBlock(DoneBB, /*IsFinished=*/true);
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001719}
1720
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001721static void emitOMPLoopBodyWithStopPoint(CodeGenFunction &CGF,
1722 const OMPLoopDirective &S,
1723 CodeGenFunction::JumpDest LoopExit) {
1724 CGF.EmitOMPLoopBody(S, LoopExit);
1725 CGF.EmitStopPoint(&S);
Hans Wennborged129ae2017-04-27 17:02:25 +00001726}
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001727
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001728/// Emit a helper variable and return corresponding lvalue.
1729static LValue EmitOMPHelperVar(CodeGenFunction &CGF,
1730 const DeclRefExpr *Helper) {
1731 auto VDecl = cast<VarDecl>(Helper->getDecl());
1732 CGF.EmitVarDecl(*VDecl);
1733 return CGF.EmitLValue(Helper);
1734}
1735
Alexey Bataevf8365372017-11-17 17:57:25 +00001736static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S,
1737 PrePostActionTy &Action) {
1738 Action.Enter(CGF);
1739 assert(isOpenMPSimdDirective(S.getDirectiveKind()) &&
1740 "Expected simd directive");
1741 OMPLoopScope PreInitScope(CGF, S);
1742 // if (PreCond) {
1743 // for (IV in 0..LastIteration) BODY;
1744 // <Final counter/linear vars updates>;
1745 // }
1746 //
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00001747 if (isOpenMPDistributeDirective(S.getDirectiveKind()) ||
1748 isOpenMPWorksharingDirective(S.getDirectiveKind()) ||
1749 isOpenMPTaskLoopDirective(S.getDirectiveKind())) {
1750 (void)EmitOMPHelperVar(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()));
1751 (void)EmitOMPHelperVar(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()));
1752 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00001753
Alexey Bataevf8365372017-11-17 17:57:25 +00001754 // Emit: if (PreCond) - begin.
1755 // If the condition constant folds and can be elided, avoid emitting the
1756 // whole loop.
1757 bool CondConstant;
1758 llvm::BasicBlock *ContBlock = nullptr;
1759 if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
1760 if (!CondConstant)
1761 return;
1762 } else {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001763 llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("simd.if.then");
Alexey Bataevf8365372017-11-17 17:57:25 +00001764 ContBlock = CGF.createBasicBlock("simd.if.end");
1765 emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
1766 CGF.getProfileCount(&S));
1767 CGF.EmitBlock(ThenBlock);
1768 CGF.incrementProfileCounter(&S);
1769 }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001770
Alexey Bataevf8365372017-11-17 17:57:25 +00001771 // Emit the loop iteration variable.
1772 const Expr *IVExpr = S.getIterationVariable();
Alexey Bataevddf3db92018-04-13 17:31:06 +00001773 const auto *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
Alexey Bataevf8365372017-11-17 17:57:25 +00001774 CGF.EmitVarDecl(*IVDecl);
1775 CGF.EmitIgnoredExpr(S.getInit());
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001776
Alexey Bataevf8365372017-11-17 17:57:25 +00001777 // Emit the iterations count variable.
1778 // If it is not a variable, Sema decided to calculate iterations count on
1779 // each iteration (e.g., it is foldable into a constant).
Alexey Bataevddf3db92018-04-13 17:31:06 +00001780 if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
Alexey Bataevf8365372017-11-17 17:57:25 +00001781 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
1782 // Emit calculation of the iterations count.
1783 CGF.EmitIgnoredExpr(S.getCalcLastIteration());
1784 }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001785
Alexey Bataevf8365372017-11-17 17:57:25 +00001786 CGF.EmitOMPSimdInit(S);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001787
Alexey Bataevf8365372017-11-17 17:57:25 +00001788 emitAlignedClause(CGF, S);
1789 (void)CGF.EmitOMPLinearClauseInit(S);
1790 {
1791 CodeGenFunction::OMPPrivateScope LoopScope(CGF);
1792 CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
1793 CGF.EmitOMPLinearClause(S, LoopScope);
1794 CGF.EmitOMPPrivateClause(S, LoopScope);
1795 CGF.EmitOMPReductionClauseInit(S, LoopScope);
1796 bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
1797 (void)LoopScope.Privatize();
Alexey Bataev60705422018-10-30 15:50:12 +00001798 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
1799 CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
Alexey Bataevf8365372017-11-17 17:57:25 +00001800 CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
1801 S.getInc(),
1802 [&S](CodeGenFunction &CGF) {
1803 CGF.EmitOMPLoopBody(S, CodeGenFunction::JumpDest());
1804 CGF.EmitStopPoint(&S);
1805 },
1806 [](CodeGenFunction &) {});
Alexey Bataevddf3db92018-04-13 17:31:06 +00001807 CGF.EmitOMPSimdFinal(S, [](CodeGenFunction &) { return nullptr; });
Alexey Bataevf8365372017-11-17 17:57:25 +00001808 // Emit final copy of the lastprivate variables at the end of loops.
1809 if (HasLastprivateClause)
1810 CGF.EmitOMPLastprivateClauseFinal(S, /*NoFinals=*/true);
1811 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_simd);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001812 emitPostUpdateForReductionClause(CGF, S,
1813 [](CodeGenFunction &) { return nullptr; });
Alexey Bataevf8365372017-11-17 17:57:25 +00001814 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00001815 CGF.EmitOMPLinearClauseFinal(S, [](CodeGenFunction &) { return nullptr; });
Alexey Bataevf8365372017-11-17 17:57:25 +00001816 // Emit: if (PreCond) - end.
1817 if (ContBlock) {
1818 CGF.EmitBranch(ContBlock);
1819 CGF.EmitBlock(ContBlock, true);
1820 }
1821}
1822
1823void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
1824 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
1825 emitOMPSimdRegion(CGF, S, Action);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001826 };
Alexey Bataev475a7442018-01-12 19:39:11 +00001827 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001828 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
Alexander Musman515ad8c2014-05-22 08:54:05 +00001829}
1830
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001831void CodeGenFunction::EmitOMPOuterLoop(
1832 bool DynamicOrOrdered, bool IsMonotonic, const OMPLoopDirective &S,
1833 CodeGenFunction::OMPPrivateScope &LoopScope,
1834 const CodeGenFunction::OMPLoopArguments &LoopArgs,
1835 const CodeGenFunction::CodeGenLoopTy &CodeGenLoop,
1836 const CodeGenFunction::CodeGenOrderedTy &CodeGenOrdered) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001837 CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
Alexander Musman92bdaab2015-03-12 13:37:50 +00001838
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001839 const Expr *IVExpr = S.getIterationVariable();
1840 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
1841 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
1842
Alexey Bataevddf3db92018-04-13 17:31:06 +00001843 JumpDest LoopExit = getJumpDestInCurrentScope("omp.dispatch.end");
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001844
1845 // Start the loop with a block that tests the condition.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001846 llvm::BasicBlock *CondBlock = createBasicBlock("omp.dispatch.cond");
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001847 EmitBlock(CondBlock);
Alexey Bataevddf3db92018-04-13 17:31:06 +00001848 const SourceRange R = S.getSourceRange();
Amara Emerson652795d2016-11-10 14:44:30 +00001849 LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()),
1850 SourceLocToDebugLoc(R.getEnd()));
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001851
1852 llvm::Value *BoolCondVal = nullptr;
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00001853 if (!DynamicOrOrdered) {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001854 // UB = min(UB, GlobalUB) or
1855 // UB = min(UB, PrevUB) for combined loop sharing constructs (e.g.
1856 // 'distribute parallel for')
1857 EmitIgnoredExpr(LoopArgs.EUB);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001858 // IV = LB
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001859 EmitIgnoredExpr(LoopArgs.Init);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001860 // IV < UB
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001861 BoolCondVal = EvaluateExprAsBool(LoopArgs.Cond);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001862 } else {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001863 BoolCondVal =
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001864 RT.emitForNext(*this, S.getBeginLoc(), IVSize, IVSigned, LoopArgs.IL,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001865 LoopArgs.LB, LoopArgs.UB, LoopArgs.ST);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001866 }
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001867
1868 // If there are any cleanups between here and the loop-exit scope,
1869 // create a block to stage a loop exit along.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001870 llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001871 if (LoopScope.requiresCleanups())
1872 ExitBlock = createBasicBlock("omp.dispatch.cleanup");
1873
Alexey Bataevddf3db92018-04-13 17:31:06 +00001874 llvm::BasicBlock *LoopBody = createBasicBlock("omp.dispatch.body");
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001875 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
1876 if (ExitBlock != LoopExit.getBlock()) {
1877 EmitBlock(ExitBlock);
1878 EmitBranchThroughCleanup(LoopExit);
1879 }
1880 EmitBlock(LoopBody);
1881
Alexander Musman92bdaab2015-03-12 13:37:50 +00001882 // Emit "IV = LB" (in case of static schedule, we have already calculated new
1883 // LB for loop condition and emitted it above).
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00001884 if (DynamicOrOrdered)
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001885 EmitIgnoredExpr(LoopArgs.Init);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001886
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001887 // Create a block for the increment.
Alexey Bataevddf3db92018-04-13 17:31:06 +00001888 JumpDest Continue = getJumpDestInCurrentScope("omp.dispatch.inc");
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001889 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1890
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001891 // Generate !llvm.loop.parallel metadata for loads and stores for loops
1892 // with dynamic/guided scheduling and without ordered clause.
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001893 if (!isOpenMPSimdDirective(S.getDirectiveKind()))
1894 LoopStack.setParallel(!IsMonotonic);
1895 else
1896 EmitOMPSimdInit(S, IsMonotonic);
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001897
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001898 SourceLocation Loc = S.getBeginLoc();
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001899
1900 // when 'distribute' is not combined with a 'for':
1901 // while (idx <= UB) { BODY; ++idx; }
1902 // when 'distribute' is combined with a 'for'
1903 // (e.g. 'distribute parallel for')
1904 // while (idx <= UB) { <CodeGen rest of pragma>; idx += ST; }
1905 EmitOMPInnerLoop(
1906 S, LoopScope.requiresCleanups(), LoopArgs.Cond, LoopArgs.IncExpr,
1907 [&S, LoopExit, &CodeGenLoop](CodeGenFunction &CGF) {
1908 CodeGenLoop(CGF, S, LoopExit);
1909 },
1910 [IVSize, IVSigned, Loc, &CodeGenOrdered](CodeGenFunction &CGF) {
1911 CodeGenOrdered(CGF, Loc, IVSize, IVSigned);
1912 });
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001913
1914 EmitBlock(Continue.getBlock());
1915 BreakContinueStack.pop_back();
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00001916 if (!DynamicOrOrdered) {
Alexander Musman92bdaab2015-03-12 13:37:50 +00001917 // Emit "LB = LB + Stride", "UB = UB + Stride".
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001918 EmitIgnoredExpr(LoopArgs.NextLB);
1919 EmitIgnoredExpr(LoopArgs.NextUB);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001920 }
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001921
1922 EmitBranch(CondBlock);
1923 LoopStack.pop();
1924 // Emit the fall-through block.
1925 EmitBlock(LoopExit.getBlock());
1926
1927 // Tell the runtime we are done.
Alexey Bataev957d8562016-11-17 15:12:05 +00001928 auto &&CodeGen = [DynamicOrOrdered, &S](CodeGenFunction &CGF) {
1929 if (!DynamicOrOrdered)
Stephen Kelly1c301dc2018-08-09 21:09:38 +00001930 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),
Alexey Bataevf43f7142017-09-06 16:17:35 +00001931 S.getDirectiveKind());
Alexey Bataev957d8562016-11-17 15:12:05 +00001932 };
1933 OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001934}
1935
1936void CodeGenFunction::EmitOMPForOuterLoop(
Alexey Bataev9ebd7422016-05-10 09:57:36 +00001937 const OpenMPScheduleTy &ScheduleKind, bool IsMonotonic,
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001938 const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001939 const OMPLoopArguments &LoopArgs,
1940 const CodeGenDispatchBoundsTy &CGDispatchBounds) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00001941 CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001942
1943 // Dynamic scheduling of the outer loop (dynamic, guided, auto, runtime).
Alexey Bataev9ebd7422016-05-10 09:57:36 +00001944 const bool DynamicOrOrdered =
1945 Ordered || RT.isDynamic(ScheduleKind.Schedule);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001946
1947 assert((Ordered ||
Alexey Bataev9ebd7422016-05-10 09:57:36 +00001948 !RT.isStaticNonchunked(ScheduleKind.Schedule,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001949 LoopArgs.Chunk != nullptr)) &&
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001950 "static non-chunked schedule does not need outer loop");
1951
1952 // Emit outer loop.
1953 //
1954 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
1955 // When schedule(dynamic,chunk_size) is specified, the iterations are
1956 // distributed to threads in the team in chunks as the threads request them.
1957 // Each thread executes a chunk of iterations, then requests another chunk,
1958 // until no chunks remain to be distributed. Each chunk contains chunk_size
1959 // iterations, except for the last chunk to be distributed, which may have
1960 // fewer iterations. When no chunk_size is specified, it defaults to 1.
1961 //
1962 // When schedule(guided,chunk_size) is specified, the iterations are assigned
1963 // to threads in the team in chunks as the executing threads request them.
1964 // Each thread executes a chunk of iterations, then requests another chunk,
1965 // until no chunks remain to be assigned. For a chunk_size of 1, the size of
1966 // each chunk is proportional to the number of unassigned iterations divided
1967 // by the number of threads in the team, decreasing to 1. For a chunk_size
1968 // with value k (greater than 1), the size of each chunk is determined in the
1969 // same way, with the restriction that the chunks do not contain fewer than k
1970 // iterations (except for the last chunk to be assigned, which may have fewer
1971 // than k iterations).
1972 //
1973 // When schedule(auto) is specified, the decision regarding scheduling is
1974 // delegated to the compiler and/or runtime system. The programmer gives the
1975 // implementation the freedom to choose any possible mapping of iterations to
1976 // threads in the team.
1977 //
1978 // When schedule(runtime) is specified, the decision regarding scheduling is
1979 // deferred until run time, and the schedule and chunk size are taken from the
1980 // run-sched-var ICV. If the ICV is set to auto, the schedule is
1981 // implementation defined
1982 //
1983 // while(__kmpc_dispatch_next(&LB, &UB)) {
1984 // idx = LB;
1985 // while (idx <= UB) { BODY; ++idx;
1986 // __kmpc_dispatch_fini_(4|8)[u](); // For ordered loops only.
1987 // } // inner loop
1988 // }
1989 //
1990 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
1991 // When schedule(static, chunk_size) is specified, iterations are divided into
1992 // chunks of size chunk_size, and the chunks are assigned to the threads in
1993 // the team in a round-robin fashion in the order of the thread number.
1994 //
1995 // while(UB = min(UB, GlobalUB), idx = LB, idx < UB) {
1996 // while (idx <= UB) { BODY; ++idx; } // inner loop
1997 // LB = LB + ST;
1998 // UB = UB + ST;
1999 // }
2000 //
2001
2002 const Expr *IVExpr = S.getIterationVariable();
2003 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
2004 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
2005
2006 if (DynamicOrOrdered) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00002007 const std::pair<llvm::Value *, llvm::Value *> DispatchBounds =
2008 CGDispatchBounds(*this, S, LoopArgs.LB, LoopArgs.UB);
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002009 llvm::Value *LBVal = DispatchBounds.first;
2010 llvm::Value *UBVal = DispatchBounds.second;
2011 CGOpenMPRuntime::DispatchRTInput DipatchRTInputValues = {LBVal, UBVal,
2012 LoopArgs.Chunk};
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002013 RT.emitForDispatchInit(*this, S.getBeginLoc(), ScheduleKind, IVSize,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002014 IVSigned, Ordered, DipatchRTInputValues);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00002015 } else {
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00002016 CGOpenMPRuntime::StaticRTInput StaticInit(
2017 IVSize, IVSigned, Ordered, LoopArgs.IL, LoopArgs.LB, LoopArgs.UB,
2018 LoopArgs.ST, LoopArgs.Chunk);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002019 RT.emitForStaticInit(*this, S.getBeginLoc(), S.getDirectiveKind(),
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00002020 ScheduleKind, StaticInit);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00002021 }
2022
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002023 auto &&CodeGenOrdered = [Ordered](CodeGenFunction &CGF, SourceLocation Loc,
2024 const unsigned IVSize,
2025 const bool IVSigned) {
2026 if (Ordered) {
2027 CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd(CGF, Loc, IVSize,
2028 IVSigned);
2029 }
2030 };
2031
2032 OMPLoopArguments OuterLoopArgs(LoopArgs.LB, LoopArgs.UB, LoopArgs.ST,
2033 LoopArgs.IL, LoopArgs.Chunk, LoopArgs.EUB);
2034 OuterLoopArgs.IncExpr = S.getInc();
2035 OuterLoopArgs.Init = S.getInit();
2036 OuterLoopArgs.Cond = S.getCond();
2037 OuterLoopArgs.NextLB = S.getNextLowerBound();
2038 OuterLoopArgs.NextUB = S.getNextUpperBound();
2039 EmitOMPOuterLoop(DynamicOrOrdered, IsMonotonic, S, LoopScope, OuterLoopArgs,
2040 emitOMPLoopBodyWithStopPoint, CodeGenOrdered);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00002041}
2042
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002043static void emitEmptyOrdered(CodeGenFunction &, SourceLocation Loc,
2044 const unsigned IVSize, const bool IVSigned) {}
2045
Carlo Bertollifc35ad22016-03-07 16:04:49 +00002046void CodeGenFunction::EmitOMPDistributeOuterLoop(
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002047 OpenMPDistScheduleClauseKind ScheduleKind, const OMPLoopDirective &S,
2048 OMPPrivateScope &LoopScope, const OMPLoopArguments &LoopArgs,
2049 const CodeGenLoopTy &CodeGenLoopContent) {
Carlo Bertollifc35ad22016-03-07 16:04:49 +00002050
Alexey Bataevddf3db92018-04-13 17:31:06 +00002051 CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
Carlo Bertollifc35ad22016-03-07 16:04:49 +00002052
2053 // Emit outer loop.
2054 // Same behavior as a OMPForOuterLoop, except that schedule cannot be
2055 // dynamic
2056 //
2057
2058 const Expr *IVExpr = S.getIterationVariable();
2059 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
2060 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
2061
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00002062 CGOpenMPRuntime::StaticRTInput StaticInit(
2063 IVSize, IVSigned, /* Ordered = */ false, LoopArgs.IL, LoopArgs.LB,
2064 LoopArgs.UB, LoopArgs.ST, LoopArgs.Chunk);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002065 RT.emitDistributeStaticInit(*this, S.getBeginLoc(), ScheduleKind, StaticInit);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00002066
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002067 // for combined 'distribute' and 'for' the increment expression of distribute
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002068 // is stored in DistInc. For 'distribute' alone, it is in Inc.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002069 Expr *IncExpr;
2070 if (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()))
2071 IncExpr = S.getDistInc();
2072 else
2073 IncExpr = S.getInc();
2074
2075 // this routine is shared by 'omp distribute parallel for' and
2076 // 'omp distribute': select the right EUB expression depending on the
2077 // directive
2078 OMPLoopArguments OuterLoopArgs;
2079 OuterLoopArgs.LB = LoopArgs.LB;
2080 OuterLoopArgs.UB = LoopArgs.UB;
2081 OuterLoopArgs.ST = LoopArgs.ST;
2082 OuterLoopArgs.IL = LoopArgs.IL;
2083 OuterLoopArgs.Chunk = LoopArgs.Chunk;
2084 OuterLoopArgs.EUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
2085 ? S.getCombinedEnsureUpperBound()
2086 : S.getEnsureUpperBound();
2087 OuterLoopArgs.IncExpr = IncExpr;
2088 OuterLoopArgs.Init = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
2089 ? S.getCombinedInit()
2090 : S.getInit();
2091 OuterLoopArgs.Cond = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
2092 ? S.getCombinedCond()
2093 : S.getCond();
2094 OuterLoopArgs.NextLB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
2095 ? S.getCombinedNextLowerBound()
2096 : S.getNextLowerBound();
2097 OuterLoopArgs.NextUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
2098 ? S.getCombinedNextUpperBound()
2099 : S.getNextUpperBound();
2100
2101 EmitOMPOuterLoop(/* DynamicOrOrdered = */ false, /* IsMonotonic = */ false, S,
2102 LoopScope, OuterLoopArgs, CodeGenLoopContent,
2103 emitEmptyOrdered);
2104}
2105
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002106static std::pair<LValue, LValue>
2107emitDistributeParallelForInnerBounds(CodeGenFunction &CGF,
2108 const OMPExecutableDirective &S) {
2109 const OMPLoopDirective &LS = cast<OMPLoopDirective>(S);
2110 LValue LB =
2111 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getLowerBoundVariable()));
2112 LValue UB =
2113 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getUpperBoundVariable()));
2114
2115 // When composing 'distribute' with 'for' (e.g. as in 'distribute
2116 // parallel for') we need to use the 'distribute'
2117 // chunk lower and upper bounds rather than the whole loop iteration
2118 // space. These are parameters to the outlined function for 'parallel'
2119 // and we copy the bounds of the previous schedule into the
2120 // the current ones.
2121 LValue PrevLB = CGF.EmitLValue(LS.getPrevLowerBoundVariable());
2122 LValue PrevUB = CGF.EmitLValue(LS.getPrevUpperBoundVariable());
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00002123 llvm::Value *PrevLBVal = CGF.EmitLoadOfScalar(
2124 PrevLB, LS.getPrevLowerBoundVariable()->getExprLoc());
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002125 PrevLBVal = CGF.EmitScalarConversion(
2126 PrevLBVal, LS.getPrevLowerBoundVariable()->getType(),
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00002127 LS.getIterationVariable()->getType(),
2128 LS.getPrevLowerBoundVariable()->getExprLoc());
2129 llvm::Value *PrevUBVal = CGF.EmitLoadOfScalar(
2130 PrevUB, LS.getPrevUpperBoundVariable()->getExprLoc());
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002131 PrevUBVal = CGF.EmitScalarConversion(
2132 PrevUBVal, LS.getPrevUpperBoundVariable()->getType(),
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00002133 LS.getIterationVariable()->getType(),
2134 LS.getPrevUpperBoundVariable()->getExprLoc());
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002135
2136 CGF.EmitStoreOfScalar(PrevLBVal, LB);
2137 CGF.EmitStoreOfScalar(PrevUBVal, UB);
2138
2139 return {LB, UB};
2140}
2141
2142/// if the 'for' loop has a dispatch schedule (e.g. dynamic, guided) then
2143/// we need to use the LB and UB expressions generated by the worksharing
2144/// code generation support, whereas in non combined situations we would
2145/// just emit 0 and the LastIteration expression
2146/// This function is necessary due to the difference of the LB and UB
2147/// types for the RT emission routines for 'for_static_init' and
2148/// 'for_dispatch_init'
2149static std::pair<llvm::Value *, llvm::Value *>
2150emitDistributeParallelForDispatchBounds(CodeGenFunction &CGF,
2151 const OMPExecutableDirective &S,
2152 Address LB, Address UB) {
2153 const OMPLoopDirective &LS = cast<OMPLoopDirective>(S);
2154 const Expr *IVExpr = LS.getIterationVariable();
2155 // when implementing a dynamic schedule for a 'for' combined with a
2156 // 'distribute' (e.g. 'distribute parallel for'), the 'for' loop
2157 // is not normalized as each team only executes its own assigned
2158 // distribute chunk
2159 QualType IteratorTy = IVExpr->getType();
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00002160 llvm::Value *LBVal =
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002161 CGF.EmitLoadOfScalar(LB, /*Volatile=*/false, IteratorTy, S.getBeginLoc());
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00002162 llvm::Value *UBVal =
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002163 CGF.EmitLoadOfScalar(UB, /*Volatile=*/false, IteratorTy, S.getBeginLoc());
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002164 return {LBVal, UBVal};
Hans Wennborged129ae2017-04-27 17:02:25 +00002165}
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002166
2167static void emitDistributeParallelForDistributeInnerBoundParams(
2168 CodeGenFunction &CGF, const OMPExecutableDirective &S,
2169 llvm::SmallVectorImpl<llvm::Value *> &CapturedVars) {
2170 const auto &Dir = cast<OMPLoopDirective>(S);
2171 LValue LB =
2172 CGF.EmitLValue(cast<DeclRefExpr>(Dir.getCombinedLowerBoundVariable()));
Alexey Bataevddf3db92018-04-13 17:31:06 +00002173 llvm::Value *LBCast = CGF.Builder.CreateIntCast(
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002174 CGF.Builder.CreateLoad(LB.getAddress()), CGF.SizeTy, /*isSigned=*/false);
2175 CapturedVars.push_back(LBCast);
2176 LValue UB =
2177 CGF.EmitLValue(cast<DeclRefExpr>(Dir.getCombinedUpperBoundVariable()));
2178
Alexey Bataevddf3db92018-04-13 17:31:06 +00002179 llvm::Value *UBCast = CGF.Builder.CreateIntCast(
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002180 CGF.Builder.CreateLoad(UB.getAddress()), CGF.SizeTy, /*isSigned=*/false);
2181 CapturedVars.push_back(UBCast);
Hans Wennborged129ae2017-04-27 17:02:25 +00002182}
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002183
2184static void
2185emitInnerParallelForWhenCombined(CodeGenFunction &CGF,
2186 const OMPLoopDirective &S,
2187 CodeGenFunction::JumpDest LoopExit) {
2188 auto &&CGInlinedWorksharingLoop = [&S](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00002189 PrePostActionTy &Action) {
2190 Action.Enter(CGF);
Alexey Bataevdcb4b8fb2017-11-22 20:19:50 +00002191 bool HasCancel = false;
2192 if (!isOpenMPSimdDirective(S.getDirectiveKind())) {
2193 if (const auto *D = dyn_cast<OMPTeamsDistributeParallelForDirective>(&S))
2194 HasCancel = D->hasCancel();
2195 else if (const auto *D = dyn_cast<OMPDistributeParallelForDirective>(&S))
2196 HasCancel = D->hasCancel();
Alexey Bataev16e79882017-11-22 21:12:03 +00002197 else if (const auto *D =
2198 dyn_cast<OMPTargetTeamsDistributeParallelForDirective>(&S))
2199 HasCancel = D->hasCancel();
Alexey Bataevdcb4b8fb2017-11-22 20:19:50 +00002200 }
2201 CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, S.getDirectiveKind(),
2202 HasCancel);
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002203 CGF.EmitOMPWorksharingLoop(S, S.getPrevEnsureUpperBound(),
2204 emitDistributeParallelForInnerBounds,
2205 emitDistributeParallelForDispatchBounds);
2206 };
2207
2208 emitCommonOMPParallelDirective(
Alexey Bataevdcb4b8fb2017-11-22 20:19:50 +00002209 CGF, S,
2210 isOpenMPSimdDirective(S.getDirectiveKind()) ? OMPD_for_simd : OMPD_for,
2211 CGInlinedWorksharingLoop,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002212 emitDistributeParallelForDistributeInnerBoundParams);
Alexander Musmandf7a8e22015-01-22 08:49:35 +00002213}
2214
Carlo Bertolli9925f152016-06-27 14:55:37 +00002215void CodeGenFunction::EmitOMPDistributeParallelForDirective(
2216 const OMPDistributeParallelForDirective &S) {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002217 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2218 CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
2219 S.getDistInc());
2220 };
Alexey Bataev475a7442018-01-12 19:39:11 +00002221 OMPLexicalScope Scope(*this, S, OMPD_parallel);
Alexey Bataev10a54312017-11-27 16:54:08 +00002222 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen);
Carlo Bertolli9925f152016-06-27 14:55:37 +00002223}
2224
Kelvin Li4a39add2016-07-05 05:00:15 +00002225void CodeGenFunction::EmitOMPDistributeParallelForSimdDirective(
2226 const OMPDistributeParallelForSimdDirective &S) {
Alexey Bataev0b49f9e2017-11-27 19:38:58 +00002227 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2228 CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
2229 S.getDistInc());
2230 };
Alexey Bataev475a7442018-01-12 19:39:11 +00002231 OMPLexicalScope Scope(*this, S, OMPD_parallel);
Alexey Bataev0b49f9e2017-11-27 19:38:58 +00002232 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen);
Kelvin Li4a39add2016-07-05 05:00:15 +00002233}
Kelvin Li787f3fc2016-07-06 04:45:38 +00002234
2235void CodeGenFunction::EmitOMPDistributeSimdDirective(
2236 const OMPDistributeSimdDirective &S) {
Alexey Bataev617db5f2017-12-04 15:38:33 +00002237 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2238 CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
2239 };
Alexey Bataev475a7442018-01-12 19:39:11 +00002240 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev617db5f2017-12-04 15:38:33 +00002241 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
Kelvin Li787f3fc2016-07-06 04:45:38 +00002242}
2243
Alexey Bataevf8365372017-11-17 17:57:25 +00002244void CodeGenFunction::EmitOMPTargetSimdDeviceFunction(
2245 CodeGenModule &CGM, StringRef ParentName, const OMPTargetSimdDirective &S) {
2246 // Emit SPMD target parallel for region as a standalone region.
2247 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2248 emitOMPSimdRegion(CGF, S, Action);
2249 };
2250 llvm::Function *Fn;
2251 llvm::Constant *Addr;
2252 // Emit target region as a standalone region.
2253 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
2254 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
2255 assert(Fn && Addr && "Target device function emission failed.");
2256}
2257
Kelvin Li986330c2016-07-20 22:57:10 +00002258void CodeGenFunction::EmitOMPTargetSimdDirective(
2259 const OMPTargetSimdDirective &S) {
Alexey Bataevf8365372017-11-17 17:57:25 +00002260 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2261 emitOMPSimdRegion(CGF, S, Action);
2262 };
2263 emitCommonOMPTargetDirective(*this, S, CodeGen);
Kelvin Li986330c2016-07-20 22:57:10 +00002264}
2265
Alexey Bataeva6f2a142015-12-31 06:52:34 +00002266namespace {
2267 struct ScheduleKindModifiersTy {
2268 OpenMPScheduleClauseKind Kind;
2269 OpenMPScheduleClauseModifier M1;
2270 OpenMPScheduleClauseModifier M2;
2271 ScheduleKindModifiersTy(OpenMPScheduleClauseKind Kind,
2272 OpenMPScheduleClauseModifier M1,
2273 OpenMPScheduleClauseModifier M2)
2274 : Kind(Kind), M1(M1), M2(M2) {}
2275 };
2276} // namespace
2277
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002278bool CodeGenFunction::EmitOMPWorksharingLoop(
2279 const OMPLoopDirective &S, Expr *EUB,
2280 const CodeGenLoopBoundsTy &CodeGenLoopBounds,
2281 const CodeGenDispatchBoundsTy &CGDispatchBounds) {
Alexander Musmanc6388682014-12-15 07:07:06 +00002282 // Emit the loop iteration variable.
Alexey Bataevddf3db92018-04-13 17:31:06 +00002283 const auto *IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
2284 const auto *IVDecl = cast<VarDecl>(IVExpr->getDecl());
Alexander Musmanc6388682014-12-15 07:07:06 +00002285 EmitVarDecl(*IVDecl);
2286
2287 // Emit the iterations count variable.
2288 // If it is not a variable, Sema decided to calculate iterations count on each
2289 // iteration (e.g., it is foldable into a constant).
Alexey Bataevddf3db92018-04-13 17:31:06 +00002290 if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
Alexander Musmanc6388682014-12-15 07:07:06 +00002291 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
2292 // Emit calculation of the iterations count.
2293 EmitIgnoredExpr(S.getCalcLastIteration());
2294 }
2295
Alexey Bataevddf3db92018-04-13 17:31:06 +00002296 CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
Alexander Musmanc6388682014-12-15 07:07:06 +00002297
Alexey Bataev38e89532015-04-16 04:54:05 +00002298 bool HasLastprivateClause;
Alexander Musmanc6388682014-12-15 07:07:06 +00002299 // Check pre-condition.
2300 {
Alexey Bataev5a3af132016-03-29 08:58:54 +00002301 OMPLoopScope PreInitScope(*this, S);
Alexander Musmanc6388682014-12-15 07:07:06 +00002302 // Skip the entire loop if we don't meet the precondition.
Alexey Bataev62dbb972015-04-22 11:59:37 +00002303 // If the condition constant folds and can be elided, avoid emitting the
2304 // whole loop.
2305 bool CondConstant;
2306 llvm::BasicBlock *ContBlock = nullptr;
2307 if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
2308 if (!CondConstant)
2309 return false;
2310 } else {
Alexey Bataevddf3db92018-04-13 17:31:06 +00002311 llvm::BasicBlock *ThenBlock = createBasicBlock("omp.precond.then");
Alexey Bataev62dbb972015-04-22 11:59:37 +00002312 ContBlock = createBasicBlock("omp.precond.end");
2313 emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock,
Justin Bogner66242d62015-04-23 23:06:47 +00002314 getProfileCount(&S));
Alexey Bataev62dbb972015-04-22 11:59:37 +00002315 EmitBlock(ThenBlock);
Justin Bogner66242d62015-04-23 23:06:47 +00002316 incrementProfileCounter(&S);
Alexey Bataev62dbb972015-04-22 11:59:37 +00002317 }
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00002318
Alexey Bataevea33dee2018-02-15 23:39:43 +00002319 RunCleanupsScope DoacrossCleanupScope(*this);
Alexey Bataev8b427062016-05-25 12:36:08 +00002320 bool Ordered = false;
Alexey Bataevddf3db92018-04-13 17:31:06 +00002321 if (const auto *OrderedClause = S.getSingleClause<OMPOrderedClause>()) {
Alexey Bataev8b427062016-05-25 12:36:08 +00002322 if (OrderedClause->getNumForLoops())
Alexey Bataevf138fda2018-08-13 19:04:24 +00002323 RT.emitDoacrossInit(*this, S, OrderedClause->getLoopNumIterations());
Alexey Bataev8b427062016-05-25 12:36:08 +00002324 else
2325 Ordered = true;
2326 }
2327
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002328 llvm::DenseSet<const Expr *> EmittedFinals;
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00002329 emitAlignedClause(*this, S);
Alexey Bataev8c3edfe2017-08-16 15:58:46 +00002330 bool HasLinears = EmitOMPLinearClauseInit(S);
Alexey Bataevef549a82016-03-09 09:49:09 +00002331 // Emit helper vars inits.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002332
2333 std::pair<LValue, LValue> Bounds = CodeGenLoopBounds(*this, S);
2334 LValue LB = Bounds.first;
2335 LValue UB = Bounds.second;
Alexey Bataevef549a82016-03-09 09:49:09 +00002336 LValue ST =
2337 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable()));
2338 LValue IL =
2339 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
2340
Alexander Musmanc6388682014-12-15 07:07:06 +00002341 // Emit 'then' code.
2342 {
Alexander Musmanc6388682014-12-15 07:07:06 +00002343 OMPPrivateScope LoopScope(*this);
Alexey Bataev8c3edfe2017-08-16 15:58:46 +00002344 if (EmitOMPFirstprivateClause(S, LoopScope) || HasLinears) {
Alexey Bataev69c62a92015-04-15 04:52:20 +00002345 // Emit implicit barrier to synchronize threads and avoid data races on
Alexey Bataevcd8b6a22016-02-15 08:07:17 +00002346 // initialization of firstprivate variables and post-update of
2347 // lastprivate variables.
Alexey Bataev25e5b442015-09-15 12:52:43 +00002348 CGM.getOpenMPRuntime().emitBarrierCall(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002349 *this, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
Alexey Bataev25e5b442015-09-15 12:52:43 +00002350 /*ForceSimpleCall=*/true);
Alexey Bataev69c62a92015-04-15 04:52:20 +00002351 }
Alexey Bataev50a64582015-04-22 12:24:45 +00002352 EmitOMPPrivateClause(S, LoopScope);
Alexey Bataev38e89532015-04-16 04:54:05 +00002353 HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +00002354 EmitOMPReductionClauseInit(S, LoopScope);
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002355 EmitOMPPrivateLoopCounters(S, LoopScope);
2356 EmitOMPLinearClause(S, LoopScope);
Alexander Musman7931b982015-03-16 07:14:41 +00002357 (void)LoopScope.Privatize();
Alexey Bataev60705422018-10-30 15:50:12 +00002358 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
2359 CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(*this, S);
Alexander Musmanc6388682014-12-15 07:07:06 +00002360
2361 // Detect the loop schedule kind and chunk.
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002362 const Expr *ChunkExpr = nullptr;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00002363 OpenMPScheduleTy ScheduleKind;
Alexey Bataevddf3db92018-04-13 17:31:06 +00002364 if (const auto *C = S.getSingleClause<OMPScheduleClause>()) {
Alexey Bataev9ebd7422016-05-10 09:57:36 +00002365 ScheduleKind.Schedule = C->getScheduleKind();
2366 ScheduleKind.M1 = C->getFirstScheduleModifier();
2367 ScheduleKind.M2 = C->getSecondScheduleModifier();
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002368 ChunkExpr = C->getChunkSize();
Gheorghe-Teodor Bercea8233af92018-09-27 20:29:00 +00002369 } else {
2370 // Default behaviour for schedule clause.
2371 CGM.getOpenMPRuntime().getDefaultScheduleAndChunk(
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002372 *this, S, ScheduleKind.Schedule, ChunkExpr);
2373 }
2374 bool HasChunkSizeOne = false;
2375 llvm::Value *Chunk = nullptr;
2376 if (ChunkExpr) {
2377 Chunk = EmitScalarExpr(ChunkExpr);
2378 Chunk = EmitScalarConversion(Chunk, ChunkExpr->getType(),
2379 S.getIterationVariable()->getType(),
2380 S.getBeginLoc());
Fangrui Song407659a2018-11-30 23:41:18 +00002381 Expr::EvalResult Result;
2382 if (ChunkExpr->EvaluateAsInt(Result, getContext())) {
2383 llvm::APSInt EvaluatedChunk = Result.Val.getInt();
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002384 HasChunkSizeOne = (EvaluatedChunk.getLimitedValue() == 1);
Fangrui Song407659a2018-11-30 23:41:18 +00002385 }
Alexey Bataev3392d762016-02-16 11:18:12 +00002386 }
Alexander Musmanc6388682014-12-15 07:07:06 +00002387 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
2388 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
Alexey Bataeva6f2a142015-12-31 06:52:34 +00002389 // OpenMP 4.5, 2.7.1 Loop Construct, Description.
2390 // If the static schedule kind is specified or if the ordered clause is
2391 // specified, and if no monotonic modifier is specified, the effect will
2392 // be as if the monotonic modifier was specified.
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002393 bool StaticChunkedOne = RT.isStaticChunked(ScheduleKind.Schedule,
2394 /* Chunked */ Chunk != nullptr) && HasChunkSizeOne &&
2395 isOpenMPLoopBoundSharingDirective(S.getDirectiveKind());
2396 if ((RT.isStaticNonchunked(ScheduleKind.Schedule,
2397 /* Chunked */ Chunk != nullptr) ||
2398 StaticChunkedOne) &&
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00002399 !Ordered) {
Alexey Bataeva6f2a142015-12-31 06:52:34 +00002400 if (isOpenMPSimdDirective(S.getDirectiveKind()))
2401 EmitOMPSimdInit(S, /*IsMonotonic=*/true);
Alexander Musmanc6388682014-12-15 07:07:06 +00002402 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
2403 // When no chunk_size is specified, the iteration space is divided into
2404 // chunks that are approximately equal in size, and at most one chunk is
2405 // distributed to each thread. Note that the size of the chunks is
2406 // unspecified in this case.
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00002407 CGOpenMPRuntime::StaticRTInput StaticInit(
2408 IVSize, IVSigned, Ordered, IL.getAddress(), LB.getAddress(),
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002409 UB.getAddress(), ST.getAddress(),
2410 StaticChunkedOne ? Chunk : nullptr);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002411 RT.emitForStaticInit(*this, S.getBeginLoc(), S.getDirectiveKind(),
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00002412 ScheduleKind, StaticInit);
Alexey Bataevddf3db92018-04-13 17:31:06 +00002413 JumpDest LoopExit =
Alexey Bataeva6f2a142015-12-31 06:52:34 +00002414 getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit"));
Alexander Musmanc6388682014-12-15 07:07:06 +00002415 // UB = min(UB, GlobalUB);
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002416 if (!StaticChunkedOne)
2417 EmitIgnoredExpr(S.getEnsureUpperBound());
Alexander Musmanc6388682014-12-15 07:07:06 +00002418 // IV = LB;
2419 EmitIgnoredExpr(S.getInit());
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00002420 // For unchunked static schedule generate:
2421 //
2422 // while (idx <= UB) {
2423 // BODY;
2424 // ++idx;
2425 // }
2426 //
2427 // For static schedule with chunk one:
2428 //
2429 // while (IV <= PrevUB) {
2430 // BODY;
2431 // IV += ST;
2432 // }
2433 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(),
2434 StaticChunkedOne ? S.getCombinedParForInDistCond() : S.getCond(),
2435 StaticChunkedOne ? S.getDistInc() : S.getInc(),
2436 [&S, LoopExit](CodeGenFunction &CGF) {
2437 CGF.EmitOMPLoopBody(S, LoopExit);
2438 CGF.EmitStopPoint(&S);
2439 },
2440 [](CodeGenFunction &) {});
Alexey Bataev0f34da12015-07-02 04:17:07 +00002441 EmitBlock(LoopExit.getBlock());
Alexander Musmanc6388682014-12-15 07:07:06 +00002442 // Tell the runtime we are done.
Alexey Bataev957d8562016-11-17 15:12:05 +00002443 auto &&CodeGen = [&S](CodeGenFunction &CGF) {
Stephen Kelly1c301dc2018-08-09 21:09:38 +00002444 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),
Alexey Bataevf43f7142017-09-06 16:17:35 +00002445 S.getDirectiveKind());
Alexey Bataev957d8562016-11-17 15:12:05 +00002446 };
2447 OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen);
Alexander Musmandf7a8e22015-01-22 08:49:35 +00002448 } else {
Alexey Bataev9ebd7422016-05-10 09:57:36 +00002449 const bool IsMonotonic =
2450 Ordered || ScheduleKind.Schedule == OMPC_SCHEDULE_static ||
2451 ScheduleKind.Schedule == OMPC_SCHEDULE_unknown ||
2452 ScheduleKind.M1 == OMPC_SCHEDULE_MODIFIER_monotonic ||
2453 ScheduleKind.M2 == OMPC_SCHEDULE_MODIFIER_monotonic;
Alexander Musmandf7a8e22015-01-22 08:49:35 +00002454 // Emit the outer loop, which requests its work chunk [LB..UB] from
2455 // runtime and runs the inner loop to process it.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002456 const OMPLoopArguments LoopArguments(LB.getAddress(), UB.getAddress(),
2457 ST.getAddress(), IL.getAddress(),
2458 Chunk, EUB);
Alexey Bataeva6f2a142015-12-31 06:52:34 +00002459 EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002460 LoopArguments, CGDispatchBounds);
Alexander Musmandf7a8e22015-01-22 08:49:35 +00002461 }
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002462 if (isOpenMPSimdDirective(S.getDirectiveKind())) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002463 EmitOMPSimdFinal(S, [IL, &S](CodeGenFunction &CGF) {
2464 return CGF.Builder.CreateIsNotNull(
2465 CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
2466 });
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002467 }
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00002468 EmitOMPReductionClauseFinal(
2469 S, /*ReductionKind=*/isOpenMPSimdDirective(S.getDirectiveKind())
2470 ? /*Parallel and Simd*/ OMPD_parallel_for_simd
2471 : /*Parallel only*/ OMPD_parallel);
Alexey Bataev61205072016-03-02 04:57:40 +00002472 // Emit post-update of the reduction variables if IsLastIter != 0.
2473 emitPostUpdateForReductionClause(
Alexey Bataevddf3db92018-04-13 17:31:06 +00002474 *this, S, [IL, &S](CodeGenFunction &CGF) {
Alexey Bataev61205072016-03-02 04:57:40 +00002475 return CGF.Builder.CreateIsNotNull(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002476 CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
Alexey Bataev61205072016-03-02 04:57:40 +00002477 });
Alexey Bataev38e89532015-04-16 04:54:05 +00002478 // Emit final copy of the lastprivate variables if IsLastIter != 0.
2479 if (HasLastprivateClause)
2480 EmitOMPLastprivateClauseFinal(
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002481 S, isOpenMPSimdDirective(S.getDirectiveKind()),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002482 Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getBeginLoc())));
Alexander Musmanc6388682014-12-15 07:07:06 +00002483 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00002484 EmitOMPLinearClauseFinal(S, [IL, &S](CodeGenFunction &CGF) {
Alexey Bataevef549a82016-03-09 09:49:09 +00002485 return CGF.Builder.CreateIsNotNull(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002486 CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
Alexey Bataevef549a82016-03-09 09:49:09 +00002487 });
Alexey Bataevea33dee2018-02-15 23:39:43 +00002488 DoacrossCleanupScope.ForceCleanup();
Alexander Musmanc6388682014-12-15 07:07:06 +00002489 // We're now done with the loop, so jump to the continuation block.
Alexey Bataev62dbb972015-04-22 11:59:37 +00002490 if (ContBlock) {
2491 EmitBranch(ContBlock);
Alexey Bataevddf3db92018-04-13 17:31:06 +00002492 EmitBlock(ContBlock, /*IsFinished=*/true);
Alexey Bataev62dbb972015-04-22 11:59:37 +00002493 }
Alexander Musmanc6388682014-12-15 07:07:06 +00002494 }
Alexey Bataev38e89532015-04-16 04:54:05 +00002495 return HasLastprivateClause;
Alexander Musmanc6388682014-12-15 07:07:06 +00002496}
2497
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002498/// The following two functions generate expressions for the loop lower
2499/// and upper bounds in case of static and dynamic (dispatch) schedule
2500/// of the associated 'for' or 'distribute' loop.
2501static std::pair<LValue, LValue>
2502emitForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00002503 const auto &LS = cast<OMPLoopDirective>(S);
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002504 LValue LB =
2505 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getLowerBoundVariable()));
2506 LValue UB =
2507 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getUpperBoundVariable()));
2508 return {LB, UB};
2509}
2510
2511/// When dealing with dispatch schedules (e.g. dynamic, guided) we do not
2512/// consider the lower and upper bound expressions generated by the
2513/// worksharing loop support, but we use 0 and the iteration space size as
2514/// constants
2515static std::pair<llvm::Value *, llvm::Value *>
2516emitDispatchForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S,
2517 Address LB, Address UB) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00002518 const auto &LS = cast<OMPLoopDirective>(S);
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002519 const Expr *IVExpr = LS.getIterationVariable();
2520 const unsigned IVSize = CGF.getContext().getTypeSize(IVExpr->getType());
2521 llvm::Value *LBVal = CGF.Builder.getIntN(IVSize, 0);
2522 llvm::Value *UBVal = CGF.EmitScalarExpr(LS.getLastIteration());
2523 return {LBVal, UBVal};
2524}
2525
Alexander Musmanc6388682014-12-15 07:07:06 +00002526void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {
Alexey Bataev38e89532015-04-16 04:54:05 +00002527 bool HasLastprivates = false;
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002528 auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF,
2529 PrePostActionTy &) {
Alexey Bataev957d8562016-11-17 15:12:05 +00002530 OMPCancelStackRAII CancelRegion(CGF, OMPD_for, S.hasCancel());
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002531 HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(),
2532 emitForLoopBounds,
2533 emitDispatchForLoopBounds);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002534 };
Alexey Bataev3392d762016-02-16 11:18:12 +00002535 {
Alexey Bataev475a7442018-01-12 19:39:11 +00002536 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev3392d762016-02-16 11:18:12 +00002537 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen,
2538 S.hasCancel());
2539 }
Alexander Musmanc6388682014-12-15 07:07:06 +00002540
2541 // Emit an implicit barrier at the end.
Alexey Bataevddf3db92018-04-13 17:31:06 +00002542 if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates)
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002543 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_for);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002544}
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002545
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00002546void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) {
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00002547 bool HasLastprivates = false;
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002548 auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF,
2549 PrePostActionTy &) {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002550 HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(),
2551 emitForLoopBounds,
2552 emitDispatchForLoopBounds);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002553 };
Alexey Bataev3392d762016-02-16 11:18:12 +00002554 {
Alexey Bataev475a7442018-01-12 19:39:11 +00002555 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev3392d762016-02-16 11:18:12 +00002556 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
2557 }
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00002558
2559 // Emit an implicit barrier at the end.
Alexey Bataevddf3db92018-04-13 17:31:06 +00002560 if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates)
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002561 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_for);
Alexander Musmanf82886e2014-09-18 05:12:34 +00002562}
2563
Alexey Bataev2df54a02015-03-12 08:53:29 +00002564static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty,
2565 const Twine &Name,
2566 llvm::Value *Init = nullptr) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00002567 LValue LVal = CGF.MakeAddrLValue(CGF.CreateMemTemp(Ty, Name), Ty);
Alexey Bataev2df54a02015-03-12 08:53:29 +00002568 if (Init)
Akira Hatanaka642f7992016-10-18 19:05:41 +00002569 CGF.EmitStoreThroughLValue(RValue::get(Init), LVal, /*isInit*/ true);
Alexey Bataev2df54a02015-03-12 08:53:29 +00002570 return LVal;
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002571}
2572
Alexey Bataev3392d762016-02-16 11:18:12 +00002573void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00002574 const Stmt *CapturedStmt = S.getInnermostCapturedStmt()->getCapturedStmt();
2575 const auto *CS = dyn_cast<CompoundStmt>(CapturedStmt);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002576 bool HasLastprivates = false;
Alexey Bataevddf3db92018-04-13 17:31:06 +00002577 auto &&CodeGen = [&S, CapturedStmt, CS,
2578 &HasLastprivates](CodeGenFunction &CGF, PrePostActionTy &) {
2579 ASTContext &C = CGF.getContext();
2580 QualType KmpInt32Ty =
2581 C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002582 // Emit helper vars inits.
2583 LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.",
2584 CGF.Builder.getInt32(0));
Alexey Bataevddf3db92018-04-13 17:31:06 +00002585 llvm::ConstantInt *GlobalUBVal = CS != nullptr
2586 ? CGF.Builder.getInt32(CS->size() - 1)
2587 : CGF.Builder.getInt32(0);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002588 LValue UB =
2589 createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal);
2590 LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.",
2591 CGF.Builder.getInt32(1));
2592 LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.",
2593 CGF.Builder.getInt32(0));
2594 // Loop counter.
2595 LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv.");
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002596 OpaqueValueExpr IVRefExpr(S.getBeginLoc(), KmpInt32Ty, VK_LValue);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002597 CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002598 OpaqueValueExpr UBRefExpr(S.getBeginLoc(), KmpInt32Ty, VK_LValue);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002599 CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
2600 // Generate condition for loop.
2601 BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue,
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002602 OK_Ordinary, S.getBeginLoc(), FPOptions());
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002603 // Increment for loop counter.
2604 UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary,
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002605 S.getBeginLoc(), true);
Alexey Bataevddf3db92018-04-13 17:31:06 +00002606 auto &&BodyGen = [CapturedStmt, CS, &S, &IV](CodeGenFunction &CGF) {
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002607 // Iterate through all sections and emit a switch construct:
2608 // switch (IV) {
2609 // case 0:
2610 // <SectionStmt[0]>;
2611 // break;
2612 // ...
2613 // case <NumSection> - 1:
2614 // <SectionStmt[<NumSection> - 1]>;
2615 // break;
2616 // }
2617 // .omp.sections.exit:
Alexey Bataevddf3db92018-04-13 17:31:06 +00002618 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".omp.sections.exit");
2619 llvm::SwitchInst *SwitchStmt =
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002620 CGF.Builder.CreateSwitch(CGF.EmitLoadOfScalar(IV, S.getBeginLoc()),
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00002621 ExitBB, CS == nullptr ? 1 : CS->size());
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002622 if (CS) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002623 unsigned CaseNumber = 0;
Alexey Bataevddf3db92018-04-13 17:31:06 +00002624 for (const Stmt *SubStmt : CS->children()) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002625 auto CaseBB = CGF.createBasicBlock(".omp.sections.case");
2626 CGF.EmitBlock(CaseBB);
2627 SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB);
Benjamin Kramer642f1732015-07-02 21:03:14 +00002628 CGF.EmitStmt(SubStmt);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002629 CGF.EmitBranch(ExitBB);
Benjamin Kramer642f1732015-07-02 21:03:14 +00002630 ++CaseNumber;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002631 }
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002632 } else {
Alexey Bataevddf3db92018-04-13 17:31:06 +00002633 llvm::BasicBlock *CaseBB = CGF.createBasicBlock(".omp.sections.case");
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002634 CGF.EmitBlock(CaseBB);
2635 SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB);
Alexey Bataevddf3db92018-04-13 17:31:06 +00002636 CGF.EmitStmt(CapturedStmt);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002637 CGF.EmitBranch(ExitBB);
Alexey Bataev2cb9b952015-04-24 03:37:03 +00002638 }
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002639 CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
Alexey Bataev2df54a02015-03-12 08:53:29 +00002640 };
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002641
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002642 CodeGenFunction::OMPPrivateScope LoopScope(CGF);
2643 if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
Alexey Bataev9efc03b2015-04-27 04:34:03 +00002644 // Emit implicit barrier to synchronize threads and avoid data races on
Alexey Bataevcd8b6a22016-02-15 08:07:17 +00002645 // initialization of firstprivate variables and post-update of lastprivate
2646 // variables.
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002647 CGF.CGM.getOpenMPRuntime().emitBarrierCall(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002648 CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002649 /*ForceSimpleCall=*/true);
Alexey Bataev9efc03b2015-04-27 04:34:03 +00002650 }
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002651 CGF.EmitOMPPrivateClause(S, LoopScope);
2652 HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
2653 CGF.EmitOMPReductionClauseInit(S, LoopScope);
2654 (void)LoopScope.Privatize();
Alexey Bataev60705422018-10-30 15:50:12 +00002655 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
2656 CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
Alexey Bataev2cb9b952015-04-24 03:37:03 +00002657
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002658 // Emit static non-chunked loop.
Alexey Bataev9ebd7422016-05-10 09:57:36 +00002659 OpenMPScheduleTy ScheduleKind;
2660 ScheduleKind.Schedule = OMPC_SCHEDULE_static;
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00002661 CGOpenMPRuntime::StaticRTInput StaticInit(
2662 /*IVSize=*/32, /*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(),
2663 LB.getAddress(), UB.getAddress(), ST.getAddress());
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002664 CGF.CGM.getOpenMPRuntime().emitForStaticInit(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002665 CGF, S.getBeginLoc(), S.getDirectiveKind(), ScheduleKind, StaticInit);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002666 // UB = min(UB, GlobalUB);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002667 llvm::Value *UBVal = CGF.EmitLoadOfScalar(UB, S.getBeginLoc());
Alexey Bataevddf3db92018-04-13 17:31:06 +00002668 llvm::Value *MinUBGlobalUB = CGF.Builder.CreateSelect(
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002669 CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
2670 CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
2671 // IV = LB;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002672 CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getBeginLoc()), IV);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002673 // while (idx <= UB) { BODY; ++idx; }
2674 CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen,
2675 [](CodeGenFunction &) {});
2676 // Tell the runtime we are done.
Alexey Bataev957d8562016-11-17 15:12:05 +00002677 auto &&CodeGen = [&S](CodeGenFunction &CGF) {
Stephen Kelly1c301dc2018-08-09 21:09:38 +00002678 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),
Alexey Bataevf43f7142017-09-06 16:17:35 +00002679 S.getDirectiveKind());
Alexey Bataev957d8562016-11-17 15:12:05 +00002680 };
2681 CGF.OMPCancelStack.emitExit(CGF, S.getDirectiveKind(), CodeGen);
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00002682 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
Alexey Bataev61205072016-03-02 04:57:40 +00002683 // Emit post-update of the reduction variables if IsLastIter != 0.
Alexey Bataevddf3db92018-04-13 17:31:06 +00002684 emitPostUpdateForReductionClause(CGF, S, [IL, &S](CodeGenFunction &CGF) {
2685 return CGF.Builder.CreateIsNotNull(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002686 CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
Alexey Bataevddf3db92018-04-13 17:31:06 +00002687 });
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002688
2689 // Emit final copy of the lastprivate variables if IsLastIter != 0.
2690 if (HasLastprivates)
2691 CGF.EmitOMPLastprivateClauseFinal(
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002692 S, /*NoFinals=*/false,
2693 CGF.Builder.CreateIsNotNull(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002694 CGF.EmitLoadOfScalar(IL, S.getBeginLoc())));
Alexey Bataev68adb7d2015-04-14 03:29:22 +00002695 };
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002696
2697 bool HasCancel = false;
2698 if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
2699 HasCancel = OSD->hasCancel();
2700 else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
2701 HasCancel = OPSD->hasCancel();
Alexey Bataev957d8562016-11-17 15:12:05 +00002702 OMPCancelStackRAII CancelRegion(*this, S.getDirectiveKind(), HasCancel);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002703 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen,
2704 HasCancel);
2705 // Emit barrier for lastprivates only if 'sections' directive has 'nowait'
2706 // clause. Otherwise the barrier will be generated by the codegen for the
2707 // directive.
2708 if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) {
Alexey Bataev2cb9b952015-04-24 03:37:03 +00002709 // Emit implicit barrier to synchronize threads and avoid data races on
2710 // initialization of firstprivate variables.
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002711 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(),
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002712 OMPD_unknown);
Alexey Bataev2cb9b952015-04-24 03:37:03 +00002713 }
Alexey Bataev68adb7d2015-04-14 03:29:22 +00002714}
Alexey Bataev2df54a02015-03-12 08:53:29 +00002715
Alexey Bataev68adb7d2015-04-14 03:29:22 +00002716void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002717 {
Alexey Bataev475a7442018-01-12 19:39:11 +00002718 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev3392d762016-02-16 11:18:12 +00002719 EmitSections(S);
2720 }
Alexey Bataev2df54a02015-03-12 08:53:29 +00002721 // Emit an implicit barrier at the end.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002722 if (!S.getSingleClause<OMPNowaitClause>()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002723 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(),
Alexey Bataev3392d762016-02-16 11:18:12 +00002724 OMPD_sections);
Alexey Bataevf2685682015-03-30 04:30:22 +00002725 }
Alexey Bataev2df54a02015-03-12 08:53:29 +00002726}
2727
2728void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002729 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataev475a7442018-01-12 19:39:11 +00002730 CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002731 };
Alexey Bataev475a7442018-01-12 19:39:11 +00002732 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev25e5b442015-09-15 12:52:43 +00002733 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen,
2734 S.hasCancel());
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002735}
2736
Alexey Bataev6956e2e2015-02-05 06:35:41 +00002737void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {
Alexey Bataeva63048e2015-03-23 06:18:07 +00002738 llvm::SmallVector<const Expr *, 8> CopyprivateVars;
Alexey Bataev420d45b2015-04-14 05:11:24 +00002739 llvm::SmallVector<const Expr *, 8> DestExprs;
Alexey Bataeva63048e2015-03-23 06:18:07 +00002740 llvm::SmallVector<const Expr *, 8> SrcExprs;
Alexey Bataeva63048e2015-03-23 06:18:07 +00002741 llvm::SmallVector<const Expr *, 8> AssignmentOps;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002742 // Check if there are any 'copyprivate' clauses associated with this
Alexey Bataevcd8b6a22016-02-15 08:07:17 +00002743 // 'single' construct.
Alexey Bataeva63048e2015-03-23 06:18:07 +00002744 // Build a list of copyprivate variables along with helper expressions
2745 // (<source>, <destination>, <destination>=<source> expressions)
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002746 for (const auto *C : S.getClausesOfKind<OMPCopyprivateClause>()) {
Alexey Bataeva63048e2015-03-23 06:18:07 +00002747 CopyprivateVars.append(C->varlists().begin(), C->varlists().end());
Alexey Bataev420d45b2015-04-14 05:11:24 +00002748 DestExprs.append(C->destination_exprs().begin(),
2749 C->destination_exprs().end());
Alexey Bataeva63048e2015-03-23 06:18:07 +00002750 SrcExprs.append(C->source_exprs().begin(), C->source_exprs().end());
Alexey Bataeva63048e2015-03-23 06:18:07 +00002751 AssignmentOps.append(C->assignment_ops().begin(),
2752 C->assignment_ops().end());
2753 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002754 // Emit code for 'single' region along with 'copyprivate' clauses
2755 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2756 Action.Enter(CGF);
2757 OMPPrivateScope SingleScope(CGF);
2758 (void)CGF.EmitOMPFirstprivateClause(S, SingleScope);
2759 CGF.EmitOMPPrivateClause(S, SingleScope);
2760 (void)SingleScope.Privatize();
Alexey Bataev475a7442018-01-12 19:39:11 +00002761 CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002762 };
Alexey Bataev3392d762016-02-16 11:18:12 +00002763 {
Alexey Bataev475a7442018-01-12 19:39:11 +00002764 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002765 CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getBeginLoc(),
Alexey Bataev3392d762016-02-16 11:18:12 +00002766 CopyprivateVars, DestExprs,
2767 SrcExprs, AssignmentOps);
2768 }
2769 // Emit an implicit barrier at the end (to avoid data race on firstprivate
2770 // init or if no 'nowait' clause was specified and no 'copyprivate' clause).
Alexey Bataev417089f2016-02-17 13:19:37 +00002771 if (!S.getSingleClause<OMPNowaitClause>() && CopyprivateVars.empty()) {
Alexey Bataev5521d782015-04-24 04:21:15 +00002772 CGM.getOpenMPRuntime().emitBarrierCall(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002773 *this, S.getBeginLoc(),
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002774 S.getSingleClause<OMPNowaitClause>() ? OMPD_unknown : OMPD_single);
Alexey Bataevf2685682015-03-30 04:30:22 +00002775 }
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002776}
2777
Alexey Bataev8d690652014-12-04 07:23:53 +00002778void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002779 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2780 Action.Enter(CGF);
Alexey Bataev475a7442018-01-12 19:39:11 +00002781 CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002782 };
Alexey Bataev475a7442018-01-12 19:39:11 +00002783 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002784 CGM.getOpenMPRuntime().emitMasterRegion(*this, CodeGen, S.getBeginLoc());
Alexander Musman80c22892014-07-17 08:54:58 +00002785}
2786
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00002787void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002788 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2789 Action.Enter(CGF);
Alexey Bataev475a7442018-01-12 19:39:11 +00002790 CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002791 };
Alexey Bataevddf3db92018-04-13 17:31:06 +00002792 const Expr *Hint = nullptr;
2793 if (const auto *HintClause = S.getSingleClause<OMPHintClause>())
Alexey Bataevfc57d162015-12-15 10:55:09 +00002794 Hint = HintClause->getHint();
Alexey Bataev475a7442018-01-12 19:39:11 +00002795 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataevfc57d162015-12-15 10:55:09 +00002796 CGM.getOpenMPRuntime().emitCriticalRegion(*this,
2797 S.getDirectiveName().getAsString(),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002798 CodeGen, S.getBeginLoc(), Hint);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002799}
2800
Alexey Bataev671605e2015-04-13 05:28:11 +00002801void CodeGenFunction::EmitOMPParallelForDirective(
2802 const OMPParallelForDirective &S) {
2803 // Emit directive as a combined directive that consists of two implicit
2804 // directives: 'parallel' with 'for' directive.
Alexey Bataevc99042b2018-03-15 18:10:54 +00002805 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2806 Action.Enter(CGF);
Alexey Bataev957d8562016-11-17 15:12:05 +00002807 OMPCancelStackRAII CancelRegion(CGF, OMPD_parallel_for, S.hasCancel());
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002808 CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds,
2809 emitDispatchForLoopBounds);
Alexey Bataev671605e2015-04-13 05:28:11 +00002810 };
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002811 emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen,
2812 emitEmptyBoundParameters);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002813}
2814
Alexander Musmane4e893b2014-09-23 09:33:00 +00002815void CodeGenFunction::EmitOMPParallelForSimdDirective(
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00002816 const OMPParallelForSimdDirective &S) {
2817 // Emit directive as a combined directive that consists of two implicit
2818 // directives: 'parallel' with 'for' directive.
Alexey Bataevc99042b2018-03-15 18:10:54 +00002819 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2820 Action.Enter(CGF);
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002821 CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds,
2822 emitDispatchForLoopBounds);
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00002823 };
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002824 emitCommonOMPParallelDirective(*this, S, OMPD_simd, CodeGen,
2825 emitEmptyBoundParameters);
Alexander Musmane4e893b2014-09-23 09:33:00 +00002826}
2827
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002828void CodeGenFunction::EmitOMPParallelSectionsDirective(
Alexey Bataev68adb7d2015-04-14 03:29:22 +00002829 const OMPParallelSectionsDirective &S) {
2830 // Emit directive as a combined directive that consists of two implicit
2831 // directives: 'parallel' with 'sections' directive.
Alexey Bataevc99042b2018-03-15 18:10:54 +00002832 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2833 Action.Enter(CGF);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002834 CGF.EmitSections(S);
2835 };
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002836 emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen,
2837 emitEmptyBoundParameters);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002838}
2839
Alexey Bataev475a7442018-01-12 19:39:11 +00002840void CodeGenFunction::EmitOMPTaskBasedDirective(
2841 const OMPExecutableDirective &S, const OpenMPDirectiveKind CapturedRegion,
2842 const RegionCodeGenTy &BodyGen, const TaskGenTy &TaskGen,
2843 OMPTaskDataTy &Data) {
Alexey Bataev62b63b12015-03-10 07:28:44 +00002844 // Emit outlined function for task construct.
Alexey Bataev475a7442018-01-12 19:39:11 +00002845 const CapturedStmt *CS = S.getCapturedStmt(CapturedRegion);
Alexey Bataevddf3db92018-04-13 17:31:06 +00002846 auto I = CS->getCapturedDecl()->param_begin();
2847 auto PartId = std::next(I);
2848 auto TaskT = std::next(I, 4);
Alexey Bataev24b5bae2016-04-28 09:23:51 +00002849 // Check if the task is final
2850 if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) {
2851 // If the condition constant folds and can be elided, try to avoid emitting
2852 // the condition and the dead arm of the if/else.
Alexey Bataevddf3db92018-04-13 17:31:06 +00002853 const Expr *Cond = Clause->getCondition();
Alexey Bataev24b5bae2016-04-28 09:23:51 +00002854 bool CondConstant;
2855 if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
2856 Data.Final.setInt(CondConstant);
2857 else
2858 Data.Final.setPointer(EvaluateExprAsBool(Cond));
2859 } else {
2860 // By default the task is not final.
2861 Data.Final.setInt(/*IntVal=*/false);
2862 }
Alexey Bataev1e1e2862016-05-10 12:21:02 +00002863 // Check if the task has 'priority' clause.
2864 if (const auto *Clause = S.getSingleClause<OMPPriorityClause>()) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00002865 const Expr *Prio = Clause->getPriority();
Alexey Bataev5140e742016-07-19 04:21:09 +00002866 Data.Priority.setInt(/*IntVal=*/true);
Alexey Bataevad537bb2016-05-30 09:06:50 +00002867 Data.Priority.setPointer(EmitScalarConversion(
2868 EmitScalarExpr(Prio), Prio->getType(),
2869 getContext().getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1),
2870 Prio->getExprLoc()));
Alexey Bataev1e1e2862016-05-10 12:21:02 +00002871 }
Alexey Bataev62b63b12015-03-10 07:28:44 +00002872 // The first function argument for tasks is a thread id, the second one is a
2873 // part id (0 for tied tasks, >=0 for untied task).
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002874 llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
2875 // Get list of private variables.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002876 for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) {
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002877 auto IRef = C->varlist_begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00002878 for (const Expr *IInit : C->private_copies()) {
2879 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002880 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
Alexey Bataev7292c292016-04-25 12:22:29 +00002881 Data.PrivateVars.push_back(*IRef);
2882 Data.PrivateCopies.push_back(IInit);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002883 }
2884 ++IRef;
2885 }
2886 }
2887 EmittedAsPrivate.clear();
2888 // Get list of firstprivate variables.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002889 for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) {
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002890 auto IRef = C->varlist_begin();
2891 auto IElemInitRef = C->inits().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00002892 for (const Expr *IInit : C->private_copies()) {
2893 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002894 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
Alexey Bataev7292c292016-04-25 12:22:29 +00002895 Data.FirstprivateVars.push_back(*IRef);
2896 Data.FirstprivateCopies.push_back(IInit);
2897 Data.FirstprivateInits.push_back(*IElemInitRef);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002898 }
Richard Trieucc3949d2016-02-18 22:34:54 +00002899 ++IRef;
2900 ++IElemInitRef;
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002901 }
2902 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00002903 // Get list of lastprivate variables (for taskloops).
2904 llvm::DenseMap<const VarDecl *, const DeclRefExpr *> LastprivateDstsOrigs;
2905 for (const auto *C : S.getClausesOfKind<OMPLastprivateClause>()) {
2906 auto IRef = C->varlist_begin();
2907 auto ID = C->destination_exprs().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00002908 for (const Expr *IInit : C->private_copies()) {
2909 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataevf93095a2016-05-05 08:46:22 +00002910 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
2911 Data.LastprivateVars.push_back(*IRef);
2912 Data.LastprivateCopies.push_back(IInit);
2913 }
2914 LastprivateDstsOrigs.insert(
2915 {cast<VarDecl>(cast<DeclRefExpr>(*ID)->getDecl()),
2916 cast<DeclRefExpr>(*IRef)});
2917 ++IRef;
2918 ++ID;
2919 }
2920 }
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002921 SmallVector<const Expr *, 4> LHSs;
2922 SmallVector<const Expr *, 4> RHSs;
2923 for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) {
2924 auto IPriv = C->privates().begin();
2925 auto IRed = C->reduction_ops().begin();
2926 auto ILHS = C->lhs_exprs().begin();
2927 auto IRHS = C->rhs_exprs().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00002928 for (const Expr *Ref : C->varlists()) {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002929 Data.ReductionVars.emplace_back(Ref);
2930 Data.ReductionCopies.emplace_back(*IPriv);
2931 Data.ReductionOps.emplace_back(*IRed);
2932 LHSs.emplace_back(*ILHS);
2933 RHSs.emplace_back(*IRHS);
2934 std::advance(IPriv, 1);
2935 std::advance(IRed, 1);
2936 std::advance(ILHS, 1);
2937 std::advance(IRHS, 1);
2938 }
2939 }
2940 Data.Reductions = CGM.getOpenMPRuntime().emitTaskReductionInit(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002941 *this, S.getBeginLoc(), LHSs, RHSs, Data);
Alexey Bataev1d2353d2015-06-24 11:01:36 +00002942 // Build list of dependences.
Alexey Bataev7292c292016-04-25 12:22:29 +00002943 for (const auto *C : S.getClausesOfKind<OMPDependClause>())
Alexey Bataevddf3db92018-04-13 17:31:06 +00002944 for (const Expr *IRef : C->varlists())
Alexey Bataev43a919f2018-04-13 17:48:43 +00002945 Data.Dependences.emplace_back(C->getDependencyKind(), IRef);
Alexey Bataev475a7442018-01-12 19:39:11 +00002946 auto &&CodeGen = [&Data, &S, CS, &BodyGen, &LastprivateDstsOrigs,
2947 CapturedRegion](CodeGenFunction &CGF,
2948 PrePostActionTy &Action) {
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002949 // Set proper addresses for generated private copies.
Alexey Bataev7292c292016-04-25 12:22:29 +00002950 OMPPrivateScope Scope(CGF);
Alexey Bataevf93095a2016-05-05 08:46:22 +00002951 if (!Data.PrivateVars.empty() || !Data.FirstprivateVars.empty() ||
2952 !Data.LastprivateVars.empty()) {
James Y Knight9871db02019-02-05 16:42:33 +00002953 llvm::FunctionType *CopyFnTy = llvm::FunctionType::get(
2954 CGF.Builder.getVoidTy(), {CGF.Builder.getInt8PtrTy()}, true);
Alexey Bataev3c595a62017-08-14 15:01:03 +00002955 enum { PrivatesParam = 2, CopyFnParam = 3 };
Alexey Bataevddf3db92018-04-13 17:31:06 +00002956 llvm::Value *CopyFn = CGF.Builder.CreateLoad(
2957 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));
2958 llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(
2959 CS->getCapturedDecl()->getParam(PrivatesParam)));
Alexey Bataev48591dd2016-04-20 04:01:36 +00002960 // Map privates.
2961 llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> PrivatePtrs;
2962 llvm::SmallVector<llvm::Value *, 16> CallArgs;
2963 CallArgs.push_back(PrivatesPtr);
Alexey Bataevddf3db92018-04-13 17:31:06 +00002964 for (const Expr *E : Data.PrivateVars) {
2965 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataev48591dd2016-04-20 04:01:36 +00002966 Address PrivatePtr = CGF.CreateMemTemp(
2967 CGF.getContext().getPointerType(E->getType()), ".priv.ptr.addr");
Alexey Bataevddf3db92018-04-13 17:31:06 +00002968 PrivatePtrs.emplace_back(VD, PrivatePtr);
Alexey Bataev48591dd2016-04-20 04:01:36 +00002969 CallArgs.push_back(PrivatePtr.getPointer());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002970 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00002971 for (const Expr *E : Data.FirstprivateVars) {
2972 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataev48591dd2016-04-20 04:01:36 +00002973 Address PrivatePtr =
2974 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
2975 ".firstpriv.ptr.addr");
Alexey Bataevddf3db92018-04-13 17:31:06 +00002976 PrivatePtrs.emplace_back(VD, PrivatePtr);
Alexey Bataev48591dd2016-04-20 04:01:36 +00002977 CallArgs.push_back(PrivatePtr.getPointer());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002978 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00002979 for (const Expr *E : Data.LastprivateVars) {
2980 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataevf93095a2016-05-05 08:46:22 +00002981 Address PrivatePtr =
2982 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
2983 ".lastpriv.ptr.addr");
Alexey Bataevddf3db92018-04-13 17:31:06 +00002984 PrivatePtrs.emplace_back(VD, PrivatePtr);
Alexey Bataevf93095a2016-05-05 08:46:22 +00002985 CallArgs.push_back(PrivatePtr.getPointer());
2986 }
James Y Knight9871db02019-02-05 16:42:33 +00002987 CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
2988 CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);
Alexey Bataevddf3db92018-04-13 17:31:06 +00002989 for (const auto &Pair : LastprivateDstsOrigs) {
2990 const auto *OrigVD = cast<VarDecl>(Pair.second->getDecl());
Bruno Ricci5fc4db72018-12-21 14:10:18 +00002991 DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(OrigVD),
2992 /*RefersToEnclosingVariableOrCapture=*/
2993 CGF.CapturedStmtInfo->lookup(OrigVD) != nullptr,
2994 Pair.second->getType(), VK_LValue,
2995 Pair.second->getExprLoc());
Alexey Bataevf93095a2016-05-05 08:46:22 +00002996 Scope.addPrivate(Pair.first, [&CGF, &DRE]() {
2997 return CGF.EmitLValue(&DRE).getAddress();
2998 });
2999 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00003000 for (const auto &Pair : PrivatePtrs) {
Alexey Bataev48591dd2016-04-20 04:01:36 +00003001 Address Replacement(CGF.Builder.CreateLoad(Pair.second),
3002 CGF.getContext().getDeclAlign(Pair.first));
3003 Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; });
3004 }
Alexey Bataev3ae88e22015-05-22 08:56:35 +00003005 }
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00003006 if (Data.Reductions) {
Alexey Bataev475a7442018-01-12 19:39:11 +00003007 OMPLexicalScope LexScope(CGF, S, CapturedRegion);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00003008 ReductionCodeGen RedCG(Data.ReductionVars, Data.ReductionCopies,
3009 Data.ReductionOps);
3010 llvm::Value *ReductionsPtr = CGF.Builder.CreateLoad(
3011 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(9)));
3012 for (unsigned Cnt = 0, E = Data.ReductionVars.size(); Cnt < E; ++Cnt) {
3013 RedCG.emitSharedLValue(CGF, Cnt);
3014 RedCG.emitAggregateType(CGF, Cnt);
Alexey Bataev2e0cbe502018-03-08 15:24:08 +00003015 // FIXME: This must removed once the runtime library is fixed.
3016 // Emit required threadprivate variables for
Raphael Isemannb23ccec2018-12-10 12:37:46 +00003017 // initializer/combiner/finalizer.
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003018 CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(),
Alexey Bataev2e0cbe502018-03-08 15:24:08 +00003019 RedCG, Cnt);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00003020 Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003021 CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00003022 Replacement =
3023 Address(CGF.EmitScalarConversion(
3024 Replacement.getPointer(), CGF.getContext().VoidPtrTy,
3025 CGF.getContext().getPointerType(
3026 Data.ReductionCopies[Cnt]->getType()),
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003027 Data.ReductionCopies[Cnt]->getExprLoc()),
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00003028 Replacement.getAlignment());
3029 Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);
3030 Scope.addPrivate(RedCG.getBaseDecl(Cnt),
3031 [Replacement]() { return Replacement; });
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00003032 }
3033 }
Alexey Bataev88202be2017-07-27 13:20:36 +00003034 // Privatize all private variables except for in_reduction items.
Alexey Bataev48591dd2016-04-20 04:01:36 +00003035 (void)Scope.Privatize();
Alexey Bataev88202be2017-07-27 13:20:36 +00003036 SmallVector<const Expr *, 4> InRedVars;
3037 SmallVector<const Expr *, 4> InRedPrivs;
3038 SmallVector<const Expr *, 4> InRedOps;
3039 SmallVector<const Expr *, 4> TaskgroupDescriptors;
3040 for (const auto *C : S.getClausesOfKind<OMPInReductionClause>()) {
3041 auto IPriv = C->privates().begin();
3042 auto IRed = C->reduction_ops().begin();
3043 auto ITD = C->taskgroup_descriptors().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00003044 for (const Expr *Ref : C->varlists()) {
Alexey Bataev88202be2017-07-27 13:20:36 +00003045 InRedVars.emplace_back(Ref);
3046 InRedPrivs.emplace_back(*IPriv);
3047 InRedOps.emplace_back(*IRed);
3048 TaskgroupDescriptors.emplace_back(*ITD);
3049 std::advance(IPriv, 1);
3050 std::advance(IRed, 1);
3051 std::advance(ITD, 1);
3052 }
3053 }
3054 // Privatize in_reduction items here, because taskgroup descriptors must be
3055 // privatized earlier.
3056 OMPPrivateScope InRedScope(CGF);
3057 if (!InRedVars.empty()) {
3058 ReductionCodeGen RedCG(InRedVars, InRedPrivs, InRedOps);
3059 for (unsigned Cnt = 0, E = InRedVars.size(); Cnt < E; ++Cnt) {
3060 RedCG.emitSharedLValue(CGF, Cnt);
3061 RedCG.emitAggregateType(CGF, Cnt);
3062 // The taskgroup descriptor variable is always implicit firstprivate and
Raphael Isemannb23ccec2018-12-10 12:37:46 +00003063 // privatized already during processing of the firstprivates.
Alexey Bataev2e0cbe502018-03-08 15:24:08 +00003064 // FIXME: This must removed once the runtime library is fixed.
3065 // Emit required threadprivate variables for
Raphael Isemannb23ccec2018-12-10 12:37:46 +00003066 // initializer/combiner/finalizer.
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003067 CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(),
Alexey Bataev2e0cbe502018-03-08 15:24:08 +00003068 RedCG, Cnt);
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003069 llvm::Value *ReductionsPtr =
3070 CGF.EmitLoadOfScalar(CGF.EmitLValue(TaskgroupDescriptors[Cnt]),
3071 TaskgroupDescriptors[Cnt]->getExprLoc());
Alexey Bataev88202be2017-07-27 13:20:36 +00003072 Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003073 CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));
Alexey Bataev88202be2017-07-27 13:20:36 +00003074 Replacement = Address(
3075 CGF.EmitScalarConversion(
3076 Replacement.getPointer(), CGF.getContext().VoidPtrTy,
3077 CGF.getContext().getPointerType(InRedPrivs[Cnt]->getType()),
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003078 InRedPrivs[Cnt]->getExprLoc()),
Alexey Bataev88202be2017-07-27 13:20:36 +00003079 Replacement.getAlignment());
3080 Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);
3081 InRedScope.addPrivate(RedCG.getBaseDecl(Cnt),
3082 [Replacement]() { return Replacement; });
Alexey Bataev88202be2017-07-27 13:20:36 +00003083 }
3084 }
3085 (void)InRedScope.Privatize();
Alexey Bataev48591dd2016-04-20 04:01:36 +00003086
3087 Action.Enter(CGF);
Alexey Bataev7292c292016-04-25 12:22:29 +00003088 BodyGen(CGF);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003089 };
James Y Knight9871db02019-02-05 16:42:33 +00003090 llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
Alexey Bataev7292c292016-04-25 12:22:29 +00003091 S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, Data.Tied,
3092 Data.NumberOfParts);
3093 OMPLexicalScope Scope(*this, S);
3094 TaskGen(*this, OutlinedFn, Data);
3095}
3096
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003097static ImplicitParamDecl *
3098createImplicitFirstprivateForType(ASTContext &C, OMPTaskDataTy &Data,
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003099 QualType Ty, CapturedDecl *CD,
3100 SourceLocation Loc) {
3101 auto *OrigVD = ImplicitParamDecl::Create(C, CD, Loc, /*Id=*/nullptr, Ty,
3102 ImplicitParamDecl::Other);
3103 auto *OrigRef = DeclRefExpr::Create(
3104 C, NestedNameSpecifierLoc(), SourceLocation(), OrigVD,
3105 /*RefersToEnclosingVariableOrCapture=*/false, Loc, Ty, VK_LValue);
3106 auto *PrivateVD = ImplicitParamDecl::Create(C, CD, Loc, /*Id=*/nullptr, Ty,
3107 ImplicitParamDecl::Other);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003108 auto *PrivateRef = DeclRefExpr::Create(
3109 C, NestedNameSpecifierLoc(), SourceLocation(), PrivateVD,
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003110 /*RefersToEnclosingVariableOrCapture=*/false, Loc, Ty, VK_LValue);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003111 QualType ElemType = C.getBaseElementType(Ty);
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003112 auto *InitVD = ImplicitParamDecl::Create(C, CD, Loc, /*Id=*/nullptr, ElemType,
3113 ImplicitParamDecl::Other);
3114 auto *InitRef = DeclRefExpr::Create(
3115 C, NestedNameSpecifierLoc(), SourceLocation(), InitVD,
3116 /*RefersToEnclosingVariableOrCapture=*/false, Loc, ElemType, VK_LValue);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003117 PrivateVD->setInitStyle(VarDecl::CInit);
3118 PrivateVD->setInit(ImplicitCastExpr::Create(C, ElemType, CK_LValueToRValue,
3119 InitRef, /*BasePath=*/nullptr,
3120 VK_RValue));
3121 Data.FirstprivateVars.emplace_back(OrigRef);
3122 Data.FirstprivateCopies.emplace_back(PrivateRef);
3123 Data.FirstprivateInits.emplace_back(InitRef);
3124 return OrigVD;
3125}
3126
3127void CodeGenFunction::EmitOMPTargetTaskBasedDirective(
3128 const OMPExecutableDirective &S, const RegionCodeGenTy &BodyGen,
3129 OMPTargetDataInfo &InputInfo) {
3130 // Emit outlined function for task construct.
Alexey Bataevddf3db92018-04-13 17:31:06 +00003131 const CapturedStmt *CS = S.getCapturedStmt(OMPD_task);
3132 Address CapturedStruct = GenerateCapturedStmtArgument(*CS);
3133 QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
3134 auto I = CS->getCapturedDecl()->param_begin();
3135 auto PartId = std::next(I);
3136 auto TaskT = std::next(I, 4);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003137 OMPTaskDataTy Data;
3138 // The task is not final.
3139 Data.Final.setInt(/*IntVal=*/false);
3140 // Get list of firstprivate variables.
3141 for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) {
3142 auto IRef = C->varlist_begin();
3143 auto IElemInitRef = C->inits().begin();
3144 for (auto *IInit : C->private_copies()) {
3145 Data.FirstprivateVars.push_back(*IRef);
3146 Data.FirstprivateCopies.push_back(IInit);
3147 Data.FirstprivateInits.push_back(*IElemInitRef);
3148 ++IRef;
3149 ++IElemInitRef;
3150 }
3151 }
3152 OMPPrivateScope TargetScope(*this);
3153 VarDecl *BPVD = nullptr;
3154 VarDecl *PVD = nullptr;
3155 VarDecl *SVD = nullptr;
3156 if (InputInfo.NumberOfTargetItems > 0) {
3157 auto *CD = CapturedDecl::Create(
3158 getContext(), getContext().getTranslationUnitDecl(), /*NumParams=*/0);
3159 llvm::APInt ArrSize(/*numBits=*/32, InputInfo.NumberOfTargetItems);
3160 QualType BaseAndPointersType = getContext().getConstantArrayType(
3161 getContext().VoidPtrTy, ArrSize, ArrayType::Normal,
3162 /*IndexTypeQuals=*/0);
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003163 BPVD = createImplicitFirstprivateForType(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003164 getContext(), Data, BaseAndPointersType, CD, S.getBeginLoc());
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003165 PVD = createImplicitFirstprivateForType(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003166 getContext(), Data, BaseAndPointersType, CD, S.getBeginLoc());
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003167 QualType SizesType = getContext().getConstantArrayType(
Alexey Bataeva90fc662019-06-25 16:00:43 +00003168 getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1),
3169 ArrSize, ArrayType::Normal,
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003170 /*IndexTypeQuals=*/0);
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00003171 SVD = createImplicitFirstprivateForType(getContext(), Data, SizesType, CD,
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003172 S.getBeginLoc());
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003173 TargetScope.addPrivate(
3174 BPVD, [&InputInfo]() { return InputInfo.BasePointersArray; });
3175 TargetScope.addPrivate(PVD,
3176 [&InputInfo]() { return InputInfo.PointersArray; });
3177 TargetScope.addPrivate(SVD,
3178 [&InputInfo]() { return InputInfo.SizesArray; });
3179 }
3180 (void)TargetScope.Privatize();
3181 // Build list of dependences.
3182 for (const auto *C : S.getClausesOfKind<OMPDependClause>())
Alexey Bataevddf3db92018-04-13 17:31:06 +00003183 for (const Expr *IRef : C->varlists())
Alexey Bataev43a919f2018-04-13 17:48:43 +00003184 Data.Dependences.emplace_back(C->getDependencyKind(), IRef);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003185 auto &&CodeGen = [&Data, &S, CS, &BodyGen, BPVD, PVD, SVD,
3186 &InputInfo](CodeGenFunction &CGF, PrePostActionTy &Action) {
3187 // Set proper addresses for generated private copies.
3188 OMPPrivateScope Scope(CGF);
3189 if (!Data.FirstprivateVars.empty()) {
James Y Knight9871db02019-02-05 16:42:33 +00003190 llvm::FunctionType *CopyFnTy = llvm::FunctionType::get(
3191 CGF.Builder.getVoidTy(), {CGF.Builder.getInt8PtrTy()}, true);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003192 enum { PrivatesParam = 2, CopyFnParam = 3 };
Alexey Bataevddf3db92018-04-13 17:31:06 +00003193 llvm::Value *CopyFn = CGF.Builder.CreateLoad(
3194 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));
3195 llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(
3196 CS->getCapturedDecl()->getParam(PrivatesParam)));
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003197 // Map privates.
3198 llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> PrivatePtrs;
3199 llvm::SmallVector<llvm::Value *, 16> CallArgs;
3200 CallArgs.push_back(PrivatesPtr);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003201 for (const Expr *E : Data.FirstprivateVars) {
3202 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003203 Address PrivatePtr =
3204 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
3205 ".firstpriv.ptr.addr");
Alexey Bataevddf3db92018-04-13 17:31:06 +00003206 PrivatePtrs.emplace_back(VD, PrivatePtr);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003207 CallArgs.push_back(PrivatePtr.getPointer());
3208 }
James Y Knight9871db02019-02-05 16:42:33 +00003209 CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
3210 CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003211 for (const auto &Pair : PrivatePtrs) {
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003212 Address Replacement(CGF.Builder.CreateLoad(Pair.second),
3213 CGF.getContext().getDeclAlign(Pair.first));
3214 Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; });
3215 }
3216 }
3217 // Privatize all private variables except for in_reduction items.
3218 (void)Scope.Privatize();
Alexey Bataev8451efa2018-01-15 19:06:12 +00003219 if (InputInfo.NumberOfTargetItems > 0) {
3220 InputInfo.BasePointersArray = CGF.Builder.CreateConstArrayGEP(
James Y Knight751fe282019-02-09 22:22:28 +00003221 CGF.GetAddrOfLocalVar(BPVD), /*Index=*/0);
Alexey Bataev8451efa2018-01-15 19:06:12 +00003222 InputInfo.PointersArray = CGF.Builder.CreateConstArrayGEP(
James Y Knight751fe282019-02-09 22:22:28 +00003223 CGF.GetAddrOfLocalVar(PVD), /*Index=*/0);
Alexey Bataev8451efa2018-01-15 19:06:12 +00003224 InputInfo.SizesArray = CGF.Builder.CreateConstArrayGEP(
James Y Knight751fe282019-02-09 22:22:28 +00003225 CGF.GetAddrOfLocalVar(SVD), /*Index=*/0);
Alexey Bataev8451efa2018-01-15 19:06:12 +00003226 }
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003227
3228 Action.Enter(CGF);
Alexey Bataev475a7442018-01-12 19:39:11 +00003229 OMPLexicalScope LexScope(CGF, S, OMPD_task, /*EmitPreInitStmt=*/false);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003230 BodyGen(CGF);
3231 };
James Y Knight9871db02019-02-05 16:42:33 +00003232 llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003233 S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, /*Tied=*/true,
3234 Data.NumberOfParts);
3235 llvm::APInt TrueOrFalse(32, S.hasClausesOfKind<OMPNowaitClause>() ? 1 : 0);
3236 IntegerLiteral IfCond(getContext(), TrueOrFalse,
3237 getContext().getIntTypeForBitwidth(32, /*Signed=*/0),
3238 SourceLocation());
3239
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003240 CGM.getOpenMPRuntime().emitTaskCall(*this, S.getBeginLoc(), S, OutlinedFn,
Alexey Bataevd2202ca2017-12-27 17:58:32 +00003241 SharedsTy, CapturedStruct, &IfCond, Data);
3242}
3243
Alexey Bataev7292c292016-04-25 12:22:29 +00003244void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
3245 // Emit outlined function for task construct.
Alexey Bataev475a7442018-01-12 19:39:11 +00003246 const CapturedStmt *CS = S.getCapturedStmt(OMPD_task);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003247 Address CapturedStruct = GenerateCapturedStmtArgument(*CS);
3248 QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
Alexey Bataev1d677132015-04-22 13:57:31 +00003249 const Expr *IfCond = nullptr;
Alexey Bataev7371aa32015-09-03 08:45:56 +00003250 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
3251 if (C->getNameModifier() == OMPD_unknown ||
3252 C->getNameModifier() == OMPD_task) {
3253 IfCond = C->getCondition();
3254 break;
3255 }
Alexey Bataev1d677132015-04-22 13:57:31 +00003256 }
Alexey Bataev7292c292016-04-25 12:22:29 +00003257
Alexey Bataev24b5bae2016-04-28 09:23:51 +00003258 OMPTaskDataTy Data;
3259 // Check if we should emit tied or untied task.
3260 Data.Tied = !S.getSingleClause<OMPUntiedClause>();
Alexey Bataev7292c292016-04-25 12:22:29 +00003261 auto &&BodyGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) {
3262 CGF.EmitStmt(CS->getCapturedStmt());
3263 };
Alexey Bataev24b5bae2016-04-28 09:23:51 +00003264 auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
James Y Knight9871db02019-02-05 16:42:33 +00003265 IfCond](CodeGenFunction &CGF, llvm::Function *OutlinedFn,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00003266 const OMPTaskDataTy &Data) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003267 CGF.CGM.getOpenMPRuntime().emitTaskCall(CGF, S.getBeginLoc(), S, OutlinedFn,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00003268 SharedsTy, CapturedStruct, IfCond,
3269 Data);
Alexey Bataev7292c292016-04-25 12:22:29 +00003270 };
Alexey Bataev475a7442018-01-12 19:39:11 +00003271 EmitOMPTaskBasedDirective(S, OMPD_task, BodyGen, TaskGen, Data);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00003272}
3273
Alexey Bataev9f797f32015-02-05 05:57:51 +00003274void CodeGenFunction::EmitOMPTaskyieldDirective(
3275 const OMPTaskyieldDirective &S) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003276 CGM.getOpenMPRuntime().emitTaskyieldCall(*this, S.getBeginLoc());
Alexey Bataev68446b72014-07-18 07:47:19 +00003277}
3278
Alexey Bataev8f7c1b02014-12-05 04:09:23 +00003279void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003280 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_barrier);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00003281}
3282
Alexey Bataev8b8e2022015-04-27 05:22:09 +00003283void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003284 CGM.getOpenMPRuntime().emitTaskwaitCall(*this, S.getBeginLoc());
Alexey Bataev2df347a2014-07-18 10:17:07 +00003285}
3286
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003287void CodeGenFunction::EmitOMPTaskgroupDirective(
3288 const OMPTaskgroupDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003289 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
3290 Action.Enter(CGF);
Alexey Bataev3b1b8952017-07-25 15:53:26 +00003291 if (const Expr *E = S.getReductionRef()) {
3292 SmallVector<const Expr *, 4> LHSs;
3293 SmallVector<const Expr *, 4> RHSs;
3294 OMPTaskDataTy Data;
3295 for (const auto *C : S.getClausesOfKind<OMPTaskReductionClause>()) {
3296 auto IPriv = C->privates().begin();
3297 auto IRed = C->reduction_ops().begin();
3298 auto ILHS = C->lhs_exprs().begin();
3299 auto IRHS = C->rhs_exprs().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00003300 for (const Expr *Ref : C->varlists()) {
Alexey Bataev3b1b8952017-07-25 15:53:26 +00003301 Data.ReductionVars.emplace_back(Ref);
3302 Data.ReductionCopies.emplace_back(*IPriv);
3303 Data.ReductionOps.emplace_back(*IRed);
3304 LHSs.emplace_back(*ILHS);
3305 RHSs.emplace_back(*IRHS);
3306 std::advance(IPriv, 1);
3307 std::advance(IRed, 1);
3308 std::advance(ILHS, 1);
3309 std::advance(IRHS, 1);
3310 }
3311 }
3312 llvm::Value *ReductionDesc =
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003313 CGF.CGM.getOpenMPRuntime().emitTaskReductionInit(CGF, S.getBeginLoc(),
Alexey Bataev3b1b8952017-07-25 15:53:26 +00003314 LHSs, RHSs, Data);
3315 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
3316 CGF.EmitVarDecl(*VD);
3317 CGF.EmitStoreOfScalar(ReductionDesc, CGF.GetAddrOfLocalVar(VD),
3318 /*Volatile=*/false, E->getType());
3319 }
Alexey Bataev475a7442018-01-12 19:39:11 +00003320 CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003321 };
Alexey Bataev475a7442018-01-12 19:39:11 +00003322 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003323 CGM.getOpenMPRuntime().emitTaskgroupRegion(*this, CodeGen, S.getBeginLoc());
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003324}
3325
Alexey Bataevcc37cc12014-11-20 04:34:54 +00003326void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00003327 CGM.getOpenMPRuntime().emitFlush(
3328 *this,
3329 [&S]() -> ArrayRef<const Expr *> {
3330 if (const auto *FlushClause = S.getSingleClause<OMPFlushClause>())
3331 return llvm::makeArrayRef(FlushClause->varlist_begin(),
3332 FlushClause->varlist_end());
3333 return llvm::None;
3334 }(),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003335 S.getBeginLoc());
Alexey Bataev6125da92014-07-21 11:26:11 +00003336}
3337
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003338void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S,
3339 const CodeGenLoopTy &CodeGenLoop,
3340 Expr *IncExpr) {
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003341 // Emit the loop iteration variable.
Alexey Bataevddf3db92018-04-13 17:31:06 +00003342 const auto *IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
3343 const auto *IVDecl = cast<VarDecl>(IVExpr->getDecl());
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003344 EmitVarDecl(*IVDecl);
3345
3346 // Emit the iterations count variable.
3347 // If it is not a variable, Sema decided to calculate iterations count on each
3348 // iteration (e.g., it is foldable into a constant).
Alexey Bataevddf3db92018-04-13 17:31:06 +00003349 if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003350 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
3351 // Emit calculation of the iterations count.
3352 EmitIgnoredExpr(S.getCalcLastIteration());
3353 }
3354
Alexey Bataevddf3db92018-04-13 17:31:06 +00003355 CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003356
Carlo Bertolli962bb802017-01-03 18:24:42 +00003357 bool HasLastprivateClause = false;
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003358 // Check pre-condition.
3359 {
Alexey Bataev5a3af132016-03-29 08:58:54 +00003360 OMPLoopScope PreInitScope(*this, S);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003361 // Skip the entire loop if we don't meet the precondition.
3362 // If the condition constant folds and can be elided, avoid emitting the
3363 // whole loop.
3364 bool CondConstant;
3365 llvm::BasicBlock *ContBlock = nullptr;
3366 if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
3367 if (!CondConstant)
3368 return;
3369 } else {
Alexey Bataevddf3db92018-04-13 17:31:06 +00003370 llvm::BasicBlock *ThenBlock = createBasicBlock("omp.precond.then");
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003371 ContBlock = createBasicBlock("omp.precond.end");
3372 emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock,
3373 getProfileCount(&S));
3374 EmitBlock(ThenBlock);
3375 incrementProfileCounter(&S);
3376 }
3377
Alexey Bataev617db5f2017-12-04 15:38:33 +00003378 emitAlignedClause(*this, S);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003379 // Emit 'then' code.
3380 {
3381 // Emit helper vars inits.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003382
3383 LValue LB = EmitOMPHelperVar(
3384 *this, cast<DeclRefExpr>(
3385 (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
3386 ? S.getCombinedLowerBoundVariable()
3387 : S.getLowerBoundVariable())));
3388 LValue UB = EmitOMPHelperVar(
3389 *this, cast<DeclRefExpr>(
3390 (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
3391 ? S.getCombinedUpperBoundVariable()
3392 : S.getUpperBoundVariable())));
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003393 LValue ST =
3394 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable()));
3395 LValue IL =
3396 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
3397
3398 OMPPrivateScope LoopScope(*this);
Carlo Bertolli962bb802017-01-03 18:24:42 +00003399 if (EmitOMPFirstprivateClause(S, LoopScope)) {
Alexey Bataev617db5f2017-12-04 15:38:33 +00003400 // Emit implicit barrier to synchronize threads and avoid data races
3401 // on initialization of firstprivate variables and post-update of
Carlo Bertolli962bb802017-01-03 18:24:42 +00003402 // lastprivate variables.
3403 CGM.getOpenMPRuntime().emitBarrierCall(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003404 *this, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
Alexey Bataev617db5f2017-12-04 15:38:33 +00003405 /*ForceSimpleCall=*/true);
Carlo Bertolli962bb802017-01-03 18:24:42 +00003406 }
3407 EmitOMPPrivateClause(S, LoopScope);
Alexey Bataev617db5f2017-12-04 15:38:33 +00003408 if (isOpenMPSimdDirective(S.getDirectiveKind()) &&
Alexey Bataev999277a2017-12-06 14:31:09 +00003409 !isOpenMPParallelDirective(S.getDirectiveKind()) &&
3410 !isOpenMPTeamsDirective(S.getDirectiveKind()))
Alexey Bataev617db5f2017-12-04 15:38:33 +00003411 EmitOMPReductionClauseInit(S, LoopScope);
Carlo Bertolli962bb802017-01-03 18:24:42 +00003412 HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
Alexey Bataev5dff95c2016-04-22 03:56:56 +00003413 EmitOMPPrivateLoopCounters(S, LoopScope);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003414 (void)LoopScope.Privatize();
Alexey Bataev60705422018-10-30 15:50:12 +00003415 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
3416 CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(*this, S);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003417
3418 // Detect the distribute schedule kind and chunk.
3419 llvm::Value *Chunk = nullptr;
3420 OpenMPDistScheduleClauseKind ScheduleKind = OMPC_DIST_SCHEDULE_unknown;
Alexey Bataevddf3db92018-04-13 17:31:06 +00003421 if (const auto *C = S.getSingleClause<OMPDistScheduleClause>()) {
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003422 ScheduleKind = C->getDistScheduleKind();
Alexey Bataevddf3db92018-04-13 17:31:06 +00003423 if (const Expr *Ch = C->getChunkSize()) {
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003424 Chunk = EmitScalarExpr(Ch);
3425 Chunk = EmitScalarConversion(Chunk, Ch->getType(),
Alexey Bataev617db5f2017-12-04 15:38:33 +00003426 S.getIterationVariable()->getType(),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003427 S.getBeginLoc());
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003428 }
Gheorghe-Teodor Bercea02650d42018-09-27 19:22:56 +00003429 } else {
3430 // Default behaviour for dist_schedule clause.
3431 CGM.getOpenMPRuntime().getDefaultDistScheduleAndChunk(
3432 *this, S, ScheduleKind, Chunk);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003433 }
3434 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
3435 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
3436
3437 // OpenMP [2.10.8, distribute Construct, Description]
3438 // If dist_schedule is specified, kind must be static. If specified,
3439 // iterations are divided into chunks of size chunk_size, chunks are
3440 // assigned to the teams of the league in a round-robin fashion in the
3441 // order of the team number. When no chunk_size is specified, the
3442 // iteration space is divided into chunks that are approximately equal
3443 // in size, and at most one chunk is distributed to each team of the
3444 // league. The size of the chunks is unspecified in this case.
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00003445 bool StaticChunked = RT.isStaticChunked(
3446 ScheduleKind, /* Chunked */ Chunk != nullptr) &&
3447 isOpenMPLoopBoundSharingDirective(S.getDirectiveKind());
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003448 if (RT.isStaticNonchunked(ScheduleKind,
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00003449 /* Chunked */ Chunk != nullptr) ||
3450 StaticChunked) {
Alexey Bataev617db5f2017-12-04 15:38:33 +00003451 if (isOpenMPSimdDirective(S.getDirectiveKind()))
3452 EmitOMPSimdInit(S, /*IsMonotonic=*/true);
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003453 CGOpenMPRuntime::StaticRTInput StaticInit(
3454 IVSize, IVSigned, /* Ordered = */ false, IL.getAddress(),
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00003455 LB.getAddress(), UB.getAddress(), ST.getAddress(),
3456 StaticChunked ? Chunk : nullptr);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003457 RT.emitDistributeStaticInit(*this, S.getBeginLoc(), ScheduleKind,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003458 StaticInit);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003459 JumpDest LoopExit =
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003460 getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit"));
3461 // UB = min(UB, GlobalUB);
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003462 EmitIgnoredExpr(isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
3463 ? S.getCombinedEnsureUpperBound()
3464 : S.getEnsureUpperBound());
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003465 // IV = LB;
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003466 EmitIgnoredExpr(isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
3467 ? S.getCombinedInit()
3468 : S.getInit());
3469
Alexey Bataevddf3db92018-04-13 17:31:06 +00003470 const Expr *Cond =
3471 isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
3472 ? S.getCombinedCond()
3473 : S.getCond();
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003474
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00003475 if (StaticChunked)
3476 Cond = S.getCombinedDistCond();
3477
3478 // For static unchunked schedules generate:
3479 //
3480 // 1. For distribute alone, codegen
3481 // while (idx <= UB) {
3482 // BODY;
3483 // ++idx;
3484 // }
3485 //
3486 // 2. When combined with 'for' (e.g. as in 'distribute parallel for')
3487 // while (idx <= UB) {
3488 // <CodeGen rest of pragma>(LB, UB);
3489 // idx += ST;
3490 // }
3491 //
3492 // For static chunk one schedule generate:
3493 //
3494 // while (IV <= GlobalUB) {
3495 // <CodeGen rest of pragma>(LB, UB);
3496 // LB += ST;
3497 // UB += ST;
3498 // UB = min(UB, GlobalUB);
3499 // IV = LB;
3500 // }
3501 //
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003502 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), Cond, IncExpr,
3503 [&S, LoopExit, &CodeGenLoop](CodeGenFunction &CGF) {
3504 CodeGenLoop(CGF, S, LoopExit);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003505 },
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00003506 [&S, StaticChunked](CodeGenFunction &CGF) {
3507 if (StaticChunked) {
3508 CGF.EmitIgnoredExpr(S.getCombinedNextLowerBound());
3509 CGF.EmitIgnoredExpr(S.getCombinedNextUpperBound());
3510 CGF.EmitIgnoredExpr(S.getCombinedEnsureUpperBound());
3511 CGF.EmitIgnoredExpr(S.getCombinedInit());
3512 }
3513 });
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003514 EmitBlock(LoopExit.getBlock());
3515 // Tell the runtime we are done.
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003516 RT.emitForStaticFinish(*this, S.getBeginLoc(), S.getDirectiveKind());
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003517 } else {
3518 // Emit the outer loop, which requests its work chunk [LB..UB] from
3519 // runtime and runs the inner loop to process it.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003520 const OMPLoopArguments LoopArguments = {
3521 LB.getAddress(), UB.getAddress(), ST.getAddress(), IL.getAddress(),
3522 Chunk};
3523 EmitOMPDistributeOuterLoop(ScheduleKind, S, LoopScope, LoopArguments,
3524 CodeGenLoop);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003525 }
Alexey Bataev617db5f2017-12-04 15:38:33 +00003526 if (isOpenMPSimdDirective(S.getDirectiveKind())) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00003527 EmitOMPSimdFinal(S, [IL, &S](CodeGenFunction &CGF) {
Alexey Bataev617db5f2017-12-04 15:38:33 +00003528 return CGF.Builder.CreateIsNotNull(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003529 CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
Alexey Bataev617db5f2017-12-04 15:38:33 +00003530 });
3531 }
Carlo Bertollibeda2142018-02-22 19:38:14 +00003532 if (isOpenMPSimdDirective(S.getDirectiveKind()) &&
3533 !isOpenMPParallelDirective(S.getDirectiveKind()) &&
3534 !isOpenMPTeamsDirective(S.getDirectiveKind())) {
Jonas Hahnfeld5aaaece2018-10-02 19:12:47 +00003535 EmitOMPReductionClauseFinal(S, OMPD_simd);
Carlo Bertollibeda2142018-02-22 19:38:14 +00003536 // Emit post-update of the reduction variables if IsLastIter != 0.
3537 emitPostUpdateForReductionClause(
Alexey Bataevddf3db92018-04-13 17:31:06 +00003538 *this, S, [IL, &S](CodeGenFunction &CGF) {
Carlo Bertollibeda2142018-02-22 19:38:14 +00003539 return CGF.Builder.CreateIsNotNull(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003540 CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
Carlo Bertollibeda2142018-02-22 19:38:14 +00003541 });
Alexey Bataev617db5f2017-12-04 15:38:33 +00003542 }
Carlo Bertolli962bb802017-01-03 18:24:42 +00003543 // Emit final copy of the lastprivate variables if IsLastIter != 0.
Alexey Bataev617db5f2017-12-04 15:38:33 +00003544 if (HasLastprivateClause) {
Carlo Bertolli962bb802017-01-03 18:24:42 +00003545 EmitOMPLastprivateClauseFinal(
3546 S, /*NoFinals=*/false,
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003547 Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getBeginLoc())));
Alexey Bataev617db5f2017-12-04 15:38:33 +00003548 }
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003549 }
3550
3551 // We're now done with the loop, so jump to the continuation block.
3552 if (ContBlock) {
3553 EmitBranch(ContBlock);
3554 EmitBlock(ContBlock, true);
3555 }
3556 }
3557}
3558
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003559void CodeGenFunction::EmitOMPDistributeDirective(
3560 const OMPDistributeDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003561 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003562 CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003563 };
Alexey Bataev475a7442018-01-12 19:39:11 +00003564 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev10a54312017-11-27 16:54:08 +00003565 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003566}
3567
Alexey Bataev5f600d62015-09-29 03:48:57 +00003568static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM,
3569 const CapturedStmt *S) {
3570 CodeGenFunction CGF(CGM, /*suppressNewContext=*/true);
3571 CodeGenFunction::CGCapturedStmtInfo CapStmtInfo;
3572 CGF.CapturedStmtInfo = &CapStmtInfo;
Alexey Bataevddf3db92018-04-13 17:31:06 +00003573 llvm::Function *Fn = CGF.GenerateOpenMPCapturedStmtFunction(*S);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003574 Fn->setDoesNotRecurse();
Alexey Bataev5f600d62015-09-29 03:48:57 +00003575 return Fn;
3576}
3577
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003578void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) {
Alexey Bataev475a7442018-01-12 19:39:11 +00003579 if (S.hasClausesOfKind<OMPDependClause>()) {
3580 assert(!S.getAssociatedStmt() &&
3581 "No associated statement must be in ordered depend construct.");
Alexey Bataev8b427062016-05-25 12:36:08 +00003582 for (const auto *DC : S.getClausesOfKind<OMPDependClause>())
3583 CGM.getOpenMPRuntime().emitDoacrossOrdered(*this, DC);
Alexey Bataev8ef31412015-12-18 07:58:25 +00003584 return;
Alexey Bataev8b427062016-05-25 12:36:08 +00003585 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00003586 const auto *C = S.getSingleClause<OMPSIMDClause>();
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003587 auto &&CodeGen = [&S, C, this](CodeGenFunction &CGF,
3588 PrePostActionTy &Action) {
Alexey Bataev475a7442018-01-12 19:39:11 +00003589 const CapturedStmt *CS = S.getInnermostCapturedStmt();
Alexey Bataev5f600d62015-09-29 03:48:57 +00003590 if (C) {
Alexey Bataev5f600d62015-09-29 03:48:57 +00003591 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
3592 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003593 llvm::Function *OutlinedFn = emitOutlinedOrderedFunction(CGM, CS);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003594 CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, S.getBeginLoc(),
Alexey Bataev3c595a62017-08-14 15:01:03 +00003595 OutlinedFn, CapturedVars);
Alexey Bataev5f600d62015-09-29 03:48:57 +00003596 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003597 Action.Enter(CGF);
Alexey Bataev475a7442018-01-12 19:39:11 +00003598 CGF.EmitStmt(CS->getCapturedStmt());
Alexey Bataev5f600d62015-09-29 03:48:57 +00003599 }
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003600 };
Alexey Bataev475a7442018-01-12 19:39:11 +00003601 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003602 CGM.getOpenMPRuntime().emitOrderedRegion(*this, CodeGen, S.getBeginLoc(), !C);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003603}
3604
Alexey Bataevb57056f2015-01-22 06:17:56 +00003605static llvm::Value *convertToScalarValue(CodeGenFunction &CGF, RValue Val,
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003606 QualType SrcType, QualType DestType,
3607 SourceLocation Loc) {
Alexey Bataevb57056f2015-01-22 06:17:56 +00003608 assert(CGF.hasScalarEvaluationKind(DestType) &&
3609 "DestType must have scalar evaluation kind.");
3610 assert(!Val.isAggregate() && "Must be a scalar or complex.");
Alexey Bataevddf3db92018-04-13 17:31:06 +00003611 return Val.isScalar() ? CGF.EmitScalarConversion(Val.getScalarVal(), SrcType,
3612 DestType, Loc)
3613 : CGF.EmitComplexToScalarConversion(
3614 Val.getComplexVal(), SrcType, DestType, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003615}
3616
3617static CodeGenFunction::ComplexPairTy
3618convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType,
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003619 QualType DestType, SourceLocation Loc) {
Alexey Bataevb57056f2015-01-22 06:17:56 +00003620 assert(CGF.getEvaluationKind(DestType) == TEK_Complex &&
3621 "DestType must have complex evaluation kind.");
3622 CodeGenFunction::ComplexPairTy ComplexVal;
3623 if (Val.isScalar()) {
3624 // Convert the input element to the element type of the complex.
Alexey Bataevddf3db92018-04-13 17:31:06 +00003625 QualType DestElementType =
3626 DestType->castAs<ComplexType>()->getElementType();
3627 llvm::Value *ScalarVal = CGF.EmitScalarConversion(
3628 Val.getScalarVal(), SrcType, DestElementType, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003629 ComplexVal = CodeGenFunction::ComplexPairTy(
3630 ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType()));
3631 } else {
3632 assert(Val.isComplex() && "Must be a scalar or complex.");
Alexey Bataevddf3db92018-04-13 17:31:06 +00003633 QualType SrcElementType = SrcType->castAs<ComplexType>()->getElementType();
3634 QualType DestElementType =
3635 DestType->castAs<ComplexType>()->getElementType();
Alexey Bataevb57056f2015-01-22 06:17:56 +00003636 ComplexVal.first = CGF.EmitScalarConversion(
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003637 Val.getComplexVal().first, SrcElementType, DestElementType, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003638 ComplexVal.second = CGF.EmitScalarConversion(
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003639 Val.getComplexVal().second, SrcElementType, DestElementType, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003640 }
3641 return ComplexVal;
3642}
3643
Alexey Bataev5e018f92015-04-23 06:35:10 +00003644static void emitSimpleAtomicStore(CodeGenFunction &CGF, bool IsSeqCst,
3645 LValue LVal, RValue RVal) {
3646 if (LVal.isGlobalReg()) {
3647 CGF.EmitStoreThroughGlobalRegLValue(RVal, LVal);
3648 } else {
JF Bastien92f4ef12016-04-06 17:26:42 +00003649 CGF.EmitAtomicStore(RVal, LVal,
3650 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3651 : llvm::AtomicOrdering::Monotonic,
Rui Ueyama49a3ad22019-07-16 04:46:31 +00003652 LVal.isVolatile(), /*isInit=*/false);
Alexey Bataev5e018f92015-04-23 06:35:10 +00003653 }
3654}
3655
Alexey Bataev8524d152016-01-21 12:35:58 +00003656void CodeGenFunction::emitOMPSimpleStore(LValue LVal, RValue RVal,
3657 QualType RValTy, SourceLocation Loc) {
3658 switch (getEvaluationKind(LVal.getType())) {
Alexey Bataev5e018f92015-04-23 06:35:10 +00003659 case TEK_Scalar:
Alexey Bataev8524d152016-01-21 12:35:58 +00003660 EmitStoreThroughLValue(RValue::get(convertToScalarValue(
3661 *this, RVal, RValTy, LVal.getType(), Loc)),
3662 LVal);
Alexey Bataev5e018f92015-04-23 06:35:10 +00003663 break;
3664 case TEK_Complex:
Alexey Bataev8524d152016-01-21 12:35:58 +00003665 EmitStoreOfComplex(
3666 convertToComplexValue(*this, RVal, RValTy, LVal.getType(), Loc), LVal,
Alexey Bataev5e018f92015-04-23 06:35:10 +00003667 /*isInit=*/false);
3668 break;
3669 case TEK_Aggregate:
3670 llvm_unreachable("Must be a scalar or complex.");
3671 }
3672}
3673
Alexey Bataevddf3db92018-04-13 17:31:06 +00003674static void emitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst,
Alexey Bataevb57056f2015-01-22 06:17:56 +00003675 const Expr *X, const Expr *V,
3676 SourceLocation Loc) {
3677 // v = x;
3678 assert(V->isLValue() && "V of 'omp atomic read' is not lvalue");
3679 assert(X->isLValue() && "X of 'omp atomic read' is not lvalue");
3680 LValue XLValue = CGF.EmitLValue(X);
3681 LValue VLValue = CGF.EmitLValue(V);
David Majnemera5b195a2015-02-14 01:35:12 +00003682 RValue Res = XLValue.isGlobalReg()
3683 ? CGF.EmitLoadOfLValue(XLValue, Loc)
JF Bastien92f4ef12016-04-06 17:26:42 +00003684 : CGF.EmitAtomicLoad(
3685 XLValue, Loc,
3686 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3687 : llvm::AtomicOrdering::Monotonic,
3688 XLValue.isVolatile());
Alexey Bataevb57056f2015-01-22 06:17:56 +00003689 // OpenMP, 2.12.6, atomic Construct
3690 // Any atomic construct with a seq_cst clause forces the atomically
3691 // performed operation to include an implicit flush operation without a
3692 // list.
3693 if (IsSeqCst)
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003694 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
Alexey Bataev8524d152016-01-21 12:35:58 +00003695 CGF.emitOMPSimpleStore(VLValue, Res, X->getType().getNonReferenceType(), Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003696}
3697
Alexey Bataevddf3db92018-04-13 17:31:06 +00003698static void emitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst,
Alexey Bataevb8329262015-02-27 06:33:30 +00003699 const Expr *X, const Expr *E,
3700 SourceLocation Loc) {
3701 // x = expr;
3702 assert(X->isLValue() && "X of 'omp atomic write' is not lvalue");
Alexey Bataev5e018f92015-04-23 06:35:10 +00003703 emitSimpleAtomicStore(CGF, IsSeqCst, CGF.EmitLValue(X), CGF.EmitAnyExpr(E));
Alexey Bataevb8329262015-02-27 06:33:30 +00003704 // OpenMP, 2.12.6, atomic Construct
3705 // Any atomic construct with a seq_cst clause forces the atomically
3706 // performed operation to include an implicit flush operation without a
3707 // list.
3708 if (IsSeqCst)
3709 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
3710}
3711
Benjamin Kramer439ee9d2015-05-01 13:59:53 +00003712static std::pair<bool, RValue> emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X,
3713 RValue Update,
3714 BinaryOperatorKind BO,
3715 llvm::AtomicOrdering AO,
3716 bool IsXLHSInRHSPart) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00003717 ASTContext &Context = CGF.getContext();
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003718 // Allow atomicrmw only if 'x' and 'update' are integer values, lvalue for 'x'
Alexey Bataevb4505a72015-03-30 05:20:59 +00003719 // expression is simple and atomic is allowed for the given type for the
3720 // target platform.
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003721 if (BO == BO_Comma || !Update.isScalar() ||
Alexey Bataev9d541a72015-05-08 11:47:16 +00003722 !Update.getScalarVal()->getType()->isIntegerTy() ||
3723 !X.isSimple() || (!isa<llvm::ConstantInt>(Update.getScalarVal()) &&
3724 (Update.getScalarVal()->getType() !=
John McCall7f416cc2015-09-08 08:05:57 +00003725 X.getAddress().getElementType())) ||
3726 !X.getAddress().getElementType()->isIntegerTy() ||
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003727 !Context.getTargetInfo().hasBuiltinAtomic(
3728 Context.getTypeSize(X.getType()), Context.toBits(X.getAlignment())))
Alexey Bataev5e018f92015-04-23 06:35:10 +00003729 return std::make_pair(false, RValue::get(nullptr));
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003730
3731 llvm::AtomicRMWInst::BinOp RMWOp;
3732 switch (BO) {
3733 case BO_Add:
3734 RMWOp = llvm::AtomicRMWInst::Add;
3735 break;
3736 case BO_Sub:
3737 if (!IsXLHSInRHSPart)
Alexey Bataev5e018f92015-04-23 06:35:10 +00003738 return std::make_pair(false, RValue::get(nullptr));
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003739 RMWOp = llvm::AtomicRMWInst::Sub;
3740 break;
3741 case BO_And:
3742 RMWOp = llvm::AtomicRMWInst::And;
3743 break;
3744 case BO_Or:
3745 RMWOp = llvm::AtomicRMWInst::Or;
3746 break;
3747 case BO_Xor:
3748 RMWOp = llvm::AtomicRMWInst::Xor;
3749 break;
3750 case BO_LT:
3751 RMWOp = X.getType()->hasSignedIntegerRepresentation()
3752 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min
3753 : llvm::AtomicRMWInst::Max)
3754 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin
3755 : llvm::AtomicRMWInst::UMax);
3756 break;
3757 case BO_GT:
3758 RMWOp = X.getType()->hasSignedIntegerRepresentation()
3759 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max
3760 : llvm::AtomicRMWInst::Min)
3761 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax
3762 : llvm::AtomicRMWInst::UMin);
3763 break;
Alexey Bataev5e018f92015-04-23 06:35:10 +00003764 case BO_Assign:
3765 RMWOp = llvm::AtomicRMWInst::Xchg;
3766 break;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003767 case BO_Mul:
3768 case BO_Div:
3769 case BO_Rem:
3770 case BO_Shl:
3771 case BO_Shr:
3772 case BO_LAnd:
3773 case BO_LOr:
Alexey Bataev5e018f92015-04-23 06:35:10 +00003774 return std::make_pair(false, RValue::get(nullptr));
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003775 case BO_PtrMemD:
3776 case BO_PtrMemI:
3777 case BO_LE:
3778 case BO_GE:
3779 case BO_EQ:
3780 case BO_NE:
Richard Smithc70f1d62017-12-14 15:16:18 +00003781 case BO_Cmp:
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003782 case BO_AddAssign:
3783 case BO_SubAssign:
3784 case BO_AndAssign:
3785 case BO_OrAssign:
3786 case BO_XorAssign:
3787 case BO_MulAssign:
3788 case BO_DivAssign:
3789 case BO_RemAssign:
3790 case BO_ShlAssign:
3791 case BO_ShrAssign:
3792 case BO_Comma:
3793 llvm_unreachable("Unsupported atomic update operation");
3794 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00003795 llvm::Value *UpdateVal = Update.getScalarVal();
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003796 if (auto *IC = dyn_cast<llvm::ConstantInt>(UpdateVal)) {
3797 UpdateVal = CGF.Builder.CreateIntCast(
John McCall7f416cc2015-09-08 08:05:57 +00003798 IC, X.getAddress().getElementType(),
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003799 X.getType()->hasSignedIntegerRepresentation());
3800 }
Alexey Bataevddf3db92018-04-13 17:31:06 +00003801 llvm::Value *Res =
3802 CGF.Builder.CreateAtomicRMW(RMWOp, X.getPointer(), UpdateVal, AO);
Alexey Bataev5e018f92015-04-23 06:35:10 +00003803 return std::make_pair(true, RValue::get(Res));
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003804}
3805
Alexey Bataev5e018f92015-04-23 06:35:10 +00003806std::pair<bool, RValue> CodeGenFunction::EmitOMPAtomicSimpleUpdateExpr(
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003807 LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart,
3808 llvm::AtomicOrdering AO, SourceLocation Loc,
Alexey Bataevddf3db92018-04-13 17:31:06 +00003809 const llvm::function_ref<RValue(RValue)> CommonGen) {
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003810 // Update expressions are allowed to have the following forms:
3811 // x binop= expr; -> xrval + expr;
3812 // x++, ++x -> xrval + 1;
3813 // x--, --x -> xrval - 1;
3814 // x = x binop expr; -> xrval binop expr
3815 // x = expr Op x; - > expr binop xrval;
Alexey Bataev5e018f92015-04-23 06:35:10 +00003816 auto Res = emitOMPAtomicRMW(*this, X, E, BO, AO, IsXLHSInRHSPart);
3817 if (!Res.first) {
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003818 if (X.isGlobalReg()) {
3819 // Emit an update expression: 'xrval' binop 'expr' or 'expr' binop
3820 // 'xrval'.
3821 EmitStoreThroughLValue(CommonGen(EmitLoadOfLValue(X, Loc)), X);
3822 } else {
3823 // Perform compare-and-swap procedure.
3824 EmitAtomicUpdate(X, AO, CommonGen, X.getType().isVolatileQualified());
Alexey Bataevb4505a72015-03-30 05:20:59 +00003825 }
3826 }
Alexey Bataev5e018f92015-04-23 06:35:10 +00003827 return Res;
Alexey Bataevb4505a72015-03-30 05:20:59 +00003828}
3829
Alexey Bataevddf3db92018-04-13 17:31:06 +00003830static void emitOMPAtomicUpdateExpr(CodeGenFunction &CGF, bool IsSeqCst,
Alexey Bataevb4505a72015-03-30 05:20:59 +00003831 const Expr *X, const Expr *E,
3832 const Expr *UE, bool IsXLHSInRHSPart,
3833 SourceLocation Loc) {
3834 assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) &&
3835 "Update expr in 'atomic update' must be a binary operator.");
Alexey Bataevddf3db92018-04-13 17:31:06 +00003836 const auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts());
Alexey Bataevb4505a72015-03-30 05:20:59 +00003837 // Update expressions are allowed to have the following forms:
3838 // x binop= expr; -> xrval + expr;
3839 // x++, ++x -> xrval + 1;
3840 // x--, --x -> xrval - 1;
3841 // x = x binop expr; -> xrval binop expr
3842 // x = expr Op x; - > expr binop xrval;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003843 assert(X->isLValue() && "X of 'omp atomic update' is not lvalue");
Alexey Bataevb4505a72015-03-30 05:20:59 +00003844 LValue XLValue = CGF.EmitLValue(X);
3845 RValue ExprRValue = CGF.EmitAnyExpr(E);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003846 llvm::AtomicOrdering AO = IsSeqCst
3847 ? llvm::AtomicOrdering::SequentiallyConsistent
3848 : llvm::AtomicOrdering::Monotonic;
3849 const auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
3850 const auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
3851 const OpaqueValueExpr *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
3852 const OpaqueValueExpr *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
3853 auto &&Gen = [&CGF, UE, ExprRValue, XRValExpr, ERValExpr](RValue XRValue) {
3854 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
3855 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);
3856 return CGF.EmitAnyExpr(UE);
3857 };
Alexey Bataev5e018f92015-04-23 06:35:10 +00003858 (void)CGF.EmitOMPAtomicSimpleUpdateExpr(
3859 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
3860 // OpenMP, 2.12.6, atomic Construct
3861 // Any atomic construct with a seq_cst clause forces the atomically
3862 // performed operation to include an implicit flush operation without a
3863 // list.
3864 if (IsSeqCst)
3865 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
3866}
3867
3868static RValue convertToType(CodeGenFunction &CGF, RValue Value,
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003869 QualType SourceType, QualType ResType,
3870 SourceLocation Loc) {
Alexey Bataev5e018f92015-04-23 06:35:10 +00003871 switch (CGF.getEvaluationKind(ResType)) {
3872 case TEK_Scalar:
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003873 return RValue::get(
3874 convertToScalarValue(CGF, Value, SourceType, ResType, Loc));
Alexey Bataev5e018f92015-04-23 06:35:10 +00003875 case TEK_Complex: {
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003876 auto Res = convertToComplexValue(CGF, Value, SourceType, ResType, Loc);
Alexey Bataev5e018f92015-04-23 06:35:10 +00003877 return RValue::getComplex(Res.first, Res.second);
3878 }
3879 case TEK_Aggregate:
3880 break;
3881 }
3882 llvm_unreachable("Must be a scalar or complex.");
3883}
3884
Alexey Bataevddf3db92018-04-13 17:31:06 +00003885static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF, bool IsSeqCst,
Alexey Bataev5e018f92015-04-23 06:35:10 +00003886 bool IsPostfixUpdate, const Expr *V,
3887 const Expr *X, const Expr *E,
3888 const Expr *UE, bool IsXLHSInRHSPart,
3889 SourceLocation Loc) {
3890 assert(X->isLValue() && "X of 'omp atomic capture' is not lvalue");
3891 assert(V->isLValue() && "V of 'omp atomic capture' is not lvalue");
3892 RValue NewVVal;
3893 LValue VLValue = CGF.EmitLValue(V);
3894 LValue XLValue = CGF.EmitLValue(X);
3895 RValue ExprRValue = CGF.EmitAnyExpr(E);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003896 llvm::AtomicOrdering AO = IsSeqCst
3897 ? llvm::AtomicOrdering::SequentiallyConsistent
3898 : llvm::AtomicOrdering::Monotonic;
Alexey Bataev5e018f92015-04-23 06:35:10 +00003899 QualType NewVValType;
3900 if (UE) {
3901 // 'x' is updated with some additional value.
3902 assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) &&
3903 "Update expr in 'atomic capture' must be a binary operator.");
Alexey Bataevddf3db92018-04-13 17:31:06 +00003904 const auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts());
Alexey Bataev5e018f92015-04-23 06:35:10 +00003905 // Update expressions are allowed to have the following forms:
3906 // x binop= expr; -> xrval + expr;
3907 // x++, ++x -> xrval + 1;
3908 // x--, --x -> xrval - 1;
3909 // x = x binop expr; -> xrval binop expr
3910 // x = expr Op x; - > expr binop xrval;
Alexey Bataevddf3db92018-04-13 17:31:06 +00003911 const auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
3912 const auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
3913 const OpaqueValueExpr *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
Alexey Bataev5e018f92015-04-23 06:35:10 +00003914 NewVValType = XRValExpr->getType();
Alexey Bataevddf3db92018-04-13 17:31:06 +00003915 const OpaqueValueExpr *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
Alexey Bataev5e018f92015-04-23 06:35:10 +00003916 auto &&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr,
Alexey Bataevddf3db92018-04-13 17:31:06 +00003917 IsPostfixUpdate](RValue XRValue) {
Alexey Bataev5e018f92015-04-23 06:35:10 +00003918 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
3919 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);
3920 RValue Res = CGF.EmitAnyExpr(UE);
3921 NewVVal = IsPostfixUpdate ? XRValue : Res;
3922 return Res;
3923 };
3924 auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr(
3925 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
3926 if (Res.first) {
3927 // 'atomicrmw' instruction was generated.
3928 if (IsPostfixUpdate) {
3929 // Use old value from 'atomicrmw'.
3930 NewVVal = Res.second;
3931 } else {
3932 // 'atomicrmw' does not provide new value, so evaluate it using old
3933 // value of 'x'.
3934 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
3935 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, Res.second);
3936 NewVVal = CGF.EmitAnyExpr(UE);
3937 }
3938 }
3939 } else {
3940 // 'x' is simply rewritten with some 'expr'.
3941 NewVValType = X->getType().getNonReferenceType();
3942 ExprRValue = convertToType(CGF, ExprRValue, E->getType(),
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003943 X->getType().getNonReferenceType(), Loc);
Alexey Bataevddf3db92018-04-13 17:31:06 +00003944 auto &&Gen = [&NewVVal, ExprRValue](RValue XRValue) {
Alexey Bataev5e018f92015-04-23 06:35:10 +00003945 NewVVal = XRValue;
3946 return ExprRValue;
3947 };
3948 // Try to perform atomicrmw xchg, otherwise simple exchange.
3949 auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr(
3950 XLValue, ExprRValue, /*BO=*/BO_Assign, /*IsXLHSInRHSPart=*/false, AO,
3951 Loc, Gen);
3952 if (Res.first) {
3953 // 'atomicrmw' instruction was generated.
3954 NewVVal = IsPostfixUpdate ? Res.second : ExprRValue;
3955 }
3956 }
3957 // Emit post-update store to 'v' of old/new 'x' value.
Alexey Bataev8524d152016-01-21 12:35:58 +00003958 CGF.emitOMPSimpleStore(VLValue, NewVVal, NewVValType, Loc);
Alexey Bataevb4505a72015-03-30 05:20:59 +00003959 // OpenMP, 2.12.6, atomic Construct
3960 // Any atomic construct with a seq_cst clause forces the atomically
3961 // performed operation to include an implicit flush operation without a
3962 // list.
3963 if (IsSeqCst)
3964 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
3965}
3966
Alexey Bataevddf3db92018-04-13 17:31:06 +00003967static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
Alexey Bataev5e018f92015-04-23 06:35:10 +00003968 bool IsSeqCst, bool IsPostfixUpdate,
3969 const Expr *X, const Expr *V, const Expr *E,
3970 const Expr *UE, bool IsXLHSInRHSPart,
3971 SourceLocation Loc) {
Alexey Bataevb57056f2015-01-22 06:17:56 +00003972 switch (Kind) {
3973 case OMPC_read:
Alexey Bataevddf3db92018-04-13 17:31:06 +00003974 emitOMPAtomicReadExpr(CGF, IsSeqCst, X, V, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003975 break;
3976 case OMPC_write:
Alexey Bataevddf3db92018-04-13 17:31:06 +00003977 emitOMPAtomicWriteExpr(CGF, IsSeqCst, X, E, Loc);
Alexey Bataevb8329262015-02-27 06:33:30 +00003978 break;
Alexey Bataevb4505a72015-03-30 05:20:59 +00003979 case OMPC_unknown:
Alexey Bataevb57056f2015-01-22 06:17:56 +00003980 case OMPC_update:
Alexey Bataevddf3db92018-04-13 17:31:06 +00003981 emitOMPAtomicUpdateExpr(CGF, IsSeqCst, X, E, UE, IsXLHSInRHSPart, Loc);
Alexey Bataevb4505a72015-03-30 05:20:59 +00003982 break;
Alexey Bataevb57056f2015-01-22 06:17:56 +00003983 case OMPC_capture:
Alexey Bataevddf3db92018-04-13 17:31:06 +00003984 emitOMPAtomicCaptureExpr(CGF, IsSeqCst, IsPostfixUpdate, V, X, E, UE,
Alexey Bataev5e018f92015-04-23 06:35:10 +00003985 IsXLHSInRHSPart, Loc);
3986 break;
Alexey Bataevb57056f2015-01-22 06:17:56 +00003987 case OMPC_if:
3988 case OMPC_final:
3989 case OMPC_num_threads:
3990 case OMPC_private:
3991 case OMPC_firstprivate:
3992 case OMPC_lastprivate:
3993 case OMPC_reduction:
Alexey Bataev169d96a2017-07-18 20:17:46 +00003994 case OMPC_task_reduction:
Alexey Bataevfa312f32017-07-21 18:48:21 +00003995 case OMPC_in_reduction:
Alexey Bataevb57056f2015-01-22 06:17:56 +00003996 case OMPC_safelen:
Alexey Bataev66b15b52015-08-21 11:14:16 +00003997 case OMPC_simdlen:
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00003998 case OMPC_allocator:
Alexey Bataeve04483e2019-03-27 14:14:31 +00003999 case OMPC_allocate:
Alexey Bataevb57056f2015-01-22 06:17:56 +00004000 case OMPC_collapse:
4001 case OMPC_default:
4002 case OMPC_seq_cst:
4003 case OMPC_shared:
4004 case OMPC_linear:
4005 case OMPC_aligned:
4006 case OMPC_copyin:
4007 case OMPC_copyprivate:
4008 case OMPC_flush:
4009 case OMPC_proc_bind:
4010 case OMPC_schedule:
4011 case OMPC_ordered:
4012 case OMPC_nowait:
4013 case OMPC_untied:
4014 case OMPC_threadprivate:
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00004015 case OMPC_depend:
Alexey Bataevb57056f2015-01-22 06:17:56 +00004016 case OMPC_mergeable:
Michael Wonge710d542015-08-07 16:16:36 +00004017 case OMPC_device:
Alexey Bataev346265e2015-09-25 10:37:12 +00004018 case OMPC_threads:
Alexey Bataevd14d1e62015-09-28 06:39:35 +00004019 case OMPC_simd:
Kelvin Li0bff7af2015-11-23 05:32:03 +00004020 case OMPC_map:
Kelvin Li099bb8c2015-11-24 20:50:12 +00004021 case OMPC_num_teams:
Kelvin Lia15fb1a2015-11-27 18:47:36 +00004022 case OMPC_thread_limit:
Alexey Bataeva0569352015-12-01 10:17:31 +00004023 case OMPC_priority:
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00004024 case OMPC_grainsize:
Alexey Bataevb825de12015-12-07 10:51:44 +00004025 case OMPC_nogroup:
Alexey Bataev382967a2015-12-08 12:06:20 +00004026 case OMPC_num_tasks:
Alexey Bataev28c75412015-12-15 08:19:24 +00004027 case OMPC_hint:
Carlo Bertollib4adf552016-01-15 18:50:31 +00004028 case OMPC_dist_schedule:
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00004029 case OMPC_defaultmap:
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004030 case OMPC_uniform:
Samuel Antao661c0902016-05-26 17:39:58 +00004031 case OMPC_to:
Samuel Antaoec172c62016-05-26 17:49:04 +00004032 case OMPC_from:
Carlo Bertolli2404b172016-07-13 15:37:16 +00004033 case OMPC_use_device_ptr:
Carlo Bertolli70594e92016-07-13 17:16:49 +00004034 case OMPC_is_device_ptr:
Kelvin Li1408f912018-09-26 04:28:39 +00004035 case OMPC_unified_address:
Alexey Bataev94c50642018-10-01 14:26:31 +00004036 case OMPC_unified_shared_memory:
Patrick Lyster6bdf63b2018-10-03 20:07:58 +00004037 case OMPC_reverse_offload:
Patrick Lyster3fe9e392018-10-11 14:41:10 +00004038 case OMPC_dynamic_allocators:
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00004039 case OMPC_atomic_default_mem_order:
Alexey Bataev729e2422019-08-23 16:11:14 +00004040 case OMPC_device_type:
Alexey Bataevdba792c2019-09-23 18:13:31 +00004041 case OMPC_match:
Alexey Bataevb57056f2015-01-22 06:17:56 +00004042 llvm_unreachable("Clause is not allowed in 'omp atomic'.");
4043 }
4044}
4045
4046void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00004047 bool IsSeqCst = S.getSingleClause<OMPSeqCstClause>();
Alexey Bataevb57056f2015-01-22 06:17:56 +00004048 OpenMPClauseKind Kind = OMPC_unknown;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004049 for (const OMPClause *C : S.clauses()) {
Alexey Bataevb57056f2015-01-22 06:17:56 +00004050 // Find first clause (skip seq_cst clause, if it is first).
4051 if (C->getClauseKind() != OMPC_seq_cst) {
4052 Kind = C->getClauseKind();
4053 break;
4054 }
4055 }
Alexey Bataev10fec572015-03-11 04:48:56 +00004056
Alexey Bataevddf3db92018-04-13 17:31:06 +00004057 const Stmt *CS = S.getInnermostCapturedStmt()->IgnoreContainers();
Bill Wendling7c44da22018-10-31 03:48:47 +00004058 if (const auto *FE = dyn_cast<FullExpr>(CS))
4059 enterFullExpression(FE);
Alexey Bataev5e018f92015-04-23 06:35:10 +00004060 // Processing for statements under 'atomic capture'.
4061 if (const auto *Compound = dyn_cast<CompoundStmt>(CS)) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00004062 for (const Stmt *C : Compound->body()) {
Bill Wendling7c44da22018-10-31 03:48:47 +00004063 if (const auto *FE = dyn_cast<FullExpr>(C))
4064 enterFullExpression(FE);
Alexey Bataev5e018f92015-04-23 06:35:10 +00004065 }
4066 }
Alexey Bataev10fec572015-03-11 04:48:56 +00004067
Alexey Bataev14fa1c62016-03-29 05:34:15 +00004068 auto &&CodeGen = [&S, Kind, IsSeqCst, CS](CodeGenFunction &CGF,
4069 PrePostActionTy &) {
Alexey Bataev33c56402015-12-14 09:26:19 +00004070 CGF.EmitStopPoint(CS);
Alexey Bataevddf3db92018-04-13 17:31:06 +00004071 emitOMPAtomicExpr(CGF, Kind, IsSeqCst, S.isPostfixUpdate(), S.getX(),
Alexey Bataev5e018f92015-04-23 06:35:10 +00004072 S.getV(), S.getExpr(), S.getUpdateExpr(),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004073 S.isXLHSInRHSPart(), S.getBeginLoc());
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00004074 };
Alexey Bataev475a7442018-01-12 19:39:11 +00004075 OMPLexicalScope Scope(*this, S, OMPD_unknown);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00004076 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_atomic, CodeGen);
Alexey Bataev0162e452014-07-22 10:10:35 +00004077}
4078
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004079static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
4080 const OMPExecutableDirective &S,
4081 const RegionCodeGenTy &CodeGen) {
4082 assert(isOpenMPTargetExecutionDirective(S.getDirectiveKind()));
4083 CodeGenModule &CGM = CGF.CGM;
Samuel Antaobed3c462015-10-02 16:14:20 +00004084
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00004085 // On device emit this construct as inlined code.
4086 if (CGM.getLangOpts().OpenMPIsDevice) {
4087 OMPLexicalScope Scope(CGF, S, OMPD_target);
4088 CGM.getOpenMPRuntime().emitInlinedDirective(
4089 CGF, OMPD_target, [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataev4ac68a22018-05-16 15:08:32 +00004090 CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00004091 });
4092 return;
4093 }
4094
Samuel Antaoee8fb302016-01-06 13:42:12 +00004095 llvm::Function *Fn = nullptr;
4096 llvm::Constant *FnID = nullptr;
Samuel Antaobed3c462015-10-02 16:14:20 +00004097
Samuel Antaobed3c462015-10-02 16:14:20 +00004098 const Expr *IfCond = nullptr;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00004099 // Check for the at most one if clause associated with the target region.
4100 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
4101 if (C->getNameModifier() == OMPD_unknown ||
4102 C->getNameModifier() == OMPD_target) {
4103 IfCond = C->getCondition();
4104 break;
4105 }
Samuel Antaobed3c462015-10-02 16:14:20 +00004106 }
4107
4108 // Check if we have any device clause associated with the directive.
4109 const Expr *Device = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004110 if (auto *C = S.getSingleClause<OMPDeviceClause>())
Samuel Antaobed3c462015-10-02 16:14:20 +00004111 Device = C->getDevice();
Samuel Antaobed3c462015-10-02 16:14:20 +00004112
Samuel Antaoee8fb302016-01-06 13:42:12 +00004113 // Check if we have an if clause whose conditional always evaluates to false
4114 // or if we do not have any targets specified. If so the target region is not
4115 // an offload entry point.
4116 bool IsOffloadEntry = true;
4117 if (IfCond) {
4118 bool Val;
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004119 if (CGF.ConstantFoldsToSimpleInteger(IfCond, Val) && !Val)
Samuel Antaoee8fb302016-01-06 13:42:12 +00004120 IsOffloadEntry = false;
4121 }
4122 if (CGM.getLangOpts().OMPTargetTriples.empty())
4123 IsOffloadEntry = false;
4124
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004125 assert(CGF.CurFuncDecl && "No parent declaration for target region!");
Samuel Antaoee8fb302016-01-06 13:42:12 +00004126 StringRef ParentName;
4127 // In case we have Ctors/Dtors we use the complete type variant to produce
4128 // the mangling of the device outlined kernel.
Alexey Bataevddf3db92018-04-13 17:31:06 +00004129 if (const auto *D = dyn_cast<CXXConstructorDecl>(CGF.CurFuncDecl))
Samuel Antaoee8fb302016-01-06 13:42:12 +00004130 ParentName = CGM.getMangledName(GlobalDecl(D, Ctor_Complete));
Alexey Bataevddf3db92018-04-13 17:31:06 +00004131 else if (const auto *D = dyn_cast<CXXDestructorDecl>(CGF.CurFuncDecl))
Samuel Antaoee8fb302016-01-06 13:42:12 +00004132 ParentName = CGM.getMangledName(GlobalDecl(D, Dtor_Complete));
4133 else
4134 ParentName =
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004135 CGM.getMangledName(GlobalDecl(cast<FunctionDecl>(CGF.CurFuncDecl)));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004136
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004137 // Emit target region as a standalone region.
4138 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(S, ParentName, Fn, FnID,
4139 IsOffloadEntry, CodeGen);
Alexey Bataev8451efa2018-01-15 19:06:12 +00004140 OMPLexicalScope Scope(CGF, S, OMPD_task);
Alexey Bataevec7946e2019-09-23 14:06:51 +00004141 auto &&SizeEmitter =
4142 [IsOffloadEntry](CodeGenFunction &CGF,
4143 const OMPLoopDirective &D) -> llvm::Value * {
4144 if (IsOffloadEntry) {
4145 OMPLoopScope(CGF, D);
4146 // Emit calculation of the iterations count.
4147 llvm::Value *NumIterations = CGF.EmitScalarExpr(D.getNumIterations());
4148 NumIterations = CGF.Builder.CreateIntCast(NumIterations, CGF.Int64Ty,
4149 /*isSigned=*/false);
4150 return NumIterations;
4151 }
4152 return nullptr;
Alexey Bataev7bb33532019-01-07 21:30:43 +00004153 };
Alexey Bataevec7946e2019-09-23 14:06:51 +00004154 CGM.getOpenMPRuntime().emitTargetCall(CGF, S, Fn, FnID, IfCond, Device,
4155 SizeEmitter);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004156}
4157
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004158static void emitTargetRegion(CodeGenFunction &CGF, const OMPTargetDirective &S,
4159 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004160 Action.Enter(CGF);
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004161 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
4162 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
4163 CGF.EmitOMPPrivateClause(S, PrivateScope);
4164 (void)PrivateScope.Privatize();
Alexey Bataev60705422018-10-30 15:50:12 +00004165 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
4166 CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004167
Alexey Bataev475a7442018-01-12 19:39:11 +00004168 CGF.EmitStmt(S.getCapturedStmt(OMPD_target)->getCapturedStmt());
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00004169}
4170
4171void CodeGenFunction::EmitOMPTargetDeviceFunction(CodeGenModule &CGM,
4172 StringRef ParentName,
4173 const OMPTargetDirective &S) {
4174 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4175 emitTargetRegion(CGF, S, Action);
4176 };
4177 llvm::Function *Fn;
4178 llvm::Constant *Addr;
4179 // Emit target region as a standalone region.
4180 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4181 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4182 assert(Fn && Addr && "Target device function emission failed.");
4183}
4184
4185void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) {
4186 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4187 emitTargetRegion(CGF, S, Action);
4188 };
4189 emitCommonOMPTargetDirective(*this, S, CodeGen);
4190}
4191
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004192static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF,
4193 const OMPExecutableDirective &S,
4194 OpenMPDirectiveKind InnermostKind,
4195 const RegionCodeGenTy &CodeGen) {
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004196 const CapturedStmt *CS = S.getCapturedStmt(OMPD_teams);
James Y Knight9871db02019-02-05 16:42:33 +00004197 llvm::Function *OutlinedFn =
Alexey Bataevddf3db92018-04-13 17:31:06 +00004198 CGF.CGM.getOpenMPRuntime().emitTeamsOutlinedFunction(
4199 S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
Samuel Antaob68e2db2016-03-03 16:20:23 +00004200
Alexey Bataevddf3db92018-04-13 17:31:06 +00004201 const auto *NT = S.getSingleClause<OMPNumTeamsClause>();
4202 const auto *TL = S.getSingleClause<OMPThreadLimitClause>();
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004203 if (NT || TL) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00004204 const Expr *NumTeams = NT ? NT->getNumTeams() : nullptr;
4205 const Expr *ThreadLimit = TL ? TL->getThreadLimit() : nullptr;
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004206
Carlo Bertollic6872252016-04-04 15:55:02 +00004207 CGF.CGM.getOpenMPRuntime().emitNumTeamsClause(CGF, NumTeams, ThreadLimit,
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004208 S.getBeginLoc());
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004209 }
4210
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00004211 OMPTeamsScope Scope(CGF, S);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00004212 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
4213 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004214 CGF.CGM.getOpenMPRuntime().emitTeamsCall(CGF, S, S.getBeginLoc(), OutlinedFn,
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004215 CapturedVars);
4216}
4217
4218void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &S) {
Kelvin Li51336dd2016-12-15 17:55:32 +00004219 // Emit teams region as a standalone region.
Alexey Bataevc99042b2018-03-15 18:10:54 +00004220 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004221 Action.Enter(CGF);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004222 OMPPrivateScope PrivateScope(CGF);
Carlo Bertolli6ad7b5a2016-03-03 22:09:40 +00004223 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
4224 CGF.EmitOMPPrivateClause(S, PrivateScope);
Arpith Chacko Jacobfc711b12017-02-16 16:48:49 +00004225 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004226 (void)PrivateScope.Privatize();
Alexey Bataev475a7442018-01-12 19:39:11 +00004227 CGF.EmitStmt(S.getCapturedStmt(OMPD_teams)->getCapturedStmt());
Arpith Chacko Jacobfc711b12017-02-16 16:48:49 +00004228 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00004229 };
Alexey Bataev2139ed62017-11-16 18:20:21 +00004230 emitCommonOMPTeamsDirective(*this, S, OMPD_distribute, CodeGen);
Alexey Bataevddf3db92018-04-13 17:31:06 +00004231 emitPostUpdateForReductionClause(*this, S,
4232 [](CodeGenFunction &) { return nullptr; });
Alexey Bataev13314bf2014-10-09 04:18:56 +00004233}
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004234
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00004235static void emitTargetTeamsRegion(CodeGenFunction &CGF, PrePostActionTy &Action,
4236 const OMPTargetTeamsDirective &S) {
4237 auto *CS = S.getCapturedStmt(OMPD_teams);
4238 Action.Enter(CGF);
Alexey Bataevf9fc42e2017-11-22 14:25:55 +00004239 // Emit teams region as a standalone region.
4240 auto &&CodeGen = [&S, CS](CodeGenFunction &CGF, PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004241 Action.Enter(CGF);
Alexey Bataevf9fc42e2017-11-22 14:25:55 +00004242 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
4243 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
4244 CGF.EmitOMPPrivateClause(S, PrivateScope);
4245 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4246 (void)PrivateScope.Privatize();
Alexey Bataev60705422018-10-30 15:50:12 +00004247 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
4248 CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00004249 CGF.EmitStmt(CS->getCapturedStmt());
Alexey Bataevf9fc42e2017-11-22 14:25:55 +00004250 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00004251 };
4252 emitCommonOMPTeamsDirective(CGF, S, OMPD_teams, CodeGen);
Alexey Bataevddf3db92018-04-13 17:31:06 +00004253 emitPostUpdateForReductionClause(CGF, S,
4254 [](CodeGenFunction &) { return nullptr; });
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00004255}
4256
4257void CodeGenFunction::EmitOMPTargetTeamsDeviceFunction(
4258 CodeGenModule &CGM, StringRef ParentName,
4259 const OMPTargetTeamsDirective &S) {
4260 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4261 emitTargetTeamsRegion(CGF, Action, S);
4262 };
4263 llvm::Function *Fn;
4264 llvm::Constant *Addr;
4265 // Emit target region as a standalone region.
4266 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4267 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4268 assert(Fn && Addr && "Target device function emission failed.");
4269}
4270
4271void CodeGenFunction::EmitOMPTargetTeamsDirective(
4272 const OMPTargetTeamsDirective &S) {
4273 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4274 emitTargetTeamsRegion(CGF, Action, S);
4275 };
4276 emitCommonOMPTargetDirective(*this, S, CodeGen);
4277}
4278
Alexey Bataevdfa430f2017-12-08 15:03:50 +00004279static void
4280emitTargetTeamsDistributeRegion(CodeGenFunction &CGF, PrePostActionTy &Action,
4281 const OMPTargetTeamsDistributeDirective &S) {
4282 Action.Enter(CGF);
4283 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4284 CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
4285 };
4286
4287 // Emit teams region as a standalone region.
4288 auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00004289 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004290 Action.Enter(CGF);
Alexey Bataevdfa430f2017-12-08 15:03:50 +00004291 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
4292 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4293 (void)PrivateScope.Privatize();
4294 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
4295 CodeGenDistribute);
4296 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4297 };
4298 emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute, CodeGen);
4299 emitPostUpdateForReductionClause(CGF, S,
4300 [](CodeGenFunction &) { return nullptr; });
4301}
4302
4303void CodeGenFunction::EmitOMPTargetTeamsDistributeDeviceFunction(
4304 CodeGenModule &CGM, StringRef ParentName,
4305 const OMPTargetTeamsDistributeDirective &S) {
4306 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4307 emitTargetTeamsDistributeRegion(CGF, Action, S);
4308 };
4309 llvm::Function *Fn;
4310 llvm::Constant *Addr;
4311 // Emit target region as a standalone region.
4312 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4313 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4314 assert(Fn && Addr && "Target device function emission failed.");
4315}
4316
4317void CodeGenFunction::EmitOMPTargetTeamsDistributeDirective(
4318 const OMPTargetTeamsDistributeDirective &S) {
4319 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4320 emitTargetTeamsDistributeRegion(CGF, Action, S);
4321 };
4322 emitCommonOMPTargetDirective(*this, S, CodeGen);
4323}
4324
Alexey Bataevfbe17fb2017-12-13 19:45:06 +00004325static void emitTargetTeamsDistributeSimdRegion(
4326 CodeGenFunction &CGF, PrePostActionTy &Action,
4327 const OMPTargetTeamsDistributeSimdDirective &S) {
4328 Action.Enter(CGF);
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 Bataevfbe17fb2017-12-13 19:45:06 +00004337 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
4338 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4339 (void)PrivateScope.Privatize();
4340 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
4341 CodeGenDistribute);
4342 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4343 };
4344 emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute_simd, CodeGen);
4345 emitPostUpdateForReductionClause(CGF, S,
4346 [](CodeGenFunction &) { return nullptr; });
4347}
4348
4349void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDeviceFunction(
4350 CodeGenModule &CGM, StringRef ParentName,
4351 const OMPTargetTeamsDistributeSimdDirective &S) {
4352 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4353 emitTargetTeamsDistributeSimdRegion(CGF, Action, S);
4354 };
4355 llvm::Function *Fn;
4356 llvm::Constant *Addr;
4357 // Emit target region as a standalone region.
4358 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4359 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4360 assert(Fn && Addr && "Target device function emission failed.");
4361}
4362
4363void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDirective(
4364 const OMPTargetTeamsDistributeSimdDirective &S) {
4365 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4366 emitTargetTeamsDistributeSimdRegion(CGF, Action, S);
4367 };
4368 emitCommonOMPTargetDirective(*this, S, CodeGen);
4369}
4370
Carlo Bertolliba1487b2017-10-04 14:12:09 +00004371void CodeGenFunction::EmitOMPTeamsDistributeDirective(
4372 const OMPTeamsDistributeDirective &S) {
4373
4374 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4375 CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
4376 };
4377
4378 // Emit teams region as a standalone region.
4379 auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00004380 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004381 Action.Enter(CGF);
Carlo Bertolliba1487b2017-10-04 14:12:09 +00004382 OMPPrivateScope PrivateScope(CGF);
4383 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4384 (void)PrivateScope.Privatize();
4385 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
4386 CodeGenDistribute);
4387 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4388 };
Alexey Bataev95c6dd42017-11-29 15:14:16 +00004389 emitCommonOMPTeamsDirective(*this, S, OMPD_distribute, CodeGen);
Carlo Bertolliba1487b2017-10-04 14:12:09 +00004390 emitPostUpdateForReductionClause(*this, S,
4391 [](CodeGenFunction &) { return nullptr; });
4392}
4393
Alexey Bataev999277a2017-12-06 14:31:09 +00004394void CodeGenFunction::EmitOMPTeamsDistributeSimdDirective(
4395 const OMPTeamsDistributeSimdDirective &S) {
4396 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4397 CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
4398 };
4399
4400 // Emit teams region as a standalone region.
4401 auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00004402 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004403 Action.Enter(CGF);
Alexey Bataev999277a2017-12-06 14:31:09 +00004404 OMPPrivateScope PrivateScope(CGF);
4405 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4406 (void)PrivateScope.Privatize();
4407 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_simd,
4408 CodeGenDistribute);
4409 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4410 };
4411 emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_simd, CodeGen);
4412 emitPostUpdateForReductionClause(*this, S,
4413 [](CodeGenFunction &) { return nullptr; });
4414}
4415
Carlo Bertolli62fae152017-11-20 20:46:39 +00004416void CodeGenFunction::EmitOMPTeamsDistributeParallelForDirective(
4417 const OMPTeamsDistributeParallelForDirective &S) {
4418 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4419 CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
4420 S.getDistInc());
4421 };
4422
4423 // Emit teams region as a standalone region.
4424 auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00004425 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004426 Action.Enter(CGF);
Carlo Bertolli62fae152017-11-20 20:46:39 +00004427 OMPPrivateScope PrivateScope(CGF);
4428 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4429 (void)PrivateScope.Privatize();
Alexey Bataev10a54312017-11-27 16:54:08 +00004430 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
4431 CodeGenDistribute);
Carlo Bertolli62fae152017-11-20 20:46:39 +00004432 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4433 };
4434 emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_parallel_for, CodeGen);
4435 emitPostUpdateForReductionClause(*this, S,
4436 [](CodeGenFunction &) { return nullptr; });
4437}
4438
Carlo Bertolli56a2aa42017-12-04 20:57:19 +00004439void CodeGenFunction::EmitOMPTeamsDistributeParallelForSimdDirective(
4440 const OMPTeamsDistributeParallelForSimdDirective &S) {
4441 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4442 CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
4443 S.getDistInc());
4444 };
4445
4446 // Emit teams region as a standalone region.
4447 auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00004448 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004449 Action.Enter(CGF);
Carlo Bertolli56a2aa42017-12-04 20:57:19 +00004450 OMPPrivateScope PrivateScope(CGF);
4451 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4452 (void)PrivateScope.Privatize();
4453 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
4454 CGF, OMPD_distribute, CodeGenDistribute, /*HasCancel=*/false);
4455 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4456 };
4457 emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_parallel_for, CodeGen);
4458 emitPostUpdateForReductionClause(*this, S,
4459 [](CodeGenFunction &) { return nullptr; });
4460}
4461
Carlo Bertolli52978c32018-01-03 21:12:44 +00004462static void emitTargetTeamsDistributeParallelForRegion(
4463 CodeGenFunction &CGF, const OMPTargetTeamsDistributeParallelForDirective &S,
4464 PrePostActionTy &Action) {
Carlo Bertolli79712092018-02-28 20:48:35 +00004465 Action.Enter(CGF);
Carlo Bertolli52978c32018-01-03 21:12:44 +00004466 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4467 CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
4468 S.getDistInc());
4469 };
4470
4471 // Emit teams region as a standalone region.
4472 auto &&CodeGenTeams = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00004473 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004474 Action.Enter(CGF);
Carlo Bertolli52978c32018-01-03 21:12:44 +00004475 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
4476 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4477 (void)PrivateScope.Privatize();
4478 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
4479 CGF, OMPD_distribute, CodeGenDistribute, /*HasCancel=*/false);
4480 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4481 };
4482
4483 emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute_parallel_for,
4484 CodeGenTeams);
4485 emitPostUpdateForReductionClause(CGF, S,
4486 [](CodeGenFunction &) { return nullptr; });
4487}
4488
4489void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDeviceFunction(
4490 CodeGenModule &CGM, StringRef ParentName,
4491 const OMPTargetTeamsDistributeParallelForDirective &S) {
4492 // Emit SPMD target teams distribute parallel for region as a standalone
4493 // region.
4494 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4495 emitTargetTeamsDistributeParallelForRegion(CGF, S, Action);
4496 };
4497 llvm::Function *Fn;
4498 llvm::Constant *Addr;
4499 // Emit target region as a standalone region.
4500 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4501 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4502 assert(Fn && Addr && "Target device function emission failed.");
4503}
4504
4505void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDirective(
4506 const OMPTargetTeamsDistributeParallelForDirective &S) {
4507 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4508 emitTargetTeamsDistributeParallelForRegion(CGF, S, Action);
4509 };
4510 emitCommonOMPTargetDirective(*this, S, CodeGen);
4511}
4512
Alexey Bataev647dd842018-01-15 20:59:40 +00004513static void emitTargetTeamsDistributeParallelForSimdRegion(
4514 CodeGenFunction &CGF,
4515 const OMPTargetTeamsDistributeParallelForSimdDirective &S,
4516 PrePostActionTy &Action) {
Carlo Bertolli79712092018-02-28 20:48:35 +00004517 Action.Enter(CGF);
Alexey Bataev647dd842018-01-15 20:59:40 +00004518 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4519 CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
4520 S.getDistInc());
4521 };
4522
4523 // Emit teams region as a standalone region.
4524 auto &&CodeGenTeams = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
Alexey Bataevc99042b2018-03-15 18:10:54 +00004525 PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004526 Action.Enter(CGF);
Alexey Bataev647dd842018-01-15 20:59:40 +00004527 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
4528 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4529 (void)PrivateScope.Privatize();
4530 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
4531 CGF, OMPD_distribute, CodeGenDistribute, /*HasCancel=*/false);
4532 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
4533 };
4534
4535 emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute_parallel_for_simd,
4536 CodeGenTeams);
4537 emitPostUpdateForReductionClause(CGF, S,
4538 [](CodeGenFunction &) { return nullptr; });
4539}
4540
4541void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(
4542 CodeGenModule &CGM, StringRef ParentName,
4543 const OMPTargetTeamsDistributeParallelForSimdDirective &S) {
4544 // Emit SPMD target teams distribute parallel for simd region as a standalone
4545 // region.
4546 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4547 emitTargetTeamsDistributeParallelForSimdRegion(CGF, S, Action);
4548 };
4549 llvm::Function *Fn;
4550 llvm::Constant *Addr;
4551 // Emit target region as a standalone region.
4552 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4553 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4554 assert(Fn && Addr && "Target device function emission failed.");
4555}
4556
4557void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDirective(
4558 const OMPTargetTeamsDistributeParallelForSimdDirective &S) {
4559 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4560 emitTargetTeamsDistributeParallelForSimdRegion(CGF, S, Action);
4561 };
4562 emitCommonOMPTargetDirective(*this, S, CodeGen);
4563}
4564
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004565void CodeGenFunction::EmitOMPCancellationPointDirective(
4566 const OMPCancellationPointDirective &S) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004567 CGM.getOpenMPRuntime().emitCancellationPointCall(*this, S.getBeginLoc(),
Alexey Bataev0f34da12015-07-02 04:17:07 +00004568 S.getCancelRegion());
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004569}
4570
Alexey Bataev80909872015-07-02 11:25:17 +00004571void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) {
Alexey Bataev87933c72015-09-18 08:07:34 +00004572 const Expr *IfCond = nullptr;
4573 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
4574 if (C->getNameModifier() == OMPD_unknown ||
4575 C->getNameModifier() == OMPD_cancel) {
4576 IfCond = C->getCondition();
4577 break;
4578 }
4579 }
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004580 CGM.getOpenMPRuntime().emitCancelCall(*this, S.getBeginLoc(), IfCond,
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00004581 S.getCancelRegion());
Alexey Bataev80909872015-07-02 11:25:17 +00004582}
4583
Alexey Bataev81c7ea02015-07-03 09:56:58 +00004584CodeGenFunction::JumpDest
4585CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) {
Alexey Bataev957d8562016-11-17 15:12:05 +00004586 if (Kind == OMPD_parallel || Kind == OMPD_task ||
4587 Kind == OMPD_target_parallel)
Alexey Bataev81c7ea02015-07-03 09:56:58 +00004588 return ReturnBlock;
Alexey Bataev25e5b442015-09-15 12:52:43 +00004589 assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
Alexey Bataev957d8562016-11-17 15:12:05 +00004590 Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for ||
4591 Kind == OMPD_distribute_parallel_for ||
Alexey Bataevdcb4b8fb2017-11-22 20:19:50 +00004592 Kind == OMPD_target_parallel_for ||
Alexey Bataev16e79882017-11-22 21:12:03 +00004593 Kind == OMPD_teams_distribute_parallel_for ||
4594 Kind == OMPD_target_teams_distribute_parallel_for);
Alexey Bataev957d8562016-11-17 15:12:05 +00004595 return OMPCancelStack.getExitBlock();
Alexey Bataev81c7ea02015-07-03 09:56:58 +00004596}
Michael Wong65f367f2015-07-21 13:44:28 +00004597
Samuel Antaocc10b852016-07-28 14:23:26 +00004598void CodeGenFunction::EmitOMPUseDevicePtrClause(
4599 const OMPClause &NC, OMPPrivateScope &PrivateScope,
4600 const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap) {
4601 const auto &C = cast<OMPUseDevicePtrClause>(NC);
4602 auto OrigVarIt = C.varlist_begin();
4603 auto InitIt = C.inits().begin();
Alexey Bataevddf3db92018-04-13 17:31:06 +00004604 for (const Expr *PvtVarIt : C.private_copies()) {
4605 const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*OrigVarIt)->getDecl());
4606 const auto *InitVD = cast<VarDecl>(cast<DeclRefExpr>(*InitIt)->getDecl());
4607 const auto *PvtVD = cast<VarDecl>(cast<DeclRefExpr>(PvtVarIt)->getDecl());
Samuel Antaocc10b852016-07-28 14:23:26 +00004608
4609 // In order to identify the right initializer we need to match the
4610 // declaration used by the mapping logic. In some cases we may get
4611 // OMPCapturedExprDecl that refers to the original declaration.
4612 const ValueDecl *MatchingVD = OrigVD;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004613 if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) {
Samuel Antaocc10b852016-07-28 14:23:26 +00004614 // OMPCapturedExprDecl are used to privative fields of the current
4615 // structure.
Alexey Bataevddf3db92018-04-13 17:31:06 +00004616 const auto *ME = cast<MemberExpr>(OED->getInit());
Samuel Antaocc10b852016-07-28 14:23:26 +00004617 assert(isa<CXXThisExpr>(ME->getBase()) &&
4618 "Base should be the current struct!");
4619 MatchingVD = ME->getMemberDecl();
4620 }
4621
4622 // If we don't have information about the current list item, move on to
4623 // the next one.
4624 auto InitAddrIt = CaptureDeviceAddrMap.find(MatchingVD);
4625 if (InitAddrIt == CaptureDeviceAddrMap.end())
4626 continue;
4627
Alexey Bataevddf3db92018-04-13 17:31:06 +00004628 bool IsRegistered = PrivateScope.addPrivate(OrigVD, [this, OrigVD,
4629 InitAddrIt, InitVD,
4630 PvtVD]() {
Samuel Antaocc10b852016-07-28 14:23:26 +00004631 // Initialize the temporary initialization variable with the address we
4632 // get from the runtime library. We have to cast the source address
4633 // because it is always a void *. References are materialized in the
4634 // privatization scope, so the initialization here disregards the fact
4635 // the original variable is a reference.
4636 QualType AddrQTy =
4637 getContext().getPointerType(OrigVD->getType().getNonReferenceType());
4638 llvm::Type *AddrTy = ConvertTypeForMem(AddrQTy);
4639 Address InitAddr = Builder.CreateBitCast(InitAddrIt->second, AddrTy);
4640 setAddrOfLocalVar(InitVD, InitAddr);
4641
4642 // Emit private declaration, it will be initialized by the value we
4643 // declaration we just added to the local declarations map.
4644 EmitDecl(*PvtVD);
4645
4646 // The initialization variables reached its purpose in the emission
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00004647 // of the previous declaration, so we don't need it anymore.
Samuel Antaocc10b852016-07-28 14:23:26 +00004648 LocalDeclMap.erase(InitVD);
4649
4650 // Return the address of the private variable.
4651 return GetAddrOfLocalVar(PvtVD);
4652 });
4653 assert(IsRegistered && "firstprivate var already registered as private");
4654 // Silence the warning about unused variable.
4655 (void)IsRegistered;
4656
4657 ++OrigVarIt;
4658 ++InitIt;
4659 }
4660}
4661
Michael Wong65f367f2015-07-21 13:44:28 +00004662// Generate the instructions for '#pragma omp target data' directive.
4663void CodeGenFunction::EmitOMPTargetDataDirective(
4664 const OMPTargetDataDirective &S) {
Samuel Antaocc10b852016-07-28 14:23:26 +00004665 CGOpenMPRuntime::TargetDataInfo Info(/*RequiresDevicePointerInfo=*/true);
4666
4667 // Create a pre/post action to signal the privatization of the device pointer.
4668 // This action can be replaced by the OpenMP runtime code generation to
4669 // deactivate privatization.
4670 bool PrivatizeDevicePointers = false;
4671 class DevicePointerPrivActionTy : public PrePostActionTy {
4672 bool &PrivatizeDevicePointers;
4673
4674 public:
4675 explicit DevicePointerPrivActionTy(bool &PrivatizeDevicePointers)
4676 : PrePostActionTy(), PrivatizeDevicePointers(PrivatizeDevicePointers) {}
4677 void Enter(CodeGenFunction &CGF) override {
4678 PrivatizeDevicePointers = true;
4679 }
Samuel Antaodf158d52016-04-27 22:58:19 +00004680 };
Samuel Antaocc10b852016-07-28 14:23:26 +00004681 DevicePointerPrivActionTy PrivAction(PrivatizeDevicePointers);
4682
4683 auto &&CodeGen = [&S, &Info, &PrivatizeDevicePointers](
Alexey Bataev475a7442018-01-12 19:39:11 +00004684 CodeGenFunction &CGF, PrePostActionTy &Action) {
Samuel Antaocc10b852016-07-28 14:23:26 +00004685 auto &&InnermostCodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataev475a7442018-01-12 19:39:11 +00004686 CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
Samuel Antaocc10b852016-07-28 14:23:26 +00004687 };
4688
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00004689 // Codegen that selects whether to generate the privatization code or not.
Samuel Antaocc10b852016-07-28 14:23:26 +00004690 auto &&PrivCodeGen = [&S, &Info, &PrivatizeDevicePointers,
4691 &InnermostCodeGen](CodeGenFunction &CGF,
4692 PrePostActionTy &Action) {
4693 RegionCodeGenTy RCG(InnermostCodeGen);
4694 PrivatizeDevicePointers = false;
4695
4696 // Call the pre-action to change the status of PrivatizeDevicePointers if
4697 // needed.
4698 Action.Enter(CGF);
4699
4700 if (PrivatizeDevicePointers) {
4701 OMPPrivateScope PrivateScope(CGF);
4702 // Emit all instances of the use_device_ptr clause.
4703 for (const auto *C : S.getClausesOfKind<OMPUseDevicePtrClause>())
4704 CGF.EmitOMPUseDevicePtrClause(*C, PrivateScope,
4705 Info.CaptureDeviceAddrMap);
4706 (void)PrivateScope.Privatize();
4707 RCG(CGF);
Alexey Bataevddf3db92018-04-13 17:31:06 +00004708 } else {
Samuel Antaocc10b852016-07-28 14:23:26 +00004709 RCG(CGF);
Alexey Bataevddf3db92018-04-13 17:31:06 +00004710 }
Samuel Antaocc10b852016-07-28 14:23:26 +00004711 };
4712
4713 // Forward the provided action to the privatization codegen.
4714 RegionCodeGenTy PrivRCG(PrivCodeGen);
4715 PrivRCG.setAction(Action);
4716
4717 // Notwithstanding the body of the region is emitted as inlined directive,
4718 // we don't use an inline scope as changes in the references inside the
4719 // region are expected to be visible outside, so we do not privative them.
4720 OMPLexicalScope Scope(CGF, S);
4721 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_target_data,
4722 PrivRCG);
4723 };
4724
4725 RegionCodeGenTy RCG(CodeGen);
Samuel Antaodf158d52016-04-27 22:58:19 +00004726
4727 // If we don't have target devices, don't bother emitting the data mapping
4728 // code.
4729 if (CGM.getLangOpts().OMPTargetTriples.empty()) {
Samuel Antaocc10b852016-07-28 14:23:26 +00004730 RCG(*this);
Samuel Antaodf158d52016-04-27 22:58:19 +00004731 return;
4732 }
4733
4734 // Check if we have any if clause associated with the directive.
4735 const Expr *IfCond = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004736 if (const auto *C = S.getSingleClause<OMPIfClause>())
Samuel Antaodf158d52016-04-27 22:58:19 +00004737 IfCond = C->getCondition();
4738
4739 // Check if we have any device clause associated with the directive.
4740 const Expr *Device = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004741 if (const auto *C = S.getSingleClause<OMPDeviceClause>())
Samuel Antaodf158d52016-04-27 22:58:19 +00004742 Device = C->getDevice();
4743
Samuel Antaocc10b852016-07-28 14:23:26 +00004744 // Set the action to signal privatization of device pointers.
4745 RCG.setAction(PrivAction);
4746
4747 // Emit region code.
4748 CGM.getOpenMPRuntime().emitTargetDataCalls(*this, S, IfCond, Device, RCG,
4749 Info);
Michael Wong65f367f2015-07-21 13:44:28 +00004750}
Alexey Bataev49f6e782015-12-01 04:18:41 +00004751
Samuel Antaodf67fc42016-01-19 19:15:56 +00004752void CodeGenFunction::EmitOMPTargetEnterDataDirective(
4753 const OMPTargetEnterDataDirective &S) {
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00004754 // If we don't have target devices, don't bother emitting the data mapping
4755 // code.
4756 if (CGM.getLangOpts().OMPTargetTriples.empty())
4757 return;
4758
4759 // Check if we have any if clause associated with the directive.
4760 const Expr *IfCond = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004761 if (const auto *C = S.getSingleClause<OMPIfClause>())
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00004762 IfCond = C->getCondition();
4763
4764 // Check if we have any device clause associated with the directive.
4765 const Expr *Device = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004766 if (const auto *C = S.getSingleClause<OMPDeviceClause>())
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00004767 Device = C->getDevice();
4768
Alexey Bataev475a7442018-01-12 19:39:11 +00004769 OMPLexicalScope Scope(*this, S, OMPD_task);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00004770 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
Samuel Antaodf67fc42016-01-19 19:15:56 +00004771}
4772
Samuel Antao72590762016-01-19 20:04:50 +00004773void CodeGenFunction::EmitOMPTargetExitDataDirective(
4774 const OMPTargetExitDataDirective &S) {
Samuel Antao8dd66282016-04-27 23:14:30 +00004775 // If we don't have target devices, don't bother emitting the data mapping
4776 // code.
4777 if (CGM.getLangOpts().OMPTargetTriples.empty())
4778 return;
4779
4780 // Check if we have any if clause associated with the directive.
4781 const Expr *IfCond = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004782 if (const auto *C = S.getSingleClause<OMPIfClause>())
Samuel Antao8dd66282016-04-27 23:14:30 +00004783 IfCond = C->getCondition();
4784
4785 // Check if we have any device clause associated with the directive.
4786 const Expr *Device = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00004787 if (const auto *C = S.getSingleClause<OMPDeviceClause>())
Samuel Antao8dd66282016-04-27 23:14:30 +00004788 Device = C->getDevice();
4789
Alexey Bataev475a7442018-01-12 19:39:11 +00004790 OMPLexicalScope Scope(*this, S, OMPD_task);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00004791 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
Samuel Antao72590762016-01-19 20:04:50 +00004792}
4793
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004794static void emitTargetParallelRegion(CodeGenFunction &CGF,
4795 const OMPTargetParallelDirective &S,
4796 PrePostActionTy &Action) {
4797 // Get the captured statement associated with the 'parallel' region.
Alexey Bataevddf3db92018-04-13 17:31:06 +00004798 const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel);
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004799 Action.Enter(CGF);
Alexey Bataevc99042b2018-03-15 18:10:54 +00004800 auto &&CodeGen = [&S, CS](CodeGenFunction &CGF, PrePostActionTy &Action) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00004801 Action.Enter(CGF);
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00004802 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
4803 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
4804 CGF.EmitOMPPrivateClause(S, PrivateScope);
4805 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4806 (void)PrivateScope.Privatize();
Alexey Bataev60705422018-10-30 15:50:12 +00004807 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
4808 CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004809 // TODO: Add support for clauses.
4810 CGF.EmitStmt(CS->getCapturedStmt());
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00004811 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004812 };
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00004813 emitCommonOMPParallelDirective(CGF, S, OMPD_parallel, CodeGen,
4814 emitEmptyBoundParameters);
Alexey Bataevddf3db92018-04-13 17:31:06 +00004815 emitPostUpdateForReductionClause(CGF, S,
4816 [](CodeGenFunction &) { return nullptr; });
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004817}
4818
4819void CodeGenFunction::EmitOMPTargetParallelDeviceFunction(
4820 CodeGenModule &CGM, StringRef ParentName,
4821 const OMPTargetParallelDirective &S) {
4822 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4823 emitTargetParallelRegion(CGF, S, Action);
4824 };
4825 llvm::Function *Fn;
4826 llvm::Constant *Addr;
4827 // Emit target region as a standalone region.
4828 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4829 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4830 assert(Fn && Addr && "Target device function emission failed.");
4831}
4832
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004833void CodeGenFunction::EmitOMPTargetParallelDirective(
4834 const OMPTargetParallelDirective &S) {
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004835 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4836 emitTargetParallelRegion(CGF, S, Action);
4837 };
4838 emitCommonOMPTargetDirective(*this, S, CodeGen);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004839}
4840
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00004841static void emitTargetParallelForRegion(CodeGenFunction &CGF,
4842 const OMPTargetParallelForDirective &S,
4843 PrePostActionTy &Action) {
4844 Action.Enter(CGF);
4845 // Emit directive as a combined directive that consists of two implicit
4846 // directives: 'parallel' with 'for' directive.
Alexey Bataevc99042b2018-03-15 18:10:54 +00004847 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4848 Action.Enter(CGF);
Alexey Bataev2139ed62017-11-16 18:20:21 +00004849 CodeGenFunction::OMPCancelStackRAII CancelRegion(
4850 CGF, OMPD_target_parallel_for, S.hasCancel());
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00004851 CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds,
4852 emitDispatchForLoopBounds);
4853 };
4854 emitCommonOMPParallelDirective(CGF, S, OMPD_for, CodeGen,
4855 emitEmptyBoundParameters);
4856}
4857
4858void CodeGenFunction::EmitOMPTargetParallelForDeviceFunction(
4859 CodeGenModule &CGM, StringRef ParentName,
4860 const OMPTargetParallelForDirective &S) {
4861 // Emit SPMD target parallel for region as a standalone region.
4862 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4863 emitTargetParallelForRegion(CGF, S, Action);
4864 };
4865 llvm::Function *Fn;
4866 llvm::Constant *Addr;
4867 // Emit target region as a standalone region.
4868 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4869 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4870 assert(Fn && Addr && "Target device function emission failed.");
4871}
4872
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004873void CodeGenFunction::EmitOMPTargetParallelForDirective(
4874 const OMPTargetParallelForDirective &S) {
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00004875 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4876 emitTargetParallelForRegion(CGF, S, Action);
4877 };
4878 emitCommonOMPTargetDirective(*this, S, CodeGen);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004879}
4880
Alexey Bataev5d7edca2017-11-09 17:32:15 +00004881static void
4882emitTargetParallelForSimdRegion(CodeGenFunction &CGF,
4883 const OMPTargetParallelForSimdDirective &S,
4884 PrePostActionTy &Action) {
4885 Action.Enter(CGF);
4886 // Emit directive as a combined directive that consists of two implicit
4887 // directives: 'parallel' with 'for' directive.
Alexey Bataevc99042b2018-03-15 18:10:54 +00004888 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4889 Action.Enter(CGF);
Alexey Bataev5d7edca2017-11-09 17:32:15 +00004890 CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds,
4891 emitDispatchForLoopBounds);
4892 };
4893 emitCommonOMPParallelDirective(CGF, S, OMPD_simd, CodeGen,
4894 emitEmptyBoundParameters);
4895}
4896
4897void CodeGenFunction::EmitOMPTargetParallelForSimdDeviceFunction(
4898 CodeGenModule &CGM, StringRef ParentName,
4899 const OMPTargetParallelForSimdDirective &S) {
4900 // Emit SPMD target parallel for region as a standalone region.
4901 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4902 emitTargetParallelForSimdRegion(CGF, S, Action);
4903 };
4904 llvm::Function *Fn;
4905 llvm::Constant *Addr;
4906 // Emit target region as a standalone region.
4907 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4908 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4909 assert(Fn && Addr && "Target device function emission failed.");
4910}
4911
4912void CodeGenFunction::EmitOMPTargetParallelForSimdDirective(
4913 const OMPTargetParallelForSimdDirective &S) {
4914 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4915 emitTargetParallelForSimdRegion(CGF, S, Action);
4916 };
4917 emitCommonOMPTargetDirective(*this, S, CodeGen);
4918}
4919
Alexey Bataev7292c292016-04-25 12:22:29 +00004920/// Emit a helper variable and return corresponding lvalue.
4921static void mapParam(CodeGenFunction &CGF, const DeclRefExpr *Helper,
4922 const ImplicitParamDecl *PVD,
4923 CodeGenFunction::OMPPrivateScope &Privates) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00004924 const auto *VDecl = cast<VarDecl>(Helper->getDecl());
4925 Privates.addPrivate(VDecl,
4926 [&CGF, PVD]() { return CGF.GetAddrOfLocalVar(PVD); });
Alexey Bataev7292c292016-04-25 12:22:29 +00004927}
4928
4929void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) {
4930 assert(isOpenMPTaskLoopDirective(S.getDirectiveKind()));
4931 // Emit outlined function for task construct.
Alexey Bataev475a7442018-01-12 19:39:11 +00004932 const CapturedStmt *CS = S.getCapturedStmt(OMPD_taskloop);
Alexey Bataevddf3db92018-04-13 17:31:06 +00004933 Address CapturedStruct = GenerateCapturedStmtArgument(*CS);
4934 QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
Alexey Bataev7292c292016-04-25 12:22:29 +00004935 const Expr *IfCond = nullptr;
4936 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
4937 if (C->getNameModifier() == OMPD_unknown ||
4938 C->getNameModifier() == OMPD_taskloop) {
4939 IfCond = C->getCondition();
4940 break;
4941 }
4942 }
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004943
4944 OMPTaskDataTy Data;
4945 // Check if taskloop must be emitted without taskgroup.
4946 Data.Nogroup = S.getSingleClause<OMPNogroupClause>();
Alexey Bataev7292c292016-04-25 12:22:29 +00004947 // TODO: Check if we should emit tied or untied task.
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004948 Data.Tied = true;
4949 // Set scheduling for taskloop
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00004950 if (const auto* Clause = S.getSingleClause<OMPGrainsizeClause>()) {
4951 // grainsize clause
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004952 Data.Schedule.setInt(/*IntVal=*/false);
4953 Data.Schedule.setPointer(EmitScalarExpr(Clause->getGrainsize()));
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00004954 } else if (const auto* Clause = S.getSingleClause<OMPNumTasksClause>()) {
4955 // num_tasks clause
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004956 Data.Schedule.setInt(/*IntVal=*/true);
4957 Data.Schedule.setPointer(EmitScalarExpr(Clause->getNumTasks()));
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00004958 }
Alexey Bataev7292c292016-04-25 12:22:29 +00004959
4960 auto &&BodyGen = [CS, &S](CodeGenFunction &CGF, PrePostActionTy &) {
4961 // if (PreCond) {
4962 // for (IV in 0..LastIteration) BODY;
4963 // <Final counter/linear vars updates>;
4964 // }
4965 //
4966
4967 // Emit: if (PreCond) - begin.
4968 // If the condition constant folds and can be elided, avoid emitting the
4969 // whole loop.
4970 bool CondConstant;
4971 llvm::BasicBlock *ContBlock = nullptr;
4972 OMPLoopScope PreInitScope(CGF, S);
4973 if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
4974 if (!CondConstant)
4975 return;
4976 } else {
Alexey Bataevddf3db92018-04-13 17:31:06 +00004977 llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("taskloop.if.then");
Alexey Bataev7292c292016-04-25 12:22:29 +00004978 ContBlock = CGF.createBasicBlock("taskloop.if.end");
4979 emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
4980 CGF.getProfileCount(&S));
4981 CGF.EmitBlock(ThenBlock);
4982 CGF.incrementProfileCounter(&S);
4983 }
4984
Alexey Bataev1e73ef32016-04-28 12:14:51 +00004985 if (isOpenMPSimdDirective(S.getDirectiveKind()))
4986 CGF.EmitOMPSimdInit(S);
4987
Alexey Bataev7292c292016-04-25 12:22:29 +00004988 OMPPrivateScope LoopScope(CGF);
4989 // Emit helper vars inits.
4990 enum { LowerBound = 5, UpperBound, Stride, LastIter };
4991 auto *I = CS->getCapturedDecl()->param_begin();
4992 auto *LBP = std::next(I, LowerBound);
4993 auto *UBP = std::next(I, UpperBound);
4994 auto *STP = std::next(I, Stride);
4995 auto *LIP = std::next(I, LastIter);
4996 mapParam(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()), *LBP,
4997 LoopScope);
4998 mapParam(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()), *UBP,
4999 LoopScope);
5000 mapParam(CGF, cast<DeclRefExpr>(S.getStrideVariable()), *STP, LoopScope);
5001 mapParam(CGF, cast<DeclRefExpr>(S.getIsLastIterVariable()), *LIP,
5002 LoopScope);
5003 CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
Alexey Bataevf93095a2016-05-05 08:46:22 +00005004 bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
Alexey Bataev7292c292016-04-25 12:22:29 +00005005 (void)LoopScope.Privatize();
5006 // Emit the loop iteration variable.
5007 const Expr *IVExpr = S.getIterationVariable();
Alexey Bataevddf3db92018-04-13 17:31:06 +00005008 const auto *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
Alexey Bataev7292c292016-04-25 12:22:29 +00005009 CGF.EmitVarDecl(*IVDecl);
5010 CGF.EmitIgnoredExpr(S.getInit());
5011
5012 // Emit the iterations count variable.
5013 // If it is not a variable, Sema decided to calculate iterations count on
5014 // each iteration (e.g., it is foldable into a constant).
Alexey Bataevddf3db92018-04-13 17:31:06 +00005015 if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
Alexey Bataev7292c292016-04-25 12:22:29 +00005016 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
5017 // Emit calculation of the iterations count.
5018 CGF.EmitIgnoredExpr(S.getCalcLastIteration());
5019 }
5020
5021 CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
5022 S.getInc(),
5023 [&S](CodeGenFunction &CGF) {
5024 CGF.EmitOMPLoopBody(S, JumpDest());
5025 CGF.EmitStopPoint(&S);
5026 },
5027 [](CodeGenFunction &) {});
5028 // Emit: if (PreCond) - end.
5029 if (ContBlock) {
5030 CGF.EmitBranch(ContBlock);
5031 CGF.EmitBlock(ContBlock, true);
5032 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00005033 // Emit final copy of the lastprivate variables if IsLastIter != 0.
5034 if (HasLastprivateClause) {
5035 CGF.EmitOMPLastprivateClauseFinal(
5036 S, isOpenMPSimdDirective(S.getDirectiveKind()),
5037 CGF.Builder.CreateIsNotNull(CGF.EmitLoadOfScalar(
5038 CGF.GetAddrOfLocalVar(*LIP), /*Volatile=*/false,
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005039 (*LIP)->getType(), S.getBeginLoc())));
Alexey Bataevf93095a2016-05-05 08:46:22 +00005040 }
Alexey Bataev7292c292016-04-25 12:22:29 +00005041 };
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005042 auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
James Y Knight9871db02019-02-05 16:42:33 +00005043 IfCond](CodeGenFunction &CGF, llvm::Function *OutlinedFn,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005044 const OMPTaskDataTy &Data) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00005045 auto &&CodeGen = [&S, OutlinedFn, SharedsTy, CapturedStruct, IfCond,
5046 &Data](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataev7292c292016-04-25 12:22:29 +00005047 OMPLoopScope PreInitScope(CGF, S);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005048 CGF.CGM.getOpenMPRuntime().emitTaskLoopCall(CGF, S.getBeginLoc(), S,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005049 OutlinedFn, SharedsTy,
5050 CapturedStruct, IfCond, Data);
Alexey Bataev7292c292016-04-25 12:22:29 +00005051 };
5052 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop,
5053 CodeGen);
5054 };
Alexey Bataev475a7442018-01-12 19:39:11 +00005055 if (Data.Nogroup) {
5056 EmitOMPTaskBasedDirective(S, OMPD_taskloop, BodyGen, TaskGen, Data);
5057 } else {
Alexey Bataev33446032017-07-12 18:09:32 +00005058 CGM.getOpenMPRuntime().emitTaskgroupRegion(
5059 *this,
5060 [&S, &BodyGen, &TaskGen, &Data](CodeGenFunction &CGF,
5061 PrePostActionTy &Action) {
5062 Action.Enter(CGF);
Alexey Bataev475a7442018-01-12 19:39:11 +00005063 CGF.EmitOMPTaskBasedDirective(S, OMPD_taskloop, BodyGen, TaskGen,
5064 Data);
Alexey Bataev33446032017-07-12 18:09:32 +00005065 },
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005066 S.getBeginLoc());
Alexey Bataev33446032017-07-12 18:09:32 +00005067 }
Alexey Bataev7292c292016-04-25 12:22:29 +00005068}
5069
Alexey Bataev49f6e782015-12-01 04:18:41 +00005070void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) {
Alexey Bataev7292c292016-04-25 12:22:29 +00005071 EmitOMPTaskLoopBasedDirective(S);
Alexey Bataev49f6e782015-12-01 04:18:41 +00005072}
5073
Alexey Bataev0a6ed842015-12-03 09:40:15 +00005074void CodeGenFunction::EmitOMPTaskLoopSimdDirective(
5075 const OMPTaskLoopSimdDirective &S) {
Alexey Bataev1e73ef32016-04-28 12:14:51 +00005076 EmitOMPTaskLoopBasedDirective(S);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00005077}
Samuel Antao686c70c2016-05-26 17:30:50 +00005078
5079// Generate the instructions for '#pragma omp target update' directive.
5080void CodeGenFunction::EmitOMPTargetUpdateDirective(
5081 const OMPTargetUpdateDirective &S) {
Samuel Antao8d2d7302016-05-26 18:30:22 +00005082 // If we don't have target devices, don't bother emitting the data mapping
5083 // code.
5084 if (CGM.getLangOpts().OMPTargetTriples.empty())
5085 return;
5086
5087 // Check if we have any if clause associated with the directive.
5088 const Expr *IfCond = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00005089 if (const auto *C = S.getSingleClause<OMPIfClause>())
Samuel Antao8d2d7302016-05-26 18:30:22 +00005090 IfCond = C->getCondition();
5091
5092 // Check if we have any device clause associated with the directive.
5093 const Expr *Device = nullptr;
Alexey Bataevddf3db92018-04-13 17:31:06 +00005094 if (const auto *C = S.getSingleClause<OMPDeviceClause>())
Samuel Antao8d2d7302016-05-26 18:30:22 +00005095 Device = C->getDevice();
5096
Alexey Bataev475a7442018-01-12 19:39:11 +00005097 OMPLexicalScope Scope(*this, S, OMPD_task);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00005098 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
Samuel Antao686c70c2016-05-26 17:30:50 +00005099}
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00005100
5101void CodeGenFunction::EmitSimpleOMPExecutableDirective(
5102 const OMPExecutableDirective &D) {
5103 if (!D.hasAssociatedStmt() || !D.getAssociatedStmt())
5104 return;
5105 auto &&CodeGen = [&D](CodeGenFunction &CGF, PrePostActionTy &Action) {
5106 if (isOpenMPSimdDirective(D.getDirectiveKind())) {
5107 emitOMPSimdRegion(CGF, cast<OMPLoopDirective>(D), Action);
5108 } else {
Alexey Bataev6ab5bb12018-10-29 15:01:58 +00005109 OMPPrivateScope LoopGlobals(CGF);
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00005110 if (const auto *LD = dyn_cast<OMPLoopDirective>(&D)) {
Alexey Bataevddf3db92018-04-13 17:31:06 +00005111 for (const Expr *E : LD->counters()) {
Alexey Bataev6ab5bb12018-10-29 15:01:58 +00005112 const auto *VD = dyn_cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
5113 if (!VD->hasLocalStorage() && !CGF.LocalDeclMap.count(VD)) {
5114 LValue GlobLVal = CGF.EmitLValue(E);
5115 LoopGlobals.addPrivate(
5116 VD, [&GlobLVal]() { return GlobLVal.getAddress(); });
5117 }
Bjorn Pettersson6c2d83b2018-10-30 08:49:26 +00005118 if (isa<OMPCapturedExprDecl>(VD)) {
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00005119 // Emit only those that were not explicitly referenced in clauses.
5120 if (!CGF.LocalDeclMap.count(VD))
5121 CGF.EmitVarDecl(*VD);
5122 }
5123 }
Alexey Bataevf138fda2018-08-13 19:04:24 +00005124 for (const auto *C : D.getClausesOfKind<OMPOrderedClause>()) {
5125 if (!C->getNumForLoops())
5126 continue;
5127 for (unsigned I = LD->getCollapsedNumber(),
5128 E = C->getLoopNumIterations().size();
5129 I < E; ++I) {
5130 if (const auto *VD = dyn_cast<OMPCapturedExprDecl>(
Mike Rice0ed46662018-09-20 17:19:41 +00005131 cast<DeclRefExpr>(C->getLoopCounter(I))->getDecl())) {
Alexey Bataevf138fda2018-08-13 19:04:24 +00005132 // Emit only those that were not explicitly referenced in clauses.
5133 if (!CGF.LocalDeclMap.count(VD))
5134 CGF.EmitVarDecl(*VD);
5135 }
5136 }
5137 }
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00005138 }
Alexey Bataev6ab5bb12018-10-29 15:01:58 +00005139 LoopGlobals.Privatize();
Alexey Bataev475a7442018-01-12 19:39:11 +00005140 CGF.EmitStmt(D.getInnermostCapturedStmt()->getCapturedStmt());
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00005141 }
5142 };
5143 OMPSimdLexicalScope Scope(*this, D);
5144 CGM.getOpenMPRuntime().emitInlinedDirective(
5145 *this,
5146 isOpenMPSimdDirective(D.getDirectiveKind()) ? OMPD_simd
5147 : D.getDirectiveKind(),
5148 CodeGen);
5149}