blob: 02a02de2cc9e5e90a533d22f1ee65700cd15dd35 [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
14#include "CGOpenMPRuntime.h"
15#include "CodeGenFunction.h"
16#include "CodeGenModule.h"
Chandler Carruth0d9593d2015-01-14 11:29:14 +000017#include "TargetInfo.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000018#include "clang/AST/Stmt.h"
19#include "clang/AST/StmtOpenMP.h"
20using namespace clang;
21using namespace CodeGen;
22
23//===----------------------------------------------------------------------===//
24// OpenMP Directive Emission
25//===----------------------------------------------------------------------===//
Alexey Bataevd74d0602014-10-13 06:02:40 +000026/// \brief Emits code for OpenMP 'if' clause using specified \a CodeGen
27/// function. Here is the logic:
28/// if (Cond) {
29/// CodeGen(true);
30/// } else {
31/// CodeGen(false);
32/// }
33static void EmitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
34 const std::function<void(bool)> &CodeGen) {
35 CodeGenFunction::LexicalScope ConditionScope(CGF, Cond->getSourceRange());
36
37 // If the condition constant folds and can be elided, try to avoid emitting
38 // the condition and the dead arm of the if/else.
39 bool CondConstant;
40 if (CGF.ConstantFoldsToSimpleInteger(Cond, CondConstant)) {
41 CodeGen(CondConstant);
42 return;
43 }
44
45 // Otherwise, the condition did not fold, or we couldn't elide it. Just
46 // emit the conditional branch.
47 auto ThenBlock = CGF.createBasicBlock(/*name*/ "omp_if.then");
48 auto ElseBlock = CGF.createBasicBlock(/*name*/ "omp_if.else");
49 auto ContBlock = CGF.createBasicBlock(/*name*/ "omp_if.end");
50 CGF.EmitBranchOnBoolExpr(Cond, ThenBlock, ElseBlock, /*TrueCount*/ 0);
51
52 // Emit the 'then' code.
53 CGF.EmitBlock(ThenBlock);
54 CodeGen(/*ThenBlock*/ true);
55 CGF.EmitBranch(ContBlock);
56 // Emit the 'else' code if present.
57 {
58 // There is no need to emit line number for unconditional branch.
Adrian Prantl95b24e92015-02-03 20:00:54 +000059 auto NL = ApplyDebugLocation::CreateEmpty(CGF);
Alexey Bataevd74d0602014-10-13 06:02:40 +000060 CGF.EmitBlock(ElseBlock);
61 }
62 CodeGen(/*ThenBlock*/ false);
63 {
64 // There is no need to emit line number for unconditional branch.
Adrian Prantl95b24e92015-02-03 20:00:54 +000065 auto NL = ApplyDebugLocation::CreateEmpty(CGF);
Alexey Bataevd74d0602014-10-13 06:02:40 +000066 CGF.EmitBranch(ContBlock);
67 }
68 // Emit the continuation block for code after the if.
69 CGF.EmitBlock(ContBlock, /*IsFinished*/ true);
70}
71
Alexey Bataev4a5bb772014-10-08 14:01:46 +000072void CodeGenFunction::EmitOMPAggregateAssign(LValue OriginalAddr,
73 llvm::Value *PrivateAddr,
74 const Expr *AssignExpr,
75 QualType OriginalType,
76 const VarDecl *VDInit) {
77 EmitBlock(createBasicBlock(".omp.assign.begin."));
78 if (!isa<CXXConstructExpr>(AssignExpr) || isTrivialInitializer(AssignExpr)) {
79 // Perform simple memcpy.
80 EmitAggregateAssign(PrivateAddr, OriginalAddr.getAddress(),
81 AssignExpr->getType());
82 } else {
83 // Perform element-by-element initialization.
84 QualType ElementTy;
85 auto SrcBegin = OriginalAddr.getAddress();
86 auto DestBegin = PrivateAddr;
87 auto ArrayTy = OriginalType->getAsArrayTypeUnsafe();
88 auto SrcNumElements = emitArrayLength(ArrayTy, ElementTy, SrcBegin);
89 auto DestNumElements = emitArrayLength(ArrayTy, ElementTy, DestBegin);
90 auto SrcEnd = Builder.CreateGEP(SrcBegin, SrcNumElements);
91 auto DestEnd = Builder.CreateGEP(DestBegin, DestNumElements);
92 // The basic structure here is a do-while loop, because we don't
93 // need to check for the zero-element case.
94 auto BodyBB = createBasicBlock("omp.arraycpy.body");
95 auto DoneBB = createBasicBlock("omp.arraycpy.done");
96 auto IsEmpty =
97 Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty");
98 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
99
100 // Enter the loop body, making that address the current address.
101 auto EntryBB = Builder.GetInsertBlock();
102 EmitBlock(BodyBB);
103 auto SrcElementPast = Builder.CreatePHI(SrcBegin->getType(), 2,
104 "omp.arraycpy.srcElementPast");
105 SrcElementPast->addIncoming(SrcEnd, EntryBB);
106 auto DestElementPast = Builder.CreatePHI(DestBegin->getType(), 2,
107 "omp.arraycpy.destElementPast");
108 DestElementPast->addIncoming(DestEnd, EntryBB);
109
110 // Shift the address back by one element.
111 auto NegativeOne = llvm::ConstantInt::get(SizeTy, -1, true);
112 auto DestElement = Builder.CreateGEP(DestElementPast, NegativeOne,
113 "omp.arraycpy.dest.element");
114 auto SrcElement = Builder.CreateGEP(SrcElementPast, NegativeOne,
115 "omp.arraycpy.src.element");
116 {
117 // Create RunCleanScope to cleanup possible temps.
118 CodeGenFunction::RunCleanupsScope Init(*this);
119 // Emit initialization for single element.
120 LocalDeclMap[VDInit] = SrcElement;
121 EmitAnyExprToMem(AssignExpr, DestElement,
122 AssignExpr->getType().getQualifiers(),
123 /*IsInitializer*/ false);
124 LocalDeclMap.erase(VDInit);
125 }
126
127 // Check whether we've reached the end.
128 auto Done =
129 Builder.CreateICmpEQ(DestElement, DestBegin, "omp.arraycpy.done");
130 Builder.CreateCondBr(Done, DoneBB, BodyBB);
131 DestElementPast->addIncoming(DestElement, Builder.GetInsertBlock());
132 SrcElementPast->addIncoming(SrcElement, Builder.GetInsertBlock());
133
134 // Done.
135 EmitBlock(DoneBB, true);
136 }
137 EmitBlock(createBasicBlock(".omp.assign.end."));
138}
139
140void CodeGenFunction::EmitOMPFirstprivateClause(
141 const OMPExecutableDirective &D,
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000142 CodeGenFunction::OMPPrivateScope &PrivateScope) {
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000143 auto PrivateFilter = [](const OMPClause *C) -> bool {
144 return C->getClauseKind() == OMPC_firstprivate;
145 };
146 for (OMPExecutableDirective::filtered_clause_iterator<decltype(PrivateFilter)>
147 I(D.clauses(), PrivateFilter); I; ++I) {
148 auto *C = cast<OMPFirstprivateClause>(*I);
149 auto IRef = C->varlist_begin();
150 auto InitsRef = C->inits().begin();
151 for (auto IInit : C->private_copies()) {
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000152 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
153 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
154 bool IsRegistered;
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000155 if (*InitsRef != nullptr) {
156 // Emit VarDecl with copy init for arrays.
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000157 auto *FD = CapturedStmtInfo->lookup(OrigVD);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000158 LValue Base = MakeNaturalAlignAddrLValue(
159 CapturedStmtInfo->getContextValue(),
160 getContext().getTagDeclType(FD->getParent()));
161 auto OriginalAddr = EmitLValueForField(Base, FD);
162 auto VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000163 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * {
164 auto Emission = EmitAutoVarAlloca(*VD);
165 // Emit initialization of aggregate firstprivate vars.
166 EmitOMPAggregateAssign(OriginalAddr, Emission.getAllocatedAddress(),
167 VD->getInit(), (*IRef)->getType(), VDInit);
168 EmitAutoVarCleanups(Emission);
169 return Emission.getAllocatedAddress();
170 });
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000171 } else
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000172 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * {
173 // Emit private VarDecl with copy init.
174 EmitDecl(*VD);
175 return GetAddrOfLocalVar(VD);
176 });
Alexander Musman7931b982015-03-16 07:14:41 +0000177 assert(IsRegistered && "firstprivate var already registered as private");
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000178 // Silence the warning about unused variable.
179 (void)IsRegistered;
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000180 ++IRef, ++InitsRef;
181 }
182 }
183}
184
Alexey Bataev03b340a2014-10-21 03:16:40 +0000185void CodeGenFunction::EmitOMPPrivateClause(
186 const OMPExecutableDirective &D,
187 CodeGenFunction::OMPPrivateScope &PrivateScope) {
188 auto PrivateFilter = [](const OMPClause *C) -> bool {
189 return C->getClauseKind() == OMPC_private;
190 };
191 for (OMPExecutableDirective::filtered_clause_iterator<decltype(PrivateFilter)>
192 I(D.clauses(), PrivateFilter); I; ++I) {
193 auto *C = cast<OMPPrivateClause>(*I);
194 auto IRef = C->varlist_begin();
195 for (auto IInit : C->private_copies()) {
196 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
197 auto VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
198 bool IsRegistered =
199 PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * {
200 // Emit private VarDecl with copy init.
201 EmitDecl(*VD);
202 return GetAddrOfLocalVar(VD);
203 });
Alexander Musman7931b982015-03-16 07:14:41 +0000204 assert(IsRegistered && "private var already registered as private");
Alexey Bataev03b340a2014-10-21 03:16:40 +0000205 // Silence the warning about unused variable.
206 (void)IsRegistered;
207 ++IRef;
208 }
209 }
210}
211
Alexey Bataevb2059782014-10-13 08:23:51 +0000212/// \brief Emits code for OpenMP parallel directive in the parallel region.
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000213static void emitOMPParallelCall(CodeGenFunction &CGF,
214 const OMPExecutableDirective &S,
Alexey Bataevb2059782014-10-13 08:23:51 +0000215 llvm::Value *OutlinedFn,
216 llvm::Value *CapturedStruct) {
217 if (auto C = S.getSingleClause(/*K*/ OMPC_num_threads)) {
218 CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
219 auto NumThreadsClause = cast<OMPNumThreadsClause>(C);
220 auto NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(),
221 /*IgnoreResultAssign*/ true);
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000222 CGF.CGM.getOpenMPRuntime().emitNumThreadsClause(
Alexey Bataevb2059782014-10-13 08:23:51 +0000223 CGF, NumThreads, NumThreadsClause->getLocStart());
224 }
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000225 CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getLocStart(), OutlinedFn,
226 CapturedStruct);
Alexey Bataevb2059782014-10-13 08:23:51 +0000227}
228
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000229static void emitCommonOMPParallelDirective(CodeGenFunction &CGF,
230 const OMPExecutableDirective &S,
231 const RegionCodeGenTy &CodeGen) {
Alexey Bataev18095712014-10-10 12:19:54 +0000232 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000233 auto CapturedStruct = CGF.GenerateCapturedStmtArgument(*CS);
234 auto OutlinedFn = CGF.CGM.getOpenMPRuntime().emitParallelOutlinedFunction(
235 S, *CS->getCapturedDecl()->param_begin(), CodeGen);
Alexey Bataevd74d0602014-10-13 06:02:40 +0000236 if (auto C = S.getSingleClause(/*K*/ OMPC_if)) {
237 auto Cond = cast<OMPIfClause>(C)->getCondition();
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000238 EmitOMPIfClause(CGF, Cond, [&](bool ThenBlock) {
Alexey Bataevd74d0602014-10-13 06:02:40 +0000239 if (ThenBlock)
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000240 emitOMPParallelCall(CGF, S, OutlinedFn, CapturedStruct);
Alexey Bataevd74d0602014-10-13 06:02:40 +0000241 else
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000242 CGF.CGM.getOpenMPRuntime().emitSerialCall(CGF, S.getLocStart(),
243 OutlinedFn, CapturedStruct);
Alexey Bataevd74d0602014-10-13 06:02:40 +0000244 });
Alexey Bataevb2059782014-10-13 08:23:51 +0000245 } else
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000246 emitOMPParallelCall(CGF, S, OutlinedFn, CapturedStruct);
247}
248
249void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
250 LexicalScope Scope(*this, S.getSourceRange());
251 // Emit parallel region as a standalone region.
252 auto &&CodeGen = [&S](CodeGenFunction &CGF) {
253 OMPPrivateScope PrivateScope(CGF);
254 CGF.EmitOMPPrivateClause(S, PrivateScope);
255 CGF.EmitOMPFirstprivateClause(S, PrivateScope);
256 if (PrivateScope.Privatize())
257 // Emit implicit barrier to synchronize threads and avoid data races.
258 CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(),
259 OMPD_unknown);
260 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
261 // Emit implicit barrier at the end of the 'parallel' directive.
262 CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(),
263 OMPD_unknown);
264 };
265 emitCommonOMPParallelDirective(*this, S, CodeGen);
Alexey Bataev9959db52014-05-06 10:08:46 +0000266}
Alexander Musman515ad8c2014-05-22 08:54:05 +0000267
Alexander Musmand196ef22014-10-07 08:57:09 +0000268void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &S,
Alexander Musmana5f070a2014-10-01 06:03:56 +0000269 bool SeparateIter) {
270 RunCleanupsScope BodyScope(*this);
271 // Update counters values on current iteration.
272 for (auto I : S.updates()) {
273 EmitIgnoredExpr(I);
274 }
Alexander Musman3276a272015-03-21 10:12:56 +0000275 // Update the linear variables.
276 for (auto C : OMPExecutableDirective::linear_filter(S.clauses())) {
277 for (auto U : C->updates()) {
278 EmitIgnoredExpr(U);
279 }
280 }
281
Alexander Musmana5f070a2014-10-01 06:03:56 +0000282 // On a continue in the body, jump to the end.
Alexander Musmand196ef22014-10-07 08:57:09 +0000283 auto Continue = getJumpDestInCurrentScope("omp.body.continue");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000284 BreakContinueStack.push_back(BreakContinue(JumpDest(), Continue));
285 // Emit loop body.
286 EmitStmt(S.getBody());
287 // The end (updates/cleanups).
288 EmitBlock(Continue.getBlock());
289 BreakContinueStack.pop_back();
290 if (SeparateIter) {
291 // TODO: Update lastprivates if the SeparateIter flag is true.
292 // This will be implemented in a follow-up OMPLastprivateClause patch, but
293 // result should be still correct without it, as we do not make these
294 // variables private yet.
295 }
296}
297
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000298void CodeGenFunction::EmitOMPInnerLoop(
299 const Stmt &S, bool RequiresCleanup, const Expr *LoopCond,
300 const Expr *IncExpr,
301 const llvm::function_ref<void(CodeGenFunction &)> &BodyGen) {
Alexander Musmand196ef22014-10-07 08:57:09 +0000302 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000303 auto Cnt = getPGORegionCounter(&S);
304
305 // Start the loop with a block that tests the condition.
Alexander Musmand196ef22014-10-07 08:57:09 +0000306 auto CondBlock = createBasicBlock("omp.inner.for.cond");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000307 EmitBlock(CondBlock);
308 LoopStack.push(CondBlock);
309
310 // If there are any cleanups between here and the loop-exit scope,
311 // create a block to stage a loop exit along.
312 auto ExitBlock = LoopExit.getBlock();
Alexey Bataev2df54a02015-03-12 08:53:29 +0000313 if (RequiresCleanup)
Alexander Musmand196ef22014-10-07 08:57:09 +0000314 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000315
Alexander Musmand196ef22014-10-07 08:57:09 +0000316 auto LoopBody = createBasicBlock("omp.inner.for.body");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000317
Alexey Bataev2df54a02015-03-12 08:53:29 +0000318 // Emit condition.
319 EmitBranchOnBoolExpr(LoopCond, LoopBody, ExitBlock, Cnt.getCount());
Alexander Musmana5f070a2014-10-01 06:03:56 +0000320 if (ExitBlock != LoopExit.getBlock()) {
321 EmitBlock(ExitBlock);
322 EmitBranchThroughCleanup(LoopExit);
323 }
324
325 EmitBlock(LoopBody);
326 Cnt.beginRegion(Builder);
327
328 // Create a block for the increment.
Alexander Musmand196ef22014-10-07 08:57:09 +0000329 auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000330 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
331
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000332 BodyGen(*this);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000333
334 // Emit "IV = IV + 1" and a back-edge to the condition block.
335 EmitBlock(Continue.getBlock());
Alexey Bataev2df54a02015-03-12 08:53:29 +0000336 EmitIgnoredExpr(IncExpr);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000337 BreakContinueStack.pop_back();
338 EmitBranch(CondBlock);
339 LoopStack.pop();
340 // Emit the fall-through block.
341 EmitBlock(LoopExit.getBlock());
342}
343
344void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) {
345 auto IC = S.counters().begin();
346 for (auto F : S.finals()) {
347 if (LocalDeclMap.lookup(cast<DeclRefExpr>((*IC))->getDecl())) {
348 EmitIgnoredExpr(F);
349 }
350 ++IC;
351 }
Alexander Musman3276a272015-03-21 10:12:56 +0000352 // Emit the final values of the linear variables.
353 for (auto C : OMPExecutableDirective::linear_filter(S.clauses())) {
354 for (auto F : C->finals()) {
355 EmitIgnoredExpr(F);
356 }
357 }
Alexander Musmana5f070a2014-10-01 06:03:56 +0000358}
359
Alexander Musman09184fe2014-09-30 05:29:28 +0000360static void EmitOMPAlignedClause(CodeGenFunction &CGF, CodeGenModule &CGM,
361 const OMPAlignedClause &Clause) {
362 unsigned ClauseAlignment = 0;
363 if (auto AlignmentExpr = Clause.getAlignment()) {
364 auto AlignmentCI =
365 cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
366 ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue());
367 }
368 for (auto E : Clause.varlists()) {
369 unsigned Alignment = ClauseAlignment;
370 if (Alignment == 0) {
371 // OpenMP [2.8.1, Description]
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000372 // If no optional parameter is specified, implementation-defined default
Alexander Musman09184fe2014-09-30 05:29:28 +0000373 // alignments for SIMD instructions on the target platforms are assumed.
374 Alignment = CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment(
375 E->getType());
376 }
377 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
378 "alignment is not power of 2");
379 if (Alignment != 0) {
380 llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
381 CGF.EmitAlignmentAssumption(PtrValue, Alignment);
382 }
383 }
384}
385
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000386static void EmitPrivateLoopCounters(CodeGenFunction &CGF,
387 CodeGenFunction::OMPPrivateScope &LoopScope,
388 ArrayRef<Expr *> Counters) {
389 for (auto *E : Counters) {
390 auto VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
391 bool IsRegistered = LoopScope.addPrivate(VD, [&]() -> llvm::Value * {
392 // Emit var without initialization.
393 auto VarEmission = CGF.EmitAutoVarAlloca(*VD);
394 CGF.EmitAutoVarCleanups(VarEmission);
395 return VarEmission.getAllocatedAddress();
396 });
397 assert(IsRegistered && "counter already registered as private");
398 // Silence the warning about unused variable.
399 (void)IsRegistered;
400 }
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000401}
402
Alexander Musman3276a272015-03-21 10:12:56 +0000403static void
404EmitPrivateLinearVars(CodeGenFunction &CGF, const OMPExecutableDirective &D,
405 CodeGenFunction::OMPPrivateScope &PrivateScope) {
406 for (auto Clause : OMPExecutableDirective::linear_filter(D.clauses())) {
407 for (auto *E : Clause->varlists()) {
408 auto VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
409 bool IsRegistered = PrivateScope.addPrivate(VD, [&]()->llvm::Value * {
410 // Emit var without initialization.
411 auto VarEmission = CGF.EmitAutoVarAlloca(*VD);
412 CGF.EmitAutoVarCleanups(VarEmission);
413 return VarEmission.getAllocatedAddress();
414 });
415 assert(IsRegistered && "linear var already registered as private");
416 // Silence the warning about unused variable.
417 (void)IsRegistered;
418 }
419 }
420}
421
Alexander Musman515ad8c2014-05-22 08:54:05 +0000422void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000423 auto &&CodeGen = [&S](CodeGenFunction &CGF) {
424 // Pragma 'simd' code depends on presence of 'lastprivate'.
425 // If present, we have to separate last iteration of the loop:
426 //
427 // if (LastIteration != 0) {
428 // for (IV in 0..LastIteration-1) BODY;
429 // BODY with updates of lastprivate vars;
430 // <Final counter/linear vars updates>;
431 // }
432 //
433 // otherwise (when there's no lastprivate):
434 //
435 // for (IV in 0..LastIteration) BODY;
436 // <Final counter/linear vars updates>;
437 //
Alexander Musmana5f070a2014-10-01 06:03:56 +0000438
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000439 // Walk clauses and process safelen/lastprivate.
440 bool SeparateIter = false;
441 CGF.LoopStack.setParallel();
442 CGF.LoopStack.setVectorizerEnable(true);
443 for (auto C : S.clauses()) {
444 switch (C->getClauseKind()) {
445 case OMPC_safelen: {
446 RValue Len = CGF.EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(),
447 AggValueSlot::ignored(), true);
448 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
449 CGF.LoopStack.setVectorizerWidth(Val->getZExtValue());
450 // In presence of finite 'safelen', it may be unsafe to mark all
451 // the memory instructions parallel, because loop-carried
452 // dependences of 'safelen' iterations are possible.
453 CGF.LoopStack.setParallel(false);
454 break;
Alexander Musman3276a272015-03-21 10:12:56 +0000455 }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000456 case OMPC_aligned:
457 EmitOMPAlignedClause(CGF, CGF.CGM, cast<OMPAlignedClause>(*C));
458 break;
459 case OMPC_lastprivate:
460 SeparateIter = true;
461 break;
462 default:
463 // Not handled yet
464 ;
465 }
466 }
Alexander Musman3276a272015-03-21 10:12:56 +0000467
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000468 // Emit inits for the linear variables.
469 for (auto C : OMPExecutableDirective::linear_filter(S.clauses())) {
470 for (auto Init : C->inits()) {
471 auto *D = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl());
472 CGF.EmitVarDecl(*D);
473 }
Alexander Musmana5f070a2014-10-01 06:03:56 +0000474 }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000475
476 // Emit the loop iteration variable.
477 const Expr *IVExpr = S.getIterationVariable();
478 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
479 CGF.EmitVarDecl(*IVDecl);
480 CGF.EmitIgnoredExpr(S.getInit());
481
482 // Emit the iterations count variable.
483 // If it is not a variable, Sema decided to calculate iterations count on
484 // each
485 // iteration (e.g., it is foldable into a constant).
486 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
487 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
488 // Emit calculation of the iterations count.
489 CGF.EmitIgnoredExpr(S.getCalcLastIteration());
Alexander Musmana5f070a2014-10-01 06:03:56 +0000490 }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000491
492 // Emit the linear steps for the linear clauses.
493 // If a step is not constant, it is pre-calculated before the loop.
494 for (auto C : OMPExecutableDirective::linear_filter(S.clauses())) {
495 if (auto CS = cast_or_null<BinaryOperator>(C->getCalcStep()))
496 if (auto SaveRef = cast<DeclRefExpr>(CS->getLHS())) {
497 CGF.EmitVarDecl(*cast<VarDecl>(SaveRef->getDecl()));
498 // Emit calculation of the linear step.
499 CGF.EmitIgnoredExpr(CS);
500 }
501 }
502
503 if (SeparateIter) {
504 // Emit: if (LastIteration > 0) - begin.
505 RegionCounter Cnt = CGF.getPGORegionCounter(&S);
506 auto ThenBlock = CGF.createBasicBlock("simd.if.then");
507 auto ContBlock = CGF.createBasicBlock("simd.if.end");
508 CGF.EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock,
509 Cnt.getCount());
510 CGF.EmitBlock(ThenBlock);
511 Cnt.beginRegion(CGF.Builder);
512 // Emit 'then' code.
513 {
514 OMPPrivateScope LoopScope(CGF);
515 EmitPrivateLoopCounters(CGF, LoopScope, S.counters());
516 EmitPrivateLinearVars(CGF, S, LoopScope);
517 CGF.EmitOMPPrivateClause(S, LoopScope);
518 (void)LoopScope.Privatize();
519 CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(),
520 S.getCond(/*SeparateIter=*/true), S.getInc(),
521 [&S](CodeGenFunction &CGF) {
522 CGF.EmitOMPLoopBody(S);
523 CGF.EmitStopPoint(&S);
524 });
525 CGF.EmitOMPLoopBody(S, /* SeparateIter */ true);
526 }
527 CGF.EmitOMPSimdFinal(S);
528 // Emit: if (LastIteration != 0) - end.
529 CGF.EmitBranch(ContBlock);
530 CGF.EmitBlock(ContBlock, true);
531 } else {
532 {
533 OMPPrivateScope LoopScope(CGF);
534 EmitPrivateLoopCounters(CGF, LoopScope, S.counters());
535 EmitPrivateLinearVars(CGF, S, LoopScope);
536 CGF.EmitOMPPrivateClause(S, LoopScope);
537 (void)LoopScope.Privatize();
538 CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(),
539 S.getCond(/*SeparateIter=*/false), S.getInc(),
540 [&S](CodeGenFunction &CGF) {
541 CGF.EmitOMPLoopBody(S);
542 CGF.EmitStopPoint(&S);
543 });
544 }
545 CGF.EmitOMPSimdFinal(S);
546 }
547 };
548 CGM.getOpenMPRuntime().emitInlinedDirective(*this, CodeGen);
Alexander Musman515ad8c2014-05-22 08:54:05 +0000549}
550
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000551void CodeGenFunction::EmitOMPForOuterLoop(OpenMPScheduleClauseKind ScheduleKind,
552 const OMPLoopDirective &S,
553 OMPPrivateScope &LoopScope,
554 llvm::Value *LB, llvm::Value *UB,
555 llvm::Value *ST, llvm::Value *IL,
556 llvm::Value *Chunk) {
557 auto &RT = CGM.getOpenMPRuntime();
Alexander Musman92bdaab2015-03-12 13:37:50 +0000558
559 // Dynamic scheduling of the outer loop (dynamic, guided, auto, runtime).
560 const bool Dynamic = RT.isDynamic(ScheduleKind);
561
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000562 assert(!RT.isStaticNonchunked(ScheduleKind, /* Chunked */ Chunk != nullptr) &&
563 "static non-chunked schedule does not need outer loop");
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000564
565 // Emit outer loop.
566 //
567 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
Alexander Musman92bdaab2015-03-12 13:37:50 +0000568 // When schedule(dynamic,chunk_size) is specified, the iterations are
569 // distributed to threads in the team in chunks as the threads request them.
570 // Each thread executes a chunk of iterations, then requests another chunk,
571 // until no chunks remain to be distributed. Each chunk contains chunk_size
572 // iterations, except for the last chunk to be distributed, which may have
573 // fewer iterations. When no chunk_size is specified, it defaults to 1.
574 //
575 // When schedule(guided,chunk_size) is specified, the iterations are assigned
576 // to threads in the team in chunks as the executing threads request them.
577 // Each thread executes a chunk of iterations, then requests another chunk,
578 // until no chunks remain to be assigned. For a chunk_size of 1, the size of
579 // each chunk is proportional to the number of unassigned iterations divided
580 // by the number of threads in the team, decreasing to 1. For a chunk_size
581 // with value k (greater than 1), the size of each chunk is determined in the
582 // same way, with the restriction that the chunks do not contain fewer than k
583 // iterations (except for the last chunk to be assigned, which may have fewer
584 // than k iterations).
585 //
586 // When schedule(auto) is specified, the decision regarding scheduling is
587 // delegated to the compiler and/or runtime system. The programmer gives the
588 // implementation the freedom to choose any possible mapping of iterations to
589 // threads in the team.
590 //
591 // When schedule(runtime) is specified, the decision regarding scheduling is
592 // deferred until run time, and the schedule and chunk size are taken from the
593 // run-sched-var ICV. If the ICV is set to auto, the schedule is
594 // implementation defined
595 //
596 // while(__kmpc_dispatch_next(&LB, &UB)) {
597 // idx = LB;
598 // while (idx <= UB) { BODY; ++idx; } // inner loop
599 // }
600 //
601 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000602 // When schedule(static, chunk_size) is specified, iterations are divided into
603 // chunks of size chunk_size, and the chunks are assigned to the threads in
604 // the team in a round-robin fashion in the order of the thread number.
605 //
606 // while(UB = min(UB, GlobalUB), idx = LB, idx < UB) {
607 // while (idx <= UB) { BODY; ++idx; } // inner loop
608 // LB = LB + ST;
609 // UB = UB + ST;
610 // }
611 //
Alexander Musman92bdaab2015-03-12 13:37:50 +0000612
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000613 const Expr *IVExpr = S.getIterationVariable();
614 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
615 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
616
Alexander Musman92bdaab2015-03-12 13:37:50 +0000617 RT.emitForInit(
618 *this, S.getLocStart(), ScheduleKind, IVSize, IVSigned, IL, LB,
619 (Dynamic ? EmitAnyExpr(S.getLastIteration()).getScalarVal() : UB), ST,
620 Chunk);
621
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000622 auto LoopExit = getJumpDestInCurrentScope("omp.dispatch.end");
623
624 // Start the loop with a block that tests the condition.
625 auto CondBlock = createBasicBlock("omp.dispatch.cond");
626 EmitBlock(CondBlock);
627 LoopStack.push(CondBlock);
628
629 llvm::Value *BoolCondVal = nullptr;
Alexander Musman92bdaab2015-03-12 13:37:50 +0000630 if (!Dynamic) {
631 // UB = min(UB, GlobalUB)
632 EmitIgnoredExpr(S.getEnsureUpperBound());
633 // IV = LB
634 EmitIgnoredExpr(S.getInit());
635 // IV < UB
636 BoolCondVal = EvaluateExprAsBool(S.getCond(false));
637 } else {
638 BoolCondVal = RT.emitForNext(*this, S.getLocStart(), IVSize, IVSigned,
639 IL, LB, UB, ST);
640 }
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000641
642 // If there are any cleanups between here and the loop-exit scope,
643 // create a block to stage a loop exit along.
644 auto ExitBlock = LoopExit.getBlock();
645 if (LoopScope.requiresCleanups())
646 ExitBlock = createBasicBlock("omp.dispatch.cleanup");
647
648 auto LoopBody = createBasicBlock("omp.dispatch.body");
649 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
650 if (ExitBlock != LoopExit.getBlock()) {
651 EmitBlock(ExitBlock);
652 EmitBranchThroughCleanup(LoopExit);
653 }
654 EmitBlock(LoopBody);
655
Alexander Musman92bdaab2015-03-12 13:37:50 +0000656 // Emit "IV = LB" (in case of static schedule, we have already calculated new
657 // LB for loop condition and emitted it above).
658 if (Dynamic)
659 EmitIgnoredExpr(S.getInit());
660
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000661 // Create a block for the increment.
662 auto Continue = getJumpDestInCurrentScope("omp.dispatch.inc");
663 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
664
Alexey Bataev2df54a02015-03-12 08:53:29 +0000665 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(),
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000666 S.getCond(/*SeparateIter=*/false), S.getInc(),
667 [&S](CodeGenFunction &CGF) {
668 CGF.EmitOMPLoopBody(S);
669 CGF.EmitStopPoint(&S);
Alexey Bataev2df54a02015-03-12 08:53:29 +0000670 });
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000671
672 EmitBlock(Continue.getBlock());
673 BreakContinueStack.pop_back();
Alexander Musman92bdaab2015-03-12 13:37:50 +0000674 if (!Dynamic) {
675 // Emit "LB = LB + Stride", "UB = UB + Stride".
676 EmitIgnoredExpr(S.getNextLowerBound());
677 EmitIgnoredExpr(S.getNextUpperBound());
678 }
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000679
680 EmitBranch(CondBlock);
681 LoopStack.pop();
682 // Emit the fall-through block.
683 EmitBlock(LoopExit.getBlock());
684
685 // Tell the runtime we are done.
Alexander Musman92bdaab2015-03-12 13:37:50 +0000686 // FIXME: Also call fini for ordered loops with dynamic scheduling.
687 if (!Dynamic)
688 RT.emitForFinish(*this, S.getLocStart(), ScheduleKind);
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000689}
690
Alexander Musmanc6388682014-12-15 07:07:06 +0000691/// \brief Emit a helper variable and return corresponding lvalue.
692static LValue EmitOMPHelperVar(CodeGenFunction &CGF,
693 const DeclRefExpr *Helper) {
694 auto VDecl = cast<VarDecl>(Helper->getDecl());
695 CGF.EmitVarDecl(*VDecl);
696 return CGF.EmitLValue(Helper);
697}
698
699void CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) {
700 // Emit the loop iteration variable.
701 auto IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
702 auto IVDecl = cast<VarDecl>(IVExpr->getDecl());
703 EmitVarDecl(*IVDecl);
704
705 // Emit the iterations count variable.
706 // If it is not a variable, Sema decided to calculate iterations count on each
707 // iteration (e.g., it is foldable into a constant).
708 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
709 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
710 // Emit calculation of the iterations count.
711 EmitIgnoredExpr(S.getCalcLastIteration());
712 }
713
714 auto &RT = CGM.getOpenMPRuntime();
715
716 // Check pre-condition.
717 {
718 // Skip the entire loop if we don't meet the precondition.
719 RegionCounter Cnt = getPGORegionCounter(&S);
720 auto ThenBlock = createBasicBlock("omp.precond.then");
721 auto ContBlock = createBasicBlock("omp.precond.end");
722 EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount());
723 EmitBlock(ThenBlock);
724 Cnt.beginRegion(Builder);
725 // Emit 'then' code.
726 {
727 // Emit helper vars inits.
728 LValue LB =
729 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getLowerBoundVariable()));
730 LValue UB =
731 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getUpperBoundVariable()));
732 LValue ST =
733 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable()));
734 LValue IL =
735 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
736
737 OMPPrivateScope LoopScope(*this);
738 EmitPrivateLoopCounters(*this, LoopScope, S.counters());
Alexander Musman7931b982015-03-16 07:14:41 +0000739 (void)LoopScope.Privatize();
Alexander Musmanc6388682014-12-15 07:07:06 +0000740
741 // Detect the loop schedule kind and chunk.
742 auto ScheduleKind = OMPC_SCHEDULE_unknown;
743 llvm::Value *Chunk = nullptr;
744 if (auto C = cast_or_null<OMPScheduleClause>(
745 S.getSingleClause(OMPC_schedule))) {
746 ScheduleKind = C->getScheduleKind();
747 if (auto Ch = C->getChunkSize()) {
748 Chunk = EmitScalarExpr(Ch);
749 Chunk = EmitScalarConversion(Chunk, Ch->getType(),
750 S.getIterationVariable()->getType());
751 }
752 }
753 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
754 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
755 if (RT.isStaticNonchunked(ScheduleKind,
756 /* Chunked */ Chunk != nullptr)) {
757 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
758 // When no chunk_size is specified, the iteration space is divided into
759 // chunks that are approximately equal in size, and at most one chunk is
760 // distributed to each thread. Note that the size of the chunks is
761 // unspecified in this case.
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000762 RT.emitForInit(*this, S.getLocStart(), ScheduleKind, IVSize, IVSigned,
763 IL.getAddress(), LB.getAddress(), UB.getAddress(),
764 ST.getAddress());
Alexander Musmanc6388682014-12-15 07:07:06 +0000765 // UB = min(UB, GlobalUB);
766 EmitIgnoredExpr(S.getEnsureUpperBound());
767 // IV = LB;
768 EmitIgnoredExpr(S.getInit());
769 // while (idx <= UB) { BODY; ++idx; }
Alexey Bataev2df54a02015-03-12 08:53:29 +0000770 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(),
771 S.getCond(/*SeparateIter=*/false), S.getInc(),
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000772 [&S](CodeGenFunction &CGF) {
773 CGF.EmitOMPLoopBody(S);
774 CGF.EmitStopPoint(&S);
Alexey Bataev2df54a02015-03-12 08:53:29 +0000775 });
Alexander Musmanc6388682014-12-15 07:07:06 +0000776 // Tell the runtime we are done.
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000777 RT.emitForFinish(*this, S.getLocStart(), ScheduleKind);
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000778 } else {
779 // Emit the outer loop, which requests its work chunk [LB..UB] from
780 // runtime and runs the inner loop to process it.
781 EmitOMPForOuterLoop(ScheduleKind, S, LoopScope, LB.getAddress(),
782 UB.getAddress(), ST.getAddress(), IL.getAddress(),
783 Chunk);
784 }
Alexander Musmanc6388682014-12-15 07:07:06 +0000785 }
786 // We're now done with the loop, so jump to the continuation block.
787 EmitBranch(ContBlock);
788 EmitBlock(ContBlock, true);
789 }
790}
791
792void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000793 LexicalScope Scope(*this, S.getSourceRange());
794 auto &&CodeGen =
795 [&S](CodeGenFunction &CGF) { CGF.EmitOMPWorksharingLoop(S); };
796 CGM.getOpenMPRuntime().emitInlinedDirective(*this, CodeGen);
Alexander Musmanc6388682014-12-15 07:07:06 +0000797
798 // Emit an implicit barrier at the end.
Alexey Bataevf2685682015-03-30 04:30:22 +0000799 if (!S.getSingleClause(OMPC_nowait)) {
800 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_for);
801 }
Alexey Bataevf29276e2014-06-18 04:14:57 +0000802}
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000803
Alexander Musmanf82886e2014-09-18 05:12:34 +0000804void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &) {
805 llvm_unreachable("CodeGen for 'omp for simd' is not supported yet.");
806}
807
Alexey Bataev2df54a02015-03-12 08:53:29 +0000808static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty,
809 const Twine &Name,
810 llvm::Value *Init = nullptr) {
811 auto LVal = CGF.MakeNaturalAlignAddrLValue(CGF.CreateMemTemp(Ty, Name), Ty);
812 if (Init)
813 CGF.EmitScalarInit(Init, LVal);
814 return LVal;
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000815}
816
Alexey Bataev2df54a02015-03-12 08:53:29 +0000817void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000818 LexicalScope Scope(*this, S.getSourceRange());
Alexey Bataev2df54a02015-03-12 08:53:29 +0000819 auto *Stmt = cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt();
820 auto *CS = dyn_cast<CompoundStmt>(Stmt);
821 if (CS && CS->size() > 1) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000822 auto &&CodeGen = [&S, CS](CodeGenFunction &CGF) {
823 auto &C = CGF.CGM.getContext();
824 auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
825 // Emit helper vars inits.
826 LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.",
827 CGF.Builder.getInt32(0));
828 auto *GlobalUBVal = CGF.Builder.getInt32(CS->size() - 1);
829 LValue UB =
830 createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal);
831 LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.",
832 CGF.Builder.getInt32(1));
833 LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.",
834 CGF.Builder.getInt32(0));
835 // Loop counter.
836 LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv.");
837 OpaqueValueExpr IVRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
838 OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV);
839 OpaqueValueExpr UBRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
840 OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
841 // Generate condition for loop.
842 BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue,
843 OK_Ordinary, S.getLocStart(),
844 /*fpContractable=*/false);
845 // Increment for loop counter.
846 UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue,
847 OK_Ordinary, S.getLocStart());
848 auto BodyGen = [CS, &S, &IV](CodeGenFunction &CGF) {
849 // Iterate through all sections and emit a switch construct:
850 // switch (IV) {
851 // case 0:
852 // <SectionStmt[0]>;
853 // break;
854 // ...
855 // case <NumSection> - 1:
856 // <SectionStmt[<NumSection> - 1]>;
857 // break;
858 // }
859 // .omp.sections.exit:
860 auto *ExitBB = CGF.createBasicBlock(".omp.sections.exit");
861 auto *SwitchStmt = CGF.Builder.CreateSwitch(
862 CGF.EmitLoadOfLValue(IV, S.getLocStart()).getScalarVal(), ExitBB,
863 CS->size());
864 unsigned CaseNumber = 0;
865 for (auto C = CS->children(); C; ++C, ++CaseNumber) {
866 auto CaseBB = CGF.createBasicBlock(".omp.sections.case");
867 CGF.EmitBlock(CaseBB);
868 SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB);
869 CGF.EmitStmt(*C);
870 CGF.EmitBranch(ExitBB);
871 }
872 CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
873 };
874 // Emit static non-chunked loop.
875 CGF.CGM.getOpenMPRuntime().emitForInit(
876 CGF, S.getLocStart(), OMPC_SCHEDULE_static, /*IVSize=*/32,
877 /*IVSigned=*/true, IL.getAddress(), LB.getAddress(), UB.getAddress(),
878 ST.getAddress());
879 // UB = min(UB, GlobalUB);
880 auto *UBVal = CGF.EmitLoadOfScalar(UB, S.getLocStart());
881 auto *MinUBGlobalUB = CGF.Builder.CreateSelect(
882 CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
883 CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
884 // IV = LB;
885 CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getLocStart()), IV);
886 // while (idx <= UB) { BODY; ++idx; }
887 CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen);
888 // Tell the runtime we are done.
889 CGF.CGM.getOpenMPRuntime().emitForFinish(CGF, S.getLocStart(),
890 OMPC_SCHEDULE_static);
Alexey Bataev2df54a02015-03-12 08:53:29 +0000891 };
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000892
893 CGM.getOpenMPRuntime().emitInlinedDirective(*this, CodeGen);
Alexey Bataev2df54a02015-03-12 08:53:29 +0000894 } else {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000895 // If only one section is found - no need to generate loop, emit as a
896 // single
Alexey Bataev2df54a02015-03-12 08:53:29 +0000897 // region.
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000898 auto &&CodeGen = [&S](CodeGenFunction &CGF) {
899 CGF.EmitStmt(
900 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
901 CGF.EnsureInsertPoint();
902 };
903 CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(),
904 llvm::None, llvm::None, llvm::None,
905 llvm::None);
Alexey Bataev2df54a02015-03-12 08:53:29 +0000906 }
907
908 // Emit an implicit barrier at the end.
Alexey Bataevf2685682015-03-30 04:30:22 +0000909 if (!S.getSingleClause(OMPC_nowait)) {
910 CGM.getOpenMPRuntime().emitBarrierCall(
911 *this, S.getLocStart(),
912 (CS && CS->size() > 1) ? OMPD_sections : OMPD_single);
913 }
Alexey Bataev2df54a02015-03-12 08:53:29 +0000914}
915
916void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000917 LexicalScope Scope(*this, S.getSourceRange());
918 auto &&CodeGen = [&S](CodeGenFunction &CGF) {
919 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
920 CGF.EnsureInsertPoint();
921 };
922 CGM.getOpenMPRuntime().emitInlinedDirective(*this, CodeGen);
Alexey Bataev1e0498a2014-06-26 08:21:58 +0000923}
924
Alexey Bataev6956e2e2015-02-05 06:35:41 +0000925void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {
Alexey Bataeva63048e2015-03-23 06:18:07 +0000926 llvm::SmallVector<const Expr *, 8> CopyprivateVars;
927 llvm::SmallVector<const Expr *, 8> SrcExprs;
928 llvm::SmallVector<const Expr *, 8> DstExprs;
929 llvm::SmallVector<const Expr *, 8> AssignmentOps;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000930 // Check if there are any 'copyprivate' clauses associated with this
931 // 'single'
Alexey Bataeva63048e2015-03-23 06:18:07 +0000932 // construct.
933 auto CopyprivateFilter = [](const OMPClause *C) -> bool {
934 return C->getClauseKind() == OMPC_copyprivate;
935 };
936 // Build a list of copyprivate variables along with helper expressions
937 // (<source>, <destination>, <destination>=<source> expressions)
938 typedef OMPExecutableDirective::filtered_clause_iterator<decltype(
939 CopyprivateFilter)> CopyprivateIter;
940 for (CopyprivateIter I(S.clauses(), CopyprivateFilter); I; ++I) {
941 auto *C = cast<OMPCopyprivateClause>(*I);
942 CopyprivateVars.append(C->varlists().begin(), C->varlists().end());
943 SrcExprs.append(C->source_exprs().begin(), C->source_exprs().end());
944 DstExprs.append(C->destination_exprs().begin(),
945 C->destination_exprs().end());
946 AssignmentOps.append(C->assignment_ops().begin(),
947 C->assignment_ops().end());
948 }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000949 LexicalScope Scope(*this, S.getSourceRange());
Alexey Bataeva63048e2015-03-23 06:18:07 +0000950 // Emit code for 'single' region along with 'copyprivate' clauses
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000951 auto &&CodeGen = [&S](CodeGenFunction &CGF) {
952 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
953 CGF.EnsureInsertPoint();
954 };
955 CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(),
956 CopyprivateVars, SrcExprs, DstExprs,
957 AssignmentOps);
Alexey Bataeva63048e2015-03-23 06:18:07 +0000958 // Emit an implicit barrier at the end.
Alexey Bataevf2685682015-03-30 04:30:22 +0000959 if (!S.getSingleClause(OMPC_nowait)) {
960 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_single);
961 }
Alexey Bataevd1e40fb2014-06-26 12:05:45 +0000962}
963
Alexey Bataev8d690652014-12-04 07:23:53 +0000964void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000965 LexicalScope Scope(*this, S.getSourceRange());
966 auto &&CodeGen = [&S](CodeGenFunction &CGF) {
967 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
968 CGF.EnsureInsertPoint();
969 };
970 CGM.getOpenMPRuntime().emitMasterRegion(*this, CodeGen, S.getLocStart());
Alexander Musman80c22892014-07-17 08:54:58 +0000971}
972
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +0000973void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000974 LexicalScope Scope(*this, S.getSourceRange());
975 auto &&CodeGen = [&S](CodeGenFunction &CGF) {
976 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
977 CGF.EnsureInsertPoint();
978 };
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000979 CGM.getOpenMPRuntime().emitCriticalRegion(
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000980 *this, S.getDirectiveName().getAsString(), CodeGen, S.getLocStart());
Alexander Musmand9ed09f2014-07-21 09:42:05 +0000981}
982
Alexey Bataev4acb8592014-07-07 13:01:15 +0000983void
984CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
985 llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet.");
986}
987
Alexander Musmane4e893b2014-09-23 09:33:00 +0000988void CodeGenFunction::EmitOMPParallelForSimdDirective(
989 const OMPParallelForSimdDirective &) {
990 llvm_unreachable("CodeGen for 'omp parallel for simd' is not supported yet.");
991}
992
Alexey Bataev84d0b3e2014-07-08 08:12:03 +0000993void CodeGenFunction::EmitOMPParallelSectionsDirective(
994 const OMPParallelSectionsDirective &) {
995 llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet.");
996}
997
Alexey Bataev62b63b12015-03-10 07:28:44 +0000998void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
999 // Emit outlined function for task construct.
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001000 LexicalScope Scope(*this, S.getSourceRange());
Alexey Bataev62b63b12015-03-10 07:28:44 +00001001 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
1002 auto CapturedStruct = GenerateCapturedStmtArgument(*CS);
1003 auto *I = CS->getCapturedDecl()->param_begin();
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001004 auto *PartId = std::next(I);
Alexey Bataev62b63b12015-03-10 07:28:44 +00001005 // The first function argument for tasks is a thread id, the second one is a
1006 // part id (0 for tied tasks, >=0 for untied task).
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001007 auto &&CodeGen = [PartId, &S](CodeGenFunction &CGF) {
1008 if (*PartId) {
1009 // TODO: emit code for untied tasks.
1010 }
1011 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
1012 };
Alexey Bataev62b63b12015-03-10 07:28:44 +00001013 auto OutlinedFn =
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001014 CGM.getOpenMPRuntime().emitTaskOutlinedFunction(S, *I, CodeGen);
Alexey Bataev62b63b12015-03-10 07:28:44 +00001015 // Check if we should emit tied or untied task.
1016 bool Tied = !S.getSingleClause(OMPC_untied);
1017 // Check if the task is final
1018 llvm::PointerIntPair<llvm::Value *, 1, bool> Final;
1019 if (auto *Clause = S.getSingleClause(OMPC_final)) {
1020 // If the condition constant folds and can be elided, try to avoid emitting
1021 // the condition and the dead arm of the if/else.
1022 auto *Cond = cast<OMPFinalClause>(Clause)->getCondition();
1023 bool CondConstant;
1024 if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
1025 Final.setInt(CondConstant);
1026 else
1027 Final.setPointer(EvaluateExprAsBool(Cond));
1028 } else {
1029 // By default the task is not final.
1030 Final.setInt(/*IntVal=*/false);
1031 }
1032 auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
1033 CGM.getOpenMPRuntime().emitTaskCall(*this, S.getLocStart(), Tied, Final,
1034 OutlinedFn, SharedsTy, CapturedStruct);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001035}
1036
Alexey Bataev9f797f32015-02-05 05:57:51 +00001037void CodeGenFunction::EmitOMPTaskyieldDirective(
1038 const OMPTaskyieldDirective &S) {
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001039 CGM.getOpenMPRuntime().emitTaskyieldCall(*this, S.getLocStart());
Alexey Bataev68446b72014-07-18 07:47:19 +00001040}
1041
Alexey Bataev8f7c1b02014-12-05 04:09:23 +00001042void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) {
Alexey Bataevf2685682015-03-30 04:30:22 +00001043 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_barrier);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001044}
1045
Alexey Bataev2df347a2014-07-18 10:17:07 +00001046void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &) {
1047 llvm_unreachable("CodeGen for 'omp taskwait' is not supported yet.");
1048}
1049
Alexey Bataevcc37cc12014-11-20 04:34:54 +00001050void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) {
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001051 CGM.getOpenMPRuntime().emitFlush(*this, [&]() -> ArrayRef<const Expr *> {
1052 if (auto C = S.getSingleClause(/*K*/ OMPC_flush)) {
1053 auto FlushClause = cast<OMPFlushClause>(C);
1054 return llvm::makeArrayRef(FlushClause->varlist_begin(),
1055 FlushClause->varlist_end());
1056 }
1057 return llvm::None;
1058 }(), S.getLocStart());
Alexey Bataev6125da92014-07-21 11:26:11 +00001059}
1060
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001061void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &) {
1062 llvm_unreachable("CodeGen for 'omp ordered' is not supported yet.");
1063}
1064
Alexey Bataevb57056f2015-01-22 06:17:56 +00001065static llvm::Value *convertToScalarValue(CodeGenFunction &CGF, RValue Val,
1066 QualType SrcType, QualType DestType) {
1067 assert(CGF.hasScalarEvaluationKind(DestType) &&
1068 "DestType must have scalar evaluation kind.");
1069 assert(!Val.isAggregate() && "Must be a scalar or complex.");
1070 return Val.isScalar()
1071 ? CGF.EmitScalarConversion(Val.getScalarVal(), SrcType, DestType)
1072 : CGF.EmitComplexToScalarConversion(Val.getComplexVal(), SrcType,
1073 DestType);
1074}
1075
1076static CodeGenFunction::ComplexPairTy
1077convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType,
1078 QualType DestType) {
1079 assert(CGF.getEvaluationKind(DestType) == TEK_Complex &&
1080 "DestType must have complex evaluation kind.");
1081 CodeGenFunction::ComplexPairTy ComplexVal;
1082 if (Val.isScalar()) {
1083 // Convert the input element to the element type of the complex.
1084 auto DestElementType = DestType->castAs<ComplexType>()->getElementType();
1085 auto ScalarVal =
1086 CGF.EmitScalarConversion(Val.getScalarVal(), SrcType, DestElementType);
1087 ComplexVal = CodeGenFunction::ComplexPairTy(
1088 ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType()));
1089 } else {
1090 assert(Val.isComplex() && "Must be a scalar or complex.");
1091 auto SrcElementType = SrcType->castAs<ComplexType>()->getElementType();
1092 auto DestElementType = DestType->castAs<ComplexType>()->getElementType();
1093 ComplexVal.first = CGF.EmitScalarConversion(
1094 Val.getComplexVal().first, SrcElementType, DestElementType);
1095 ComplexVal.second = CGF.EmitScalarConversion(
1096 Val.getComplexVal().second, SrcElementType, DestElementType);
1097 }
1098 return ComplexVal;
1099}
1100
1101static void EmitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst,
1102 const Expr *X, const Expr *V,
1103 SourceLocation Loc) {
1104 // v = x;
1105 assert(V->isLValue() && "V of 'omp atomic read' is not lvalue");
1106 assert(X->isLValue() && "X of 'omp atomic read' is not lvalue");
1107 LValue XLValue = CGF.EmitLValue(X);
1108 LValue VLValue = CGF.EmitLValue(V);
David Majnemera5b195a2015-02-14 01:35:12 +00001109 RValue Res = XLValue.isGlobalReg()
1110 ? CGF.EmitLoadOfLValue(XLValue, Loc)
1111 : CGF.EmitAtomicLoad(XLValue, Loc,
1112 IsSeqCst ? llvm::SequentiallyConsistent
Alexey Bataevb8329262015-02-27 06:33:30 +00001113 : llvm::Monotonic,
1114 XLValue.isVolatile());
Alexey Bataevb57056f2015-01-22 06:17:56 +00001115 // OpenMP, 2.12.6, atomic Construct
1116 // Any atomic construct with a seq_cst clause forces the atomically
1117 // performed operation to include an implicit flush operation without a
1118 // list.
1119 if (IsSeqCst)
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001120 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +00001121 switch (CGF.getEvaluationKind(V->getType())) {
1122 case TEK_Scalar:
1123 CGF.EmitStoreOfScalar(
1124 convertToScalarValue(CGF, Res, X->getType(), V->getType()), VLValue);
1125 break;
1126 case TEK_Complex:
1127 CGF.EmitStoreOfComplex(
1128 convertToComplexValue(CGF, Res, X->getType(), V->getType()), VLValue,
1129 /*isInit=*/false);
1130 break;
1131 case TEK_Aggregate:
1132 llvm_unreachable("Must be a scalar or complex.");
1133 }
1134}
1135
Alexey Bataevb8329262015-02-27 06:33:30 +00001136static void EmitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst,
1137 const Expr *X, const Expr *E,
1138 SourceLocation Loc) {
1139 // x = expr;
1140 assert(X->isLValue() && "X of 'omp atomic write' is not lvalue");
1141 LValue XLValue = CGF.EmitLValue(X);
1142 RValue ExprRValue = CGF.EmitAnyExpr(E);
1143 if (XLValue.isGlobalReg())
1144 CGF.EmitStoreThroughGlobalRegLValue(ExprRValue, XLValue);
1145 else
1146 CGF.EmitAtomicStore(ExprRValue, XLValue,
1147 IsSeqCst ? llvm::SequentiallyConsistent
1148 : llvm::Monotonic,
1149 XLValue.isVolatile(), /*IsInit=*/false);
1150 // OpenMP, 2.12.6, atomic Construct
1151 // Any atomic construct with a seq_cst clause forces the atomically
1152 // performed operation to include an implicit flush operation without a
1153 // list.
1154 if (IsSeqCst)
1155 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
1156}
1157
Alexey Bataevb4505a72015-03-30 05:20:59 +00001158static Optional<llvm::AtomicRMWInst::BinOp>
1159getCompatibleAtomicRMWBinOp(ASTContext &Context, BinaryOperatorKind Op,
1160 bool IsXLHSInRHSPart, LValue XLValue,
1161 RValue ExprRValue) {
1162 Optional<llvm::AtomicRMWInst::BinOp> RMWOp;
1163 // Allow atomicrmw only if 'x' and 'expr' are integer values, lvalue for 'x'
1164 // expression is simple and atomic is allowed for the given type for the
1165 // target platform.
1166 if (ExprRValue.isScalar() &&
1167 ExprRValue.getScalarVal()->getType()->isIntegerTy() &&
1168 XLValue.isSimple() &&
1169 (isa<llvm::ConstantInt>(ExprRValue.getScalarVal()) ||
1170 (ExprRValue.getScalarVal()->getType() ==
1171 XLValue.getAddress()->getType()->getPointerElementType())) &&
1172 Context.getTargetInfo().hasBuiltinAtomic(
1173 Context.getTypeSize(XLValue.getType()),
1174 Context.toBits(XLValue.getAlignment()))) {
1175 switch (Op) {
1176 case BO_Add:
1177 RMWOp = llvm::AtomicRMWInst::Add;
1178 break;
1179 case BO_Sub:
1180 if (IsXLHSInRHSPart) {
1181 RMWOp = llvm::AtomicRMWInst::Sub;
1182 }
1183 break;
1184 case BO_And:
1185 RMWOp = llvm::AtomicRMWInst::And;
1186 break;
1187 case BO_Or:
1188 RMWOp = llvm::AtomicRMWInst::Or;
1189 break;
1190 case BO_Xor:
1191 RMWOp = llvm::AtomicRMWInst::Xor;
1192 break;
1193 case BO_Mul:
1194 case BO_Div:
1195 case BO_Rem:
1196 case BO_Shl:
1197 case BO_Shr:
1198 break;
1199 case BO_PtrMemD:
1200 case BO_PtrMemI:
1201 case BO_LT:
1202 case BO_GT:
1203 case BO_LE:
1204 case BO_GE:
1205 case BO_EQ:
1206 case BO_NE:
1207 case BO_LAnd:
1208 case BO_LOr:
1209 case BO_Assign:
1210 case BO_MulAssign:
1211 case BO_DivAssign:
1212 case BO_RemAssign:
1213 case BO_AddAssign:
1214 case BO_SubAssign:
1215 case BO_ShlAssign:
1216 case BO_ShrAssign:
1217 case BO_AndAssign:
1218 case BO_XorAssign:
1219 case BO_OrAssign:
1220 case BO_Comma:
1221 llvm_unreachable("Unexpected binary operation in 'atomic update'.");
1222 }
1223 }
1224 return std::move(RMWOp);
1225}
1226
1227static void EmitOMPAtomicUpdateExpr(CodeGenFunction &CGF, bool IsSeqCst,
1228 const Expr *X, const Expr *E,
1229 const Expr *UE, bool IsXLHSInRHSPart,
1230 SourceLocation Loc) {
1231 assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) &&
1232 "Update expr in 'atomic update' must be a binary operator.");
1233 auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts());
1234 // Update expressions are allowed to have the following forms:
1235 // x binop= expr; -> xrval + expr;
1236 // x++, ++x -> xrval + 1;
1237 // x--, --x -> xrval - 1;
1238 // x = x binop expr; -> xrval binop expr
1239 // x = expr Op x; - > expr binop xrval;
1240 assert(X->isLValue() && "X of 'omp atomic write' is not lvalue");
1241 LValue XLValue = CGF.EmitLValue(X);
1242 RValue ExprRValue = CGF.EmitAnyExpr(E);
1243 const auto &Op =
1244 getCompatibleAtomicRMWBinOp(CGF.CGM.getContext(), BOUE->getOpcode(),
1245 IsXLHSInRHSPart, XLValue, ExprRValue);
1246 auto AO = IsSeqCst ? llvm::SequentiallyConsistent : llvm::Monotonic;
1247 if (Op) {
1248 auto *ExprVal = ExprRValue.getScalarVal();
1249 if (auto *IC = dyn_cast<llvm::ConstantInt>(ExprVal)) {
1250 ExprVal = CGF.Builder.CreateIntCast(
1251 IC, XLValue.getAddress()->getType()->getPointerElementType(),
1252 XLValue.getType()->hasSignedIntegerRepresentation());
1253 }
1254 CGF.Builder.CreateAtomicRMW(*Op, XLValue.getAddress(), ExprVal, AO);
1255 } else {
1256 auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
1257 auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
1258 CodeGenFunction::OpaqueValueMapping MapExpr(
1259 CGF, IsXLHSInRHSPart ? RHS : LHS, ExprRValue);
1260 auto *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
1261 if (XLValue.isGlobalReg()) {
1262 // Emit an update expression: 'xrval' binop 'expr' or 'expr' binop
1263 // 'xrval'.
1264 CodeGenFunction::OpaqueValueMapping MapX(
1265 CGF, XRValExpr, CGF.EmitLoadOfLValue(XLValue, Loc));
1266 CGF.EmitStoreThroughLValue(CGF.EmitAnyExpr(UE), XLValue);
1267 } else {
1268 // Perform compare-and-swap procedure.
1269 CGF.EmitAtomicUpdate(
1270 XLValue, AO, [&CGF, &UE, &XRValExpr](RValue XRVal) -> RValue {
1271 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRVal);
1272 return CGF.EmitAnyExpr(UE);
1273 }, /*IsVolatile=*/false);
1274 }
1275 }
1276 // OpenMP, 2.12.6, atomic Construct
1277 // Any atomic construct with a seq_cst clause forces the atomically
1278 // performed operation to include an implicit flush operation without a
1279 // list.
1280 if (IsSeqCst)
1281 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
1282}
1283
Alexey Bataevb57056f2015-01-22 06:17:56 +00001284static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
1285 bool IsSeqCst, const Expr *X, const Expr *V,
Alexey Bataevb4505a72015-03-30 05:20:59 +00001286 const Expr *E, const Expr *UE,
1287 bool IsXLHSInRHSPart, SourceLocation Loc) {
Alexey Bataevb57056f2015-01-22 06:17:56 +00001288 switch (Kind) {
1289 case OMPC_read:
1290 EmitOMPAtomicReadExpr(CGF, IsSeqCst, X, V, Loc);
1291 break;
1292 case OMPC_write:
Alexey Bataevb8329262015-02-27 06:33:30 +00001293 EmitOMPAtomicWriteExpr(CGF, IsSeqCst, X, E, Loc);
1294 break;
Alexey Bataevb4505a72015-03-30 05:20:59 +00001295 case OMPC_unknown:
Alexey Bataevb57056f2015-01-22 06:17:56 +00001296 case OMPC_update:
Alexey Bataevb4505a72015-03-30 05:20:59 +00001297 EmitOMPAtomicUpdateExpr(CGF, IsSeqCst, X, E, UE, IsXLHSInRHSPart, Loc);
1298 break;
Alexey Bataevb57056f2015-01-22 06:17:56 +00001299 case OMPC_capture:
1300 llvm_unreachable("CodeGen for 'omp atomic clause' is not supported yet.");
1301 case OMPC_if:
1302 case OMPC_final:
1303 case OMPC_num_threads:
1304 case OMPC_private:
1305 case OMPC_firstprivate:
1306 case OMPC_lastprivate:
1307 case OMPC_reduction:
1308 case OMPC_safelen:
1309 case OMPC_collapse:
1310 case OMPC_default:
1311 case OMPC_seq_cst:
1312 case OMPC_shared:
1313 case OMPC_linear:
1314 case OMPC_aligned:
1315 case OMPC_copyin:
1316 case OMPC_copyprivate:
1317 case OMPC_flush:
1318 case OMPC_proc_bind:
1319 case OMPC_schedule:
1320 case OMPC_ordered:
1321 case OMPC_nowait:
1322 case OMPC_untied:
1323 case OMPC_threadprivate:
1324 case OMPC_mergeable:
Alexey Bataevb57056f2015-01-22 06:17:56 +00001325 llvm_unreachable("Clause is not allowed in 'omp atomic'.");
1326 }
1327}
1328
1329void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
1330 bool IsSeqCst = S.getSingleClause(/*K=*/OMPC_seq_cst);
1331 OpenMPClauseKind Kind = OMPC_unknown;
1332 for (auto *C : S.clauses()) {
1333 // Find first clause (skip seq_cst clause, if it is first).
1334 if (C->getClauseKind() != OMPC_seq_cst) {
1335 Kind = C->getClauseKind();
1336 break;
1337 }
1338 }
Alexey Bataev10fec572015-03-11 04:48:56 +00001339
1340 const auto *CS =
1341 S.getAssociatedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
1342 if (const auto *EWC = dyn_cast<ExprWithCleanups>(CS))
1343 enterFullExpression(EWC);
Alexey Bataev10fec572015-03-11 04:48:56 +00001344
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001345 LexicalScope Scope(*this, S.getSourceRange());
1346 auto &&CodeGen = [&S, Kind, IsSeqCst](CodeGenFunction &CGF) {
1347 EmitOMPAtomicExpr(CGF, Kind, IsSeqCst, S.getX(), S.getV(), S.getExpr(),
1348 S.getUpdateExpr(), S.isXLHSInRHSPart(), S.getLocStart());
1349 };
1350 CGM.getOpenMPRuntime().emitInlinedDirective(*this, CodeGen);
Alexey Bataev0162e452014-07-22 10:10:35 +00001351}
1352
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001353void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) {
1354 llvm_unreachable("CodeGen for 'omp target' is not supported yet.");
1355}
1356
Alexey Bataev13314bf2014-10-09 04:18:56 +00001357void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &) {
1358 llvm_unreachable("CodeGen for 'omp teams' is not supported yet.");
1359}
1360