blob: 71797e2e6fbe961c11a5e1fc596a5298fe2bc9da [file] [log] [blame]
Alexey Bataev9959db52014-05-06 10:08:46 +00001//===--- CGStmtOpenMP.cpp - Emit LLVM Code from Statements ----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This contains code to emit OpenMP nodes as LLVM code.
11//
12//===----------------------------------------------------------------------===//
13
Alexey Bataev3392d762016-02-16 11:18:12 +000014#include "CGCleanup.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000015#include "CGOpenMPRuntime.h"
16#include "CodeGenFunction.h"
17#include "CodeGenModule.h"
Chandler Carruth0d9593d2015-01-14 11:29:14 +000018#include "TargetInfo.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000019#include "clang/AST/Stmt.h"
20#include "clang/AST/StmtOpenMP.h"
Alexey Bataev2bbf7212016-03-03 03:52:24 +000021#include "clang/AST/DeclOpenMP.h"
Alexey Bataeva839ddd2016-03-17 10:19:46 +000022#include "llvm/IR/CallSite.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000023using namespace clang;
24using namespace CodeGen;
25
Alexey Bataev3392d762016-02-16 11:18:12 +000026namespace {
27/// Lexical scope for OpenMP executable constructs, that handles correct codegen
28/// for captured expressions.
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000029class OMPLexicalScope : public CodeGenFunction::LexicalScope {
Alexey Bataev3392d762016-02-16 11:18:12 +000030 void emitPreInitStmt(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
31 for (const auto *C : S.clauses()) {
32 if (auto *CPI = OMPClauseWithPreInit::get(C)) {
33 if (auto *PreInit = cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {
Alexey Bataev2bbf7212016-03-03 03:52:24 +000034 for (const auto *I : PreInit->decls()) {
35 if (!I->hasAttr<OMPCaptureNoInitAttr>())
36 CGF.EmitVarDecl(cast<VarDecl>(*I));
37 else {
38 CodeGenFunction::AutoVarEmission Emission =
39 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
40 CGF.EmitAutoVarCleanups(Emission);
41 }
42 }
Alexey Bataev3392d762016-02-16 11:18:12 +000043 }
44 }
45 }
46 }
Alexey Bataev4ba78a42016-04-27 07:56:03 +000047 CodeGenFunction::OMPPrivateScope InlinedShareds;
48
49 static bool isCapturedVar(CodeGenFunction &CGF, const VarDecl *VD) {
50 return CGF.LambdaCaptureFields.lookup(VD) ||
51 (CGF.CapturedStmtInfo && CGF.CapturedStmtInfo->lookup(VD)) ||
52 (CGF.CurCodeDecl && isa<BlockDecl>(CGF.CurCodeDecl));
53 }
Alexey Bataev3392d762016-02-16 11:18:12 +000054
Alexey Bataev3392d762016-02-16 11:18:12 +000055public:
Alexey Bataev4ba78a42016-04-27 07:56:03 +000056 OMPLexicalScope(CodeGenFunction &CGF, const OMPExecutableDirective &S,
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000057 bool AsInlined = false, bool EmitPreInitStmt = true)
Alexey Bataev4ba78a42016-04-27 07:56:03 +000058 : CodeGenFunction::LexicalScope(CGF, S.getSourceRange()),
59 InlinedShareds(CGF) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000060 if (EmitPreInitStmt)
61 emitPreInitStmt(CGF, S);
Alexey Bataev4ba78a42016-04-27 07:56:03 +000062 if (AsInlined) {
63 if (S.hasAssociatedStmt()) {
64 auto *CS = cast<CapturedStmt>(S.getAssociatedStmt());
65 for (auto &C : CS->captures()) {
66 if (C.capturesVariable() || C.capturesVariableByCopy()) {
67 auto *VD = C.getCapturedVar();
68 DeclRefExpr DRE(const_cast<VarDecl *>(VD),
69 isCapturedVar(CGF, VD) ||
70 (CGF.CapturedStmtInfo &&
71 InlinedShareds.isGlobalVarCaptured(VD)),
72 VD->getType().getNonReferenceType(), VK_LValue,
73 SourceLocation());
74 InlinedShareds.addPrivate(VD, [&CGF, &DRE]() -> Address {
75 return CGF.EmitLValue(&DRE).getAddress();
76 });
77 }
78 }
79 (void)InlinedShareds.Privatize();
80 }
81 }
Alexey Bataev3392d762016-02-16 11:18:12 +000082 }
83};
Alexey Bataev14fa1c62016-03-29 05:34:15 +000084
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000085/// Lexical scope for OpenMP parallel construct, that handles correct codegen
86/// for captured expressions.
87class OMPParallelScope final : public OMPLexicalScope {
88 bool EmitPreInitStmt(const OMPExecutableDirective &S) {
89 OpenMPDirectiveKind Kind = S.getDirectiveKind();
Carlo Bertollib0ff0a62017-04-25 17:52:12 +000090 return !(isOpenMPTargetExecutionDirective(Kind) ||
91 isOpenMPLoopBoundSharingDirective(Kind)) &&
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000092 isOpenMPParallelDirective(Kind);
93 }
94
95public:
96 OMPParallelScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
97 : OMPLexicalScope(CGF, S,
98 /*AsInlined=*/false,
99 /*EmitPreInitStmt=*/EmitPreInitStmt(S)) {}
100};
101
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +0000102/// Lexical scope for OpenMP teams construct, that handles correct codegen
103/// for captured expressions.
104class OMPTeamsScope final : public OMPLexicalScope {
105 bool EmitPreInitStmt(const OMPExecutableDirective &S) {
106 OpenMPDirectiveKind Kind = S.getDirectiveKind();
107 return !isOpenMPTargetExecutionDirective(Kind) &&
108 isOpenMPTeamsDirective(Kind);
109 }
110
111public:
112 OMPTeamsScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
113 : OMPLexicalScope(CGF, S,
114 /*AsInlined=*/false,
115 /*EmitPreInitStmt=*/EmitPreInitStmt(S)) {}
116};
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) {
122 if (auto *LD = dyn_cast<OMPLoopDirective>(&S)) {
123 if (auto *PreInits = cast_or_null<DeclStmt>(LD->getPreInits())) {
124 for (const auto *I : PreInits->decls())
125 CGF.EmitVarDecl(cast<VarDecl>(*I));
126 }
127 }
128 }
129
130public:
131 OMPLoopScope(CodeGenFunction &CGF, const OMPLoopDirective &S)
132 : CodeGenFunction::RunCleanupsScope(CGF) {
133 emitPreInitStmt(CGF, S);
134 }
135};
136
Alexey Bataev3392d762016-02-16 11:18:12 +0000137} // namespace
138
Alexey Bataev1189bd02016-01-26 12:20:39 +0000139llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) {
140 auto &C = getContext();
141 llvm::Value *Size = nullptr;
142 auto SizeInChars = C.getTypeSizeInChars(Ty);
143 if (SizeInChars.isZero()) {
144 // getTypeSizeInChars() returns 0 for a VLA.
145 while (auto *VAT = C.getAsVariableArrayType(Ty)) {
146 llvm::Value *ArraySize;
147 std::tie(ArraySize, Ty) = getVLASize(VAT);
148 Size = Size ? Builder.CreateNUWMul(Size, ArraySize) : ArraySize;
149 }
150 SizeInChars = C.getTypeSizeInChars(Ty);
151 if (SizeInChars.isZero())
152 return llvm::ConstantInt::get(SizeTy, /*V=*/0);
153 Size = Builder.CreateNUWMul(Size, CGM.getSize(SizeInChars));
154 } else
155 Size = CGM.getSize(SizeInChars);
156 return Size;
157}
158
Alexey Bataev2377fe92015-09-10 08:12:02 +0000159void CodeGenFunction::GenerateOpenMPCapturedVars(
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000160 const CapturedStmt &S, SmallVectorImpl<llvm::Value *> &CapturedVars) {
Alexey Bataev2377fe92015-09-10 08:12:02 +0000161 const RecordDecl *RD = S.getCapturedRecordDecl();
162 auto CurField = RD->field_begin();
163 auto CurCap = S.captures().begin();
164 for (CapturedStmt::const_capture_init_iterator I = S.capture_init_begin(),
165 E = S.capture_init_end();
166 I != E; ++I, ++CurField, ++CurCap) {
167 if (CurField->hasCapturedVLAType()) {
168 auto VAT = CurField->getCapturedVLAType();
Samuel Antaobed3c462015-10-02 16:14:20 +0000169 auto *Val = VLASizeMap[VAT->getSizeExpr()];
Samuel Antaobed3c462015-10-02 16:14:20 +0000170 CapturedVars.push_back(Val);
Alexey Bataev2377fe92015-09-10 08:12:02 +0000171 } else if (CurCap->capturesThis())
172 CapturedVars.push_back(CXXThisValue);
Samuel Antao6d004262016-06-16 18:39:34 +0000173 else if (CurCap->capturesVariableByCopy()) {
174 llvm::Value *CV =
175 EmitLoadOfLValue(EmitLValue(*I), SourceLocation()).getScalarVal();
176
177 // If the field is not a pointer, we need to save the actual value
178 // and load it as a void pointer.
179 if (!CurField->getType()->isAnyPointerType()) {
180 auto &Ctx = getContext();
181 auto DstAddr = CreateMemTemp(
182 Ctx.getUIntPtrType(),
183 Twine(CurCap->getCapturedVar()->getName()) + ".casted");
184 LValue DstLV = MakeAddrLValue(DstAddr, Ctx.getUIntPtrType());
185
186 auto *SrcAddrVal = EmitScalarConversion(
187 DstAddr.getPointer(), Ctx.getPointerType(Ctx.getUIntPtrType()),
188 Ctx.getPointerType(CurField->getType()), SourceLocation());
189 LValue SrcLV =
190 MakeNaturalAlignAddrLValue(SrcAddrVal, CurField->getType());
191
192 // Store the value using the source type pointer.
193 EmitStoreThroughLValue(RValue::get(CV), SrcLV);
194
195 // Load the value using the destination type pointer.
196 CV = EmitLoadOfLValue(DstLV, SourceLocation()).getScalarVal();
197 }
198 CapturedVars.push_back(CV);
199 } else {
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000200 assert(CurCap->capturesVariable() && "Expected capture by reference.");
Alexey Bataev2377fe92015-09-10 08:12:02 +0000201 CapturedVars.push_back(EmitLValue(*I).getAddress().getPointer());
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000202 }
Alexey Bataev2377fe92015-09-10 08:12:02 +0000203 }
204}
205
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000206static Address castValueFromUintptr(CodeGenFunction &CGF, QualType DstType,
207 StringRef Name, LValue AddrLV,
208 bool isReferenceType = false) {
209 ASTContext &Ctx = CGF.getContext();
210
211 auto *CastedPtr = CGF.EmitScalarConversion(
212 AddrLV.getAddress().getPointer(), Ctx.getUIntPtrType(),
213 Ctx.getPointerType(DstType), SourceLocation());
214 auto TmpAddr =
215 CGF.MakeNaturalAlignAddrLValue(CastedPtr, Ctx.getPointerType(DstType))
216 .getAddress();
217
218 // If we are dealing with references we need to return the address of the
219 // reference instead of the reference of the value.
220 if (isReferenceType) {
221 QualType RefType = Ctx.getLValueReferenceType(DstType);
222 auto *RefVal = TmpAddr.getPointer();
223 TmpAddr = CGF.CreateMemTemp(RefType, Twine(Name) + ".ref");
224 auto TmpLVal = CGF.MakeAddrLValue(TmpAddr, RefType);
Akira Hatanaka642f7992016-10-18 19:05:41 +0000225 CGF.EmitStoreThroughLValue(RValue::get(RefVal), TmpLVal, /*isInit*/ true);
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000226 }
227
228 return TmpAddr;
229}
230
Alexey Bataevf7ce1662017-04-10 19:16:45 +0000231static QualType getCanonicalParamType(ASTContext &C, QualType T) {
232 if (T->isLValueReferenceType()) {
233 return C.getLValueReferenceType(
234 getCanonicalParamType(C, T.getNonReferenceType()),
235 /*SpelledAsLValue=*/false);
236 }
237 if (T->isPointerType())
238 return C.getPointerType(getCanonicalParamType(C, T->getPointeeType()));
239 return C.getCanonicalParamType(T);
240}
241
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000242namespace {
243 /// Contains required data for proper outlined function codegen.
244 struct FunctionOptions {
245 /// Captured statement for which the function is generated.
246 const CapturedStmt *S = nullptr;
247 /// true if cast to/from UIntPtr is required for variables captured by
248 /// value.
249 bool UIntPtrCastRequired = true;
250 /// true if only casted argumefnts must be registered as local args or VLA
251 /// sizes.
252 bool RegisterCastedArgsOnly = false;
253 /// Name of the generated function.
254 StringRef FunctionName;
255 explicit FunctionOptions(const CapturedStmt *S, bool UIntPtrCastRequired,
256 bool RegisterCastedArgsOnly,
257 StringRef FunctionName)
258 : S(S), UIntPtrCastRequired(UIntPtrCastRequired),
259 RegisterCastedArgsOnly(UIntPtrCastRequired && RegisterCastedArgsOnly),
260 FunctionName(FunctionName) {}
261 };
262}
263
264static std::pair<llvm::Function *, bool> emitOutlinedFunctionPrologue(
265 CodeGenFunction &CGF, FunctionArgList &Args,
266 llvm::DenseMap<const Decl *, std::pair<const VarDecl *, Address>>
267 &LocalAddrs,
268 llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>>
269 &VLASizes,
270 llvm::Value *&CXXThisValue, const FunctionOptions &FO) {
271 const CapturedDecl *CD = FO.S->getCapturedDecl();
272 const RecordDecl *RD = FO.S->getCapturedRecordDecl();
Alexey Bataev2377fe92015-09-10 08:12:02 +0000273 assert(CD->hasBody() && "missing CapturedDecl body");
274
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000275 CXXThisValue = nullptr;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000276 // Build the argument list.
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000277 CodeGenModule &CGM = CGF.CGM;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000278 ASTContext &Ctx = CGM.getContext();
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000279 bool HasUIntPtrArgs = false;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000280 Args.append(CD->param_begin(),
281 std::next(CD->param_begin(), CD->getContextParamPosition()));
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000282 auto I = FO.S->captures().begin();
Alexey Bataev2377fe92015-09-10 08:12:02 +0000283 for (auto *FD : RD->fields()) {
284 QualType ArgType = FD->getType();
285 IdentifierInfo *II = nullptr;
286 VarDecl *CapVar = nullptr;
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000287
288 // If this is a capture by copy and the type is not a pointer, the outlined
289 // function argument type should be uintptr and the value properly casted to
290 // uintptr. This is necessary given that the runtime library is only able to
291 // deal with pointers. We can pass in the same way the VLA type sizes to the
292 // outlined function.
Samuel Antao6d004262016-06-16 18:39:34 +0000293 if ((I->capturesVariableByCopy() && !ArgType->isAnyPointerType()) ||
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000294 I->capturesVariableArrayType()) {
295 HasUIntPtrArgs = true;
296 if (FO.UIntPtrCastRequired)
297 ArgType = Ctx.getUIntPtrType();
298 }
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000299
300 if (I->capturesVariable() || I->capturesVariableByCopy()) {
Alexey Bataev2377fe92015-09-10 08:12:02 +0000301 CapVar = I->getCapturedVar();
302 II = CapVar->getIdentifier();
303 } else if (I->capturesThis())
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000304 II = &Ctx.Idents.get("this");
Alexey Bataev2377fe92015-09-10 08:12:02 +0000305 else {
306 assert(I->capturesVariableArrayType());
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000307 II = &Ctx.Idents.get("vla");
Alexey Bataev2377fe92015-09-10 08:12:02 +0000308 }
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000309 if (ArgType->isVariablyModifiedType())
310 ArgType = getCanonicalParamType(Ctx, ArgType.getNonReferenceType());
311 Args.push_back(ImplicitParamDecl::Create(Ctx, /*DC=*/nullptr,
Alexey Bataev56223232017-06-09 13:40:18 +0000312 FD->getLocation(), II, ArgType,
313 ImplicitParamDecl::Other));
Alexey Bataev2377fe92015-09-10 08:12:02 +0000314 ++I;
315 }
316 Args.append(
317 std::next(CD->param_begin(), CD->getContextParamPosition() + 1),
318 CD->param_end());
319
320 // Create the function declaration.
321 FunctionType::ExtInfo ExtInfo;
322 const CGFunctionInfo &FuncInfo =
John McCallc56a8b32016-03-11 04:30:31 +0000323 CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
Alexey Bataev2377fe92015-09-10 08:12:02 +0000324 llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo);
325
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000326 llvm::Function *F =
327 llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
328 FO.FunctionName, &CGM.getModule());
Alexey Bataev2377fe92015-09-10 08:12:02 +0000329 CGM.SetInternalFunctionAttributes(CD, F, FuncInfo);
330 if (CD->isNothrow())
331 F->addFnAttr(llvm::Attribute::NoUnwind);
332
333 // Generate the function.
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000334 CGF.StartFunction(CD, Ctx.VoidTy, F, FuncInfo, Args, CD->getLocation(),
335 CD->getBody()->getLocStart());
Alexey Bataev2377fe92015-09-10 08:12:02 +0000336 unsigned Cnt = CD->getContextParamPosition();
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000337 I = FO.S->captures().begin();
Alexey Bataev2377fe92015-09-10 08:12:02 +0000338 for (auto *FD : RD->fields()) {
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000339 // If we are capturing a pointer by copy we don't need to do anything, just
340 // use the value that we get from the arguments.
341 if (I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) {
Samuel Antao403ffd42016-07-27 22:49:49 +0000342 const VarDecl *CurVD = I->getCapturedVar();
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000343 Address LocalAddr = CGF.GetAddrOfLocalVar(Args[Cnt]);
Samuel Antao403ffd42016-07-27 22:49:49 +0000344 // If the variable is a reference we need to materialize it here.
345 if (CurVD->getType()->isReferenceType()) {
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000346 Address RefAddr = CGF.CreateMemTemp(
347 CurVD->getType(), CGM.getPointerAlign(), ".materialized_ref");
348 CGF.EmitStoreOfScalar(LocalAddr.getPointer(), RefAddr,
349 /*Volatile=*/false, CurVD->getType());
Samuel Antao403ffd42016-07-27 22:49:49 +0000350 LocalAddr = RefAddr;
351 }
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000352 if (!FO.RegisterCastedArgsOnly)
353 LocalAddrs.insert({Args[Cnt], {CurVD, LocalAddr}});
Richard Trieucc3949d2016-02-18 22:34:54 +0000354 ++Cnt;
355 ++I;
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000356 continue;
357 }
358
Krzysztof Parzyszek8f248232017-05-18 17:07:11 +0000359 LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000360 LValue ArgLVal = CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(Args[Cnt]),
361 Args[Cnt]->getType(), BaseInfo);
Alexey Bataev2377fe92015-09-10 08:12:02 +0000362 if (FD->hasCapturedVLAType()) {
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000363 if (FO.UIntPtrCastRequired) {
364 ArgLVal = CGF.MakeAddrLValue(castValueFromUintptr(CGF, FD->getType(),
365 Args[Cnt]->getName(),
366 ArgLVal),
367 FD->getType(), BaseInfo);
368 }
Alexey Bataev2377fe92015-09-10 08:12:02 +0000369 auto *ExprArg =
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000370 CGF.EmitLoadOfLValue(ArgLVal, SourceLocation()).getScalarVal();
Alexey Bataev2377fe92015-09-10 08:12:02 +0000371 auto VAT = FD->getCapturedVLAType();
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000372 VLASizes.insert({Args[Cnt], {VAT->getSizeExpr(), ExprArg}});
Alexey Bataev2377fe92015-09-10 08:12:02 +0000373 } else if (I->capturesVariable()) {
374 auto *Var = I->getCapturedVar();
375 QualType VarTy = Var->getType();
376 Address ArgAddr = ArgLVal.getAddress();
377 if (!VarTy->isReferenceType()) {
Alexey Bataev2f5ed342016-10-13 09:52:46 +0000378 if (ArgLVal.getType()->isLValueReferenceType()) {
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000379 ArgAddr = CGF.EmitLoadOfReference(
Alexey Bataev2f5ed342016-10-13 09:52:46 +0000380 ArgAddr, ArgLVal.getType()->castAs<ReferenceType>());
Alexey Bataevac5eabb2016-11-07 11:16:04 +0000381 } else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) {
Alexey Bataev2f5ed342016-10-13 09:52:46 +0000382 assert(ArgLVal.getType()->isPointerType());
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000383 ArgAddr = CGF.EmitLoadOfPointer(
Alexey Bataev2f5ed342016-10-13 09:52:46 +0000384 ArgAddr, ArgLVal.getType()->castAs<PointerType>());
385 }
Alexey Bataev2377fe92015-09-10 08:12:02 +0000386 }
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000387 if (!FO.RegisterCastedArgsOnly) {
388 LocalAddrs.insert(
389 {Args[Cnt],
390 {Var, Address(ArgAddr.getPointer(), Ctx.getDeclAlign(Var))}});
391 }
Samuel Antao4af1b7b2015-12-02 17:44:43 +0000392 } else if (I->capturesVariableByCopy()) {
393 assert(!FD->getType()->isAnyPointerType() &&
394 "Not expecting a captured pointer.");
395 auto *Var = I->getCapturedVar();
396 QualType VarTy = Var->getType();
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000397 LocalAddrs.insert(
398 {Args[Cnt],
399 {Var,
400 FO.UIntPtrCastRequired
401 ? castValueFromUintptr(CGF, FD->getType(), Args[Cnt]->getName(),
402 ArgLVal, VarTy->isReferenceType())
403 : ArgLVal.getAddress()}});
Alexey Bataev2377fe92015-09-10 08:12:02 +0000404 } else {
405 // If 'this' is captured, load it into CXXThisValue.
406 assert(I->capturesThis());
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000407 CXXThisValue = CGF.EmitLoadOfLValue(ArgLVal, Args[Cnt]->getLocation())
408 .getScalarVal();
409 LocalAddrs.insert({Args[Cnt], {nullptr, ArgLVal.getAddress()}});
Alexey Bataev2377fe92015-09-10 08:12:02 +0000410 }
Richard Trieucc3949d2016-02-18 22:34:54 +0000411 ++Cnt;
412 ++I;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000413 }
414
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000415 return {F, HasUIntPtrArgs};
416}
417
418llvm::Function *
419CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
420 assert(
421 CapturedStmtInfo &&
422 "CapturedStmtInfo should be set when generating the captured function");
423 const CapturedDecl *CD = S.getCapturedDecl();
424 // Build the argument list.
425 bool NeedWrapperFunction =
426 getDebugInfo() &&
427 CGM.getCodeGenOpts().getDebugInfo() >= codegenoptions::LimitedDebugInfo;
428 FunctionArgList Args;
429 llvm::DenseMap<const Decl *, std::pair<const VarDecl *, Address>> LocalAddrs;
430 llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> VLASizes;
431 FunctionOptions FO(&S, !NeedWrapperFunction, /*RegisterCastedArgsOnly=*/false,
432 CapturedStmtInfo->getHelperName());
433 llvm::Function *F;
434 bool HasUIntPtrArgs;
435 std::tie(F, HasUIntPtrArgs) = emitOutlinedFunctionPrologue(
436 *this, Args, LocalAddrs, VLASizes, CXXThisValue, FO);
437 for (const auto &LocalAddrPair : LocalAddrs) {
438 if (LocalAddrPair.second.first) {
439 setAddrOfLocalVar(LocalAddrPair.second.first,
440 LocalAddrPair.second.second);
441 }
442 }
443 for (const auto &VLASizePair : VLASizes)
444 VLASizeMap[VLASizePair.second.first] = VLASizePair.second.second;
Serge Pavlov3a561452015-12-06 14:32:39 +0000445 PGO.assignRegionCounters(GlobalDecl(CD), F);
Alexey Bataev2377fe92015-09-10 08:12:02 +0000446 CapturedStmtInfo->EmitBody(*this, CD->getBody());
447 FinishFunction(CD->getBodyRBrace());
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000448 if (!NeedWrapperFunction || !HasUIntPtrArgs)
449 return F;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000450
Alexey Bataev1fdfdf72017-06-29 16:43:05 +0000451 FunctionOptions WrapperFO(&S, /*UIntPtrCastRequired=*/true,
452 /*RegisterCastedArgsOnly=*/true,
453 ".nondebug_wrapper.");
454 CodeGenFunction WrapperCGF(CGM, /*suppressNewContext=*/true);
455 WrapperCGF.disableDebugInfo();
456 Args.clear();
457 LocalAddrs.clear();
458 VLASizes.clear();
459 llvm::Function *WrapperF =
460 emitOutlinedFunctionPrologue(WrapperCGF, Args, LocalAddrs, VLASizes,
461 WrapperCGF.CXXThisValue, WrapperFO).first;
462 LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
463 llvm::SmallVector<llvm::Value *, 4> CallArgs;
464 for (const auto *Arg : Args) {
465 llvm::Value *CallArg;
466 auto I = LocalAddrs.find(Arg);
467 if (I != LocalAddrs.end()) {
468 LValue LV =
469 WrapperCGF.MakeAddrLValue(I->second.second, Arg->getType(), BaseInfo);
470 CallArg = WrapperCGF.EmitLoadOfScalar(LV, SourceLocation());
471 } else {
472 auto EI = VLASizes.find(Arg);
473 if (EI != VLASizes.end())
474 CallArg = EI->second.second;
475 else {
476 LValue LV = WrapperCGF.MakeAddrLValue(WrapperCGF.GetAddrOfLocalVar(Arg),
477 Arg->getType(), BaseInfo);
478 CallArg = WrapperCGF.EmitLoadOfScalar(LV, SourceLocation());
479 }
480 }
481 CallArgs.emplace_back(CallArg);
482 }
483 WrapperCGF.Builder.CreateCall(F, CallArgs);
484 WrapperCGF.FinishFunction();
485 return WrapperF;
Alexey Bataev2377fe92015-09-10 08:12:02 +0000486}
487
Alexey Bataev9959db52014-05-06 10:08:46 +0000488//===----------------------------------------------------------------------===//
489// OpenMP Directive Emission
490//===----------------------------------------------------------------------===//
Alexey Bataev420d45b2015-04-14 05:11:24 +0000491void CodeGenFunction::EmitOMPAggregateAssign(
John McCall7f416cc2015-09-08 08:05:57 +0000492 Address DestAddr, Address SrcAddr, QualType OriginalType,
493 const llvm::function_ref<void(Address, Address)> &CopyGen) {
Alexey Bataev420d45b2015-04-14 05:11:24 +0000494 // Perform element-by-element initialization.
495 QualType ElementTy;
John McCall7f416cc2015-09-08 08:05:57 +0000496
497 // Drill down to the base element type on both arrays.
Alexey Bataev420d45b2015-04-14 05:11:24 +0000498 auto ArrayTy = OriginalType->getAsArrayTypeUnsafe();
John McCall7f416cc2015-09-08 08:05:57 +0000499 auto NumElements = emitArrayLength(ArrayTy, ElementTy, DestAddr);
500 SrcAddr = Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());
501
502 auto SrcBegin = SrcAddr.getPointer();
503 auto DestBegin = DestAddr.getPointer();
Alexey Bataev420d45b2015-04-14 05:11:24 +0000504 // Cast from pointer to array type to pointer to single element.
Alexey Bataev420d45b2015-04-14 05:11:24 +0000505 auto DestEnd = Builder.CreateGEP(DestBegin, NumElements);
506 // The basic structure here is a while-do loop.
507 auto BodyBB = createBasicBlock("omp.arraycpy.body");
508 auto DoneBB = createBasicBlock("omp.arraycpy.done");
509 auto IsEmpty =
510 Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty");
511 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000512
Alexey Bataev420d45b2015-04-14 05:11:24 +0000513 // Enter the loop body, making that address the current address.
514 auto EntryBB = Builder.GetInsertBlock();
515 EmitBlock(BodyBB);
John McCall7f416cc2015-09-08 08:05:57 +0000516
517 CharUnits ElementSize = getContext().getTypeSizeInChars(ElementTy);
518
519 llvm::PHINode *SrcElementPHI =
520 Builder.CreatePHI(SrcBegin->getType(), 2, "omp.arraycpy.srcElementPast");
521 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
522 Address SrcElementCurrent =
523 Address(SrcElementPHI,
524 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
525
526 llvm::PHINode *DestElementPHI =
527 Builder.CreatePHI(DestBegin->getType(), 2, "omp.arraycpy.destElementPast");
528 DestElementPHI->addIncoming(DestBegin, EntryBB);
529 Address DestElementCurrent =
530 Address(DestElementPHI,
531 DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000532
Alexey Bataev420d45b2015-04-14 05:11:24 +0000533 // Emit copy.
534 CopyGen(DestElementCurrent, SrcElementCurrent);
535
536 // Shift the address forward by one element.
537 auto DestElementNext = Builder.CreateConstGEP1_32(
John McCall7f416cc2015-09-08 08:05:57 +0000538 DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
Alexey Bataev420d45b2015-04-14 05:11:24 +0000539 auto SrcElementNext = Builder.CreateConstGEP1_32(
John McCall7f416cc2015-09-08 08:05:57 +0000540 SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.src.element");
Alexey Bataev420d45b2015-04-14 05:11:24 +0000541 // Check whether we've reached the end.
542 auto Done =
543 Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");
544 Builder.CreateCondBr(Done, DoneBB, BodyBB);
John McCall7f416cc2015-09-08 08:05:57 +0000545 DestElementPHI->addIncoming(DestElementNext, Builder.GetInsertBlock());
546 SrcElementPHI->addIncoming(SrcElementNext, Builder.GetInsertBlock());
Alexey Bataev420d45b2015-04-14 05:11:24 +0000547
548 // Done.
549 EmitBlock(DoneBB, /*IsFinished=*/true);
550}
551
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000552/// Check if the combiner is a call to UDR combiner and if it is so return the
553/// UDR decl used for reduction.
554static const OMPDeclareReductionDecl *
555getReductionInit(const Expr *ReductionOp) {
556 if (auto *CE = dyn_cast<CallExpr>(ReductionOp))
557 if (auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
558 if (auto *DRE =
559 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
560 if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl()))
561 return DRD;
562 return nullptr;
563}
564
565static void emitInitWithReductionInitializer(CodeGenFunction &CGF,
566 const OMPDeclareReductionDecl *DRD,
567 const Expr *InitOp,
568 Address Private, Address Original,
569 QualType Ty) {
570 if (DRD->getInitializer()) {
571 std::pair<llvm::Function *, llvm::Function *> Reduction =
572 CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD);
573 auto *CE = cast<CallExpr>(InitOp);
574 auto *OVE = cast<OpaqueValueExpr>(CE->getCallee());
575 const Expr *LHS = CE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
576 const Expr *RHS = CE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
577 auto *LHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(LHS)->getSubExpr());
578 auto *RHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(RHS)->getSubExpr());
579 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
580 PrivateScope.addPrivate(cast<VarDecl>(LHSDRE->getDecl()),
581 [=]() -> Address { return Private; });
582 PrivateScope.addPrivate(cast<VarDecl>(RHSDRE->getDecl()),
583 [=]() -> Address { return Original; });
584 (void)PrivateScope.Privatize();
585 RValue Func = RValue::get(Reduction.second);
586 CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func);
587 CGF.EmitIgnoredExpr(InitOp);
588 } else {
589 llvm::Constant *Init = CGF.CGM.EmitNullConstant(Ty);
590 auto *GV = new llvm::GlobalVariable(
591 CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
592 llvm::GlobalValue::PrivateLinkage, Init, ".init");
593 LValue LV = CGF.MakeNaturalAlignAddrLValue(GV, Ty);
594 RValue InitRVal;
595 switch (CGF.getEvaluationKind(Ty)) {
596 case TEK_Scalar:
597 InitRVal = CGF.EmitLoadOfLValue(LV, SourceLocation());
598 break;
599 case TEK_Complex:
600 InitRVal =
601 RValue::getComplex(CGF.EmitLoadOfComplex(LV, SourceLocation()));
602 break;
603 case TEK_Aggregate:
604 InitRVal = RValue::getAggregate(LV.getAddress());
605 break;
606 }
607 OpaqueValueExpr OVE(SourceLocation(), Ty, VK_RValue);
608 CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, InitRVal);
609 CGF.EmitAnyExprToMem(&OVE, Private, Ty.getQualifiers(),
610 /*IsInitializer=*/false);
611 }
612}
613
Alexey Bataevf24e7b12015-10-08 09:10:53 +0000614/// \brief Emit initialization of arrays of complex types.
Alexey Bataevf24e7b12015-10-08 09:10:53 +0000615/// \param DestAddr Address of the array.
616/// \param Type Type of array.
617/// \param Init Initial expression of array.
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000618/// \param SrcAddr Address of the original array.
Alexey Bataevf24e7b12015-10-08 09:10:53 +0000619static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr,
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000620 QualType Type, const Expr *Init,
621 Address SrcAddr = Address::invalid()) {
622 auto *DRD = getReductionInit(Init);
Alexey Bataevf24e7b12015-10-08 09:10:53 +0000623 // Perform element-by-element initialization.
624 QualType ElementTy;
625
626 // Drill down to the base element type on both arrays.
627 auto ArrayTy = Type->getAsArrayTypeUnsafe();
628 auto NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, DestAddr);
629 DestAddr =
630 CGF.Builder.CreateElementBitCast(DestAddr, DestAddr.getElementType());
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000631 if (DRD)
632 SrcAddr =
633 CGF.Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());
Alexey Bataevf24e7b12015-10-08 09:10:53 +0000634
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000635 llvm::Value *SrcBegin = nullptr;
636 if (DRD)
637 SrcBegin = SrcAddr.getPointer();
Alexey Bataevf24e7b12015-10-08 09:10:53 +0000638 auto DestBegin = DestAddr.getPointer();
639 // Cast from pointer to array type to pointer to single element.
640 auto DestEnd = CGF.Builder.CreateGEP(DestBegin, NumElements);
641 // The basic structure here is a while-do loop.
642 auto BodyBB = CGF.createBasicBlock("omp.arrayinit.body");
643 auto DoneBB = CGF.createBasicBlock("omp.arrayinit.done");
644 auto IsEmpty =
645 CGF.Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arrayinit.isempty");
646 CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
647
648 // Enter the loop body, making that address the current address.
649 auto EntryBB = CGF.Builder.GetInsertBlock();
650 CGF.EmitBlock(BodyBB);
651
652 CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy);
653
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000654 llvm::PHINode *SrcElementPHI = nullptr;
655 Address SrcElementCurrent = Address::invalid();
656 if (DRD) {
657 SrcElementPHI = CGF.Builder.CreatePHI(SrcBegin->getType(), 2,
658 "omp.arraycpy.srcElementPast");
659 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
660 SrcElementCurrent =
661 Address(SrcElementPHI,
662 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
663 }
Alexey Bataevf24e7b12015-10-08 09:10:53 +0000664 llvm::PHINode *DestElementPHI = CGF.Builder.CreatePHI(
665 DestBegin->getType(), 2, "omp.arraycpy.destElementPast");
666 DestElementPHI->addIncoming(DestBegin, EntryBB);
667 Address DestElementCurrent =
668 Address(DestElementPHI,
669 DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));
670
671 // Emit copy.
672 {
673 CodeGenFunction::RunCleanupsScope InitScope(CGF);
Alexey Bataev8fbae8cf2016-04-27 11:38:05 +0000674 if (DRD && (DRD->getInitializer() || !Init)) {
Alexey Bataeva839ddd2016-03-17 10:19:46 +0000675 emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent,
676 SrcElementCurrent, ElementTy);
677 } else
678 CGF.EmitAnyExprToMem(Init, DestElementCurrent, ElementTy.getQualifiers(),
679 /*IsInitializer=*/false);
680 }
681
682 if (DRD) {
683 // Shift the address forward by one element.
684 auto SrcElementNext = CGF.Builder.CreateConstGEP1_32(
685 SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
686 SrcElementPHI->addIncoming(SrcElementNext, CGF.Builder.GetInsertBlock());
Alexey Bataevf24e7b12015-10-08 09:10:53 +0000687 }
688
689 // Shift the address forward by one element.
690 auto DestElementNext = CGF.Builder.CreateConstGEP1_32(
691 DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
692 // Check whether we've reached the end.
693 auto Done =
694 CGF.Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");
695 CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB);
696 DestElementPHI->addIncoming(DestElementNext, CGF.Builder.GetInsertBlock());
697
698 // Done.
699 CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
700}
701
John McCall7f416cc2015-09-08 08:05:57 +0000702void CodeGenFunction::EmitOMPCopy(QualType OriginalType, Address DestAddr,
703 Address SrcAddr, const VarDecl *DestVD,
Alexey Bataev420d45b2015-04-14 05:11:24 +0000704 const VarDecl *SrcVD, const Expr *Copy) {
705 if (OriginalType->isArrayType()) {
706 auto *BO = dyn_cast<BinaryOperator>(Copy);
707 if (BO && BO->getOpcode() == BO_Assign) {
708 // Perform simple memcpy for simple copying.
John McCall7f416cc2015-09-08 08:05:57 +0000709 EmitAggregateAssign(DestAddr, SrcAddr, OriginalType);
Alexey Bataev420d45b2015-04-14 05:11:24 +0000710 } else {
711 // For arrays with complex element types perform element by element
712 // copying.
John McCall7f416cc2015-09-08 08:05:57 +0000713 EmitOMPAggregateAssign(
Alexey Bataev420d45b2015-04-14 05:11:24 +0000714 DestAddr, SrcAddr, OriginalType,
John McCall7f416cc2015-09-08 08:05:57 +0000715 [this, Copy, SrcVD, DestVD](Address DestElement, Address SrcElement) {
Alexey Bataev420d45b2015-04-14 05:11:24 +0000716 // Working with the single array element, so have to remap
717 // destination and source variables to corresponding array
718 // elements.
John McCall7f416cc2015-09-08 08:05:57 +0000719 CodeGenFunction::OMPPrivateScope Remap(*this);
720 Remap.addPrivate(DestVD, [DestElement]() -> Address {
Alexey Bataev420d45b2015-04-14 05:11:24 +0000721 return DestElement;
722 });
723 Remap.addPrivate(
John McCall7f416cc2015-09-08 08:05:57 +0000724 SrcVD, [SrcElement]() -> Address { return SrcElement; });
Alexey Bataev420d45b2015-04-14 05:11:24 +0000725 (void)Remap.Privatize();
John McCall7f416cc2015-09-08 08:05:57 +0000726 EmitIgnoredExpr(Copy);
Alexey Bataev420d45b2015-04-14 05:11:24 +0000727 });
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000728 }
Alexey Bataev420d45b2015-04-14 05:11:24 +0000729 } else {
730 // Remap pseudo source variable to private copy.
John McCall7f416cc2015-09-08 08:05:57 +0000731 CodeGenFunction::OMPPrivateScope Remap(*this);
732 Remap.addPrivate(SrcVD, [SrcAddr]() -> Address { return SrcAddr; });
733 Remap.addPrivate(DestVD, [DestAddr]() -> Address { return DestAddr; });
Alexey Bataev420d45b2015-04-14 05:11:24 +0000734 (void)Remap.Privatize();
735 // Emit copying of the whole variable.
John McCall7f416cc2015-09-08 08:05:57 +0000736 EmitIgnoredExpr(Copy);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000737 }
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000738}
739
Alexey Bataev69c62a92015-04-15 04:52:20 +0000740bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
741 OMPPrivateScope &PrivateScope) {
Alexey Bataev8ef31412015-12-18 07:58:25 +0000742 if (!HaveInsertPoint())
743 return false;
Alexey Bataevcd8b6a22016-02-15 08:07:17 +0000744 bool FirstprivateIsLastprivate = false;
745 llvm::DenseSet<const VarDecl *> Lastprivates;
746 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
747 for (const auto *D : C->varlists())
748 Lastprivates.insert(
749 cast<VarDecl>(cast<DeclRefExpr>(D)->getDecl())->getCanonicalDecl());
750 }
Alexey Bataev69c62a92015-04-15 04:52:20 +0000751 llvm::DenseSet<const VarDecl *> EmittedAsFirstprivate;
Alexey Bataev9afe5752016-05-24 07:40:12 +0000752 CGCapturedStmtInfo CapturesInfo(cast<CapturedStmt>(*D.getAssociatedStmt()));
Benjamin Kramerfc600dc2015-08-30 15:12:28 +0000753 for (const auto *C : D.getClausesOfKind<OMPFirstprivateClause>()) {
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000754 auto IRef = C->varlist_begin();
755 auto InitsRef = C->inits().begin();
756 for (auto IInit : C->private_copies()) {
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000757 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000758 bool ThisFirstprivateIsLastprivate =
759 Lastprivates.count(OrigVD->getCanonicalDecl()) > 0;
Alexey Bataev9afe5752016-05-24 07:40:12 +0000760 auto *CapFD = CapturesInfo.lookup(OrigVD);
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000761 auto *FD = CapturedStmtInfo->lookup(OrigVD);
Alexey Bataev9afe5752016-05-24 07:40:12 +0000762 if (!ThisFirstprivateIsLastprivate && FD && (FD == CapFD) &&
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000763 !FD->getType()->isReferenceType()) {
764 EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl());
765 ++IRef;
766 ++InitsRef;
767 continue;
768 }
Alexey Bataevcd8b6a22016-02-15 08:07:17 +0000769 FirstprivateIsLastprivate =
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000770 FirstprivateIsLastprivate || ThisFirstprivateIsLastprivate;
Alexey Bataevcd8b6a22016-02-15 08:07:17 +0000771 if (EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()).second) {
Alexey Bataev69c62a92015-04-15 04:52:20 +0000772 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
773 auto *VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
774 bool IsRegistered;
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000775 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),
776 /*RefersToEnclosingVariableOrCapture=*/FD != nullptr,
777 (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
John McCall7f416cc2015-09-08 08:05:57 +0000778 Address OriginalAddr = EmitLValue(&DRE).getAddress();
Alexey Bataevfeddd642016-04-22 09:05:03 +0000779 QualType Type = VD->getType();
Alexey Bataev1d9c15c2015-05-19 12:31:28 +0000780 if (Type->isArrayType()) {
Alexey Bataev69c62a92015-04-15 04:52:20 +0000781 // Emit VarDecl with copy init for arrays.
782 // Get the address of the original variable captured in current
783 // captured region.
John McCall7f416cc2015-09-08 08:05:57 +0000784 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address {
Alexey Bataev69c62a92015-04-15 04:52:20 +0000785 auto Emission = EmitAutoVarAlloca(*VD);
786 auto *Init = VD->getInit();
787 if (!isa<CXXConstructExpr>(Init) || isTrivialInitializer(Init)) {
788 // Perform simple memcpy.
789 EmitAggregateAssign(Emission.getAllocatedAddress(), OriginalAddr,
Alexey Bataev1d9c15c2015-05-19 12:31:28 +0000790 Type);
Alexey Bataev69c62a92015-04-15 04:52:20 +0000791 } else {
792 EmitOMPAggregateAssign(
Alexey Bataev1d9c15c2015-05-19 12:31:28 +0000793 Emission.getAllocatedAddress(), OriginalAddr, Type,
John McCall7f416cc2015-09-08 08:05:57 +0000794 [this, VDInit, Init](Address DestElement,
795 Address SrcElement) {
Alexey Bataev69c62a92015-04-15 04:52:20 +0000796 // Clean up any temporaries needed by the initialization.
797 RunCleanupsScope InitScope(*this);
798 // Emit initialization for single element.
John McCall7f416cc2015-09-08 08:05:57 +0000799 setAddrOfLocalVar(VDInit, SrcElement);
Alexey Bataev69c62a92015-04-15 04:52:20 +0000800 EmitAnyExprToMem(Init, DestElement,
801 Init->getType().getQualifiers(),
802 /*IsInitializer*/ false);
803 LocalDeclMap.erase(VDInit);
804 });
805 }
806 EmitAutoVarCleanups(Emission);
807 return Emission.getAllocatedAddress();
808 });
809 } else {
John McCall7f416cc2015-09-08 08:05:57 +0000810 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address {
Alexey Bataev69c62a92015-04-15 04:52:20 +0000811 // Emit private VarDecl with copy init.
812 // Remap temp VDInit variable to the address of the original
813 // variable
814 // (for proper handling of captured global variables).
John McCall7f416cc2015-09-08 08:05:57 +0000815 setAddrOfLocalVar(VDInit, OriginalAddr);
Alexey Bataev69c62a92015-04-15 04:52:20 +0000816 EmitDecl(*VD);
817 LocalDeclMap.erase(VDInit);
818 return GetAddrOfLocalVar(VD);
819 });
820 }
821 assert(IsRegistered &&
822 "firstprivate var already registered as private");
823 // Silence the warning about unused variable.
824 (void)IsRegistered;
825 }
Richard Trieucc3949d2016-02-18 22:34:54 +0000826 ++IRef;
827 ++InitsRef;
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000828 }
829 }
Alexey Bataevcd8b6a22016-02-15 08:07:17 +0000830 return FirstprivateIsLastprivate && !EmittedAsFirstprivate.empty();
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000831}
832
Alexey Bataev03b340a2014-10-21 03:16:40 +0000833void CodeGenFunction::EmitOMPPrivateClause(
834 const OMPExecutableDirective &D,
835 CodeGenFunction::OMPPrivateScope &PrivateScope) {
Alexey Bataev8ef31412015-12-18 07:58:25 +0000836 if (!HaveInsertPoint())
837 return;
Alexey Bataev50a64582015-04-22 12:24:45 +0000838 llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +0000839 for (const auto *C : D.getClausesOfKind<OMPPrivateClause>()) {
Alexey Bataev03b340a2014-10-21 03:16:40 +0000840 auto IRef = C->varlist_begin();
841 for (auto IInit : C->private_copies()) {
842 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataev50a64582015-04-22 12:24:45 +0000843 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
844 auto VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
845 bool IsRegistered =
John McCall7f416cc2015-09-08 08:05:57 +0000846 PrivateScope.addPrivate(OrigVD, [&]() -> Address {
Alexey Bataev50a64582015-04-22 12:24:45 +0000847 // Emit private VarDecl with copy init.
848 EmitDecl(*VD);
849 return GetAddrOfLocalVar(VD);
850 });
851 assert(IsRegistered && "private var already registered as private");
852 // Silence the warning about unused variable.
853 (void)IsRegistered;
854 }
Alexey Bataev03b340a2014-10-21 03:16:40 +0000855 ++IRef;
856 }
857 }
858}
859
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000860bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) {
Alexey Bataev8ef31412015-12-18 07:58:25 +0000861 if (!HaveInsertPoint())
862 return false;
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000863 // threadprivate_var1 = master_threadprivate_var1;
864 // operator=(threadprivate_var2, master_threadprivate_var2);
865 // ...
866 // __kmpc_barrier(&loc, global_tid);
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000867 llvm::DenseSet<const VarDecl *> CopiedVars;
868 llvm::BasicBlock *CopyBegin = nullptr, *CopyEnd = nullptr;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +0000869 for (const auto *C : D.getClausesOfKind<OMPCopyinClause>()) {
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000870 auto IRef = C->varlist_begin();
871 auto ISrcRef = C->source_exprs().begin();
872 auto IDestRef = C->destination_exprs().begin();
873 for (auto *AssignOp : C->assignment_ops()) {
874 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataev1d9c15c2015-05-19 12:31:28 +0000875 QualType Type = VD->getType();
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000876 if (CopiedVars.insert(VD->getCanonicalDecl()).second) {
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000877 // Get the address of the master variable. If we are emitting code with
878 // TLS support, the address is passed from the master as field in the
879 // captured declaration.
John McCall7f416cc2015-09-08 08:05:57 +0000880 Address MasterAddr = Address::invalid();
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000881 if (getLangOpts().OpenMPUseTLS &&
882 getContext().getTargetInfo().isTLSSupported()) {
883 assert(CapturedStmtInfo->lookup(VD) &&
884 "Copyin threadprivates should have been captured!");
885 DeclRefExpr DRE(const_cast<VarDecl *>(VD), true, (*IRef)->getType(),
886 VK_LValue, (*IRef)->getExprLoc());
887 MasterAddr = EmitLValue(&DRE).getAddress();
Alexey Bataev2377fe92015-09-10 08:12:02 +0000888 LocalDeclMap.erase(VD);
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000889 } else {
John McCall7f416cc2015-09-08 08:05:57 +0000890 MasterAddr =
891 Address(VD->isStaticLocal() ? CGM.getStaticLocalDeclAddress(VD)
892 : CGM.GetAddrOfGlobal(VD),
893 getContext().getDeclAlign(VD));
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000894 }
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000895 // Get the address of the threadprivate variable.
John McCall7f416cc2015-09-08 08:05:57 +0000896 Address PrivateAddr = EmitLValue(*IRef).getAddress();
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000897 if (CopiedVars.size() == 1) {
898 // At first check if current thread is a master thread. If it is, no
899 // need to copy data.
900 CopyBegin = createBasicBlock("copyin.not.master");
901 CopyEnd = createBasicBlock("copyin.not.master.end");
902 Builder.CreateCondBr(
903 Builder.CreateICmpNE(
John McCall7f416cc2015-09-08 08:05:57 +0000904 Builder.CreatePtrToInt(MasterAddr.getPointer(), CGM.IntPtrTy),
905 Builder.CreatePtrToInt(PrivateAddr.getPointer(), CGM.IntPtrTy)),
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000906 CopyBegin, CopyEnd);
907 EmitBlock(CopyBegin);
908 }
909 auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
910 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
John McCall7f416cc2015-09-08 08:05:57 +0000911 EmitOMPCopy(Type, PrivateAddr, MasterAddr, DestVD, SrcVD, AssignOp);
Alexey Bataevf56f98c2015-04-16 05:39:01 +0000912 }
913 ++IRef;
914 ++ISrcRef;
915 ++IDestRef;
916 }
917 }
918 if (CopyEnd) {
919 // Exit out of copying procedure for non-master thread.
920 EmitBlock(CopyEnd, /*IsFinished=*/true);
921 return true;
922 }
923 return false;
924}
925
Alexey Bataev38e89532015-04-16 04:54:05 +0000926bool CodeGenFunction::EmitOMPLastprivateClauseInit(
927 const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) {
Alexey Bataev8ef31412015-12-18 07:58:25 +0000928 if (!HaveInsertPoint())
929 return false;
Alexey Bataev38e89532015-04-16 04:54:05 +0000930 bool HasAtLeastOneLastprivate = false;
Alexey Bataev5dff95c2016-04-22 03:56:56 +0000931 llvm::DenseSet<const VarDecl *> SIMDLCVs;
932 if (isOpenMPSimdDirective(D.getDirectiveKind())) {
933 auto *LoopDirective = cast<OMPLoopDirective>(&D);
934 for (auto *C : LoopDirective->counters()) {
935 SIMDLCVs.insert(
936 cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl());
937 }
938 }
Alexey Bataev38e89532015-04-16 04:54:05 +0000939 llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +0000940 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
Alexey Bataevd130fd12015-05-13 10:23:02 +0000941 HasAtLeastOneLastprivate = true;
Alexey Bataevf93095a2016-05-05 08:46:22 +0000942 if (isOpenMPTaskLoopDirective(D.getDirectiveKind()))
943 break;
Alexey Bataev38e89532015-04-16 04:54:05 +0000944 auto IRef = C->varlist_begin();
945 auto IDestRef = C->destination_exprs().begin();
946 for (auto *IInit : C->private_copies()) {
947 // Keep the address of the original variable for future update at the end
948 // of the loop.
949 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
Alexey Bataevf93095a2016-05-05 08:46:22 +0000950 // Taskloops do not require additional initialization, it is done in
951 // runtime support library.
Alexey Bataev38e89532015-04-16 04:54:05 +0000952 if (AlreadyEmittedVars.insert(OrigVD->getCanonicalDecl()).second) {
953 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
John McCall7f416cc2015-09-08 08:05:57 +0000954 PrivateScope.addPrivate(DestVD, [this, OrigVD, IRef]() -> Address {
Alexey Bataev38e89532015-04-16 04:54:05 +0000955 DeclRefExpr DRE(
956 const_cast<VarDecl *>(OrigVD),
957 /*RefersToEnclosingVariableOrCapture=*/CapturedStmtInfo->lookup(
958 OrigVD) != nullptr,
959 (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
960 return EmitLValue(&DRE).getAddress();
961 });
962 // Check if the variable is also a firstprivate: in this case IInit is
963 // not generated. Initialization of this variable will happen in codegen
964 // for 'firstprivate' clause.
Alexey Bataev5dff95c2016-04-22 03:56:56 +0000965 if (IInit && !SIMDLCVs.count(OrigVD->getCanonicalDecl())) {
Alexey Bataevd130fd12015-05-13 10:23:02 +0000966 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
Alexey Bataevf93095a2016-05-05 08:46:22 +0000967 bool IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address {
968 // Emit private VarDecl with copy init.
969 EmitDecl(*VD);
970 return GetAddrOfLocalVar(VD);
971 });
Alexey Bataevd130fd12015-05-13 10:23:02 +0000972 assert(IsRegistered &&
973 "lastprivate var already registered as private");
974 (void)IsRegistered;
975 }
Alexey Bataev38e89532015-04-16 04:54:05 +0000976 }
Richard Trieucc3949d2016-02-18 22:34:54 +0000977 ++IRef;
978 ++IDestRef;
Alexey Bataev38e89532015-04-16 04:54:05 +0000979 }
980 }
981 return HasAtLeastOneLastprivate;
982}
983
984void CodeGenFunction::EmitOMPLastprivateClauseFinal(
Alexey Bataev5dff95c2016-04-22 03:56:56 +0000985 const OMPExecutableDirective &D, bool NoFinals,
986 llvm::Value *IsLastIterCond) {
Alexey Bataev8ef31412015-12-18 07:58:25 +0000987 if (!HaveInsertPoint())
988 return;
Alexey Bataev38e89532015-04-16 04:54:05 +0000989 // Emit following code:
990 // if (<IsLastIterCond>) {
991 // orig_var1 = private_orig_var1;
992 // ...
993 // orig_varn = private_orig_varn;
994 // }
Alexey Bataevfc087ec2015-06-16 13:14:42 +0000995 llvm::BasicBlock *ThenBB = nullptr;
996 llvm::BasicBlock *DoneBB = nullptr;
997 if (IsLastIterCond) {
998 ThenBB = createBasicBlock(".omp.lastprivate.then");
999 DoneBB = createBasicBlock(".omp.lastprivate.done");
1000 Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB);
1001 EmitBlock(ThenBB);
1002 }
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001003 llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
1004 llvm::DenseMap<const VarDecl *, const Expr *> LoopCountersAndUpdates;
Alexey Bataev7a228ff2015-05-21 07:59:51 +00001005 if (auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) {
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001006 auto IC = LoopDirective->counters().begin();
1007 for (auto F : LoopDirective->finals()) {
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001008 auto *D =
1009 cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl())->getCanonicalDecl();
1010 if (NoFinals)
1011 AlreadyEmittedVars.insert(D);
1012 else
1013 LoopCountersAndUpdates[D] = F;
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001014 ++IC;
Alexey Bataev7a228ff2015-05-21 07:59:51 +00001015 }
1016 }
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001017 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
1018 auto IRef = C->varlist_begin();
1019 auto ISrcRef = C->source_exprs().begin();
1020 auto IDestRef = C->destination_exprs().begin();
1021 for (auto *AssignOp : C->assignment_ops()) {
1022 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
1023 QualType Type = PrivateVD->getType();
1024 auto *CanonicalVD = PrivateVD->getCanonicalDecl();
1025 if (AlreadyEmittedVars.insert(CanonicalVD).second) {
1026 // If lastprivate variable is a loop control variable for loop-based
1027 // directive, update its value before copyin back to original
1028 // variable.
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001029 if (auto *FinalExpr = LoopCountersAndUpdates.lookup(CanonicalVD))
1030 EmitIgnoredExpr(FinalExpr);
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001031 auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
1032 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
1033 // Get the address of the original variable.
1034 Address OriginalAddr = GetAddrOfLocalVar(DestVD);
1035 // Get the address of the private variable.
1036 Address PrivateAddr = GetAddrOfLocalVar(PrivateVD);
1037 if (auto RefTy = PrivateVD->getType()->getAs<ReferenceType>())
1038 PrivateAddr =
John McCall7f416cc2015-09-08 08:05:57 +00001039 Address(Builder.CreateLoad(PrivateAddr),
1040 getNaturalTypeAlignment(RefTy->getPointeeType()));
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001041 EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp);
Alexey Bataev38e89532015-04-16 04:54:05 +00001042 }
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001043 ++IRef;
1044 ++ISrcRef;
1045 ++IDestRef;
Alexey Bataev38e89532015-04-16 04:54:05 +00001046 }
Alexey Bataev005248a2016-02-25 05:25:57 +00001047 if (auto *PostUpdate = C->getPostUpdateExpr())
1048 EmitIgnoredExpr(PostUpdate);
Alexey Bataev38e89532015-04-16 04:54:05 +00001049 }
Alexey Bataev8ffcc942016-02-18 13:48:15 +00001050 if (IsLastIterCond)
Alexey Bataevfc087ec2015-06-16 13:14:42 +00001051 EmitBlock(DoneBB, /*IsFinished=*/true);
Alexey Bataev38e89532015-04-16 04:54:05 +00001052}
1053
Alexey Bataev31300ed2016-02-04 11:27:03 +00001054static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
1055 LValue BaseLV, llvm::Value *Addr) {
1056 Address Tmp = Address::invalid();
1057 Address TopTmp = Address::invalid();
1058 Address MostTopTmp = Address::invalid();
1059 BaseTy = BaseTy.getNonReferenceType();
1060 while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
1061 !CGF.getContext().hasSameType(BaseTy, ElTy)) {
1062 Tmp = CGF.CreateMemTemp(BaseTy);
1063 if (TopTmp.isValid())
1064 CGF.Builder.CreateStore(Tmp.getPointer(), TopTmp);
1065 else
1066 MostTopTmp = Tmp;
1067 TopTmp = Tmp;
1068 BaseTy = BaseTy->getPointeeType();
1069 }
1070 llvm::Type *Ty = BaseLV.getPointer()->getType();
1071 if (Tmp.isValid())
1072 Ty = Tmp.getElementType();
1073 Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Ty);
1074 if (Tmp.isValid()) {
1075 CGF.Builder.CreateStore(Addr, Tmp);
1076 return MostTopTmp;
1077 }
1078 return Address(Addr, BaseLV.getAlignment());
1079}
1080
1081static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
1082 LValue BaseLV) {
1083 BaseTy = BaseTy.getNonReferenceType();
1084 while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
1085 !CGF.getContext().hasSameType(BaseTy, ElTy)) {
1086 if (auto *PtrTy = BaseTy->getAs<PointerType>())
1087 BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(), PtrTy);
1088 else {
1089 BaseLV = CGF.EmitLoadOfReferenceLValue(BaseLV.getAddress(),
1090 BaseTy->castAs<ReferenceType>());
1091 }
1092 BaseTy = BaseTy->getPointeeType();
1093 }
1094 return CGF.MakeAddrLValue(
1095 Address(
1096 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
1097 BaseLV.getPointer(), CGF.ConvertTypeForMem(ElTy)->getPointerTo()),
1098 BaseLV.getAlignment()),
Krzysztof Parzyszek8f248232017-05-18 17:07:11 +00001099 BaseLV.getType(), BaseLV.getBaseInfo());
Alexey Bataev31300ed2016-02-04 11:27:03 +00001100}
1101
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001102void CodeGenFunction::EmitOMPReductionClauseInit(
1103 const OMPExecutableDirective &D,
1104 CodeGenFunction::OMPPrivateScope &PrivateScope) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001105 if (!HaveInsertPoint())
1106 return;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001107 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001108 auto ILHS = C->lhs_exprs().begin();
1109 auto IRHS = C->rhs_exprs().begin();
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001110 auto IPriv = C->privates().begin();
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001111 auto IRed = C->reduction_ops().begin();
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001112 for (auto IRef : C->varlists()) {
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001113 auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001114 auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
1115 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl());
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001116 auto *DRD = getReductionInit(*IRed);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001117 if (auto *OASE = dyn_cast<OMPArraySectionExpr>(IRef)) {
1118 auto *Base = OASE->getBase()->IgnoreParenImpCasts();
1119 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
1120 Base = TempOASE->getBase()->IgnoreParenImpCasts();
1121 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
1122 Base = TempASE->getBase()->IgnoreParenImpCasts();
1123 auto *DE = cast<DeclRefExpr>(Base);
1124 auto *OrigVD = cast<VarDecl>(DE->getDecl());
1125 auto OASELValueLB = EmitOMPArraySectionExpr(OASE);
1126 auto OASELValueUB =
1127 EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false);
1128 auto OriginalBaseLValue = EmitLValue(DE);
Alexey Bataev31300ed2016-02-04 11:27:03 +00001129 LValue BaseLValue =
1130 loadToBegin(*this, OrigVD->getType(), OASELValueLB.getType(),
1131 OriginalBaseLValue);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001132 // Store the address of the original variable associated with the LHS
1133 // implicit variable.
Malcolm Parsonsc6e45832017-01-13 18:55:32 +00001134 PrivateScope.addPrivate(LHSVD, [OASELValueLB]() -> Address {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001135 return OASELValueLB.getAddress();
1136 });
1137 // Emit reduction copy.
1138 bool IsRegistered = PrivateScope.addPrivate(
Alexey Bataev31300ed2016-02-04 11:27:03 +00001139 OrigVD, [this, OrigVD, PrivateVD, BaseLValue, OASELValueLB,
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001140 OASELValueUB, OriginalBaseLValue, DRD, IRed]() -> Address {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001141 // Emit VarDecl with copy init for arrays.
1142 // Get the address of the original variable captured in current
1143 // captured region.
1144 auto *Size = Builder.CreatePtrDiff(OASELValueUB.getPointer(),
1145 OASELValueLB.getPointer());
1146 Size = Builder.CreateNUWAdd(
1147 Size, llvm::ConstantInt::get(Size->getType(), /*V=*/1));
1148 CodeGenFunction::OpaqueValueMapping OpaqueMap(
1149 *this, cast<OpaqueValueExpr>(
1150 getContext()
1151 .getAsVariableArrayType(PrivateVD->getType())
1152 ->getSizeExpr()),
1153 RValue::get(Size));
1154 EmitVariablyModifiedType(PrivateVD->getType());
1155 auto Emission = EmitAutoVarAlloca(*PrivateVD);
1156 auto Addr = Emission.getAllocatedAddress();
1157 auto *Init = PrivateVD->getInit();
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001158 EmitOMPAggregateInit(*this, Addr, PrivateVD->getType(),
1159 DRD ? *IRed : Init,
1160 OASELValueLB.getAddress());
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001161 EmitAutoVarCleanups(Emission);
1162 // Emit private VarDecl with reduction init.
1163 auto *Offset = Builder.CreatePtrDiff(BaseLValue.getPointer(),
1164 OASELValueLB.getPointer());
1165 auto *Ptr = Builder.CreateGEP(Addr.getPointer(), Offset);
Alexey Bataev31300ed2016-02-04 11:27:03 +00001166 return castToBase(*this, OrigVD->getType(),
1167 OASELValueLB.getType(), OriginalBaseLValue,
1168 Ptr);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001169 });
1170 assert(IsRegistered && "private var already registered as private");
1171 // Silence the warning about unused variable.
1172 (void)IsRegistered;
1173 PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address {
1174 return GetAddrOfLocalVar(PrivateVD);
1175 });
1176 } else if (auto *ASE = dyn_cast<ArraySubscriptExpr>(IRef)) {
1177 auto *Base = ASE->getBase()->IgnoreParenImpCasts();
1178 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
1179 Base = TempASE->getBase()->IgnoreParenImpCasts();
1180 auto *DE = cast<DeclRefExpr>(Base);
1181 auto *OrigVD = cast<VarDecl>(DE->getDecl());
1182 auto ASELValue = EmitLValue(ASE);
1183 auto OriginalBaseLValue = EmitLValue(DE);
Alexey Bataev31300ed2016-02-04 11:27:03 +00001184 LValue BaseLValue = loadToBegin(
1185 *this, OrigVD->getType(), ASELValue.getType(), OriginalBaseLValue);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001186 // Store the address of the original variable associated with the LHS
1187 // implicit variable.
Malcolm Parsonsc6e45832017-01-13 18:55:32 +00001188 PrivateScope.addPrivate(
1189 LHSVD, [ASELValue]() -> Address { return ASELValue.getAddress(); });
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001190 // Emit reduction copy.
1191 bool IsRegistered = PrivateScope.addPrivate(
Alexey Bataev31300ed2016-02-04 11:27:03 +00001192 OrigVD, [this, OrigVD, PrivateVD, BaseLValue, ASELValue,
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001193 OriginalBaseLValue, DRD, IRed]() -> Address {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001194 // Emit private VarDecl with reduction init.
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001195 AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD);
1196 auto Addr = Emission.getAllocatedAddress();
Alexey Bataev8fbae8cf2016-04-27 11:38:05 +00001197 if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001198 emitInitWithReductionInitializer(*this, DRD, *IRed, Addr,
1199 ASELValue.getAddress(),
1200 ASELValue.getType());
1201 } else
1202 EmitAutoVarInit(Emission);
1203 EmitAutoVarCleanups(Emission);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001204 auto *Offset = Builder.CreatePtrDiff(BaseLValue.getPointer(),
1205 ASELValue.getPointer());
1206 auto *Ptr = Builder.CreateGEP(Addr.getPointer(), Offset);
Alexey Bataev31300ed2016-02-04 11:27:03 +00001207 return castToBase(*this, OrigVD->getType(), ASELValue.getType(),
1208 OriginalBaseLValue, Ptr);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001209 });
1210 assert(IsRegistered && "private var already registered as private");
1211 // Silence the warning about unused variable.
1212 (void)IsRegistered;
Alexey Bataev1189bd02016-01-26 12:20:39 +00001213 PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() -> Address {
1214 return Builder.CreateElementBitCast(
1215 GetAddrOfLocalVar(PrivateVD), ConvertTypeForMem(RHSVD->getType()),
1216 "rhs.begin");
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001217 });
1218 } else {
1219 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl());
Alexey Bataev1189bd02016-01-26 12:20:39 +00001220 QualType Type = PrivateVD->getType();
1221 if (getContext().getAsArrayType(Type)) {
1222 // Store the address of the original variable associated with the LHS
1223 // implicit variable.
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001224 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),
1225 CapturedStmtInfo->lookup(OrigVD) != nullptr,
1226 IRef->getType(), VK_LValue, IRef->getExprLoc());
Alexey Bataev1189bd02016-01-26 12:20:39 +00001227 Address OriginalAddr = EmitLValue(&DRE).getAddress();
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001228 PrivateScope.addPrivate(LHSVD, [this, &OriginalAddr,
Alexey Bataev1189bd02016-01-26 12:20:39 +00001229 LHSVD]() -> Address {
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001230 OriginalAddr = Builder.CreateElementBitCast(
1231 OriginalAddr, ConvertTypeForMem(LHSVD->getType()), "lhs.begin");
1232 return OriginalAddr;
Alexey Bataev1189bd02016-01-26 12:20:39 +00001233 });
1234 bool IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address {
1235 if (Type->isVariablyModifiedType()) {
1236 CodeGenFunction::OpaqueValueMapping OpaqueMap(
1237 *this, cast<OpaqueValueExpr>(
1238 getContext()
1239 .getAsVariableArrayType(PrivateVD->getType())
1240 ->getSizeExpr()),
1241 RValue::get(
1242 getTypeSize(OrigVD->getType().getNonReferenceType())));
1243 EmitVariablyModifiedType(Type);
1244 }
1245 auto Emission = EmitAutoVarAlloca(*PrivateVD);
1246 auto Addr = Emission.getAllocatedAddress();
1247 auto *Init = PrivateVD->getInit();
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001248 EmitOMPAggregateInit(*this, Addr, PrivateVD->getType(),
1249 DRD ? *IRed : Init, OriginalAddr);
Alexey Bataev1189bd02016-01-26 12:20:39 +00001250 EmitAutoVarCleanups(Emission);
1251 return Emission.getAllocatedAddress();
1252 });
1253 assert(IsRegistered && "private var already registered as private");
1254 // Silence the warning about unused variable.
1255 (void)IsRegistered;
1256 PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() -> Address {
1257 return Builder.CreateElementBitCast(
1258 GetAddrOfLocalVar(PrivateVD),
1259 ConvertTypeForMem(RHSVD->getType()), "rhs.begin");
1260 });
1261 } else {
1262 // Store the address of the original variable associated with the LHS
1263 // implicit variable.
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001264 Address OriginalAddr = Address::invalid();
1265 PrivateScope.addPrivate(LHSVD, [this, OrigVD, IRef,
1266 &OriginalAddr]() -> Address {
Alexey Bataev1189bd02016-01-26 12:20:39 +00001267 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),
1268 CapturedStmtInfo->lookup(OrigVD) != nullptr,
1269 IRef->getType(), VK_LValue, IRef->getExprLoc());
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001270 OriginalAddr = EmitLValue(&DRE).getAddress();
1271 return OriginalAddr;
Alexey Bataev1189bd02016-01-26 12:20:39 +00001272 });
1273 // Emit reduction copy.
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001274 bool IsRegistered = PrivateScope.addPrivate(
1275 OrigVD, [this, PrivateVD, OriginalAddr, DRD, IRed]() -> Address {
Alexey Bataev1189bd02016-01-26 12:20:39 +00001276 // Emit private VarDecl with reduction init.
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001277 AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD);
1278 auto Addr = Emission.getAllocatedAddress();
Alexey Bataev8fbae8cf2016-04-27 11:38:05 +00001279 if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001280 emitInitWithReductionInitializer(*this, DRD, *IRed, Addr,
1281 OriginalAddr,
1282 PrivateVD->getType());
1283 } else
1284 EmitAutoVarInit(Emission);
1285 EmitAutoVarCleanups(Emission);
1286 return Addr;
Alexey Bataev1189bd02016-01-26 12:20:39 +00001287 });
1288 assert(IsRegistered && "private var already registered as private");
1289 // Silence the warning about unused variable.
1290 (void)IsRegistered;
1291 PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address {
1292 return GetAddrOfLocalVar(PrivateVD);
1293 });
1294 }
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001295 }
Richard Trieucc3949d2016-02-18 22:34:54 +00001296 ++ILHS;
1297 ++IRHS;
1298 ++IPriv;
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001299 ++IRed;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001300 }
1301 }
1302}
1303
1304void CodeGenFunction::EmitOMPReductionClauseFinal(
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001305 const OMPExecutableDirective &D, const OpenMPDirectiveKind ReductionKind) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001306 if (!HaveInsertPoint())
1307 return;
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001308 llvm::SmallVector<const Expr *, 8> Privates;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001309 llvm::SmallVector<const Expr *, 8> LHSExprs;
1310 llvm::SmallVector<const Expr *, 8> RHSExprs;
1311 llvm::SmallVector<const Expr *, 8> ReductionOps;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001312 bool HasAtLeastOneReduction = false;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001313 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001314 HasAtLeastOneReduction = true;
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001315 Privates.append(C->privates().begin(), C->privates().end());
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001316 LHSExprs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
1317 RHSExprs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
1318 ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
1319 }
1320 if (HasAtLeastOneReduction) {
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001321 bool WithNowait = D.getSingleClause<OMPNowaitClause>() ||
1322 isOpenMPParallelDirective(D.getDirectiveKind()) ||
1323 D.getDirectiveKind() == OMPD_simd;
1324 bool SimpleReduction = D.getDirectiveKind() == OMPD_simd;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001325 // Emit nowait reduction if nowait clause is present or directive is a
1326 // parallel directive (it always has implicit barrier).
1327 CGM.getOpenMPRuntime().emitReduction(
Alexey Bataevf24e7b12015-10-08 09:10:53 +00001328 *this, D.getLocEnd(), Privates, LHSExprs, RHSExprs, ReductionOps,
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001329 {WithNowait, SimpleReduction, ReductionKind});
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001330 }
1331}
1332
Alexey Bataev61205072016-03-02 04:57:40 +00001333static void emitPostUpdateForReductionClause(
1334 CodeGenFunction &CGF, const OMPExecutableDirective &D,
1335 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen) {
1336 if (!CGF.HaveInsertPoint())
1337 return;
1338 llvm::BasicBlock *DoneBB = nullptr;
1339 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
1340 if (auto *PostUpdate = C->getPostUpdateExpr()) {
1341 if (!DoneBB) {
1342 if (auto *Cond = CondGen(CGF)) {
1343 // If the first post-update expression is found, emit conditional
1344 // block if it was requested.
1345 auto *ThenBB = CGF.createBasicBlock(".omp.reduction.pu");
1346 DoneBB = CGF.createBasicBlock(".omp.reduction.pu.done");
1347 CGF.Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1348 CGF.EmitBlock(ThenBB);
1349 }
1350 }
1351 CGF.EmitIgnoredExpr(PostUpdate);
1352 }
1353 }
1354 if (DoneBB)
1355 CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
1356}
1357
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001358namespace {
1359/// Codegen lambda for appending distribute lower and upper bounds to outlined
1360/// parallel function. This is necessary for combined constructs such as
1361/// 'distribute parallel for'
1362typedef llvm::function_ref<void(CodeGenFunction &,
1363 const OMPExecutableDirective &,
1364 llvm::SmallVectorImpl<llvm::Value *> &)>
1365 CodeGenBoundParametersTy;
1366} // anonymous namespace
1367
1368static void emitCommonOMPParallelDirective(
1369 CodeGenFunction &CGF, const OMPExecutableDirective &S,
1370 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
1371 const CodeGenBoundParametersTy &CodeGenBoundParameters) {
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00001372 const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel);
1373 auto OutlinedFn = CGF.CGM.getOpenMPRuntime().emitParallelOutlinedFunction(
1374 S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001375 if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>()) {
Alexey Bataev1d677132015-04-22 13:57:31 +00001376 CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
Alexey Bataev1d677132015-04-22 13:57:31 +00001377 auto NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(),
1378 /*IgnoreResultAssign*/ true);
1379 CGF.CGM.getOpenMPRuntime().emitNumThreadsClause(
1380 CGF, NumThreads, NumThreadsClause->getLocStart());
1381 }
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001382 if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>()) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001383 CodeGenFunction::RunCleanupsScope ProcBindScope(CGF);
Alexey Bataev7f210c62015-06-18 13:40:03 +00001384 CGF.CGM.getOpenMPRuntime().emitProcBindClause(
1385 CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getLocStart());
1386 }
Alexey Bataev1d677132015-04-22 13:57:31 +00001387 const Expr *IfCond = nullptr;
Alexey Bataev7371aa32015-09-03 08:45:56 +00001388 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
1389 if (C->getNameModifier() == OMPD_unknown ||
1390 C->getNameModifier() == OMPD_parallel) {
1391 IfCond = C->getCondition();
1392 break;
1393 }
Alexey Bataev1d677132015-04-22 13:57:31 +00001394 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001395
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00001396 OMPParallelScope Scope(CGF, S);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001397 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001398 // Combining 'distribute' with 'for' requires sharing each 'distribute' chunk
1399 // lower and upper bounds with the pragma 'for' chunking mechanism.
1400 // The following lambda takes care of appending the lower and upper bound
1401 // parameters when necessary
1402 CodeGenBoundParameters(CGF, S, CapturedVars);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001403 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
Alexey Bataev1d677132015-04-22 13:57:31 +00001404 CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getLocStart(), OutlinedFn,
Alexey Bataev2377fe92015-09-10 08:12:02 +00001405 CapturedVars, IfCond);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001406}
1407
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001408static void emitEmptyBoundParameters(CodeGenFunction &,
1409 const OMPExecutableDirective &,
1410 llvm::SmallVectorImpl<llvm::Value *> &) {}
1411
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001412void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001413 // Emit parallel region as a standalone region.
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001414 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001415 OMPPrivateScope PrivateScope(CGF);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00001416 bool Copyins = CGF.EmitOMPCopyinClause(S);
Alexey Bataevcd8b6a22016-02-15 08:07:17 +00001417 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
1418 if (Copyins) {
Alexey Bataev69c62a92015-04-15 04:52:20 +00001419 // Emit implicit barrier to synchronize threads and avoid data races on
Alexey Bataevcd8b6a22016-02-15 08:07:17 +00001420 // propagation master's thread values of threadprivate variables to local
1421 // instances of that variables of all other implicit threads.
Alexey Bataev25e5b442015-09-15 12:52:43 +00001422 CGF.CGM.getOpenMPRuntime().emitBarrierCall(
1423 CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
1424 /*ForceSimpleCall=*/true);
Alexey Bataev69c62a92015-04-15 04:52:20 +00001425 }
1426 CGF.EmitOMPPrivateClause(S, PrivateScope);
1427 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
1428 (void)PrivateScope.Privatize();
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001429 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001430 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001431 };
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001432 emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen,
1433 emitEmptyBoundParameters);
Alexey Bataev61205072016-03-02 04:57:40 +00001434 emitPostUpdateForReductionClause(
1435 *this, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
Alexey Bataev9959db52014-05-06 10:08:46 +00001436}
Alexander Musman515ad8c2014-05-22 08:54:05 +00001437
Alexey Bataev0f34da12015-07-02 04:17:07 +00001438void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D,
1439 JumpDest LoopExit) {
Alexander Musmana5f070a2014-10-01 06:03:56 +00001440 RunCleanupsScope BodyScope(*this);
1441 // Update counters values on current iteration.
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001442 for (auto I : D.updates()) {
Alexander Musmana5f070a2014-10-01 06:03:56 +00001443 EmitIgnoredExpr(I);
1444 }
Alexander Musman3276a272015-03-21 10:12:56 +00001445 // Update the linear variables.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001446 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001447 for (auto *U : C->updates())
Alexander Musman3276a272015-03-21 10:12:56 +00001448 EmitIgnoredExpr(U);
Alexander Musman3276a272015-03-21 10:12:56 +00001449 }
1450
Alexander Musmana5f070a2014-10-01 06:03:56 +00001451 // On a continue in the body, jump to the end.
Alexander Musmand196ef22014-10-07 08:57:09 +00001452 auto Continue = getJumpDestInCurrentScope("omp.body.continue");
Alexey Bataev0f34da12015-07-02 04:17:07 +00001453 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
Alexander Musmana5f070a2014-10-01 06:03:56 +00001454 // Emit loop body.
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001455 EmitStmt(D.getBody());
Alexander Musmana5f070a2014-10-01 06:03:56 +00001456 // The end (updates/cleanups).
1457 EmitBlock(Continue.getBlock());
1458 BreakContinueStack.pop_back();
Alexander Musmana5f070a2014-10-01 06:03:56 +00001459}
1460
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001461void CodeGenFunction::EmitOMPInnerLoop(
1462 const Stmt &S, bool RequiresCleanup, const Expr *LoopCond,
1463 const Expr *IncExpr,
Alexey Bataev98eb6e32015-04-22 11:15:40 +00001464 const llvm::function_ref<void(CodeGenFunction &)> &BodyGen,
1465 const llvm::function_ref<void(CodeGenFunction &)> &PostIncGen) {
Alexander Musmand196ef22014-10-07 08:57:09 +00001466 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
Alexander Musmana5f070a2014-10-01 06:03:56 +00001467
1468 // Start the loop with a block that tests the condition.
Alexander Musmand196ef22014-10-07 08:57:09 +00001469 auto CondBlock = createBasicBlock("omp.inner.for.cond");
Alexander Musmana5f070a2014-10-01 06:03:56 +00001470 EmitBlock(CondBlock);
Amara Emerson652795d2016-11-10 14:44:30 +00001471 const SourceRange &R = S.getSourceRange();
1472 LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()),
1473 SourceLocToDebugLoc(R.getEnd()));
Alexander Musmana5f070a2014-10-01 06:03:56 +00001474
1475 // If there are any cleanups between here and the loop-exit scope,
1476 // create a block to stage a loop exit along.
1477 auto ExitBlock = LoopExit.getBlock();
Alexey Bataev2df54a02015-03-12 08:53:29 +00001478 if (RequiresCleanup)
Alexander Musmand196ef22014-10-07 08:57:09 +00001479 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
Alexander Musmana5f070a2014-10-01 06:03:56 +00001480
Alexander Musmand196ef22014-10-07 08:57:09 +00001481 auto LoopBody = createBasicBlock("omp.inner.for.body");
Alexander Musmana5f070a2014-10-01 06:03:56 +00001482
Alexey Bataev2df54a02015-03-12 08:53:29 +00001483 // Emit condition.
Justin Bogner66242d62015-04-23 23:06:47 +00001484 EmitBranchOnBoolExpr(LoopCond, LoopBody, ExitBlock, getProfileCount(&S));
Alexander Musmana5f070a2014-10-01 06:03:56 +00001485 if (ExitBlock != LoopExit.getBlock()) {
1486 EmitBlock(ExitBlock);
1487 EmitBranchThroughCleanup(LoopExit);
1488 }
1489
1490 EmitBlock(LoopBody);
Justin Bogner66242d62015-04-23 23:06:47 +00001491 incrementProfileCounter(&S);
Alexander Musmana5f070a2014-10-01 06:03:56 +00001492
1493 // Create a block for the increment.
Alexander Musmand196ef22014-10-07 08:57:09 +00001494 auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
Alexander Musmana5f070a2014-10-01 06:03:56 +00001495 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1496
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001497 BodyGen(*this);
Alexander Musmana5f070a2014-10-01 06:03:56 +00001498
1499 // Emit "IV = IV + 1" and a back-edge to the condition block.
1500 EmitBlock(Continue.getBlock());
Alexey Bataev2df54a02015-03-12 08:53:29 +00001501 EmitIgnoredExpr(IncExpr);
Alexey Bataev98eb6e32015-04-22 11:15:40 +00001502 PostIncGen(*this);
Alexander Musmana5f070a2014-10-01 06:03:56 +00001503 BreakContinueStack.pop_back();
1504 EmitBranch(CondBlock);
1505 LoopStack.pop();
1506 // Emit the fall-through block.
1507 EmitBlock(LoopExit.getBlock());
1508}
1509
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00001510void CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001511 if (!HaveInsertPoint())
1512 return;
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001513 // Emit inits for the linear variables.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001514 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001515 for (auto *Init : C->inits()) {
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001516 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl());
Alexey Bataevef549a82016-03-09 09:49:09 +00001517 if (auto *Ref = dyn_cast<DeclRefExpr>(VD->getInit()->IgnoreImpCasts())) {
1518 AutoVarEmission Emission = EmitAutoVarAlloca(*VD);
1519 auto *OrigVD = cast<VarDecl>(Ref->getDecl());
1520 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),
1521 CapturedStmtInfo->lookup(OrigVD) != nullptr,
1522 VD->getInit()->getType(), VK_LValue,
1523 VD->getInit()->getExprLoc());
1524 EmitExprAsInit(&DRE, VD, MakeAddrLValue(Emission.getAllocatedAddress(),
1525 VD->getType()),
1526 /*capturedByInit=*/false);
1527 EmitAutoVarCleanups(Emission);
1528 } else
1529 EmitVarDecl(*VD);
Alexander Musmana5f070a2014-10-01 06:03:56 +00001530 }
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001531 // Emit the linear steps for the linear clauses.
1532 // If a step is not constant, it is pre-calculated before the loop.
1533 if (auto CS = cast_or_null<BinaryOperator>(C->getCalcStep()))
1534 if (auto SaveRef = cast<DeclRefExpr>(CS->getLHS())) {
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00001535 EmitVarDecl(*cast<VarDecl>(SaveRef->getDecl()));
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001536 // Emit calculation of the linear step.
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00001537 EmitIgnoredExpr(CS);
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001538 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00001539 }
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001540}
1541
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001542void CodeGenFunction::EmitOMPLinearClauseFinal(
1543 const OMPLoopDirective &D,
Alexey Bataevef549a82016-03-09 09:49:09 +00001544 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen) {
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001545 if (!HaveInsertPoint())
Alexey Bataev8ef31412015-12-18 07:58:25 +00001546 return;
Alexey Bataevef549a82016-03-09 09:49:09 +00001547 llvm::BasicBlock *DoneBB = nullptr;
Alexander Musman3276a272015-03-21 10:12:56 +00001548 // Emit the final values of the linear variables.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001549 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
Alexey Bataev39f915b82015-05-08 10:41:21 +00001550 auto IC = C->varlist_begin();
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001551 for (auto *F : C->finals()) {
Alexey Bataevef549a82016-03-09 09:49:09 +00001552 if (!DoneBB) {
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001553 if (auto *Cond = CondGen(*this)) {
Alexey Bataevef549a82016-03-09 09:49:09 +00001554 // If the first post-update expression is found, emit conditional
1555 // block if it was requested.
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001556 auto *ThenBB = createBasicBlock(".omp.linear.pu");
1557 DoneBB = createBasicBlock(".omp.linear.pu.done");
1558 Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1559 EmitBlock(ThenBB);
Alexey Bataevef549a82016-03-09 09:49:09 +00001560 }
1561 }
Alexey Bataev39f915b82015-05-08 10:41:21 +00001562 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl());
1563 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001564 CapturedStmtInfo->lookup(OrigVD) != nullptr,
Alexey Bataev39f915b82015-05-08 10:41:21 +00001565 (*IC)->getType(), VK_LValue, (*IC)->getExprLoc());
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001566 Address OrigAddr = EmitLValue(&DRE).getAddress();
1567 CodeGenFunction::OMPPrivateScope VarScope(*this);
1568 VarScope.addPrivate(OrigVD, [OrigAddr]() -> Address { return OrigAddr; });
Alexey Bataev39f915b82015-05-08 10:41:21 +00001569 (void)VarScope.Privatize();
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001570 EmitIgnoredExpr(F);
Alexey Bataev39f915b82015-05-08 10:41:21 +00001571 ++IC;
Alexander Musman3276a272015-03-21 10:12:56 +00001572 }
Alexey Bataev78849fb2016-03-09 09:49:00 +00001573 if (auto *PostUpdate = C->getPostUpdateExpr())
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001574 EmitIgnoredExpr(PostUpdate);
Alexander Musman3276a272015-03-21 10:12:56 +00001575 }
Alexey Bataevef549a82016-03-09 09:49:09 +00001576 if (DoneBB)
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001577 EmitBlock(DoneBB, /*IsFinished=*/true);
Alexander Musmana5f070a2014-10-01 06:03:56 +00001578}
1579
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001580static void emitAlignedClause(CodeGenFunction &CGF,
1581 const OMPExecutableDirective &D) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001582 if (!CGF.HaveInsertPoint())
1583 return;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001584 for (const auto *Clause : D.getClausesOfKind<OMPAlignedClause>()) {
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001585 unsigned ClauseAlignment = 0;
1586 if (auto AlignmentExpr = Clause->getAlignment()) {
1587 auto AlignmentCI =
1588 cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
1589 ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue());
Alexander Musman09184fe2014-09-30 05:29:28 +00001590 }
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001591 for (auto E : Clause->varlists()) {
1592 unsigned Alignment = ClauseAlignment;
1593 if (Alignment == 0) {
1594 // OpenMP [2.8.1, Description]
1595 // If no optional parameter is specified, implementation-defined default
1596 // alignments for SIMD instructions on the target platforms are assumed.
1597 Alignment =
Alexey Bataev00396512015-07-02 03:40:19 +00001598 CGF.getContext()
1599 .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign(
1600 E->getType()->getPointeeType()))
1601 .getQuantity();
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001602 }
1603 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
1604 "alignment is not power of 2");
1605 if (Alignment != 0) {
1606 llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
1607 CGF.EmitAlignmentAssumption(PtrValue, Alignment);
1608 }
Alexander Musman09184fe2014-09-30 05:29:28 +00001609 }
1610 }
1611}
1612
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001613void CodeGenFunction::EmitOMPPrivateLoopCounters(
1614 const OMPLoopDirective &S, CodeGenFunction::OMPPrivateScope &LoopScope) {
1615 if (!HaveInsertPoint())
Alexey Bataev8ef31412015-12-18 07:58:25 +00001616 return;
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001617 auto I = S.private_counters().begin();
1618 for (auto *E : S.counters()) {
Alexey Bataeva8899172015-08-06 12:30:57 +00001619 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
1620 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl());
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001621 (void)LoopScope.addPrivate(VD, [&]() -> Address {
Alexey Bataev435ad7b2014-10-10 09:48:26 +00001622 // Emit var without initialization.
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001623 if (!LocalDeclMap.count(PrivateVD)) {
1624 auto VarEmission = EmitAutoVarAlloca(*PrivateVD);
1625 EmitAutoVarCleanups(VarEmission);
1626 }
1627 DeclRefExpr DRE(const_cast<VarDecl *>(PrivateVD),
1628 /*RefersToEnclosingVariableOrCapture=*/false,
1629 (*I)->getType(), VK_LValue, (*I)->getExprLoc());
1630 return EmitLValue(&DRE).getAddress();
Alexey Bataev435ad7b2014-10-10 09:48:26 +00001631 });
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001632 if (LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD) ||
1633 VD->hasGlobalStorage()) {
1634 (void)LoopScope.addPrivate(PrivateVD, [&]() -> Address {
1635 DeclRefExpr DRE(const_cast<VarDecl *>(VD),
1636 LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD),
1637 E->getType(), VK_LValue, E->getExprLoc());
1638 return EmitLValue(&DRE).getAddress();
1639 });
1640 }
Alexey Bataeva8899172015-08-06 12:30:57 +00001641 ++I;
Alexey Bataev435ad7b2014-10-10 09:48:26 +00001642 }
Alexey Bataev435ad7b2014-10-10 09:48:26 +00001643}
1644
Alexey Bataev62dbb972015-04-22 11:59:37 +00001645static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S,
1646 const Expr *Cond, llvm::BasicBlock *TrueBlock,
1647 llvm::BasicBlock *FalseBlock, uint64_t TrueCount) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001648 if (!CGF.HaveInsertPoint())
1649 return;
Alexey Bataev6e8248f2015-06-11 10:53:56 +00001650 {
1651 CodeGenFunction::OMPPrivateScope PreCondScope(CGF);
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001652 CGF.EmitOMPPrivateLoopCounters(S, PreCondScope);
Alexey Bataev6e8248f2015-06-11 10:53:56 +00001653 (void)PreCondScope.Privatize();
Alexey Bataev6e8248f2015-06-11 10:53:56 +00001654 // Get initial values of real counters.
Alexey Bataevb08f89f2015-08-14 12:25:37 +00001655 for (auto I : S.inits()) {
Alexey Bataev6e8248f2015-06-11 10:53:56 +00001656 CGF.EmitIgnoredExpr(I);
1657 }
Alexey Bataev62dbb972015-04-22 11:59:37 +00001658 }
1659 // Check that loop is executed at least one time.
1660 CGF.EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount);
1661}
1662
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001663void CodeGenFunction::EmitOMPLinearClause(
1664 const OMPLoopDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) {
1665 if (!HaveInsertPoint())
Alexey Bataev8ef31412015-12-18 07:58:25 +00001666 return;
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001667 llvm::DenseSet<const VarDecl *> SIMDLCVs;
1668 if (isOpenMPSimdDirective(D.getDirectiveKind())) {
1669 auto *LoopDirective = cast<OMPLoopDirective>(&D);
1670 for (auto *C : LoopDirective->counters()) {
1671 SIMDLCVs.insert(
1672 cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl());
1673 }
1674 }
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001675 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
Alexey Bataevbd9fec12015-08-18 06:47:21 +00001676 auto CurPrivate = C->privates().begin();
Alexey Bataevc925aa32015-04-27 08:00:32 +00001677 for (auto *E : C->varlists()) {
Alexey Bataevbd9fec12015-08-18 06:47:21 +00001678 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
1679 auto *PrivateVD =
1680 cast<VarDecl>(cast<DeclRefExpr>(*CurPrivate)->getDecl());
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001681 if (!SIMDLCVs.count(VD->getCanonicalDecl())) {
1682 bool IsRegistered = PrivateScope.addPrivate(VD, [&]() -> Address {
1683 // Emit private VarDecl with copy init.
1684 EmitVarDecl(*PrivateVD);
1685 return GetAddrOfLocalVar(PrivateVD);
1686 });
1687 assert(IsRegistered && "linear var already registered as private");
1688 // Silence the warning about unused variable.
1689 (void)IsRegistered;
1690 } else
1691 EmitVarDecl(*PrivateVD);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00001692 ++CurPrivate;
Alexander Musman3276a272015-03-21 10:12:56 +00001693 }
1694 }
1695}
1696
Alexey Bataev45bfad52015-08-21 12:19:04 +00001697static void emitSimdlenSafelenClause(CodeGenFunction &CGF,
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001698 const OMPExecutableDirective &D,
1699 bool IsMonotonic) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001700 if (!CGF.HaveInsertPoint())
1701 return;
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001702 if (const auto *C = D.getSingleClause<OMPSimdlenClause>()) {
Alexey Bataev45bfad52015-08-21 12:19:04 +00001703 RValue Len = CGF.EmitAnyExpr(C->getSimdlen(), AggValueSlot::ignored(),
1704 /*ignoreResult=*/true);
1705 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
1706 CGF.LoopStack.setVectorizeWidth(Val->getZExtValue());
1707 // In presence of finite 'safelen', it may be unsafe to mark all
1708 // the memory instructions parallel, because loop-carried
1709 // dependences of 'safelen' iterations are possible.
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001710 if (!IsMonotonic)
1711 CGF.LoopStack.setParallel(!D.getSingleClause<OMPSafelenClause>());
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00001712 } else if (const auto *C = D.getSingleClause<OMPSafelenClause>()) {
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001713 RValue Len = CGF.EmitAnyExpr(C->getSafelen(), AggValueSlot::ignored(),
1714 /*ignoreResult=*/true);
1715 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
Tyler Nowickida46d0e2015-07-14 23:03:09 +00001716 CGF.LoopStack.setVectorizeWidth(Val->getZExtValue());
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00001717 // In presence of finite 'safelen', it may be unsafe to mark all
1718 // the memory instructions parallel, because loop-carried
1719 // dependences of 'safelen' iterations are possible.
1720 CGF.LoopStack.setParallel(false);
1721 }
1722}
1723
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001724void CodeGenFunction::EmitOMPSimdInit(const OMPLoopDirective &D,
1725 bool IsMonotonic) {
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001726 // Walk clauses and process safelen/lastprivate.
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001727 LoopStack.setParallel(!IsMonotonic);
Tyler Nowickida46d0e2015-07-14 23:03:09 +00001728 LoopStack.setVectorizeEnable(true);
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001729 emitSimdlenSafelenClause(*this, D, IsMonotonic);
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001730}
1731
Alexey Bataevef549a82016-03-09 09:49:09 +00001732void CodeGenFunction::EmitOMPSimdFinal(
1733 const OMPLoopDirective &D,
1734 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001735 if (!HaveInsertPoint())
1736 return;
Alexey Bataevef549a82016-03-09 09:49:09 +00001737 llvm::BasicBlock *DoneBB = nullptr;
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001738 auto IC = D.counters().begin();
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001739 auto IPC = D.private_counters().begin();
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001740 for (auto F : D.finals()) {
1741 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl());
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001742 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>((*IPC))->getDecl());
1743 auto *CED = dyn_cast<OMPCapturedExprDecl>(OrigVD);
1744 if (LocalDeclMap.count(OrigVD) || CapturedStmtInfo->lookup(OrigVD) ||
1745 OrigVD->hasGlobalStorage() || CED) {
Alexey Bataevef549a82016-03-09 09:49:09 +00001746 if (!DoneBB) {
1747 if (auto *Cond = CondGen(*this)) {
1748 // If the first post-update expression is found, emit conditional
1749 // block if it was requested.
1750 auto *ThenBB = createBasicBlock(".omp.final.then");
1751 DoneBB = createBasicBlock(".omp.final.done");
1752 Builder.CreateCondBr(Cond, ThenBB, DoneBB);
1753 EmitBlock(ThenBB);
1754 }
1755 }
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001756 Address OrigAddr = Address::invalid();
1757 if (CED)
1758 OrigAddr = EmitLValue(CED->getInit()->IgnoreImpCasts()).getAddress();
1759 else {
1760 DeclRefExpr DRE(const_cast<VarDecl *>(PrivateVD),
1761 /*RefersToEnclosingVariableOrCapture=*/false,
1762 (*IPC)->getType(), VK_LValue, (*IPC)->getExprLoc());
1763 OrigAddr = EmitLValue(&DRE).getAddress();
1764 }
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001765 OMPPrivateScope VarScope(*this);
1766 VarScope.addPrivate(OrigVD,
John McCall7f416cc2015-09-08 08:05:57 +00001767 [OrigAddr]() -> Address { return OrigAddr; });
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001768 (void)VarScope.Privatize();
1769 EmitIgnoredExpr(F);
1770 }
1771 ++IC;
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001772 ++IPC;
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001773 }
Alexey Bataevef549a82016-03-09 09:49:09 +00001774 if (DoneBB)
1775 EmitBlock(DoneBB, /*IsFinished=*/true);
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001776}
1777
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001778static void emitOMPLoopBodyWithStopPoint(CodeGenFunction &CGF,
1779 const OMPLoopDirective &S,
1780 CodeGenFunction::JumpDest LoopExit) {
1781 CGF.EmitOMPLoopBody(S, LoopExit);
1782 CGF.EmitStopPoint(&S);
Hans Wennborged129ae2017-04-27 17:02:25 +00001783}
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001784
Alexander Musman515ad8c2014-05-22 08:54:05 +00001785void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001786 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataev5a3af132016-03-29 08:58:54 +00001787 OMPLoopScope PreInitScope(CGF, S);
Alexey Bataev62dbb972015-04-22 11:59:37 +00001788 // if (PreCond) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001789 // for (IV in 0..LastIteration) BODY;
1790 // <Final counter/linear vars updates>;
Alexey Bataev62dbb972015-04-22 11:59:37 +00001791 // }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001792 //
Alexander Musmana5f070a2014-10-01 06:03:56 +00001793
Alexey Bataev62dbb972015-04-22 11:59:37 +00001794 // Emit: if (PreCond) - begin.
1795 // If the condition constant folds and can be elided, avoid emitting the
1796 // whole loop.
1797 bool CondConstant;
1798 llvm::BasicBlock *ContBlock = nullptr;
1799 if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
1800 if (!CondConstant)
1801 return;
1802 } else {
Alexey Bataev62dbb972015-04-22 11:59:37 +00001803 auto *ThenBlock = CGF.createBasicBlock("simd.if.then");
1804 ContBlock = CGF.createBasicBlock("simd.if.end");
Justin Bogner66242d62015-04-23 23:06:47 +00001805 emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
1806 CGF.getProfileCount(&S));
Alexey Bataev62dbb972015-04-22 11:59:37 +00001807 CGF.EmitBlock(ThenBlock);
Justin Bogner66242d62015-04-23 23:06:47 +00001808 CGF.incrementProfileCounter(&S);
Alexey Bataev62dbb972015-04-22 11:59:37 +00001809 }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001810
1811 // Emit the loop iteration variable.
1812 const Expr *IVExpr = S.getIterationVariable();
1813 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
1814 CGF.EmitVarDecl(*IVDecl);
1815 CGF.EmitIgnoredExpr(S.getInit());
1816
1817 // Emit the iterations count variable.
1818 // If it is not a variable, Sema decided to calculate iterations count on
Alexey Bataev7a228ff2015-05-21 07:59:51 +00001819 // each iteration (e.g., it is foldable into a constant).
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001820 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
1821 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
1822 // Emit calculation of the iterations count.
1823 CGF.EmitIgnoredExpr(S.getCalcLastIteration());
Alexander Musmana5f070a2014-10-01 06:03:56 +00001824 }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001825
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001826 CGF.EmitOMPSimdInit(S);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001827
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001828 emitAlignedClause(CGF, S);
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00001829 CGF.EmitOMPLinearClauseInit(S);
Alexey Bataev62dbb972015-04-22 11:59:37 +00001830 {
1831 OMPPrivateScope LoopScope(CGF);
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001832 CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
1833 CGF.EmitOMPLinearClause(S, LoopScope);
Alexey Bataev62dbb972015-04-22 11:59:37 +00001834 CGF.EmitOMPPrivateClause(S, LoopScope);
Alexey Bataev89e7e8e2015-06-17 06:21:39 +00001835 CGF.EmitOMPReductionClauseInit(S, LoopScope);
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001836 bool HasLastprivateClause =
1837 CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
Alexey Bataev62dbb972015-04-22 11:59:37 +00001838 (void)LoopScope.Privatize();
Alexey Bataev0f34da12015-07-02 04:17:07 +00001839 CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
1840 S.getInc(),
Alexey Bataev62dbb972015-04-22 11:59:37 +00001841 [&S](CodeGenFunction &CGF) {
Alexey Bataev0f34da12015-07-02 04:17:07 +00001842 CGF.EmitOMPLoopBody(S, JumpDest());
Alexey Bataev62dbb972015-04-22 11:59:37 +00001843 CGF.EmitStopPoint(&S);
1844 },
1845 [](CodeGenFunction &) {});
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001846 CGF.EmitOMPSimdFinal(
1847 S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
Alexey Bataevfc087ec2015-06-16 13:14:42 +00001848 // Emit final copy of the lastprivate variables at the end of loops.
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001849 if (HasLastprivateClause)
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001850 CGF.EmitOMPLastprivateClauseFinal(S, /*NoFinals=*/true);
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00001851 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_simd);
Alexey Bataev61205072016-03-02 04:57:40 +00001852 emitPostUpdateForReductionClause(
1853 CGF, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
Alexey Bataev62dbb972015-04-22 11:59:37 +00001854 }
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001855 CGF.EmitOMPLinearClauseFinal(
Alexey Bataevef549a82016-03-09 09:49:09 +00001856 S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
Alexey Bataev62dbb972015-04-22 11:59:37 +00001857 // Emit: if (PreCond) - end.
1858 if (ContBlock) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001859 CGF.EmitBranch(ContBlock);
1860 CGF.EmitBlock(ContBlock, true);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001861 }
1862 };
Alexey Bataev4ba78a42016-04-27 07:56:03 +00001863 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001864 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
Alexander Musman515ad8c2014-05-22 08:54:05 +00001865}
1866
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001867void CodeGenFunction::EmitOMPOuterLoop(
1868 bool DynamicOrOrdered, bool IsMonotonic, const OMPLoopDirective &S,
1869 CodeGenFunction::OMPPrivateScope &LoopScope,
1870 const CodeGenFunction::OMPLoopArguments &LoopArgs,
1871 const CodeGenFunction::CodeGenLoopTy &CodeGenLoop,
1872 const CodeGenFunction::CodeGenOrderedTy &CodeGenOrdered) {
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001873 auto &RT = CGM.getOpenMPRuntime();
Alexander Musman92bdaab2015-03-12 13:37:50 +00001874
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001875 const Expr *IVExpr = S.getIterationVariable();
1876 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
1877 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
1878
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001879 auto LoopExit = getJumpDestInCurrentScope("omp.dispatch.end");
1880
1881 // Start the loop with a block that tests the condition.
1882 auto CondBlock = createBasicBlock("omp.dispatch.cond");
1883 EmitBlock(CondBlock);
Amara Emerson652795d2016-11-10 14:44:30 +00001884 const SourceRange &R = S.getSourceRange();
1885 LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()),
1886 SourceLocToDebugLoc(R.getEnd()));
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001887
1888 llvm::Value *BoolCondVal = nullptr;
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00001889 if (!DynamicOrOrdered) {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001890 // UB = min(UB, GlobalUB) or
1891 // UB = min(UB, PrevUB) for combined loop sharing constructs (e.g.
1892 // 'distribute parallel for')
1893 EmitIgnoredExpr(LoopArgs.EUB);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001894 // IV = LB
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001895 EmitIgnoredExpr(LoopArgs.Init);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001896 // IV < UB
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001897 BoolCondVal = EvaluateExprAsBool(LoopArgs.Cond);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001898 } else {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001899 BoolCondVal =
1900 RT.emitForNext(*this, S.getLocStart(), IVSize, IVSigned, LoopArgs.IL,
1901 LoopArgs.LB, LoopArgs.UB, LoopArgs.ST);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001902 }
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001903
1904 // If there are any cleanups between here and the loop-exit scope,
1905 // create a block to stage a loop exit along.
1906 auto ExitBlock = LoopExit.getBlock();
1907 if (LoopScope.requiresCleanups())
1908 ExitBlock = createBasicBlock("omp.dispatch.cleanup");
1909
1910 auto LoopBody = createBasicBlock("omp.dispatch.body");
1911 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
1912 if (ExitBlock != LoopExit.getBlock()) {
1913 EmitBlock(ExitBlock);
1914 EmitBranchThroughCleanup(LoopExit);
1915 }
1916 EmitBlock(LoopBody);
1917
Alexander Musman92bdaab2015-03-12 13:37:50 +00001918 // Emit "IV = LB" (in case of static schedule, we have already calculated new
1919 // LB for loop condition and emitted it above).
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00001920 if (DynamicOrOrdered)
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001921 EmitIgnoredExpr(LoopArgs.Init);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001922
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001923 // Create a block for the increment.
1924 auto Continue = getJumpDestInCurrentScope("omp.dispatch.inc");
1925 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1926
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001927 // Generate !llvm.loop.parallel metadata for loads and stores for loops
1928 // with dynamic/guided scheduling and without ordered clause.
Alexey Bataeva6f2a142015-12-31 06:52:34 +00001929 if (!isOpenMPSimdDirective(S.getDirectiveKind()))
1930 LoopStack.setParallel(!IsMonotonic);
1931 else
1932 EmitOMPSimdInit(S, IsMonotonic);
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00001933
Alexey Bataev98eb6e32015-04-22 11:15:40 +00001934 SourceLocation Loc = S.getLocStart();
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001935
1936 // when 'distribute' is not combined with a 'for':
1937 // while (idx <= UB) { BODY; ++idx; }
1938 // when 'distribute' is combined with a 'for'
1939 // (e.g. 'distribute parallel for')
1940 // while (idx <= UB) { <CodeGen rest of pragma>; idx += ST; }
1941 EmitOMPInnerLoop(
1942 S, LoopScope.requiresCleanups(), LoopArgs.Cond, LoopArgs.IncExpr,
1943 [&S, LoopExit, &CodeGenLoop](CodeGenFunction &CGF) {
1944 CodeGenLoop(CGF, S, LoopExit);
1945 },
1946 [IVSize, IVSigned, Loc, &CodeGenOrdered](CodeGenFunction &CGF) {
1947 CodeGenOrdered(CGF, Loc, IVSize, IVSigned);
1948 });
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001949
1950 EmitBlock(Continue.getBlock());
1951 BreakContinueStack.pop_back();
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00001952 if (!DynamicOrOrdered) {
Alexander Musman92bdaab2015-03-12 13:37:50 +00001953 // Emit "LB = LB + Stride", "UB = UB + Stride".
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001954 EmitIgnoredExpr(LoopArgs.NextLB);
1955 EmitIgnoredExpr(LoopArgs.NextUB);
Alexander Musman92bdaab2015-03-12 13:37:50 +00001956 }
Alexander Musmandf7a8e22015-01-22 08:49:35 +00001957
1958 EmitBranch(CondBlock);
1959 LoopStack.pop();
1960 // Emit the fall-through block.
1961 EmitBlock(LoopExit.getBlock());
1962
1963 // Tell the runtime we are done.
Alexey Bataev957d8562016-11-17 15:12:05 +00001964 auto &&CodeGen = [DynamicOrOrdered, &S](CodeGenFunction &CGF) {
1965 if (!DynamicOrOrdered)
1966 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocEnd());
1967 };
1968 OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001969}
1970
1971void CodeGenFunction::EmitOMPForOuterLoop(
Alexey Bataev9ebd7422016-05-10 09:57:36 +00001972 const OpenMPScheduleTy &ScheduleKind, bool IsMonotonic,
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001973 const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001974 const OMPLoopArguments &LoopArgs,
1975 const CodeGenDispatchBoundsTy &CGDispatchBounds) {
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001976 auto &RT = CGM.getOpenMPRuntime();
1977
1978 // Dynamic scheduling of the outer loop (dynamic, guided, auto, runtime).
Alexey Bataev9ebd7422016-05-10 09:57:36 +00001979 const bool DynamicOrOrdered =
1980 Ordered || RT.isDynamic(ScheduleKind.Schedule);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001981
1982 assert((Ordered ||
Alexey Bataev9ebd7422016-05-10 09:57:36 +00001983 !RT.isStaticNonchunked(ScheduleKind.Schedule,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00001984 LoopArgs.Chunk != nullptr)) &&
Carlo Bertollifc35ad22016-03-07 16:04:49 +00001985 "static non-chunked schedule does not need outer loop");
1986
1987 // Emit outer loop.
1988 //
1989 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
1990 // When schedule(dynamic,chunk_size) is specified, the iterations are
1991 // distributed to threads in the team in chunks as the threads request them.
1992 // Each thread executes a chunk of iterations, then requests another chunk,
1993 // until no chunks remain to be distributed. Each chunk contains chunk_size
1994 // iterations, except for the last chunk to be distributed, which may have
1995 // fewer iterations. When no chunk_size is specified, it defaults to 1.
1996 //
1997 // When schedule(guided,chunk_size) is specified, the iterations are assigned
1998 // to threads in the team in chunks as the executing threads request them.
1999 // Each thread executes a chunk of iterations, then requests another chunk,
2000 // until no chunks remain to be assigned. For a chunk_size of 1, the size of
2001 // each chunk is proportional to the number of unassigned iterations divided
2002 // by the number of threads in the team, decreasing to 1. For a chunk_size
2003 // with value k (greater than 1), the size of each chunk is determined in the
2004 // same way, with the restriction that the chunks do not contain fewer than k
2005 // iterations (except for the last chunk to be assigned, which may have fewer
2006 // than k iterations).
2007 //
2008 // When schedule(auto) is specified, the decision regarding scheduling is
2009 // delegated to the compiler and/or runtime system. The programmer gives the
2010 // implementation the freedom to choose any possible mapping of iterations to
2011 // threads in the team.
2012 //
2013 // When schedule(runtime) is specified, the decision regarding scheduling is
2014 // deferred until run time, and the schedule and chunk size are taken from the
2015 // run-sched-var ICV. If the ICV is set to auto, the schedule is
2016 // implementation defined
2017 //
2018 // while(__kmpc_dispatch_next(&LB, &UB)) {
2019 // idx = LB;
2020 // while (idx <= UB) { BODY; ++idx;
2021 // __kmpc_dispatch_fini_(4|8)[u](); // For ordered loops only.
2022 // } // inner loop
2023 // }
2024 //
2025 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
2026 // When schedule(static, chunk_size) is specified, iterations are divided into
2027 // chunks of size chunk_size, and the chunks are assigned to the threads in
2028 // the team in a round-robin fashion in the order of the thread number.
2029 //
2030 // while(UB = min(UB, GlobalUB), idx = LB, idx < UB) {
2031 // while (idx <= UB) { BODY; ++idx; } // inner loop
2032 // LB = LB + ST;
2033 // UB = UB + ST;
2034 // }
2035 //
2036
2037 const Expr *IVExpr = S.getIterationVariable();
2038 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
2039 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
2040
2041 if (DynamicOrOrdered) {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002042 auto DispatchBounds = CGDispatchBounds(*this, S, LoopArgs.LB, LoopArgs.UB);
2043 llvm::Value *LBVal = DispatchBounds.first;
2044 llvm::Value *UBVal = DispatchBounds.second;
2045 CGOpenMPRuntime::DispatchRTInput DipatchRTInputValues = {LBVal, UBVal,
2046 LoopArgs.Chunk};
Alexey Bataev9ebd7422016-05-10 09:57:36 +00002047 RT.emitForDispatchInit(*this, S.getLocStart(), ScheduleKind, IVSize,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002048 IVSigned, Ordered, DipatchRTInputValues);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00002049 } else {
2050 RT.emitForStaticInit(*this, S.getLocStart(), ScheduleKind, IVSize, IVSigned,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002051 Ordered, LoopArgs.IL, LoopArgs.LB, LoopArgs.UB,
2052 LoopArgs.ST, LoopArgs.Chunk);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00002053 }
2054
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002055 auto &&CodeGenOrdered = [Ordered](CodeGenFunction &CGF, SourceLocation Loc,
2056 const unsigned IVSize,
2057 const bool IVSigned) {
2058 if (Ordered) {
2059 CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd(CGF, Loc, IVSize,
2060 IVSigned);
2061 }
2062 };
2063
2064 OMPLoopArguments OuterLoopArgs(LoopArgs.LB, LoopArgs.UB, LoopArgs.ST,
2065 LoopArgs.IL, LoopArgs.Chunk, LoopArgs.EUB);
2066 OuterLoopArgs.IncExpr = S.getInc();
2067 OuterLoopArgs.Init = S.getInit();
2068 OuterLoopArgs.Cond = S.getCond();
2069 OuterLoopArgs.NextLB = S.getNextLowerBound();
2070 OuterLoopArgs.NextUB = S.getNextUpperBound();
2071 EmitOMPOuterLoop(DynamicOrOrdered, IsMonotonic, S, LoopScope, OuterLoopArgs,
2072 emitOMPLoopBodyWithStopPoint, CodeGenOrdered);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00002073}
2074
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002075static void emitEmptyOrdered(CodeGenFunction &, SourceLocation Loc,
2076 const unsigned IVSize, const bool IVSigned) {}
2077
Carlo Bertollifc35ad22016-03-07 16:04:49 +00002078void CodeGenFunction::EmitOMPDistributeOuterLoop(
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002079 OpenMPDistScheduleClauseKind ScheduleKind, const OMPLoopDirective &S,
2080 OMPPrivateScope &LoopScope, const OMPLoopArguments &LoopArgs,
2081 const CodeGenLoopTy &CodeGenLoopContent) {
Carlo Bertollifc35ad22016-03-07 16:04:49 +00002082
2083 auto &RT = CGM.getOpenMPRuntime();
2084
2085 // Emit outer loop.
2086 // Same behavior as a OMPForOuterLoop, except that schedule cannot be
2087 // dynamic
2088 //
2089
2090 const Expr *IVExpr = S.getIterationVariable();
2091 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
2092 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
2093
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002094 RT.emitDistributeStaticInit(*this, S.getLocStart(), ScheduleKind, IVSize,
2095 IVSigned, /* Ordered = */ false, LoopArgs.IL,
2096 LoopArgs.LB, LoopArgs.UB, LoopArgs.ST,
2097 LoopArgs.Chunk);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00002098
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002099 // for combined 'distribute' and 'for' the increment expression of distribute
2100 // is store in DistInc. For 'distribute' alone, it is in Inc.
2101 Expr *IncExpr;
2102 if (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()))
2103 IncExpr = S.getDistInc();
2104 else
2105 IncExpr = S.getInc();
2106
2107 // this routine is shared by 'omp distribute parallel for' and
2108 // 'omp distribute': select the right EUB expression depending on the
2109 // directive
2110 OMPLoopArguments OuterLoopArgs;
2111 OuterLoopArgs.LB = LoopArgs.LB;
2112 OuterLoopArgs.UB = LoopArgs.UB;
2113 OuterLoopArgs.ST = LoopArgs.ST;
2114 OuterLoopArgs.IL = LoopArgs.IL;
2115 OuterLoopArgs.Chunk = LoopArgs.Chunk;
2116 OuterLoopArgs.EUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
2117 ? S.getCombinedEnsureUpperBound()
2118 : S.getEnsureUpperBound();
2119 OuterLoopArgs.IncExpr = IncExpr;
2120 OuterLoopArgs.Init = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
2121 ? S.getCombinedInit()
2122 : S.getInit();
2123 OuterLoopArgs.Cond = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
2124 ? S.getCombinedCond()
2125 : S.getCond();
2126 OuterLoopArgs.NextLB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
2127 ? S.getCombinedNextLowerBound()
2128 : S.getNextLowerBound();
2129 OuterLoopArgs.NextUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
2130 ? S.getCombinedNextUpperBound()
2131 : S.getNextUpperBound();
2132
2133 EmitOMPOuterLoop(/* DynamicOrOrdered = */ false, /* IsMonotonic = */ false, S,
2134 LoopScope, OuterLoopArgs, CodeGenLoopContent,
2135 emitEmptyOrdered);
2136}
2137
2138/// Emit a helper variable and return corresponding lvalue.
2139static LValue EmitOMPHelperVar(CodeGenFunction &CGF,
2140 const DeclRefExpr *Helper) {
2141 auto VDecl = cast<VarDecl>(Helper->getDecl());
2142 CGF.EmitVarDecl(*VDecl);
2143 return CGF.EmitLValue(Helper);
2144}
2145
2146static std::pair<LValue, LValue>
2147emitDistributeParallelForInnerBounds(CodeGenFunction &CGF,
2148 const OMPExecutableDirective &S) {
2149 const OMPLoopDirective &LS = cast<OMPLoopDirective>(S);
2150 LValue LB =
2151 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getLowerBoundVariable()));
2152 LValue UB =
2153 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getUpperBoundVariable()));
2154
2155 // When composing 'distribute' with 'for' (e.g. as in 'distribute
2156 // parallel for') we need to use the 'distribute'
2157 // chunk lower and upper bounds rather than the whole loop iteration
2158 // space. These are parameters to the outlined function for 'parallel'
2159 // and we copy the bounds of the previous schedule into the
2160 // the current ones.
2161 LValue PrevLB = CGF.EmitLValue(LS.getPrevLowerBoundVariable());
2162 LValue PrevUB = CGF.EmitLValue(LS.getPrevUpperBoundVariable());
2163 llvm::Value *PrevLBVal = CGF.EmitLoadOfScalar(PrevLB, SourceLocation());
2164 PrevLBVal = CGF.EmitScalarConversion(
2165 PrevLBVal, LS.getPrevLowerBoundVariable()->getType(),
2166 LS.getIterationVariable()->getType(), SourceLocation());
2167 llvm::Value *PrevUBVal = CGF.EmitLoadOfScalar(PrevUB, SourceLocation());
2168 PrevUBVal = CGF.EmitScalarConversion(
2169 PrevUBVal, LS.getPrevUpperBoundVariable()->getType(),
2170 LS.getIterationVariable()->getType(), SourceLocation());
2171
2172 CGF.EmitStoreOfScalar(PrevLBVal, LB);
2173 CGF.EmitStoreOfScalar(PrevUBVal, UB);
2174
2175 return {LB, UB};
2176}
2177
2178/// if the 'for' loop has a dispatch schedule (e.g. dynamic, guided) then
2179/// we need to use the LB and UB expressions generated by the worksharing
2180/// code generation support, whereas in non combined situations we would
2181/// just emit 0 and the LastIteration expression
2182/// This function is necessary due to the difference of the LB and UB
2183/// types for the RT emission routines for 'for_static_init' and
2184/// 'for_dispatch_init'
2185static std::pair<llvm::Value *, llvm::Value *>
2186emitDistributeParallelForDispatchBounds(CodeGenFunction &CGF,
2187 const OMPExecutableDirective &S,
2188 Address LB, Address UB) {
2189 const OMPLoopDirective &LS = cast<OMPLoopDirective>(S);
2190 const Expr *IVExpr = LS.getIterationVariable();
2191 // when implementing a dynamic schedule for a 'for' combined with a
2192 // 'distribute' (e.g. 'distribute parallel for'), the 'for' loop
2193 // is not normalized as each team only executes its own assigned
2194 // distribute chunk
2195 QualType IteratorTy = IVExpr->getType();
2196 llvm::Value *LBVal = CGF.EmitLoadOfScalar(LB, /*Volatile=*/false, IteratorTy,
2197 SourceLocation());
2198 llvm::Value *UBVal = CGF.EmitLoadOfScalar(UB, /*Volatile=*/false, IteratorTy,
2199 SourceLocation());
2200 return {LBVal, UBVal};
Hans Wennborged129ae2017-04-27 17:02:25 +00002201}
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002202
2203static void emitDistributeParallelForDistributeInnerBoundParams(
2204 CodeGenFunction &CGF, const OMPExecutableDirective &S,
2205 llvm::SmallVectorImpl<llvm::Value *> &CapturedVars) {
2206 const auto &Dir = cast<OMPLoopDirective>(S);
2207 LValue LB =
2208 CGF.EmitLValue(cast<DeclRefExpr>(Dir.getCombinedLowerBoundVariable()));
2209 auto LBCast = CGF.Builder.CreateIntCast(
2210 CGF.Builder.CreateLoad(LB.getAddress()), CGF.SizeTy, /*isSigned=*/false);
2211 CapturedVars.push_back(LBCast);
2212 LValue UB =
2213 CGF.EmitLValue(cast<DeclRefExpr>(Dir.getCombinedUpperBoundVariable()));
2214
2215 auto UBCast = CGF.Builder.CreateIntCast(
2216 CGF.Builder.CreateLoad(UB.getAddress()), CGF.SizeTy, /*isSigned=*/false);
2217 CapturedVars.push_back(UBCast);
Hans Wennborged129ae2017-04-27 17:02:25 +00002218}
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002219
2220static void
2221emitInnerParallelForWhenCombined(CodeGenFunction &CGF,
2222 const OMPLoopDirective &S,
2223 CodeGenFunction::JumpDest LoopExit) {
2224 auto &&CGInlinedWorksharingLoop = [&S](CodeGenFunction &CGF,
2225 PrePostActionTy &) {
2226 CGF.EmitOMPWorksharingLoop(S, S.getPrevEnsureUpperBound(),
2227 emitDistributeParallelForInnerBounds,
2228 emitDistributeParallelForDispatchBounds);
2229 };
2230
2231 emitCommonOMPParallelDirective(
2232 CGF, S, OMPD_for, CGInlinedWorksharingLoop,
2233 emitDistributeParallelForDistributeInnerBoundParams);
Alexander Musmandf7a8e22015-01-22 08:49:35 +00002234}
2235
Carlo Bertolli9925f152016-06-27 14:55:37 +00002236void CodeGenFunction::EmitOMPDistributeParallelForDirective(
2237 const OMPDistributeParallelForDirective &S) {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002238 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2239 CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
2240 S.getDistInc());
2241 };
Carlo Bertolli9925f152016-06-27 14:55:37 +00002242 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002243 OMPCancelStackRAII CancelRegion(*this, OMPD_distribute_parallel_for,
2244 /*HasCancel=*/false);
2245 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen,
2246 /*HasCancel=*/false);
Carlo Bertolli9925f152016-06-27 14:55:37 +00002247}
2248
Kelvin Li4a39add2016-07-05 05:00:15 +00002249void CodeGenFunction::EmitOMPDistributeParallelForSimdDirective(
2250 const OMPDistributeParallelForSimdDirective &S) {
2251 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2252 CGM.getOpenMPRuntime().emitInlinedDirective(
2253 *this, OMPD_distribute_parallel_for_simd,
2254 [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2255 OMPLoopScope PreInitScope(CGF, S);
2256 CGF.EmitStmt(
2257 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2258 });
2259}
Kelvin Li787f3fc2016-07-06 04:45:38 +00002260
2261void CodeGenFunction::EmitOMPDistributeSimdDirective(
2262 const OMPDistributeSimdDirective &S) {
2263 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2264 CGM.getOpenMPRuntime().emitInlinedDirective(
2265 *this, OMPD_distribute_simd,
2266 [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2267 OMPLoopScope PreInitScope(CGF, S);
2268 CGF.EmitStmt(
2269 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2270 });
2271}
2272
Kelvin Lia579b912016-07-14 02:54:56 +00002273void CodeGenFunction::EmitOMPTargetParallelForSimdDirective(
2274 const OMPTargetParallelForSimdDirective &S) {
2275 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2276 CGM.getOpenMPRuntime().emitInlinedDirective(
2277 *this, OMPD_target_parallel_for_simd,
2278 [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2279 OMPLoopScope PreInitScope(CGF, S);
2280 CGF.EmitStmt(
2281 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2282 });
2283}
2284
Kelvin Li986330c2016-07-20 22:57:10 +00002285void CodeGenFunction::EmitOMPTargetSimdDirective(
2286 const OMPTargetSimdDirective &S) {
2287 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2288 CGM.getOpenMPRuntime().emitInlinedDirective(
2289 *this, OMPD_target_simd, [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2290 OMPLoopScope PreInitScope(CGF, S);
2291 CGF.EmitStmt(
2292 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2293 });
2294}
2295
Kelvin Li02532872016-08-05 14:37:37 +00002296void CodeGenFunction::EmitOMPTeamsDistributeDirective(
2297 const OMPTeamsDistributeDirective &S) {
2298 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2299 CGM.getOpenMPRuntime().emitInlinedDirective(
2300 *this, OMPD_teams_distribute,
2301 [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2302 OMPLoopScope PreInitScope(CGF, S);
2303 CGF.EmitStmt(
2304 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2305 });
2306}
2307
Kelvin Li4e325f72016-10-25 12:50:55 +00002308void CodeGenFunction::EmitOMPTeamsDistributeSimdDirective(
2309 const OMPTeamsDistributeSimdDirective &S) {
2310 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2311 CGM.getOpenMPRuntime().emitInlinedDirective(
2312 *this, OMPD_teams_distribute_simd,
2313 [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2314 OMPLoopScope PreInitScope(CGF, S);
2315 CGF.EmitStmt(
2316 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2317 });
2318}
2319
Kelvin Li579e41c2016-11-30 23:51:03 +00002320void CodeGenFunction::EmitOMPTeamsDistributeParallelForSimdDirective(
2321 const OMPTeamsDistributeParallelForSimdDirective &S) {
2322 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2323 CGM.getOpenMPRuntime().emitInlinedDirective(
2324 *this, OMPD_teams_distribute_parallel_for_simd,
2325 [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2326 OMPLoopScope PreInitScope(CGF, S);
2327 CGF.EmitStmt(
2328 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2329 });
2330}
Kelvin Li4e325f72016-10-25 12:50:55 +00002331
Kelvin Li7ade93f2016-12-09 03:24:30 +00002332void CodeGenFunction::EmitOMPTeamsDistributeParallelForDirective(
2333 const OMPTeamsDistributeParallelForDirective &S) {
2334 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
2335 CGM.getOpenMPRuntime().emitInlinedDirective(
2336 *this, OMPD_teams_distribute_parallel_for,
2337 [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2338 OMPLoopScope PreInitScope(CGF, S);
2339 CGF.EmitStmt(
2340 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2341 });
2342}
2343
Kelvin Li83c451e2016-12-25 04:52:54 +00002344void CodeGenFunction::EmitOMPTargetTeamsDistributeDirective(
2345 const OMPTargetTeamsDistributeDirective &S) {
Kelvin Li26fd21a2016-12-28 17:57:07 +00002346 CGM.getOpenMPRuntime().emitInlinedDirective(
2347 *this, OMPD_target_teams_distribute,
Kelvin Li83c451e2016-12-25 04:52:54 +00002348 [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Kelvin Li26fd21a2016-12-28 17:57:07 +00002349 CGF.EmitStmt(
2350 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
Kelvin Li83c451e2016-12-25 04:52:54 +00002351 });
2352}
2353
Kelvin Li80e8f562016-12-29 22:16:30 +00002354void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDirective(
2355 const OMPTargetTeamsDistributeParallelForDirective &S) {
2356 CGM.getOpenMPRuntime().emitInlinedDirective(
2357 *this, OMPD_target_teams_distribute_parallel_for,
2358 [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2359 CGF.EmitStmt(
2360 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2361 });
2362}
2363
Kelvin Li1851df52017-01-03 05:23:48 +00002364void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDirective(
2365 const OMPTargetTeamsDistributeParallelForSimdDirective &S) {
2366 CGM.getOpenMPRuntime().emitInlinedDirective(
2367 *this, OMPD_target_teams_distribute_parallel_for_simd,
2368 [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2369 CGF.EmitStmt(
2370 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2371 });
2372}
2373
Kelvin Lida681182017-01-10 18:08:18 +00002374void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDirective(
2375 const OMPTargetTeamsDistributeSimdDirective &S) {
2376 CGM.getOpenMPRuntime().emitInlinedDirective(
2377 *this, OMPD_target_teams_distribute_simd,
2378 [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2379 CGF.EmitStmt(
2380 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2381 });
2382}
2383
Alexey Bataeva6f2a142015-12-31 06:52:34 +00002384namespace {
2385 struct ScheduleKindModifiersTy {
2386 OpenMPScheduleClauseKind Kind;
2387 OpenMPScheduleClauseModifier M1;
2388 OpenMPScheduleClauseModifier M2;
2389 ScheduleKindModifiersTy(OpenMPScheduleClauseKind Kind,
2390 OpenMPScheduleClauseModifier M1,
2391 OpenMPScheduleClauseModifier M2)
2392 : Kind(Kind), M1(M1), M2(M2) {}
2393 };
2394} // namespace
2395
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002396bool CodeGenFunction::EmitOMPWorksharingLoop(
2397 const OMPLoopDirective &S, Expr *EUB,
2398 const CodeGenLoopBoundsTy &CodeGenLoopBounds,
2399 const CodeGenDispatchBoundsTy &CGDispatchBounds) {
Alexander Musmanc6388682014-12-15 07:07:06 +00002400 // Emit the loop iteration variable.
2401 auto IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
2402 auto IVDecl = cast<VarDecl>(IVExpr->getDecl());
2403 EmitVarDecl(*IVDecl);
2404
2405 // Emit the iterations count variable.
2406 // If it is not a variable, Sema decided to calculate iterations count on each
2407 // iteration (e.g., it is foldable into a constant).
2408 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
2409 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
2410 // Emit calculation of the iterations count.
2411 EmitIgnoredExpr(S.getCalcLastIteration());
2412 }
2413
2414 auto &RT = CGM.getOpenMPRuntime();
2415
Alexey Bataev38e89532015-04-16 04:54:05 +00002416 bool HasLastprivateClause;
Alexander Musmanc6388682014-12-15 07:07:06 +00002417 // Check pre-condition.
2418 {
Alexey Bataev5a3af132016-03-29 08:58:54 +00002419 OMPLoopScope PreInitScope(*this, S);
Alexander Musmanc6388682014-12-15 07:07:06 +00002420 // Skip the entire loop if we don't meet the precondition.
Alexey Bataev62dbb972015-04-22 11:59:37 +00002421 // If the condition constant folds and can be elided, avoid emitting the
2422 // whole loop.
2423 bool CondConstant;
2424 llvm::BasicBlock *ContBlock = nullptr;
2425 if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
2426 if (!CondConstant)
2427 return false;
2428 } else {
Alexey Bataev62dbb972015-04-22 11:59:37 +00002429 auto *ThenBlock = createBasicBlock("omp.precond.then");
2430 ContBlock = createBasicBlock("omp.precond.end");
2431 emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock,
Justin Bogner66242d62015-04-23 23:06:47 +00002432 getProfileCount(&S));
Alexey Bataev62dbb972015-04-22 11:59:37 +00002433 EmitBlock(ThenBlock);
Justin Bogner66242d62015-04-23 23:06:47 +00002434 incrementProfileCounter(&S);
Alexey Bataev62dbb972015-04-22 11:59:37 +00002435 }
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00002436
Alexey Bataev8b427062016-05-25 12:36:08 +00002437 bool Ordered = false;
2438 if (auto *OrderedClause = S.getSingleClause<OMPOrderedClause>()) {
2439 if (OrderedClause->getNumForLoops())
2440 RT.emitDoacrossInit(*this, S);
2441 else
2442 Ordered = true;
2443 }
2444
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002445 llvm::DenseSet<const Expr *> EmittedFinals;
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00002446 emitAlignedClause(*this, S);
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00002447 EmitOMPLinearClauseInit(S);
Alexey Bataevef549a82016-03-09 09:49:09 +00002448 // Emit helper vars inits.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002449
2450 std::pair<LValue, LValue> Bounds = CodeGenLoopBounds(*this, S);
2451 LValue LB = Bounds.first;
2452 LValue UB = Bounds.second;
Alexey Bataevef549a82016-03-09 09:49:09 +00002453 LValue ST =
2454 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable()));
2455 LValue IL =
2456 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
2457
Alexander Musmanc6388682014-12-15 07:07:06 +00002458 // Emit 'then' code.
2459 {
Alexander Musmanc6388682014-12-15 07:07:06 +00002460 OMPPrivateScope LoopScope(*this);
Alexey Bataev69c62a92015-04-15 04:52:20 +00002461 if (EmitOMPFirstprivateClause(S, LoopScope)) {
2462 // Emit implicit barrier to synchronize threads and avoid data races on
Alexey Bataevcd8b6a22016-02-15 08:07:17 +00002463 // initialization of firstprivate variables and post-update of
2464 // lastprivate variables.
Alexey Bataev25e5b442015-09-15 12:52:43 +00002465 CGM.getOpenMPRuntime().emitBarrierCall(
2466 *this, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
2467 /*ForceSimpleCall=*/true);
Alexey Bataev69c62a92015-04-15 04:52:20 +00002468 }
Alexey Bataev50a64582015-04-22 12:24:45 +00002469 EmitOMPPrivateClause(S, LoopScope);
Alexey Bataev38e89532015-04-16 04:54:05 +00002470 HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +00002471 EmitOMPReductionClauseInit(S, LoopScope);
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002472 EmitOMPPrivateLoopCounters(S, LoopScope);
2473 EmitOMPLinearClause(S, LoopScope);
Alexander Musman7931b982015-03-16 07:14:41 +00002474 (void)LoopScope.Privatize();
Alexander Musmanc6388682014-12-15 07:07:06 +00002475
2476 // Detect the loop schedule kind and chunk.
Alexey Bataev3392d762016-02-16 11:18:12 +00002477 llvm::Value *Chunk = nullptr;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00002478 OpenMPScheduleTy ScheduleKind;
Alexey Bataev3392d762016-02-16 11:18:12 +00002479 if (auto *C = S.getSingleClause<OMPScheduleClause>()) {
Alexey Bataev9ebd7422016-05-10 09:57:36 +00002480 ScheduleKind.Schedule = C->getScheduleKind();
2481 ScheduleKind.M1 = C->getFirstScheduleModifier();
2482 ScheduleKind.M2 = C->getSecondScheduleModifier();
Alexey Bataev3392d762016-02-16 11:18:12 +00002483 if (const auto *Ch = C->getChunkSize()) {
2484 Chunk = EmitScalarExpr(Ch);
2485 Chunk = EmitScalarConversion(Chunk, Ch->getType(),
2486 S.getIterationVariable()->getType(),
2487 S.getLocStart());
2488 }
2489 }
Alexander Musmanc6388682014-12-15 07:07:06 +00002490 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
2491 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
Alexey Bataeva6f2a142015-12-31 06:52:34 +00002492 // OpenMP 4.5, 2.7.1 Loop Construct, Description.
2493 // If the static schedule kind is specified or if the ordered clause is
2494 // specified, and if no monotonic modifier is specified, the effect will
2495 // be as if the monotonic modifier was specified.
Alexey Bataev9ebd7422016-05-10 09:57:36 +00002496 if (RT.isStaticNonchunked(ScheduleKind.Schedule,
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00002497 /* Chunked */ Chunk != nullptr) &&
2498 !Ordered) {
Alexey Bataeva6f2a142015-12-31 06:52:34 +00002499 if (isOpenMPSimdDirective(S.getDirectiveKind()))
2500 EmitOMPSimdInit(S, /*IsMonotonic=*/true);
Alexander Musmanc6388682014-12-15 07:07:06 +00002501 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
2502 // When no chunk_size is specified, the iteration space is divided into
2503 // chunks that are approximately equal in size, and at most one chunk is
2504 // distributed to each thread. Note that the size of the chunks is
2505 // unspecified in this case.
John McCall7f416cc2015-09-08 08:05:57 +00002506 RT.emitForStaticInit(*this, S.getLocStart(), ScheduleKind,
2507 IVSize, IVSigned, Ordered,
2508 IL.getAddress(), LB.getAddress(),
2509 UB.getAddress(), ST.getAddress());
Alexey Bataeva6f2a142015-12-31 06:52:34 +00002510 auto LoopExit =
2511 getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit"));
Alexander Musmanc6388682014-12-15 07:07:06 +00002512 // UB = min(UB, GlobalUB);
2513 EmitIgnoredExpr(S.getEnsureUpperBound());
2514 // IV = LB;
2515 EmitIgnoredExpr(S.getInit());
2516 // while (idx <= UB) { BODY; ++idx; }
Alexey Bataevae05c292015-06-16 11:59:36 +00002517 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
2518 S.getInc(),
Alexey Bataev0f34da12015-07-02 04:17:07 +00002519 [&S, LoopExit](CodeGenFunction &CGF) {
2520 CGF.EmitOMPLoopBody(S, LoopExit);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002521 CGF.EmitStopPoint(&S);
Alexey Bataev98eb6e32015-04-22 11:15:40 +00002522 },
2523 [](CodeGenFunction &) {});
Alexey Bataev0f34da12015-07-02 04:17:07 +00002524 EmitBlock(LoopExit.getBlock());
Alexander Musmanc6388682014-12-15 07:07:06 +00002525 // Tell the runtime we are done.
Alexey Bataev957d8562016-11-17 15:12:05 +00002526 auto &&CodeGen = [&S](CodeGenFunction &CGF) {
2527 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocEnd());
2528 };
2529 OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen);
Alexander Musmandf7a8e22015-01-22 08:49:35 +00002530 } else {
Alexey Bataev9ebd7422016-05-10 09:57:36 +00002531 const bool IsMonotonic =
2532 Ordered || ScheduleKind.Schedule == OMPC_SCHEDULE_static ||
2533 ScheduleKind.Schedule == OMPC_SCHEDULE_unknown ||
2534 ScheduleKind.M1 == OMPC_SCHEDULE_MODIFIER_monotonic ||
2535 ScheduleKind.M2 == OMPC_SCHEDULE_MODIFIER_monotonic;
Alexander Musmandf7a8e22015-01-22 08:49:35 +00002536 // Emit the outer loop, which requests its work chunk [LB..UB] from
2537 // runtime and runs the inner loop to process it.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002538 const OMPLoopArguments LoopArguments(LB.getAddress(), UB.getAddress(),
2539 ST.getAddress(), IL.getAddress(),
2540 Chunk, EUB);
Alexey Bataeva6f2a142015-12-31 06:52:34 +00002541 EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered,
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002542 LoopArguments, CGDispatchBounds);
Alexander Musmandf7a8e22015-01-22 08:49:35 +00002543 }
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002544 if (isOpenMPSimdDirective(S.getDirectiveKind())) {
2545 EmitOMPSimdFinal(S,
2546 [&](CodeGenFunction &CGF) -> llvm::Value * {
2547 return CGF.Builder.CreateIsNotNull(
2548 CGF.EmitLoadOfScalar(IL, S.getLocStart()));
2549 });
2550 }
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00002551 EmitOMPReductionClauseFinal(
2552 S, /*ReductionKind=*/isOpenMPSimdDirective(S.getDirectiveKind())
2553 ? /*Parallel and Simd*/ OMPD_parallel_for_simd
2554 : /*Parallel only*/ OMPD_parallel);
Alexey Bataev61205072016-03-02 04:57:40 +00002555 // Emit post-update of the reduction variables if IsLastIter != 0.
2556 emitPostUpdateForReductionClause(
2557 *this, S, [&](CodeGenFunction &CGF) -> llvm::Value * {
2558 return CGF.Builder.CreateIsNotNull(
2559 CGF.EmitLoadOfScalar(IL, S.getLocStart()));
2560 });
Alexey Bataev38e89532015-04-16 04:54:05 +00002561 // Emit final copy of the lastprivate variables if IsLastIter != 0.
2562 if (HasLastprivateClause)
2563 EmitOMPLastprivateClauseFinal(
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002564 S, isOpenMPSimdDirective(S.getDirectiveKind()),
2565 Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getLocStart())));
Alexander Musmanc6388682014-12-15 07:07:06 +00002566 }
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002567 EmitOMPLinearClauseFinal(S, [&](CodeGenFunction &CGF) -> llvm::Value * {
Alexey Bataevef549a82016-03-09 09:49:09 +00002568 return CGF.Builder.CreateIsNotNull(
2569 CGF.EmitLoadOfScalar(IL, S.getLocStart()));
2570 });
Alexander Musmanc6388682014-12-15 07:07:06 +00002571 // We're now done with the loop, so jump to the continuation block.
Alexey Bataev62dbb972015-04-22 11:59:37 +00002572 if (ContBlock) {
2573 EmitBranch(ContBlock);
2574 EmitBlock(ContBlock, true);
2575 }
Alexander Musmanc6388682014-12-15 07:07:06 +00002576 }
Alexey Bataev38e89532015-04-16 04:54:05 +00002577 return HasLastprivateClause;
Alexander Musmanc6388682014-12-15 07:07:06 +00002578}
2579
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002580/// The following two functions generate expressions for the loop lower
2581/// and upper bounds in case of static and dynamic (dispatch) schedule
2582/// of the associated 'for' or 'distribute' loop.
2583static std::pair<LValue, LValue>
2584emitForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
2585 const OMPLoopDirective &LS = cast<OMPLoopDirective>(S);
2586 LValue LB =
2587 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getLowerBoundVariable()));
2588 LValue UB =
2589 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getUpperBoundVariable()));
2590 return {LB, UB};
2591}
2592
2593/// When dealing with dispatch schedules (e.g. dynamic, guided) we do not
2594/// consider the lower and upper bound expressions generated by the
2595/// worksharing loop support, but we use 0 and the iteration space size as
2596/// constants
2597static std::pair<llvm::Value *, llvm::Value *>
2598emitDispatchForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S,
2599 Address LB, Address UB) {
2600 const OMPLoopDirective &LS = cast<OMPLoopDirective>(S);
2601 const Expr *IVExpr = LS.getIterationVariable();
2602 const unsigned IVSize = CGF.getContext().getTypeSize(IVExpr->getType());
2603 llvm::Value *LBVal = CGF.Builder.getIntN(IVSize, 0);
2604 llvm::Value *UBVal = CGF.EmitScalarExpr(LS.getLastIteration());
2605 return {LBVal, UBVal};
2606}
2607
Alexander Musmanc6388682014-12-15 07:07:06 +00002608void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {
Alexey Bataev38e89532015-04-16 04:54:05 +00002609 bool HasLastprivates = false;
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002610 auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF,
2611 PrePostActionTy &) {
Alexey Bataev957d8562016-11-17 15:12:05 +00002612 OMPCancelStackRAII CancelRegion(CGF, OMPD_for, S.hasCancel());
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002613 HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(),
2614 emitForLoopBounds,
2615 emitDispatchForLoopBounds);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002616 };
Alexey Bataev3392d762016-02-16 11:18:12 +00002617 {
Alexey Bataev4ba78a42016-04-27 07:56:03 +00002618 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
Alexey Bataev3392d762016-02-16 11:18:12 +00002619 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen,
2620 S.hasCancel());
2621 }
Alexander Musmanc6388682014-12-15 07:07:06 +00002622
2623 // Emit an implicit barrier at the end.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002624 if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) {
Alexey Bataevf2685682015-03-30 04:30:22 +00002625 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_for);
2626 }
Alexey Bataevf29276e2014-06-18 04:14:57 +00002627}
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002628
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00002629void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) {
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00002630 bool HasLastprivates = false;
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002631 auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF,
2632 PrePostActionTy &) {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002633 HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(),
2634 emitForLoopBounds,
2635 emitDispatchForLoopBounds);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002636 };
Alexey Bataev3392d762016-02-16 11:18:12 +00002637 {
Alexey Bataev4ba78a42016-04-27 07:56:03 +00002638 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
Alexey Bataev3392d762016-02-16 11:18:12 +00002639 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
2640 }
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00002641
2642 // Emit an implicit barrier at the end.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002643 if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) {
Alexey Bataevcbdcbb72015-06-17 07:45:51 +00002644 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_for);
2645 }
Alexander Musmanf82886e2014-09-18 05:12:34 +00002646}
2647
Alexey Bataev2df54a02015-03-12 08:53:29 +00002648static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty,
2649 const Twine &Name,
2650 llvm::Value *Init = nullptr) {
John McCall7f416cc2015-09-08 08:05:57 +00002651 auto LVal = CGF.MakeAddrLValue(CGF.CreateMemTemp(Ty, Name), Ty);
Alexey Bataev2df54a02015-03-12 08:53:29 +00002652 if (Init)
Akira Hatanaka642f7992016-10-18 19:05:41 +00002653 CGF.EmitStoreThroughLValue(RValue::get(Init), LVal, /*isInit*/ true);
Alexey Bataev2df54a02015-03-12 08:53:29 +00002654 return LVal;
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002655}
2656
Alexey Bataev3392d762016-02-16 11:18:12 +00002657void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
Alexey Bataev2df54a02015-03-12 08:53:29 +00002658 auto *Stmt = cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt();
2659 auto *CS = dyn_cast<CompoundStmt>(Stmt);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002660 bool HasLastprivates = false;
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002661 auto &&CodeGen = [&S, Stmt, CS, &HasLastprivates](CodeGenFunction &CGF,
2662 PrePostActionTy &) {
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002663 auto &C = CGF.CGM.getContext();
2664 auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
2665 // Emit helper vars inits.
2666 LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.",
2667 CGF.Builder.getInt32(0));
2668 auto *GlobalUBVal = CS != nullptr ? CGF.Builder.getInt32(CS->size() - 1)
2669 : CGF.Builder.getInt32(0);
2670 LValue UB =
2671 createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal);
2672 LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.",
2673 CGF.Builder.getInt32(1));
2674 LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.",
2675 CGF.Builder.getInt32(0));
2676 // Loop counter.
2677 LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv.");
2678 OpaqueValueExpr IVRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
2679 CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV);
2680 OpaqueValueExpr UBRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
2681 CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
2682 // Generate condition for loop.
2683 BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue,
Adam Nemet484aa452017-03-27 19:17:25 +00002684 OK_Ordinary, S.getLocStart(), FPOptions());
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002685 // Increment for loop counter.
2686 UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary,
2687 S.getLocStart());
2688 auto BodyGen = [Stmt, CS, &S, &IV](CodeGenFunction &CGF) {
2689 // Iterate through all sections and emit a switch construct:
2690 // switch (IV) {
2691 // case 0:
2692 // <SectionStmt[0]>;
2693 // break;
2694 // ...
2695 // case <NumSection> - 1:
2696 // <SectionStmt[<NumSection> - 1]>;
2697 // break;
2698 // }
2699 // .omp.sections.exit:
2700 auto *ExitBB = CGF.createBasicBlock(".omp.sections.exit");
2701 auto *SwitchStmt = CGF.Builder.CreateSwitch(
2702 CGF.EmitLoadOfLValue(IV, S.getLocStart()).getScalarVal(), ExitBB,
2703 CS == nullptr ? 1 : CS->size());
2704 if (CS) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002705 unsigned CaseNumber = 0;
Benjamin Kramer642f1732015-07-02 21:03:14 +00002706 for (auto *SubStmt : CS->children()) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002707 auto CaseBB = CGF.createBasicBlock(".omp.sections.case");
2708 CGF.EmitBlock(CaseBB);
2709 SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB);
Benjamin Kramer642f1732015-07-02 21:03:14 +00002710 CGF.EmitStmt(SubStmt);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002711 CGF.EmitBranch(ExitBB);
Benjamin Kramer642f1732015-07-02 21:03:14 +00002712 ++CaseNumber;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002713 }
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002714 } else {
2715 auto CaseBB = CGF.createBasicBlock(".omp.sections.case");
2716 CGF.EmitBlock(CaseBB);
2717 SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB);
2718 CGF.EmitStmt(Stmt);
2719 CGF.EmitBranch(ExitBB);
Alexey Bataev2cb9b952015-04-24 03:37:03 +00002720 }
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002721 CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
Alexey Bataev2df54a02015-03-12 08:53:29 +00002722 };
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002723
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002724 CodeGenFunction::OMPPrivateScope LoopScope(CGF);
2725 if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
Alexey Bataev9efc03b2015-04-27 04:34:03 +00002726 // Emit implicit barrier to synchronize threads and avoid data races on
Alexey Bataevcd8b6a22016-02-15 08:07:17 +00002727 // initialization of firstprivate variables and post-update of lastprivate
2728 // variables.
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002729 CGF.CGM.getOpenMPRuntime().emitBarrierCall(
2730 CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
2731 /*ForceSimpleCall=*/true);
Alexey Bataev9efc03b2015-04-27 04:34:03 +00002732 }
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002733 CGF.EmitOMPPrivateClause(S, LoopScope);
2734 HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
2735 CGF.EmitOMPReductionClauseInit(S, LoopScope);
2736 (void)LoopScope.Privatize();
Alexey Bataev2cb9b952015-04-24 03:37:03 +00002737
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002738 // Emit static non-chunked loop.
Alexey Bataev9ebd7422016-05-10 09:57:36 +00002739 OpenMPScheduleTy ScheduleKind;
2740 ScheduleKind.Schedule = OMPC_SCHEDULE_static;
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002741 CGF.CGM.getOpenMPRuntime().emitForStaticInit(
Alexey Bataev9ebd7422016-05-10 09:57:36 +00002742 CGF, S.getLocStart(), ScheduleKind, /*IVSize=*/32,
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002743 /*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(), LB.getAddress(),
2744 UB.getAddress(), ST.getAddress());
2745 // UB = min(UB, GlobalUB);
2746 auto *UBVal = CGF.EmitLoadOfScalar(UB, S.getLocStart());
2747 auto *MinUBGlobalUB = CGF.Builder.CreateSelect(
2748 CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
2749 CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
2750 // IV = LB;
2751 CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getLocStart()), IV);
2752 // while (idx <= UB) { BODY; ++idx; }
2753 CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen,
2754 [](CodeGenFunction &) {});
2755 // Tell the runtime we are done.
Alexey Bataev957d8562016-11-17 15:12:05 +00002756 auto &&CodeGen = [&S](CodeGenFunction &CGF) {
2757 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocEnd());
2758 };
2759 CGF.OMPCancelStack.emitExit(CGF, S.getDirectiveKind(), CodeGen);
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00002760 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
Alexey Bataev61205072016-03-02 04:57:40 +00002761 // Emit post-update of the reduction variables if IsLastIter != 0.
2762 emitPostUpdateForReductionClause(
2763 CGF, S, [&](CodeGenFunction &CGF) -> llvm::Value * {
2764 return CGF.Builder.CreateIsNotNull(
2765 CGF.EmitLoadOfScalar(IL, S.getLocStart()));
2766 });
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002767
2768 // Emit final copy of the lastprivate variables if IsLastIter != 0.
2769 if (HasLastprivates)
2770 CGF.EmitOMPLastprivateClauseFinal(
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002771 S, /*NoFinals=*/false,
2772 CGF.Builder.CreateIsNotNull(
2773 CGF.EmitLoadOfScalar(IL, S.getLocStart())));
Alexey Bataev68adb7d2015-04-14 03:29:22 +00002774 };
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002775
2776 bool HasCancel = false;
2777 if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
2778 HasCancel = OSD->hasCancel();
2779 else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
2780 HasCancel = OPSD->hasCancel();
Alexey Bataev957d8562016-11-17 15:12:05 +00002781 OMPCancelStackRAII CancelRegion(*this, S.getDirectiveKind(), HasCancel);
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002782 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen,
2783 HasCancel);
2784 // Emit barrier for lastprivates only if 'sections' directive has 'nowait'
2785 // clause. Otherwise the barrier will be generated by the codegen for the
2786 // directive.
2787 if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) {
Alexey Bataev2cb9b952015-04-24 03:37:03 +00002788 // Emit implicit barrier to synchronize threads and avoid data races on
2789 // initialization of firstprivate variables.
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002790 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
2791 OMPD_unknown);
Alexey Bataev2cb9b952015-04-24 03:37:03 +00002792 }
Alexey Bataev68adb7d2015-04-14 03:29:22 +00002793}
Alexey Bataev2df54a02015-03-12 08:53:29 +00002794
Alexey Bataev68adb7d2015-04-14 03:29:22 +00002795void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002796 {
Alexey Bataev4ba78a42016-04-27 07:56:03 +00002797 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
Alexey Bataev3392d762016-02-16 11:18:12 +00002798 EmitSections(S);
2799 }
Alexey Bataev2df54a02015-03-12 08:53:29 +00002800 // Emit an implicit barrier at the end.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002801 if (!S.getSingleClause<OMPNowaitClause>()) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002802 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
2803 OMPD_sections);
Alexey Bataevf2685682015-03-30 04:30:22 +00002804 }
Alexey Bataev2df54a02015-03-12 08:53:29 +00002805}
2806
2807void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002808 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002809 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002810 };
Alexey Bataev4ba78a42016-04-27 07:56:03 +00002811 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
Alexey Bataev25e5b442015-09-15 12:52:43 +00002812 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen,
2813 S.hasCancel());
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002814}
2815
Alexey Bataev6956e2e2015-02-05 06:35:41 +00002816void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {
Alexey Bataeva63048e2015-03-23 06:18:07 +00002817 llvm::SmallVector<const Expr *, 8> CopyprivateVars;
Alexey Bataev420d45b2015-04-14 05:11:24 +00002818 llvm::SmallVector<const Expr *, 8> DestExprs;
Alexey Bataeva63048e2015-03-23 06:18:07 +00002819 llvm::SmallVector<const Expr *, 8> SrcExprs;
Alexey Bataeva63048e2015-03-23 06:18:07 +00002820 llvm::SmallVector<const Expr *, 8> AssignmentOps;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002821 // Check if there are any 'copyprivate' clauses associated with this
Alexey Bataevcd8b6a22016-02-15 08:07:17 +00002822 // 'single' construct.
Alexey Bataeva63048e2015-03-23 06:18:07 +00002823 // Build a list of copyprivate variables along with helper expressions
2824 // (<source>, <destination>, <destination>=<source> expressions)
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002825 for (const auto *C : S.getClausesOfKind<OMPCopyprivateClause>()) {
Alexey Bataeva63048e2015-03-23 06:18:07 +00002826 CopyprivateVars.append(C->varlists().begin(), C->varlists().end());
Alexey Bataev420d45b2015-04-14 05:11:24 +00002827 DestExprs.append(C->destination_exprs().begin(),
2828 C->destination_exprs().end());
Alexey Bataeva63048e2015-03-23 06:18:07 +00002829 SrcExprs.append(C->source_exprs().begin(), C->source_exprs().end());
Alexey Bataeva63048e2015-03-23 06:18:07 +00002830 AssignmentOps.append(C->assignment_ops().begin(),
2831 C->assignment_ops().end());
2832 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002833 // Emit code for 'single' region along with 'copyprivate' clauses
2834 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2835 Action.Enter(CGF);
2836 OMPPrivateScope SingleScope(CGF);
2837 (void)CGF.EmitOMPFirstprivateClause(S, SingleScope);
2838 CGF.EmitOMPPrivateClause(S, SingleScope);
2839 (void)SingleScope.Privatize();
2840 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
2841 };
Alexey Bataev3392d762016-02-16 11:18:12 +00002842 {
Alexey Bataev4ba78a42016-04-27 07:56:03 +00002843 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
Alexey Bataev3392d762016-02-16 11:18:12 +00002844 CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(),
2845 CopyprivateVars, DestExprs,
2846 SrcExprs, AssignmentOps);
2847 }
2848 // Emit an implicit barrier at the end (to avoid data race on firstprivate
2849 // init or if no 'nowait' clause was specified and no 'copyprivate' clause).
Alexey Bataev417089f2016-02-17 13:19:37 +00002850 if (!S.getSingleClause<OMPNowaitClause>() && CopyprivateVars.empty()) {
Alexey Bataev5521d782015-04-24 04:21:15 +00002851 CGM.getOpenMPRuntime().emitBarrierCall(
2852 *this, S.getLocStart(),
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002853 S.getSingleClause<OMPNowaitClause>() ? OMPD_unknown : OMPD_single);
Alexey Bataevf2685682015-03-30 04:30:22 +00002854 }
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002855}
2856
Alexey Bataev8d690652014-12-04 07:23:53 +00002857void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002858 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2859 Action.Enter(CGF);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002860 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002861 };
Alexey Bataev4ba78a42016-04-27 07:56:03 +00002862 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002863 CGM.getOpenMPRuntime().emitMasterRegion(*this, CodeGen, S.getLocStart());
Alexander Musman80c22892014-07-17 08:54:58 +00002864}
2865
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00002866void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002867 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
2868 Action.Enter(CGF);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002869 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002870 };
Alexey Bataevfc57d162015-12-15 10:55:09 +00002871 Expr *Hint = nullptr;
2872 if (auto *HintClause = S.getSingleClause<OMPHintClause>())
2873 Hint = HintClause->getHint();
Alexey Bataev4ba78a42016-04-27 07:56:03 +00002874 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
Alexey Bataevfc57d162015-12-15 10:55:09 +00002875 CGM.getOpenMPRuntime().emitCriticalRegion(*this,
2876 S.getDirectiveName().getAsString(),
2877 CodeGen, S.getLocStart(), Hint);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002878}
2879
Alexey Bataev671605e2015-04-13 05:28:11 +00002880void CodeGenFunction::EmitOMPParallelForDirective(
2881 const OMPParallelForDirective &S) {
2882 // Emit directive as a combined directive that consists of two implicit
2883 // directives: 'parallel' with 'for' directive.
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002884 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataev957d8562016-11-17 15:12:05 +00002885 OMPCancelStackRAII CancelRegion(CGF, OMPD_parallel_for, S.hasCancel());
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002886 CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds,
2887 emitDispatchForLoopBounds);
Alexey Bataev671605e2015-04-13 05:28:11 +00002888 };
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002889 emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen,
2890 emitEmptyBoundParameters);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002891}
2892
Alexander Musmane4e893b2014-09-23 09:33:00 +00002893void CodeGenFunction::EmitOMPParallelForSimdDirective(
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00002894 const OMPParallelForSimdDirective &S) {
2895 // Emit directive as a combined directive that consists of two implicit
2896 // directives: 'parallel' with 'for' directive.
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002897 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002898 CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds,
2899 emitDispatchForLoopBounds);
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00002900 };
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002901 emitCommonOMPParallelDirective(*this, S, OMPD_simd, CodeGen,
2902 emitEmptyBoundParameters);
Alexander Musmane4e893b2014-09-23 09:33:00 +00002903}
2904
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002905void CodeGenFunction::EmitOMPParallelSectionsDirective(
Alexey Bataev68adb7d2015-04-14 03:29:22 +00002906 const OMPParallelSectionsDirective &S) {
2907 // Emit directive as a combined directive that consists of two implicit
2908 // directives: 'parallel' with 'sections' directive.
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002909 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
2910 CGF.EmitSections(S);
2911 };
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00002912 emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen,
2913 emitEmptyBoundParameters);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002914}
2915
Alexey Bataev7292c292016-04-25 12:22:29 +00002916void CodeGenFunction::EmitOMPTaskBasedDirective(const OMPExecutableDirective &S,
2917 const RegionCodeGenTy &BodyGen,
2918 const TaskGenTy &TaskGen,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00002919 OMPTaskDataTy &Data) {
Alexey Bataev62b63b12015-03-10 07:28:44 +00002920 // Emit outlined function for task construct.
2921 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
Alexey Bataev62b63b12015-03-10 07:28:44 +00002922 auto *I = CS->getCapturedDecl()->param_begin();
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00002923 auto *PartId = std::next(I);
Alexey Bataev48591dd2016-04-20 04:01:36 +00002924 auto *TaskT = std::next(I, 4);
Alexey Bataev24b5bae2016-04-28 09:23:51 +00002925 // Check if the task is final
2926 if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) {
2927 // If the condition constant folds and can be elided, try to avoid emitting
2928 // the condition and the dead arm of the if/else.
2929 auto *Cond = Clause->getCondition();
2930 bool CondConstant;
2931 if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
2932 Data.Final.setInt(CondConstant);
2933 else
2934 Data.Final.setPointer(EvaluateExprAsBool(Cond));
2935 } else {
2936 // By default the task is not final.
2937 Data.Final.setInt(/*IntVal=*/false);
2938 }
Alexey Bataev1e1e2862016-05-10 12:21:02 +00002939 // Check if the task has 'priority' clause.
2940 if (const auto *Clause = S.getSingleClause<OMPPriorityClause>()) {
Alexey Bataev1e1e2862016-05-10 12:21:02 +00002941 auto *Prio = Clause->getPriority();
Alexey Bataev5140e742016-07-19 04:21:09 +00002942 Data.Priority.setInt(/*IntVal=*/true);
Alexey Bataevad537bb2016-05-30 09:06:50 +00002943 Data.Priority.setPointer(EmitScalarConversion(
2944 EmitScalarExpr(Prio), Prio->getType(),
2945 getContext().getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1),
2946 Prio->getExprLoc()));
Alexey Bataev1e1e2862016-05-10 12:21:02 +00002947 }
Alexey Bataev62b63b12015-03-10 07:28:44 +00002948 // The first function argument for tasks is a thread id, the second one is a
2949 // part id (0 for tied tasks, >=0 for untied task).
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002950 llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
2951 // Get list of private variables.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002952 for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) {
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002953 auto IRef = C->varlist_begin();
2954 for (auto *IInit : C->private_copies()) {
2955 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
2956 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
Alexey Bataev7292c292016-04-25 12:22:29 +00002957 Data.PrivateVars.push_back(*IRef);
2958 Data.PrivateCopies.push_back(IInit);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002959 }
2960 ++IRef;
2961 }
2962 }
2963 EmittedAsPrivate.clear();
2964 // Get list of firstprivate variables.
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00002965 for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) {
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002966 auto IRef = C->varlist_begin();
2967 auto IElemInitRef = C->inits().begin();
2968 for (auto *IInit : C->private_copies()) {
2969 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
2970 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
Alexey Bataev7292c292016-04-25 12:22:29 +00002971 Data.FirstprivateVars.push_back(*IRef);
2972 Data.FirstprivateCopies.push_back(IInit);
2973 Data.FirstprivateInits.push_back(*IElemInitRef);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002974 }
Richard Trieucc3949d2016-02-18 22:34:54 +00002975 ++IRef;
2976 ++IElemInitRef;
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002977 }
2978 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00002979 // Get list of lastprivate variables (for taskloops).
2980 llvm::DenseMap<const VarDecl *, const DeclRefExpr *> LastprivateDstsOrigs;
2981 for (const auto *C : S.getClausesOfKind<OMPLastprivateClause>()) {
2982 auto IRef = C->varlist_begin();
2983 auto ID = C->destination_exprs().begin();
2984 for (auto *IInit : C->private_copies()) {
2985 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
2986 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
2987 Data.LastprivateVars.push_back(*IRef);
2988 Data.LastprivateCopies.push_back(IInit);
2989 }
2990 LastprivateDstsOrigs.insert(
2991 {cast<VarDecl>(cast<DeclRefExpr>(*ID)->getDecl()),
2992 cast<DeclRefExpr>(*IRef)});
2993 ++IRef;
2994 ++ID;
2995 }
2996 }
Alexey Bataev1d2353d2015-06-24 11:01:36 +00002997 // Build list of dependences.
Alexey Bataev7292c292016-04-25 12:22:29 +00002998 for (const auto *C : S.getClausesOfKind<OMPDependClause>())
2999 for (auto *IRef : C->varlists())
3000 Data.Dependences.push_back(std::make_pair(C->getDependencyKind(), IRef));
Malcolm Parsonsc6e45832017-01-13 18:55:32 +00003001 auto &&CodeGen = [&Data, CS, &BodyGen, &LastprivateDstsOrigs](
Alexey Bataevf93095a2016-05-05 08:46:22 +00003002 CodeGenFunction &CGF, PrePostActionTy &Action) {
Alexey Bataev3ae88e22015-05-22 08:56:35 +00003003 // Set proper addresses for generated private copies.
Alexey Bataev7292c292016-04-25 12:22:29 +00003004 OMPPrivateScope Scope(CGF);
Alexey Bataevf93095a2016-05-05 08:46:22 +00003005 if (!Data.PrivateVars.empty() || !Data.FirstprivateVars.empty() ||
3006 !Data.LastprivateVars.empty()) {
Alexey Bataev48591dd2016-04-20 04:01:36 +00003007 auto *CopyFn = CGF.Builder.CreateLoad(
3008 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(3)));
3009 auto *PrivatesPtr = CGF.Builder.CreateLoad(
3010 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(2)));
3011 // Map privates.
3012 llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> PrivatePtrs;
3013 llvm::SmallVector<llvm::Value *, 16> CallArgs;
3014 CallArgs.push_back(PrivatesPtr);
Alexey Bataev7292c292016-04-25 12:22:29 +00003015 for (auto *E : Data.PrivateVars) {
Alexey Bataev48591dd2016-04-20 04:01:36 +00003016 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
3017 Address PrivatePtr = CGF.CreateMemTemp(
3018 CGF.getContext().getPointerType(E->getType()), ".priv.ptr.addr");
3019 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
3020 CallArgs.push_back(PrivatePtr.getPointer());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00003021 }
Alexey Bataev7292c292016-04-25 12:22:29 +00003022 for (auto *E : Data.FirstprivateVars) {
Alexey Bataev48591dd2016-04-20 04:01:36 +00003023 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
3024 Address PrivatePtr =
3025 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
3026 ".firstpriv.ptr.addr");
3027 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
3028 CallArgs.push_back(PrivatePtr.getPointer());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00003029 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00003030 for (auto *E : Data.LastprivateVars) {
3031 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
3032 Address PrivatePtr =
3033 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
3034 ".lastpriv.ptr.addr");
3035 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
3036 CallArgs.push_back(PrivatePtr.getPointer());
3037 }
Alexey Bataev48591dd2016-04-20 04:01:36 +00003038 CGF.EmitRuntimeCall(CopyFn, CallArgs);
Alexey Bataevf93095a2016-05-05 08:46:22 +00003039 for (auto &&Pair : LastprivateDstsOrigs) {
3040 auto *OrigVD = cast<VarDecl>(Pair.second->getDecl());
3041 DeclRefExpr DRE(
3042 const_cast<VarDecl *>(OrigVD),
3043 /*RefersToEnclosingVariableOrCapture=*/CGF.CapturedStmtInfo->lookup(
3044 OrigVD) != nullptr,
3045 Pair.second->getType(), VK_LValue, Pair.second->getExprLoc());
3046 Scope.addPrivate(Pair.first, [&CGF, &DRE]() {
3047 return CGF.EmitLValue(&DRE).getAddress();
3048 });
3049 }
Alexey Bataev48591dd2016-04-20 04:01:36 +00003050 for (auto &&Pair : PrivatePtrs) {
3051 Address Replacement(CGF.Builder.CreateLoad(Pair.second),
3052 CGF.getContext().getDeclAlign(Pair.first));
3053 Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; });
3054 }
Alexey Bataev3ae88e22015-05-22 08:56:35 +00003055 }
Alexey Bataev48591dd2016-04-20 04:01:36 +00003056 (void)Scope.Privatize();
3057
3058 Action.Enter(CGF);
Alexey Bataev7292c292016-04-25 12:22:29 +00003059 BodyGen(CGF);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003060 };
Alexey Bataev7292c292016-04-25 12:22:29 +00003061 auto *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
3062 S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, Data.Tied,
3063 Data.NumberOfParts);
3064 OMPLexicalScope Scope(*this, S);
3065 TaskGen(*this, OutlinedFn, Data);
3066}
3067
3068void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
3069 // Emit outlined function for task construct.
3070 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
3071 auto CapturedStruct = GenerateCapturedStmtArgument(*CS);
Alexey Bataev62b63b12015-03-10 07:28:44 +00003072 auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
Alexey Bataev1d677132015-04-22 13:57:31 +00003073 const Expr *IfCond = nullptr;
Alexey Bataev7371aa32015-09-03 08:45:56 +00003074 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
3075 if (C->getNameModifier() == OMPD_unknown ||
3076 C->getNameModifier() == OMPD_task) {
3077 IfCond = C->getCondition();
3078 break;
3079 }
Alexey Bataev1d677132015-04-22 13:57:31 +00003080 }
Alexey Bataev7292c292016-04-25 12:22:29 +00003081
Alexey Bataev24b5bae2016-04-28 09:23:51 +00003082 OMPTaskDataTy Data;
3083 // Check if we should emit tied or untied task.
3084 Data.Tied = !S.getSingleClause<OMPUntiedClause>();
Alexey Bataev7292c292016-04-25 12:22:29 +00003085 auto &&BodyGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) {
3086 CGF.EmitStmt(CS->getCapturedStmt());
3087 };
Alexey Bataev24b5bae2016-04-28 09:23:51 +00003088 auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
Alexey Bataev7292c292016-04-25 12:22:29 +00003089 IfCond](CodeGenFunction &CGF, llvm::Value *OutlinedFn,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00003090 const OMPTaskDataTy &Data) {
3091 CGF.CGM.getOpenMPRuntime().emitTaskCall(CGF, S.getLocStart(), S, OutlinedFn,
3092 SharedsTy, CapturedStruct, IfCond,
3093 Data);
Alexey Bataev7292c292016-04-25 12:22:29 +00003094 };
Alexey Bataev24b5bae2016-04-28 09:23:51 +00003095 EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Data);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00003096}
3097
Alexey Bataev9f797f32015-02-05 05:57:51 +00003098void CodeGenFunction::EmitOMPTaskyieldDirective(
3099 const OMPTaskyieldDirective &S) {
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003100 CGM.getOpenMPRuntime().emitTaskyieldCall(*this, S.getLocStart());
Alexey Bataev68446b72014-07-18 07:47:19 +00003101}
3102
Alexey Bataev8f7c1b02014-12-05 04:09:23 +00003103void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) {
Alexey Bataevf2685682015-03-30 04:30:22 +00003104 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_barrier);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00003105}
3106
Alexey Bataev8b8e2022015-04-27 05:22:09 +00003107void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S) {
3108 CGM.getOpenMPRuntime().emitTaskwaitCall(*this, S.getLocStart());
Alexey Bataev2df347a2014-07-18 10:17:07 +00003109}
3110
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003111void CodeGenFunction::EmitOMPTaskgroupDirective(
3112 const OMPTaskgroupDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003113 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
3114 Action.Enter(CGF);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003115 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003116 };
Alexey Bataev4ba78a42016-04-27 07:56:03 +00003117 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003118 CGM.getOpenMPRuntime().emitTaskgroupRegion(*this, CodeGen, S.getLocStart());
3119}
3120
Alexey Bataevcc37cc12014-11-20 04:34:54 +00003121void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) {
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003122 CGM.getOpenMPRuntime().emitFlush(*this, [&]() -> ArrayRef<const Expr *> {
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00003123 if (const auto *FlushClause = S.getSingleClause<OMPFlushClause>()) {
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003124 return llvm::makeArrayRef(FlushClause->varlist_begin(),
3125 FlushClause->varlist_end());
3126 }
3127 return llvm::None;
3128 }(), S.getLocStart());
Alexey Bataev6125da92014-07-21 11:26:11 +00003129}
3130
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003131void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S,
3132 const CodeGenLoopTy &CodeGenLoop,
3133 Expr *IncExpr) {
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003134 // Emit the loop iteration variable.
3135 auto IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
3136 auto IVDecl = cast<VarDecl>(IVExpr->getDecl());
3137 EmitVarDecl(*IVDecl);
3138
3139 // Emit the iterations count variable.
3140 // If it is not a variable, Sema decided to calculate iterations count on each
3141 // iteration (e.g., it is foldable into a constant).
3142 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
3143 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
3144 // Emit calculation of the iterations count.
3145 EmitIgnoredExpr(S.getCalcLastIteration());
3146 }
3147
3148 auto &RT = CGM.getOpenMPRuntime();
3149
Carlo Bertolli962bb802017-01-03 18:24:42 +00003150 bool HasLastprivateClause = false;
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003151 // Check pre-condition.
3152 {
Alexey Bataev5a3af132016-03-29 08:58:54 +00003153 OMPLoopScope PreInitScope(*this, S);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003154 // Skip the entire loop if we don't meet the precondition.
3155 // If the condition constant folds and can be elided, avoid emitting the
3156 // whole loop.
3157 bool CondConstant;
3158 llvm::BasicBlock *ContBlock = nullptr;
3159 if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
3160 if (!CondConstant)
3161 return;
3162 } else {
3163 auto *ThenBlock = createBasicBlock("omp.precond.then");
3164 ContBlock = createBasicBlock("omp.precond.end");
3165 emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock,
3166 getProfileCount(&S));
3167 EmitBlock(ThenBlock);
3168 incrementProfileCounter(&S);
3169 }
3170
3171 // Emit 'then' code.
3172 {
3173 // Emit helper vars inits.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003174
3175 LValue LB = EmitOMPHelperVar(
3176 *this, cast<DeclRefExpr>(
3177 (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
3178 ? S.getCombinedLowerBoundVariable()
3179 : S.getLowerBoundVariable())));
3180 LValue UB = EmitOMPHelperVar(
3181 *this, cast<DeclRefExpr>(
3182 (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
3183 ? S.getCombinedUpperBoundVariable()
3184 : S.getUpperBoundVariable())));
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003185 LValue ST =
3186 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable()));
3187 LValue IL =
3188 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
3189
3190 OMPPrivateScope LoopScope(*this);
Carlo Bertolli962bb802017-01-03 18:24:42 +00003191 if (EmitOMPFirstprivateClause(S, LoopScope)) {
3192 // Emit implicit barrier to synchronize threads and avoid data races on
3193 // initialization of firstprivate variables and post-update of
3194 // lastprivate variables.
3195 CGM.getOpenMPRuntime().emitBarrierCall(
3196 *this, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
3197 /*ForceSimpleCall=*/true);
3198 }
3199 EmitOMPPrivateClause(S, LoopScope);
3200 HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
Alexey Bataev5dff95c2016-04-22 03:56:56 +00003201 EmitOMPPrivateLoopCounters(S, LoopScope);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003202 (void)LoopScope.Privatize();
3203
3204 // Detect the distribute schedule kind and chunk.
3205 llvm::Value *Chunk = nullptr;
3206 OpenMPDistScheduleClauseKind ScheduleKind = OMPC_DIST_SCHEDULE_unknown;
3207 if (auto *C = S.getSingleClause<OMPDistScheduleClause>()) {
3208 ScheduleKind = C->getDistScheduleKind();
3209 if (const auto *Ch = C->getChunkSize()) {
3210 Chunk = EmitScalarExpr(Ch);
3211 Chunk = EmitScalarConversion(Chunk, Ch->getType(),
3212 S.getIterationVariable()->getType(),
3213 S.getLocStart());
3214 }
3215 }
3216 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
3217 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
3218
3219 // OpenMP [2.10.8, distribute Construct, Description]
3220 // If dist_schedule is specified, kind must be static. If specified,
3221 // iterations are divided into chunks of size chunk_size, chunks are
3222 // assigned to the teams of the league in a round-robin fashion in the
3223 // order of the team number. When no chunk_size is specified, the
3224 // iteration space is divided into chunks that are approximately equal
3225 // in size, and at most one chunk is distributed to each team of the
3226 // league. The size of the chunks is unspecified in this case.
3227 if (RT.isStaticNonchunked(ScheduleKind,
3228 /* Chunked */ Chunk != nullptr)) {
3229 RT.emitDistributeStaticInit(*this, S.getLocStart(), ScheduleKind,
3230 IVSize, IVSigned, /* Ordered = */ false,
3231 IL.getAddress(), LB.getAddress(),
3232 UB.getAddress(), ST.getAddress());
3233 auto LoopExit =
3234 getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit"));
3235 // UB = min(UB, GlobalUB);
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003236 EmitIgnoredExpr(isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
3237 ? S.getCombinedEnsureUpperBound()
3238 : S.getEnsureUpperBound());
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003239 // IV = LB;
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003240 EmitIgnoredExpr(isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
3241 ? S.getCombinedInit()
3242 : S.getInit());
3243
3244 Expr *Cond = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
3245 ? S.getCombinedCond()
3246 : S.getCond();
3247
3248 // for distribute alone, codegen
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003249 // while (idx <= UB) { BODY; ++idx; }
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003250 // when combined with 'for' (e.g. as in 'distribute parallel for')
3251 // while (idx <= UB) { <CodeGen rest of pragma>; idx += ST; }
3252 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), Cond, IncExpr,
3253 [&S, LoopExit, &CodeGenLoop](CodeGenFunction &CGF) {
3254 CodeGenLoop(CGF, S, LoopExit);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003255 },
3256 [](CodeGenFunction &) {});
3257 EmitBlock(LoopExit.getBlock());
3258 // Tell the runtime we are done.
3259 RT.emitForStaticFinish(*this, S.getLocStart());
3260 } else {
3261 // Emit the outer loop, which requests its work chunk [LB..UB] from
3262 // runtime and runs the inner loop to process it.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003263 const OMPLoopArguments LoopArguments = {
3264 LB.getAddress(), UB.getAddress(), ST.getAddress(), IL.getAddress(),
3265 Chunk};
3266 EmitOMPDistributeOuterLoop(ScheduleKind, S, LoopScope, LoopArguments,
3267 CodeGenLoop);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003268 }
Carlo Bertolli962bb802017-01-03 18:24:42 +00003269
3270 // Emit final copy of the lastprivate variables if IsLastIter != 0.
3271 if (HasLastprivateClause)
3272 EmitOMPLastprivateClauseFinal(
3273 S, /*NoFinals=*/false,
3274 Builder.CreateIsNotNull(
3275 EmitLoadOfScalar(IL, S.getLocStart())));
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003276 }
3277
3278 // We're now done with the loop, so jump to the continuation block.
3279 if (ContBlock) {
3280 EmitBranch(ContBlock);
3281 EmitBlock(ContBlock, true);
3282 }
3283 }
3284}
3285
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003286void CodeGenFunction::EmitOMPDistributeDirective(
3287 const OMPDistributeDirective &S) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003288 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003289
3290 CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003291 };
Alexey Bataev4ba78a42016-04-27 07:56:03 +00003292 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003293 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen,
3294 false);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003295}
3296
Alexey Bataev5f600d62015-09-29 03:48:57 +00003297static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM,
3298 const CapturedStmt *S) {
3299 CodeGenFunction CGF(CGM, /*suppressNewContext=*/true);
3300 CodeGenFunction::CGCapturedStmtInfo CapStmtInfo;
3301 CGF.CapturedStmtInfo = &CapStmtInfo;
3302 auto *Fn = CGF.GenerateOpenMPCapturedStmtFunction(*S);
3303 Fn->addFnAttr(llvm::Attribute::NoInline);
3304 return Fn;
3305}
3306
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003307void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) {
Alexey Bataev8b427062016-05-25 12:36:08 +00003308 if (!S.getAssociatedStmt()) {
3309 for (const auto *DC : S.getClausesOfKind<OMPDependClause>())
3310 CGM.getOpenMPRuntime().emitDoacrossOrdered(*this, DC);
Alexey Bataev8ef31412015-12-18 07:58:25 +00003311 return;
Alexey Bataev8b427062016-05-25 12:36:08 +00003312 }
Alexey Bataev5f600d62015-09-29 03:48:57 +00003313 auto *C = S.getSingleClause<OMPSIMDClause>();
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003314 auto &&CodeGen = [&S, C, this](CodeGenFunction &CGF,
3315 PrePostActionTy &Action) {
Alexey Bataev5f600d62015-09-29 03:48:57 +00003316 if (C) {
3317 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
3318 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
3319 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
3320 auto *OutlinedFn = emitOutlinedOrderedFunction(CGM, CS);
3321 CGF.EmitNounwindRuntimeCall(OutlinedFn, CapturedVars);
3322 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003323 Action.Enter(CGF);
Alexey Bataev5f600d62015-09-29 03:48:57 +00003324 CGF.EmitStmt(
3325 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
3326 }
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003327 };
Alexey Bataev4ba78a42016-04-27 07:56:03 +00003328 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
Alexey Bataev5f600d62015-09-29 03:48:57 +00003329 CGM.getOpenMPRuntime().emitOrderedRegion(*this, CodeGen, S.getLocStart(), !C);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003330}
3331
Alexey Bataevb57056f2015-01-22 06:17:56 +00003332static llvm::Value *convertToScalarValue(CodeGenFunction &CGF, RValue Val,
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003333 QualType SrcType, QualType DestType,
3334 SourceLocation Loc) {
Alexey Bataevb57056f2015-01-22 06:17:56 +00003335 assert(CGF.hasScalarEvaluationKind(DestType) &&
3336 "DestType must have scalar evaluation kind.");
3337 assert(!Val.isAggregate() && "Must be a scalar or complex.");
3338 return Val.isScalar()
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003339 ? CGF.EmitScalarConversion(Val.getScalarVal(), SrcType, DestType,
3340 Loc)
Alexey Bataevb57056f2015-01-22 06:17:56 +00003341 : CGF.EmitComplexToScalarConversion(Val.getComplexVal(), SrcType,
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003342 DestType, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003343}
3344
3345static CodeGenFunction::ComplexPairTy
3346convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType,
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003347 QualType DestType, SourceLocation Loc) {
Alexey Bataevb57056f2015-01-22 06:17:56 +00003348 assert(CGF.getEvaluationKind(DestType) == TEK_Complex &&
3349 "DestType must have complex evaluation kind.");
3350 CodeGenFunction::ComplexPairTy ComplexVal;
3351 if (Val.isScalar()) {
3352 // Convert the input element to the element type of the complex.
3353 auto DestElementType = DestType->castAs<ComplexType>()->getElementType();
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003354 auto ScalarVal = CGF.EmitScalarConversion(Val.getScalarVal(), SrcType,
3355 DestElementType, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003356 ComplexVal = CodeGenFunction::ComplexPairTy(
3357 ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType()));
3358 } else {
3359 assert(Val.isComplex() && "Must be a scalar or complex.");
3360 auto SrcElementType = SrcType->castAs<ComplexType>()->getElementType();
3361 auto DestElementType = DestType->castAs<ComplexType>()->getElementType();
3362 ComplexVal.first = CGF.EmitScalarConversion(
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003363 Val.getComplexVal().first, SrcElementType, DestElementType, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003364 ComplexVal.second = CGF.EmitScalarConversion(
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003365 Val.getComplexVal().second, SrcElementType, DestElementType, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003366 }
3367 return ComplexVal;
3368}
3369
Alexey Bataev5e018f92015-04-23 06:35:10 +00003370static void emitSimpleAtomicStore(CodeGenFunction &CGF, bool IsSeqCst,
3371 LValue LVal, RValue RVal) {
3372 if (LVal.isGlobalReg()) {
3373 CGF.EmitStoreThroughGlobalRegLValue(RVal, LVal);
3374 } else {
JF Bastien92f4ef12016-04-06 17:26:42 +00003375 CGF.EmitAtomicStore(RVal, LVal,
3376 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3377 : llvm::AtomicOrdering::Monotonic,
Alexey Bataev5e018f92015-04-23 06:35:10 +00003378 LVal.isVolatile(), /*IsInit=*/false);
3379 }
3380}
3381
Alexey Bataev8524d152016-01-21 12:35:58 +00003382void CodeGenFunction::emitOMPSimpleStore(LValue LVal, RValue RVal,
3383 QualType RValTy, SourceLocation Loc) {
3384 switch (getEvaluationKind(LVal.getType())) {
Alexey Bataev5e018f92015-04-23 06:35:10 +00003385 case TEK_Scalar:
Alexey Bataev8524d152016-01-21 12:35:58 +00003386 EmitStoreThroughLValue(RValue::get(convertToScalarValue(
3387 *this, RVal, RValTy, LVal.getType(), Loc)),
3388 LVal);
Alexey Bataev5e018f92015-04-23 06:35:10 +00003389 break;
3390 case TEK_Complex:
Alexey Bataev8524d152016-01-21 12:35:58 +00003391 EmitStoreOfComplex(
3392 convertToComplexValue(*this, RVal, RValTy, LVal.getType(), Loc), LVal,
Alexey Bataev5e018f92015-04-23 06:35:10 +00003393 /*isInit=*/false);
3394 break;
3395 case TEK_Aggregate:
3396 llvm_unreachable("Must be a scalar or complex.");
3397 }
3398}
3399
Alexey Bataevb57056f2015-01-22 06:17:56 +00003400static void EmitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst,
3401 const Expr *X, const Expr *V,
3402 SourceLocation Loc) {
3403 // v = x;
3404 assert(V->isLValue() && "V of 'omp atomic read' is not lvalue");
3405 assert(X->isLValue() && "X of 'omp atomic read' is not lvalue");
3406 LValue XLValue = CGF.EmitLValue(X);
3407 LValue VLValue = CGF.EmitLValue(V);
David Majnemera5b195a2015-02-14 01:35:12 +00003408 RValue Res = XLValue.isGlobalReg()
3409 ? CGF.EmitLoadOfLValue(XLValue, Loc)
JF Bastien92f4ef12016-04-06 17:26:42 +00003410 : CGF.EmitAtomicLoad(
3411 XLValue, Loc,
3412 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3413 : llvm::AtomicOrdering::Monotonic,
3414 XLValue.isVolatile());
Alexey Bataevb57056f2015-01-22 06:17:56 +00003415 // OpenMP, 2.12.6, atomic Construct
3416 // Any atomic construct with a seq_cst clause forces the atomically
3417 // performed operation to include an implicit flush operation without a
3418 // list.
3419 if (IsSeqCst)
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003420 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
Alexey Bataev8524d152016-01-21 12:35:58 +00003421 CGF.emitOMPSimpleStore(VLValue, Res, X->getType().getNonReferenceType(), Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00003422}
3423
Alexey Bataevb8329262015-02-27 06:33:30 +00003424static void EmitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst,
3425 const Expr *X, const Expr *E,
3426 SourceLocation Loc) {
3427 // x = expr;
3428 assert(X->isLValue() && "X of 'omp atomic write' is not lvalue");
Alexey Bataev5e018f92015-04-23 06:35:10 +00003429 emitSimpleAtomicStore(CGF, IsSeqCst, CGF.EmitLValue(X), CGF.EmitAnyExpr(E));
Alexey Bataevb8329262015-02-27 06:33:30 +00003430 // OpenMP, 2.12.6, atomic Construct
3431 // Any atomic construct with a seq_cst clause forces the atomically
3432 // performed operation to include an implicit flush operation without a
3433 // list.
3434 if (IsSeqCst)
3435 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
3436}
3437
Benjamin Kramer439ee9d2015-05-01 13:59:53 +00003438static std::pair<bool, RValue> emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X,
3439 RValue Update,
3440 BinaryOperatorKind BO,
3441 llvm::AtomicOrdering AO,
3442 bool IsXLHSInRHSPart) {
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003443 auto &Context = CGF.CGM.getContext();
3444 // Allow atomicrmw only if 'x' and 'update' are integer values, lvalue for 'x'
Alexey Bataevb4505a72015-03-30 05:20:59 +00003445 // expression is simple and atomic is allowed for the given type for the
3446 // target platform.
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003447 if (BO == BO_Comma || !Update.isScalar() ||
Alexey Bataev9d541a72015-05-08 11:47:16 +00003448 !Update.getScalarVal()->getType()->isIntegerTy() ||
3449 !X.isSimple() || (!isa<llvm::ConstantInt>(Update.getScalarVal()) &&
3450 (Update.getScalarVal()->getType() !=
John McCall7f416cc2015-09-08 08:05:57 +00003451 X.getAddress().getElementType())) ||
3452 !X.getAddress().getElementType()->isIntegerTy() ||
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003453 !Context.getTargetInfo().hasBuiltinAtomic(
3454 Context.getTypeSize(X.getType()), Context.toBits(X.getAlignment())))
Alexey Bataev5e018f92015-04-23 06:35:10 +00003455 return std::make_pair(false, RValue::get(nullptr));
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003456
3457 llvm::AtomicRMWInst::BinOp RMWOp;
3458 switch (BO) {
3459 case BO_Add:
3460 RMWOp = llvm::AtomicRMWInst::Add;
3461 break;
3462 case BO_Sub:
3463 if (!IsXLHSInRHSPart)
Alexey Bataev5e018f92015-04-23 06:35:10 +00003464 return std::make_pair(false, RValue::get(nullptr));
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003465 RMWOp = llvm::AtomicRMWInst::Sub;
3466 break;
3467 case BO_And:
3468 RMWOp = llvm::AtomicRMWInst::And;
3469 break;
3470 case BO_Or:
3471 RMWOp = llvm::AtomicRMWInst::Or;
3472 break;
3473 case BO_Xor:
3474 RMWOp = llvm::AtomicRMWInst::Xor;
3475 break;
3476 case BO_LT:
3477 RMWOp = X.getType()->hasSignedIntegerRepresentation()
3478 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min
3479 : llvm::AtomicRMWInst::Max)
3480 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin
3481 : llvm::AtomicRMWInst::UMax);
3482 break;
3483 case BO_GT:
3484 RMWOp = X.getType()->hasSignedIntegerRepresentation()
3485 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max
3486 : llvm::AtomicRMWInst::Min)
3487 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax
3488 : llvm::AtomicRMWInst::UMin);
3489 break;
Alexey Bataev5e018f92015-04-23 06:35:10 +00003490 case BO_Assign:
3491 RMWOp = llvm::AtomicRMWInst::Xchg;
3492 break;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003493 case BO_Mul:
3494 case BO_Div:
3495 case BO_Rem:
3496 case BO_Shl:
3497 case BO_Shr:
3498 case BO_LAnd:
3499 case BO_LOr:
Alexey Bataev5e018f92015-04-23 06:35:10 +00003500 return std::make_pair(false, RValue::get(nullptr));
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003501 case BO_PtrMemD:
3502 case BO_PtrMemI:
3503 case BO_LE:
3504 case BO_GE:
3505 case BO_EQ:
3506 case BO_NE:
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003507 case BO_AddAssign:
3508 case BO_SubAssign:
3509 case BO_AndAssign:
3510 case BO_OrAssign:
3511 case BO_XorAssign:
3512 case BO_MulAssign:
3513 case BO_DivAssign:
3514 case BO_RemAssign:
3515 case BO_ShlAssign:
3516 case BO_ShrAssign:
3517 case BO_Comma:
3518 llvm_unreachable("Unsupported atomic update operation");
3519 }
3520 auto *UpdateVal = Update.getScalarVal();
3521 if (auto *IC = dyn_cast<llvm::ConstantInt>(UpdateVal)) {
3522 UpdateVal = CGF.Builder.CreateIntCast(
John McCall7f416cc2015-09-08 08:05:57 +00003523 IC, X.getAddress().getElementType(),
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003524 X.getType()->hasSignedIntegerRepresentation());
3525 }
John McCall7f416cc2015-09-08 08:05:57 +00003526 auto *Res = CGF.Builder.CreateAtomicRMW(RMWOp, X.getPointer(), UpdateVal, AO);
Alexey Bataev5e018f92015-04-23 06:35:10 +00003527 return std::make_pair(true, RValue::get(Res));
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003528}
3529
Alexey Bataev5e018f92015-04-23 06:35:10 +00003530std::pair<bool, RValue> CodeGenFunction::EmitOMPAtomicSimpleUpdateExpr(
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003531 LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart,
3532 llvm::AtomicOrdering AO, SourceLocation Loc,
3533 const llvm::function_ref<RValue(RValue)> &CommonGen) {
3534 // Update expressions are allowed to have the following forms:
3535 // x binop= expr; -> xrval + expr;
3536 // x++, ++x -> xrval + 1;
3537 // x--, --x -> xrval - 1;
3538 // x = x binop expr; -> xrval binop expr
3539 // x = expr Op x; - > expr binop xrval;
Alexey Bataev5e018f92015-04-23 06:35:10 +00003540 auto Res = emitOMPAtomicRMW(*this, X, E, BO, AO, IsXLHSInRHSPart);
3541 if (!Res.first) {
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003542 if (X.isGlobalReg()) {
3543 // Emit an update expression: 'xrval' binop 'expr' or 'expr' binop
3544 // 'xrval'.
3545 EmitStoreThroughLValue(CommonGen(EmitLoadOfLValue(X, Loc)), X);
3546 } else {
3547 // Perform compare-and-swap procedure.
3548 EmitAtomicUpdate(X, AO, CommonGen, X.getType().isVolatileQualified());
Alexey Bataevb4505a72015-03-30 05:20:59 +00003549 }
3550 }
Alexey Bataev5e018f92015-04-23 06:35:10 +00003551 return Res;
Alexey Bataevb4505a72015-03-30 05:20:59 +00003552}
3553
3554static void EmitOMPAtomicUpdateExpr(CodeGenFunction &CGF, bool IsSeqCst,
3555 const Expr *X, const Expr *E,
3556 const Expr *UE, bool IsXLHSInRHSPart,
3557 SourceLocation Loc) {
3558 assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) &&
3559 "Update expr in 'atomic update' must be a binary operator.");
3560 auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts());
3561 // Update expressions are allowed to have the following forms:
3562 // x binop= expr; -> xrval + expr;
3563 // x++, ++x -> xrval + 1;
3564 // x--, --x -> xrval - 1;
3565 // x = x binop expr; -> xrval binop expr
3566 // x = expr Op x; - > expr binop xrval;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003567 assert(X->isLValue() && "X of 'omp atomic update' is not lvalue");
Alexey Bataevb4505a72015-03-30 05:20:59 +00003568 LValue XLValue = CGF.EmitLValue(X);
3569 RValue ExprRValue = CGF.EmitAnyExpr(E);
JF Bastien92f4ef12016-04-06 17:26:42 +00003570 auto AO = IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3571 : llvm::AtomicOrdering::Monotonic;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00003572 auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
3573 auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
3574 auto *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
3575 auto *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
3576 auto Gen =
3577 [&CGF, UE, ExprRValue, XRValExpr, ERValExpr](RValue XRValue) -> RValue {
3578 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
3579 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);
3580 return CGF.EmitAnyExpr(UE);
3581 };
Alexey Bataev5e018f92015-04-23 06:35:10 +00003582 (void)CGF.EmitOMPAtomicSimpleUpdateExpr(
3583 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
3584 // OpenMP, 2.12.6, atomic Construct
3585 // Any atomic construct with a seq_cst clause forces the atomically
3586 // performed operation to include an implicit flush operation without a
3587 // list.
3588 if (IsSeqCst)
3589 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
3590}
3591
3592static RValue convertToType(CodeGenFunction &CGF, RValue Value,
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003593 QualType SourceType, QualType ResType,
3594 SourceLocation Loc) {
Alexey Bataev5e018f92015-04-23 06:35:10 +00003595 switch (CGF.getEvaluationKind(ResType)) {
3596 case TEK_Scalar:
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003597 return RValue::get(
3598 convertToScalarValue(CGF, Value, SourceType, ResType, Loc));
Alexey Bataev5e018f92015-04-23 06:35:10 +00003599 case TEK_Complex: {
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003600 auto Res = convertToComplexValue(CGF, Value, SourceType, ResType, Loc);
Alexey Bataev5e018f92015-04-23 06:35:10 +00003601 return RValue::getComplex(Res.first, Res.second);
3602 }
3603 case TEK_Aggregate:
3604 break;
3605 }
3606 llvm_unreachable("Must be a scalar or complex.");
3607}
3608
3609static void EmitOMPAtomicCaptureExpr(CodeGenFunction &CGF, bool IsSeqCst,
3610 bool IsPostfixUpdate, const Expr *V,
3611 const Expr *X, const Expr *E,
3612 const Expr *UE, bool IsXLHSInRHSPart,
3613 SourceLocation Loc) {
3614 assert(X->isLValue() && "X of 'omp atomic capture' is not lvalue");
3615 assert(V->isLValue() && "V of 'omp atomic capture' is not lvalue");
3616 RValue NewVVal;
3617 LValue VLValue = CGF.EmitLValue(V);
3618 LValue XLValue = CGF.EmitLValue(X);
3619 RValue ExprRValue = CGF.EmitAnyExpr(E);
JF Bastien92f4ef12016-04-06 17:26:42 +00003620 auto AO = IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent
3621 : llvm::AtomicOrdering::Monotonic;
Alexey Bataev5e018f92015-04-23 06:35:10 +00003622 QualType NewVValType;
3623 if (UE) {
3624 // 'x' is updated with some additional value.
3625 assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) &&
3626 "Update expr in 'atomic capture' must be a binary operator.");
3627 auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts());
3628 // Update expressions are allowed to have the following forms:
3629 // x binop= expr; -> xrval + expr;
3630 // x++, ++x -> xrval + 1;
3631 // x--, --x -> xrval - 1;
3632 // x = x binop expr; -> xrval binop expr
3633 // x = expr Op x; - > expr binop xrval;
3634 auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
3635 auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
3636 auto *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
3637 NewVValType = XRValExpr->getType();
3638 auto *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
3639 auto &&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr,
Malcolm Parsonsc6e45832017-01-13 18:55:32 +00003640 IsPostfixUpdate](RValue XRValue) -> RValue {
Alexey Bataev5e018f92015-04-23 06:35:10 +00003641 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
3642 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);
3643 RValue Res = CGF.EmitAnyExpr(UE);
3644 NewVVal = IsPostfixUpdate ? XRValue : Res;
3645 return Res;
3646 };
3647 auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr(
3648 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
3649 if (Res.first) {
3650 // 'atomicrmw' instruction was generated.
3651 if (IsPostfixUpdate) {
3652 // Use old value from 'atomicrmw'.
3653 NewVVal = Res.second;
3654 } else {
3655 // 'atomicrmw' does not provide new value, so evaluate it using old
3656 // value of 'x'.
3657 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
3658 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, Res.second);
3659 NewVVal = CGF.EmitAnyExpr(UE);
3660 }
3661 }
3662 } else {
3663 // 'x' is simply rewritten with some 'expr'.
3664 NewVValType = X->getType().getNonReferenceType();
3665 ExprRValue = convertToType(CGF, ExprRValue, E->getType(),
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003666 X->getType().getNonReferenceType(), Loc);
Malcolm Parsonsc6e45832017-01-13 18:55:32 +00003667 auto &&Gen = [&NewVVal, ExprRValue](RValue XRValue) -> RValue {
Alexey Bataev5e018f92015-04-23 06:35:10 +00003668 NewVVal = XRValue;
3669 return ExprRValue;
3670 };
3671 // Try to perform atomicrmw xchg, otherwise simple exchange.
3672 auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr(
3673 XLValue, ExprRValue, /*BO=*/BO_Assign, /*IsXLHSInRHSPart=*/false, AO,
3674 Loc, Gen);
3675 if (Res.first) {
3676 // 'atomicrmw' instruction was generated.
3677 NewVVal = IsPostfixUpdate ? Res.second : ExprRValue;
3678 }
3679 }
3680 // Emit post-update store to 'v' of old/new 'x' value.
Alexey Bataev8524d152016-01-21 12:35:58 +00003681 CGF.emitOMPSimpleStore(VLValue, NewVVal, NewVValType, Loc);
Alexey Bataevb4505a72015-03-30 05:20:59 +00003682 // OpenMP, 2.12.6, atomic Construct
3683 // Any atomic construct with a seq_cst clause forces the atomically
3684 // performed operation to include an implicit flush operation without a
3685 // list.
3686 if (IsSeqCst)
3687 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
3688}
3689
Alexey Bataevb57056f2015-01-22 06:17:56 +00003690static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
Alexey Bataev5e018f92015-04-23 06:35:10 +00003691 bool IsSeqCst, bool IsPostfixUpdate,
3692 const Expr *X, const Expr *V, const Expr *E,
3693 const Expr *UE, bool IsXLHSInRHSPart,
3694 SourceLocation Loc) {
Alexey Bataevb57056f2015-01-22 06:17:56 +00003695 switch (Kind) {
3696 case OMPC_read:
3697 EmitOMPAtomicReadExpr(CGF, IsSeqCst, X, V, Loc);
3698 break;
3699 case OMPC_write:
Alexey Bataevb8329262015-02-27 06:33:30 +00003700 EmitOMPAtomicWriteExpr(CGF, IsSeqCst, X, E, Loc);
3701 break;
Alexey Bataevb4505a72015-03-30 05:20:59 +00003702 case OMPC_unknown:
Alexey Bataevb57056f2015-01-22 06:17:56 +00003703 case OMPC_update:
Alexey Bataevb4505a72015-03-30 05:20:59 +00003704 EmitOMPAtomicUpdateExpr(CGF, IsSeqCst, X, E, UE, IsXLHSInRHSPart, Loc);
3705 break;
Alexey Bataevb57056f2015-01-22 06:17:56 +00003706 case OMPC_capture:
Alexey Bataev5e018f92015-04-23 06:35:10 +00003707 EmitOMPAtomicCaptureExpr(CGF, IsSeqCst, IsPostfixUpdate, V, X, E, UE,
3708 IsXLHSInRHSPart, Loc);
3709 break;
Alexey Bataevb57056f2015-01-22 06:17:56 +00003710 case OMPC_if:
3711 case OMPC_final:
3712 case OMPC_num_threads:
3713 case OMPC_private:
3714 case OMPC_firstprivate:
3715 case OMPC_lastprivate:
3716 case OMPC_reduction:
3717 case OMPC_safelen:
Alexey Bataev66b15b52015-08-21 11:14:16 +00003718 case OMPC_simdlen:
Alexey Bataevb57056f2015-01-22 06:17:56 +00003719 case OMPC_collapse:
3720 case OMPC_default:
3721 case OMPC_seq_cst:
3722 case OMPC_shared:
3723 case OMPC_linear:
3724 case OMPC_aligned:
3725 case OMPC_copyin:
3726 case OMPC_copyprivate:
3727 case OMPC_flush:
3728 case OMPC_proc_bind:
3729 case OMPC_schedule:
3730 case OMPC_ordered:
3731 case OMPC_nowait:
3732 case OMPC_untied:
3733 case OMPC_threadprivate:
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00003734 case OMPC_depend:
Alexey Bataevb57056f2015-01-22 06:17:56 +00003735 case OMPC_mergeable:
Michael Wonge710d542015-08-07 16:16:36 +00003736 case OMPC_device:
Alexey Bataev346265e2015-09-25 10:37:12 +00003737 case OMPC_threads:
Alexey Bataevd14d1e62015-09-28 06:39:35 +00003738 case OMPC_simd:
Kelvin Li0bff7af2015-11-23 05:32:03 +00003739 case OMPC_map:
Kelvin Li099bb8c2015-11-24 20:50:12 +00003740 case OMPC_num_teams:
Kelvin Lia15fb1a2015-11-27 18:47:36 +00003741 case OMPC_thread_limit:
Alexey Bataeva0569352015-12-01 10:17:31 +00003742 case OMPC_priority:
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00003743 case OMPC_grainsize:
Alexey Bataevb825de12015-12-07 10:51:44 +00003744 case OMPC_nogroup:
Alexey Bataev382967a2015-12-08 12:06:20 +00003745 case OMPC_num_tasks:
Alexey Bataev28c75412015-12-15 08:19:24 +00003746 case OMPC_hint:
Carlo Bertollib4adf552016-01-15 18:50:31 +00003747 case OMPC_dist_schedule:
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00003748 case OMPC_defaultmap:
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00003749 case OMPC_uniform:
Samuel Antao661c0902016-05-26 17:39:58 +00003750 case OMPC_to:
Samuel Antaoec172c62016-05-26 17:49:04 +00003751 case OMPC_from:
Carlo Bertolli2404b172016-07-13 15:37:16 +00003752 case OMPC_use_device_ptr:
Carlo Bertolli70594e92016-07-13 17:16:49 +00003753 case OMPC_is_device_ptr:
Alexey Bataevb57056f2015-01-22 06:17:56 +00003754 llvm_unreachable("Clause is not allowed in 'omp atomic'.");
3755 }
3756}
3757
3758void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00003759 bool IsSeqCst = S.getSingleClause<OMPSeqCstClause>();
Alexey Bataevb57056f2015-01-22 06:17:56 +00003760 OpenMPClauseKind Kind = OMPC_unknown;
3761 for (auto *C : S.clauses()) {
3762 // Find first clause (skip seq_cst clause, if it is first).
3763 if (C->getClauseKind() != OMPC_seq_cst) {
3764 Kind = C->getClauseKind();
3765 break;
3766 }
3767 }
Alexey Bataev10fec572015-03-11 04:48:56 +00003768
3769 const auto *CS =
3770 S.getAssociatedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
Alexey Bataev5e018f92015-04-23 06:35:10 +00003771 if (const auto *EWC = dyn_cast<ExprWithCleanups>(CS)) {
Alexey Bataev10fec572015-03-11 04:48:56 +00003772 enterFullExpression(EWC);
Alexey Bataev5e018f92015-04-23 06:35:10 +00003773 }
3774 // Processing for statements under 'atomic capture'.
3775 if (const auto *Compound = dyn_cast<CompoundStmt>(CS)) {
3776 for (const auto *C : Compound->body()) {
3777 if (const auto *EWC = dyn_cast<ExprWithCleanups>(C)) {
3778 enterFullExpression(EWC);
3779 }
3780 }
3781 }
Alexey Bataev10fec572015-03-11 04:48:56 +00003782
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003783 auto &&CodeGen = [&S, Kind, IsSeqCst, CS](CodeGenFunction &CGF,
3784 PrePostActionTy &) {
Alexey Bataev33c56402015-12-14 09:26:19 +00003785 CGF.EmitStopPoint(CS);
Alexey Bataev5e018f92015-04-23 06:35:10 +00003786 EmitOMPAtomicExpr(CGF, Kind, IsSeqCst, S.isPostfixUpdate(), S.getX(),
3787 S.getV(), S.getExpr(), S.getUpdateExpr(),
3788 S.isXLHSInRHSPart(), S.getLocStart());
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003789 };
Alexey Bataev4ba78a42016-04-27 07:56:03 +00003790 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00003791 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_atomic, CodeGen);
Alexey Bataev0162e452014-07-22 10:10:35 +00003792}
3793
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00003794static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
3795 const OMPExecutableDirective &S,
3796 const RegionCodeGenTy &CodeGen) {
3797 assert(isOpenMPTargetExecutionDirective(S.getDirectiveKind()));
3798 CodeGenModule &CGM = CGF.CGM;
Samuel Antaobed3c462015-10-02 16:14:20 +00003799 const CapturedStmt &CS = *cast<CapturedStmt>(S.getAssociatedStmt());
3800
Samuel Antaoee8fb302016-01-06 13:42:12 +00003801 llvm::Function *Fn = nullptr;
3802 llvm::Constant *FnID = nullptr;
Samuel Antaobed3c462015-10-02 16:14:20 +00003803
Samuel Antaobed3c462015-10-02 16:14:20 +00003804 const Expr *IfCond = nullptr;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00003805 // Check for the at most one if clause associated with the target region.
3806 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
3807 if (C->getNameModifier() == OMPD_unknown ||
3808 C->getNameModifier() == OMPD_target) {
3809 IfCond = C->getCondition();
3810 break;
3811 }
Samuel Antaobed3c462015-10-02 16:14:20 +00003812 }
3813
3814 // Check if we have any device clause associated with the directive.
3815 const Expr *Device = nullptr;
3816 if (auto *C = S.getSingleClause<OMPDeviceClause>()) {
3817 Device = C->getDevice();
3818 }
3819
Samuel Antaoee8fb302016-01-06 13:42:12 +00003820 // Check if we have an if clause whose conditional always evaluates to false
3821 // or if we do not have any targets specified. If so the target region is not
3822 // an offload entry point.
3823 bool IsOffloadEntry = true;
3824 if (IfCond) {
3825 bool Val;
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00003826 if (CGF.ConstantFoldsToSimpleInteger(IfCond, Val) && !Val)
Samuel Antaoee8fb302016-01-06 13:42:12 +00003827 IsOffloadEntry = false;
3828 }
3829 if (CGM.getLangOpts().OMPTargetTriples.empty())
3830 IsOffloadEntry = false;
3831
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00003832 assert(CGF.CurFuncDecl && "No parent declaration for target region!");
Samuel Antaoee8fb302016-01-06 13:42:12 +00003833 StringRef ParentName;
3834 // In case we have Ctors/Dtors we use the complete type variant to produce
3835 // the mangling of the device outlined kernel.
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00003836 if (auto *D = dyn_cast<CXXConstructorDecl>(CGF.CurFuncDecl))
Samuel Antaoee8fb302016-01-06 13:42:12 +00003837 ParentName = CGM.getMangledName(GlobalDecl(D, Ctor_Complete));
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00003838 else if (auto *D = dyn_cast<CXXDestructorDecl>(CGF.CurFuncDecl))
Samuel Antaoee8fb302016-01-06 13:42:12 +00003839 ParentName = CGM.getMangledName(GlobalDecl(D, Dtor_Complete));
3840 else
3841 ParentName =
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00003842 CGM.getMangledName(GlobalDecl(cast<FunctionDecl>(CGF.CurFuncDecl)));
Samuel Antaoee8fb302016-01-06 13:42:12 +00003843
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00003844 // Emit target region as a standalone region.
3845 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(S, ParentName, Fn, FnID,
3846 IsOffloadEntry, CodeGen);
3847 OMPLexicalScope Scope(CGF, S);
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00003848 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
3849 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00003850 CGM.getOpenMPRuntime().emitTargetCall(CGF, S, Fn, FnID, IfCond, Device,
Samuel Antaobed3c462015-10-02 16:14:20 +00003851 CapturedVars);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00003852}
3853
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00003854static void emitTargetRegion(CodeGenFunction &CGF, const OMPTargetDirective &S,
3855 PrePostActionTy &Action) {
3856 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
3857 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
3858 CGF.EmitOMPPrivateClause(S, PrivateScope);
3859 (void)PrivateScope.Privatize();
3860
3861 Action.Enter(CGF);
3862 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
3863}
3864
3865void CodeGenFunction::EmitOMPTargetDeviceFunction(CodeGenModule &CGM,
3866 StringRef ParentName,
3867 const OMPTargetDirective &S) {
3868 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
3869 emitTargetRegion(CGF, S, Action);
3870 };
3871 llvm::Function *Fn;
3872 llvm::Constant *Addr;
3873 // Emit target region as a standalone region.
3874 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
3875 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
3876 assert(Fn && Addr && "Target device function emission failed.");
3877}
3878
3879void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) {
3880 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
3881 emitTargetRegion(CGF, S, Action);
3882 };
3883 emitCommonOMPTargetDirective(*this, S, CodeGen);
3884}
3885
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00003886static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF,
3887 const OMPExecutableDirective &S,
3888 OpenMPDirectiveKind InnermostKind,
3889 const RegionCodeGenTy &CodeGen) {
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003890 const CapturedStmt *CS = S.getCapturedStmt(OMPD_teams);
3891 auto OutlinedFn = CGF.CGM.getOpenMPRuntime().emitTeamsOutlinedFunction(
3892 S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
Samuel Antaob68e2db2016-03-03 16:20:23 +00003893
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00003894 const OMPNumTeamsClause *NT = S.getSingleClause<OMPNumTeamsClause>();
3895 const OMPThreadLimitClause *TL = S.getSingleClause<OMPThreadLimitClause>();
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00003896 if (NT || TL) {
Carlo Bertollic6872252016-04-04 15:55:02 +00003897 Expr *NumTeams = (NT) ? NT->getNumTeams() : nullptr;
3898 Expr *ThreadLimit = (TL) ? TL->getThreadLimit() : nullptr;
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00003899
Carlo Bertollic6872252016-04-04 15:55:02 +00003900 CGF.CGM.getOpenMPRuntime().emitNumTeamsClause(CGF, NumTeams, ThreadLimit,
3901 S.getLocStart());
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00003902 }
3903
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00003904 OMPTeamsScope Scope(CGF, S);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003905 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
3906 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00003907 CGF.CGM.getOpenMPRuntime().emitTeamsCall(CGF, S, S.getLocStart(), OutlinedFn,
3908 CapturedVars);
3909}
3910
3911void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &S) {
Kelvin Li51336dd2016-12-15 17:55:32 +00003912 // Emit teams region as a standalone region.
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003913 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00003914 OMPPrivateScope PrivateScope(CGF);
Carlo Bertolli6ad7b5a2016-03-03 22:09:40 +00003915 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
3916 CGF.EmitOMPPrivateClause(S, PrivateScope);
Arpith Chacko Jacobfc711b12017-02-16 16:48:49 +00003917 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00003918 (void)PrivateScope.Privatize();
3919 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
Arpith Chacko Jacobfc711b12017-02-16 16:48:49 +00003920 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00003921 };
3922 emitCommonOMPTeamsDirective(*this, S, OMPD_teams, CodeGen);
Arpith Chacko Jacobfc711b12017-02-16 16:48:49 +00003923 emitPostUpdateForReductionClause(
3924 *this, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
Alexey Bataev13314bf2014-10-09 04:18:56 +00003925}
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003926
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00003927static void emitTargetTeamsRegion(CodeGenFunction &CGF, PrePostActionTy &Action,
3928 const OMPTargetTeamsDirective &S) {
3929 auto *CS = S.getCapturedStmt(OMPD_teams);
3930 Action.Enter(CGF);
3931 auto &&CodeGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) {
3932 // TODO: Add support for clauses.
3933 CGF.EmitStmt(CS->getCapturedStmt());
3934 };
3935 emitCommonOMPTeamsDirective(CGF, S, OMPD_teams, CodeGen);
3936}
3937
3938void CodeGenFunction::EmitOMPTargetTeamsDeviceFunction(
3939 CodeGenModule &CGM, StringRef ParentName,
3940 const OMPTargetTeamsDirective &S) {
3941 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
3942 emitTargetTeamsRegion(CGF, Action, S);
3943 };
3944 llvm::Function *Fn;
3945 llvm::Constant *Addr;
3946 // Emit target region as a standalone region.
3947 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
3948 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
3949 assert(Fn && Addr && "Target device function emission failed.");
3950}
3951
3952void CodeGenFunction::EmitOMPTargetTeamsDirective(
3953 const OMPTargetTeamsDirective &S) {
3954 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
3955 emitTargetTeamsRegion(CGF, Action, S);
3956 };
3957 emitCommonOMPTargetDirective(*this, S, CodeGen);
3958}
3959
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003960void CodeGenFunction::EmitOMPCancellationPointDirective(
3961 const OMPCancellationPointDirective &S) {
Alexey Bataev0f34da12015-07-02 04:17:07 +00003962 CGM.getOpenMPRuntime().emitCancellationPointCall(*this, S.getLocStart(),
3963 S.getCancelRegion());
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003964}
3965
Alexey Bataev80909872015-07-02 11:25:17 +00003966void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) {
Alexey Bataev87933c72015-09-18 08:07:34 +00003967 const Expr *IfCond = nullptr;
3968 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
3969 if (C->getNameModifier() == OMPD_unknown ||
3970 C->getNameModifier() == OMPD_cancel) {
3971 IfCond = C->getCondition();
3972 break;
3973 }
3974 }
3975 CGM.getOpenMPRuntime().emitCancelCall(*this, S.getLocStart(), IfCond,
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00003976 S.getCancelRegion());
Alexey Bataev80909872015-07-02 11:25:17 +00003977}
3978
Alexey Bataev81c7ea02015-07-03 09:56:58 +00003979CodeGenFunction::JumpDest
3980CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) {
Alexey Bataev957d8562016-11-17 15:12:05 +00003981 if (Kind == OMPD_parallel || Kind == OMPD_task ||
3982 Kind == OMPD_target_parallel)
Alexey Bataev81c7ea02015-07-03 09:56:58 +00003983 return ReturnBlock;
Alexey Bataev25e5b442015-09-15 12:52:43 +00003984 assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
Alexey Bataev957d8562016-11-17 15:12:05 +00003985 Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for ||
3986 Kind == OMPD_distribute_parallel_for ||
3987 Kind == OMPD_target_parallel_for);
3988 return OMPCancelStack.getExitBlock();
Alexey Bataev81c7ea02015-07-03 09:56:58 +00003989}
Michael Wong65f367f2015-07-21 13:44:28 +00003990
Samuel Antaocc10b852016-07-28 14:23:26 +00003991void CodeGenFunction::EmitOMPUseDevicePtrClause(
3992 const OMPClause &NC, OMPPrivateScope &PrivateScope,
3993 const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap) {
3994 const auto &C = cast<OMPUseDevicePtrClause>(NC);
3995 auto OrigVarIt = C.varlist_begin();
3996 auto InitIt = C.inits().begin();
3997 for (auto PvtVarIt : C.private_copies()) {
3998 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*OrigVarIt)->getDecl());
3999 auto *InitVD = cast<VarDecl>(cast<DeclRefExpr>(*InitIt)->getDecl());
4000 auto *PvtVD = cast<VarDecl>(cast<DeclRefExpr>(PvtVarIt)->getDecl());
4001
4002 // In order to identify the right initializer we need to match the
4003 // declaration used by the mapping logic. In some cases we may get
4004 // OMPCapturedExprDecl that refers to the original declaration.
4005 const ValueDecl *MatchingVD = OrigVD;
4006 if (auto *OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) {
4007 // OMPCapturedExprDecl are used to privative fields of the current
4008 // structure.
4009 auto *ME = cast<MemberExpr>(OED->getInit());
4010 assert(isa<CXXThisExpr>(ME->getBase()) &&
4011 "Base should be the current struct!");
4012 MatchingVD = ME->getMemberDecl();
4013 }
4014
4015 // If we don't have information about the current list item, move on to
4016 // the next one.
4017 auto InitAddrIt = CaptureDeviceAddrMap.find(MatchingVD);
4018 if (InitAddrIt == CaptureDeviceAddrMap.end())
4019 continue;
4020
4021 bool IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address {
4022 // Initialize the temporary initialization variable with the address we
4023 // get from the runtime library. We have to cast the source address
4024 // because it is always a void *. References are materialized in the
4025 // privatization scope, so the initialization here disregards the fact
4026 // the original variable is a reference.
4027 QualType AddrQTy =
4028 getContext().getPointerType(OrigVD->getType().getNonReferenceType());
4029 llvm::Type *AddrTy = ConvertTypeForMem(AddrQTy);
4030 Address InitAddr = Builder.CreateBitCast(InitAddrIt->second, AddrTy);
4031 setAddrOfLocalVar(InitVD, InitAddr);
4032
4033 // Emit private declaration, it will be initialized by the value we
4034 // declaration we just added to the local declarations map.
4035 EmitDecl(*PvtVD);
4036
4037 // The initialization variables reached its purpose in the emission
4038 // ofthe previous declaration, so we don't need it anymore.
4039 LocalDeclMap.erase(InitVD);
4040
4041 // Return the address of the private variable.
4042 return GetAddrOfLocalVar(PvtVD);
4043 });
4044 assert(IsRegistered && "firstprivate var already registered as private");
4045 // Silence the warning about unused variable.
4046 (void)IsRegistered;
4047
4048 ++OrigVarIt;
4049 ++InitIt;
4050 }
4051}
4052
Michael Wong65f367f2015-07-21 13:44:28 +00004053// Generate the instructions for '#pragma omp target data' directive.
4054void CodeGenFunction::EmitOMPTargetDataDirective(
4055 const OMPTargetDataDirective &S) {
Samuel Antaocc10b852016-07-28 14:23:26 +00004056 CGOpenMPRuntime::TargetDataInfo Info(/*RequiresDevicePointerInfo=*/true);
4057
4058 // Create a pre/post action to signal the privatization of the device pointer.
4059 // This action can be replaced by the OpenMP runtime code generation to
4060 // deactivate privatization.
4061 bool PrivatizeDevicePointers = false;
4062 class DevicePointerPrivActionTy : public PrePostActionTy {
4063 bool &PrivatizeDevicePointers;
4064
4065 public:
4066 explicit DevicePointerPrivActionTy(bool &PrivatizeDevicePointers)
4067 : PrePostActionTy(), PrivatizeDevicePointers(PrivatizeDevicePointers) {}
4068 void Enter(CodeGenFunction &CGF) override {
4069 PrivatizeDevicePointers = true;
4070 }
Samuel Antaodf158d52016-04-27 22:58:19 +00004071 };
Samuel Antaocc10b852016-07-28 14:23:26 +00004072 DevicePointerPrivActionTy PrivAction(PrivatizeDevicePointers);
4073
4074 auto &&CodeGen = [&S, &Info, &PrivatizeDevicePointers](
4075 CodeGenFunction &CGF, PrePostActionTy &Action) {
4076 auto &&InnermostCodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
4077 CGF.EmitStmt(
4078 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
4079 };
4080
4081 // Codegen that selects wheather to generate the privatization code or not.
4082 auto &&PrivCodeGen = [&S, &Info, &PrivatizeDevicePointers,
4083 &InnermostCodeGen](CodeGenFunction &CGF,
4084 PrePostActionTy &Action) {
4085 RegionCodeGenTy RCG(InnermostCodeGen);
4086 PrivatizeDevicePointers = false;
4087
4088 // Call the pre-action to change the status of PrivatizeDevicePointers if
4089 // needed.
4090 Action.Enter(CGF);
4091
4092 if (PrivatizeDevicePointers) {
4093 OMPPrivateScope PrivateScope(CGF);
4094 // Emit all instances of the use_device_ptr clause.
4095 for (const auto *C : S.getClausesOfKind<OMPUseDevicePtrClause>())
4096 CGF.EmitOMPUseDevicePtrClause(*C, PrivateScope,
4097 Info.CaptureDeviceAddrMap);
4098 (void)PrivateScope.Privatize();
4099 RCG(CGF);
4100 } else
4101 RCG(CGF);
4102 };
4103
4104 // Forward the provided action to the privatization codegen.
4105 RegionCodeGenTy PrivRCG(PrivCodeGen);
4106 PrivRCG.setAction(Action);
4107
4108 // Notwithstanding the body of the region is emitted as inlined directive,
4109 // we don't use an inline scope as changes in the references inside the
4110 // region are expected to be visible outside, so we do not privative them.
4111 OMPLexicalScope Scope(CGF, S);
4112 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_target_data,
4113 PrivRCG);
4114 };
4115
4116 RegionCodeGenTy RCG(CodeGen);
Samuel Antaodf158d52016-04-27 22:58:19 +00004117
4118 // If we don't have target devices, don't bother emitting the data mapping
4119 // code.
4120 if (CGM.getLangOpts().OMPTargetTriples.empty()) {
Samuel Antaocc10b852016-07-28 14:23:26 +00004121 RCG(*this);
Samuel Antaodf158d52016-04-27 22:58:19 +00004122 return;
4123 }
4124
4125 // Check if we have any if clause associated with the directive.
4126 const Expr *IfCond = nullptr;
4127 if (auto *C = S.getSingleClause<OMPIfClause>())
4128 IfCond = C->getCondition();
4129
4130 // Check if we have any device clause associated with the directive.
4131 const Expr *Device = nullptr;
4132 if (auto *C = S.getSingleClause<OMPDeviceClause>())
4133 Device = C->getDevice();
4134
Samuel Antaocc10b852016-07-28 14:23:26 +00004135 // Set the action to signal privatization of device pointers.
4136 RCG.setAction(PrivAction);
4137
4138 // Emit region code.
4139 CGM.getOpenMPRuntime().emitTargetDataCalls(*this, S, IfCond, Device, RCG,
4140 Info);
Michael Wong65f367f2015-07-21 13:44:28 +00004141}
Alexey Bataev49f6e782015-12-01 04:18:41 +00004142
Samuel Antaodf67fc42016-01-19 19:15:56 +00004143void CodeGenFunction::EmitOMPTargetEnterDataDirective(
4144 const OMPTargetEnterDataDirective &S) {
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00004145 // If we don't have target devices, don't bother emitting the data mapping
4146 // code.
4147 if (CGM.getLangOpts().OMPTargetTriples.empty())
4148 return;
4149
4150 // Check if we have any if clause associated with the directive.
4151 const Expr *IfCond = nullptr;
4152 if (auto *C = S.getSingleClause<OMPIfClause>())
4153 IfCond = C->getCondition();
4154
4155 // Check if we have any device clause associated with the directive.
4156 const Expr *Device = nullptr;
4157 if (auto *C = S.getSingleClause<OMPDeviceClause>())
4158 Device = C->getDevice();
4159
Samuel Antao8d2d7302016-05-26 18:30:22 +00004160 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
Samuel Antaodf67fc42016-01-19 19:15:56 +00004161}
4162
Samuel Antao72590762016-01-19 20:04:50 +00004163void CodeGenFunction::EmitOMPTargetExitDataDirective(
4164 const OMPTargetExitDataDirective &S) {
Samuel Antao8dd66282016-04-27 23:14:30 +00004165 // If we don't have target devices, don't bother emitting the data mapping
4166 // code.
4167 if (CGM.getLangOpts().OMPTargetTriples.empty())
4168 return;
4169
4170 // Check if we have any if clause associated with the directive.
4171 const Expr *IfCond = nullptr;
4172 if (auto *C = S.getSingleClause<OMPIfClause>())
4173 IfCond = C->getCondition();
4174
4175 // Check if we have any device clause associated with the directive.
4176 const Expr *Device = nullptr;
4177 if (auto *C = S.getSingleClause<OMPDeviceClause>())
4178 Device = C->getDevice();
4179
Samuel Antao8d2d7302016-05-26 18:30:22 +00004180 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
Samuel Antao72590762016-01-19 20:04:50 +00004181}
4182
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004183static void emitTargetParallelRegion(CodeGenFunction &CGF,
4184 const OMPTargetParallelDirective &S,
4185 PrePostActionTy &Action) {
4186 // Get the captured statement associated with the 'parallel' region.
4187 auto *CS = S.getCapturedStmt(OMPD_parallel);
4188 Action.Enter(CGF);
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00004189 auto &&CodeGen = [&S, CS](CodeGenFunction &CGF, PrePostActionTy &) {
4190 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
4191 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
4192 CGF.EmitOMPPrivateClause(S, PrivateScope);
4193 CGF.EmitOMPReductionClauseInit(S, PrivateScope);
4194 (void)PrivateScope.Privatize();
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004195 // TODO: Add support for clauses.
4196 CGF.EmitStmt(CS->getCapturedStmt());
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00004197 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004198 };
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00004199 emitCommonOMPParallelDirective(CGF, S, OMPD_parallel, CodeGen,
4200 emitEmptyBoundParameters);
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00004201 emitPostUpdateForReductionClause(
4202 CGF, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004203}
4204
4205void CodeGenFunction::EmitOMPTargetParallelDeviceFunction(
4206 CodeGenModule &CGM, StringRef ParentName,
4207 const OMPTargetParallelDirective &S) {
4208 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4209 emitTargetParallelRegion(CGF, S, Action);
4210 };
4211 llvm::Function *Fn;
4212 llvm::Constant *Addr;
4213 // Emit target region as a standalone region.
4214 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
4215 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
4216 assert(Fn && Addr && "Target device function emission failed.");
4217}
4218
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004219void CodeGenFunction::EmitOMPTargetParallelDirective(
4220 const OMPTargetParallelDirective &S) {
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00004221 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
4222 emitTargetParallelRegion(CGF, S, Action);
4223 };
4224 emitCommonOMPTargetDirective(*this, S, CodeGen);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004225}
4226
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004227void CodeGenFunction::EmitOMPTargetParallelForDirective(
4228 const OMPTargetParallelForDirective &S) {
4229 // TODO: codegen for target parallel for.
4230}
4231
Alexey Bataev7292c292016-04-25 12:22:29 +00004232/// Emit a helper variable and return corresponding lvalue.
4233static void mapParam(CodeGenFunction &CGF, const DeclRefExpr *Helper,
4234 const ImplicitParamDecl *PVD,
4235 CodeGenFunction::OMPPrivateScope &Privates) {
4236 auto *VDecl = cast<VarDecl>(Helper->getDecl());
4237 Privates.addPrivate(
4238 VDecl, [&CGF, PVD]() -> Address { return CGF.GetAddrOfLocalVar(PVD); });
4239}
4240
4241void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) {
4242 assert(isOpenMPTaskLoopDirective(S.getDirectiveKind()));
4243 // Emit outlined function for task construct.
4244 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
4245 auto CapturedStruct = GenerateCapturedStmtArgument(*CS);
4246 auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
4247 const Expr *IfCond = nullptr;
4248 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
4249 if (C->getNameModifier() == OMPD_unknown ||
4250 C->getNameModifier() == OMPD_taskloop) {
4251 IfCond = C->getCondition();
4252 break;
4253 }
4254 }
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004255
4256 OMPTaskDataTy Data;
4257 // Check if taskloop must be emitted without taskgroup.
4258 Data.Nogroup = S.getSingleClause<OMPNogroupClause>();
Alexey Bataev7292c292016-04-25 12:22:29 +00004259 // TODO: Check if we should emit tied or untied task.
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004260 Data.Tied = true;
4261 // Set scheduling for taskloop
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00004262 if (const auto* Clause = S.getSingleClause<OMPGrainsizeClause>()) {
4263 // grainsize clause
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004264 Data.Schedule.setInt(/*IntVal=*/false);
4265 Data.Schedule.setPointer(EmitScalarExpr(Clause->getGrainsize()));
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00004266 } else if (const auto* Clause = S.getSingleClause<OMPNumTasksClause>()) {
4267 // num_tasks clause
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004268 Data.Schedule.setInt(/*IntVal=*/true);
4269 Data.Schedule.setPointer(EmitScalarExpr(Clause->getNumTasks()));
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00004270 }
Alexey Bataev7292c292016-04-25 12:22:29 +00004271
4272 auto &&BodyGen = [CS, &S](CodeGenFunction &CGF, PrePostActionTy &) {
4273 // if (PreCond) {
4274 // for (IV in 0..LastIteration) BODY;
4275 // <Final counter/linear vars updates>;
4276 // }
4277 //
4278
4279 // Emit: if (PreCond) - begin.
4280 // If the condition constant folds and can be elided, avoid emitting the
4281 // whole loop.
4282 bool CondConstant;
4283 llvm::BasicBlock *ContBlock = nullptr;
4284 OMPLoopScope PreInitScope(CGF, S);
4285 if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
4286 if (!CondConstant)
4287 return;
4288 } else {
4289 auto *ThenBlock = CGF.createBasicBlock("taskloop.if.then");
4290 ContBlock = CGF.createBasicBlock("taskloop.if.end");
4291 emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
4292 CGF.getProfileCount(&S));
4293 CGF.EmitBlock(ThenBlock);
4294 CGF.incrementProfileCounter(&S);
4295 }
4296
Alexey Bataev1e73ef32016-04-28 12:14:51 +00004297 if (isOpenMPSimdDirective(S.getDirectiveKind()))
4298 CGF.EmitOMPSimdInit(S);
4299
Alexey Bataev7292c292016-04-25 12:22:29 +00004300 OMPPrivateScope LoopScope(CGF);
4301 // Emit helper vars inits.
4302 enum { LowerBound = 5, UpperBound, Stride, LastIter };
4303 auto *I = CS->getCapturedDecl()->param_begin();
4304 auto *LBP = std::next(I, LowerBound);
4305 auto *UBP = std::next(I, UpperBound);
4306 auto *STP = std::next(I, Stride);
4307 auto *LIP = std::next(I, LastIter);
4308 mapParam(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()), *LBP,
4309 LoopScope);
4310 mapParam(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()), *UBP,
4311 LoopScope);
4312 mapParam(CGF, cast<DeclRefExpr>(S.getStrideVariable()), *STP, LoopScope);
4313 mapParam(CGF, cast<DeclRefExpr>(S.getIsLastIterVariable()), *LIP,
4314 LoopScope);
4315 CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
Alexey Bataevf93095a2016-05-05 08:46:22 +00004316 bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
Alexey Bataev7292c292016-04-25 12:22:29 +00004317 (void)LoopScope.Privatize();
4318 // Emit the loop iteration variable.
4319 const Expr *IVExpr = S.getIterationVariable();
4320 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
4321 CGF.EmitVarDecl(*IVDecl);
4322 CGF.EmitIgnoredExpr(S.getInit());
4323
4324 // Emit the iterations count variable.
4325 // If it is not a variable, Sema decided to calculate iterations count on
4326 // each iteration (e.g., it is foldable into a constant).
4327 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
4328 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
4329 // Emit calculation of the iterations count.
4330 CGF.EmitIgnoredExpr(S.getCalcLastIteration());
4331 }
4332
4333 CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
4334 S.getInc(),
4335 [&S](CodeGenFunction &CGF) {
4336 CGF.EmitOMPLoopBody(S, JumpDest());
4337 CGF.EmitStopPoint(&S);
4338 },
4339 [](CodeGenFunction &) {});
4340 // Emit: if (PreCond) - end.
4341 if (ContBlock) {
4342 CGF.EmitBranch(ContBlock);
4343 CGF.EmitBlock(ContBlock, true);
4344 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00004345 // Emit final copy of the lastprivate variables if IsLastIter != 0.
4346 if (HasLastprivateClause) {
4347 CGF.EmitOMPLastprivateClauseFinal(
4348 S, isOpenMPSimdDirective(S.getDirectiveKind()),
4349 CGF.Builder.CreateIsNotNull(CGF.EmitLoadOfScalar(
4350 CGF.GetAddrOfLocalVar(*LIP), /*Volatile=*/false,
4351 (*LIP)->getType(), S.getLocStart())));
4352 }
Alexey Bataev7292c292016-04-25 12:22:29 +00004353 };
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004354 auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
4355 IfCond](CodeGenFunction &CGF, llvm::Value *OutlinedFn,
4356 const OMPTaskDataTy &Data) {
Alexey Bataev7292c292016-04-25 12:22:29 +00004357 auto &&CodeGen = [&](CodeGenFunction &CGF, PrePostActionTy &) {
4358 OMPLoopScope PreInitScope(CGF, S);
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004359 CGF.CGM.getOpenMPRuntime().emitTaskLoopCall(CGF, S.getLocStart(), S,
4360 OutlinedFn, SharedsTy,
4361 CapturedStruct, IfCond, Data);
Alexey Bataev7292c292016-04-25 12:22:29 +00004362 };
4363 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop,
4364 CodeGen);
4365 };
Alexey Bataev33446032017-07-12 18:09:32 +00004366 if (Data.Nogroup)
4367 EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Data);
4368 else {
4369 CGM.getOpenMPRuntime().emitTaskgroupRegion(
4370 *this,
4371 [&S, &BodyGen, &TaskGen, &Data](CodeGenFunction &CGF,
4372 PrePostActionTy &Action) {
4373 Action.Enter(CGF);
4374 CGF.EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Data);
4375 },
4376 S.getLocStart());
4377 }
Alexey Bataev7292c292016-04-25 12:22:29 +00004378}
4379
Alexey Bataev49f6e782015-12-01 04:18:41 +00004380void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) {
Alexey Bataev7292c292016-04-25 12:22:29 +00004381 EmitOMPTaskLoopBasedDirective(S);
Alexey Bataev49f6e782015-12-01 04:18:41 +00004382}
4383
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004384void CodeGenFunction::EmitOMPTaskLoopSimdDirective(
4385 const OMPTaskLoopSimdDirective &S) {
Alexey Bataev1e73ef32016-04-28 12:14:51 +00004386 EmitOMPTaskLoopBasedDirective(S);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004387}
Samuel Antao686c70c2016-05-26 17:30:50 +00004388
4389// Generate the instructions for '#pragma omp target update' directive.
4390void CodeGenFunction::EmitOMPTargetUpdateDirective(
4391 const OMPTargetUpdateDirective &S) {
Samuel Antao8d2d7302016-05-26 18:30:22 +00004392 // If we don't have target devices, don't bother emitting the data mapping
4393 // code.
4394 if (CGM.getLangOpts().OMPTargetTriples.empty())
4395 return;
4396
4397 // Check if we have any if clause associated with the directive.
4398 const Expr *IfCond = nullptr;
4399 if (auto *C = S.getSingleClause<OMPIfClause>())
4400 IfCond = C->getCondition();
4401
4402 // Check if we have any device clause associated with the directive.
4403 const Expr *Device = nullptr;
4404 if (auto *C = S.getSingleClause<OMPDeviceClause>())
4405 Device = C->getDevice();
4406
4407 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
Samuel Antao686c70c2016-05-26 17:30:50 +00004408}