blob: 0a82adf9654ddc923dff081579d077e992954417 [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 Bataev36bf0112015-03-10 05:15:26 +000026namespace {
27/// \brief RAII for inlined OpenMP regions (like 'omp for', 'omp simd', 'omp
28/// critical' etc.). Helps to generate proper debug info and provides correct
29/// code generation for such constructs.
30class InlinedOpenMPRegionScopeRAII {
31 InlinedOpenMPRegionRAII Region;
32 CodeGenFunction::LexicalScope DirectiveScope;
33
34public:
35 InlinedOpenMPRegionScopeRAII(CodeGenFunction &CGF,
36 const OMPExecutableDirective &D)
37 : Region(CGF, D), DirectiveScope(CGF, D.getSourceRange()) {}
38};
39} // namespace
Alexey Bataev9959db52014-05-06 10:08:46 +000040
Alexey Bataevd74d0602014-10-13 06:02:40 +000041/// \brief Emits code for OpenMP 'if' clause using specified \a CodeGen
42/// function. Here is the logic:
43/// if (Cond) {
44/// CodeGen(true);
45/// } else {
46/// CodeGen(false);
47/// }
48static void EmitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
49 const std::function<void(bool)> &CodeGen) {
50 CodeGenFunction::LexicalScope ConditionScope(CGF, Cond->getSourceRange());
51
52 // If the condition constant folds and can be elided, try to avoid emitting
53 // the condition and the dead arm of the if/else.
54 bool CondConstant;
55 if (CGF.ConstantFoldsToSimpleInteger(Cond, CondConstant)) {
56 CodeGen(CondConstant);
57 return;
58 }
59
60 // Otherwise, the condition did not fold, or we couldn't elide it. Just
61 // emit the conditional branch.
62 auto ThenBlock = CGF.createBasicBlock(/*name*/ "omp_if.then");
63 auto ElseBlock = CGF.createBasicBlock(/*name*/ "omp_if.else");
64 auto ContBlock = CGF.createBasicBlock(/*name*/ "omp_if.end");
65 CGF.EmitBranchOnBoolExpr(Cond, ThenBlock, ElseBlock, /*TrueCount*/ 0);
66
67 // Emit the 'then' code.
68 CGF.EmitBlock(ThenBlock);
69 CodeGen(/*ThenBlock*/ true);
70 CGF.EmitBranch(ContBlock);
71 // Emit the 'else' code if present.
72 {
73 // There is no need to emit line number for unconditional branch.
Adrian Prantl95b24e92015-02-03 20:00:54 +000074 auto NL = ApplyDebugLocation::CreateEmpty(CGF);
Alexey Bataevd74d0602014-10-13 06:02:40 +000075 CGF.EmitBlock(ElseBlock);
76 }
77 CodeGen(/*ThenBlock*/ false);
78 {
79 // There is no need to emit line number for unconditional branch.
Adrian Prantl95b24e92015-02-03 20:00:54 +000080 auto NL = ApplyDebugLocation::CreateEmpty(CGF);
Alexey Bataevd74d0602014-10-13 06:02:40 +000081 CGF.EmitBranch(ContBlock);
82 }
83 // Emit the continuation block for code after the if.
84 CGF.EmitBlock(ContBlock, /*IsFinished*/ true);
85}
86
Alexey Bataev4a5bb772014-10-08 14:01:46 +000087void CodeGenFunction::EmitOMPAggregateAssign(LValue OriginalAddr,
88 llvm::Value *PrivateAddr,
89 const Expr *AssignExpr,
90 QualType OriginalType,
91 const VarDecl *VDInit) {
92 EmitBlock(createBasicBlock(".omp.assign.begin."));
93 if (!isa<CXXConstructExpr>(AssignExpr) || isTrivialInitializer(AssignExpr)) {
94 // Perform simple memcpy.
95 EmitAggregateAssign(PrivateAddr, OriginalAddr.getAddress(),
96 AssignExpr->getType());
97 } else {
98 // Perform element-by-element initialization.
99 QualType ElementTy;
100 auto SrcBegin = OriginalAddr.getAddress();
101 auto DestBegin = PrivateAddr;
102 auto ArrayTy = OriginalType->getAsArrayTypeUnsafe();
103 auto SrcNumElements = emitArrayLength(ArrayTy, ElementTy, SrcBegin);
104 auto DestNumElements = emitArrayLength(ArrayTy, ElementTy, DestBegin);
105 auto SrcEnd = Builder.CreateGEP(SrcBegin, SrcNumElements);
106 auto DestEnd = Builder.CreateGEP(DestBegin, DestNumElements);
107 // The basic structure here is a do-while loop, because we don't
108 // need to check for the zero-element case.
109 auto BodyBB = createBasicBlock("omp.arraycpy.body");
110 auto DoneBB = createBasicBlock("omp.arraycpy.done");
111 auto IsEmpty =
112 Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty");
113 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
114
115 // Enter the loop body, making that address the current address.
116 auto EntryBB = Builder.GetInsertBlock();
117 EmitBlock(BodyBB);
118 auto SrcElementPast = Builder.CreatePHI(SrcBegin->getType(), 2,
119 "omp.arraycpy.srcElementPast");
120 SrcElementPast->addIncoming(SrcEnd, EntryBB);
121 auto DestElementPast = Builder.CreatePHI(DestBegin->getType(), 2,
122 "omp.arraycpy.destElementPast");
123 DestElementPast->addIncoming(DestEnd, EntryBB);
124
125 // Shift the address back by one element.
126 auto NegativeOne = llvm::ConstantInt::get(SizeTy, -1, true);
127 auto DestElement = Builder.CreateGEP(DestElementPast, NegativeOne,
128 "omp.arraycpy.dest.element");
129 auto SrcElement = Builder.CreateGEP(SrcElementPast, NegativeOne,
130 "omp.arraycpy.src.element");
131 {
132 // Create RunCleanScope to cleanup possible temps.
133 CodeGenFunction::RunCleanupsScope Init(*this);
134 // Emit initialization for single element.
135 LocalDeclMap[VDInit] = SrcElement;
136 EmitAnyExprToMem(AssignExpr, DestElement,
137 AssignExpr->getType().getQualifiers(),
138 /*IsInitializer*/ false);
139 LocalDeclMap.erase(VDInit);
140 }
141
142 // Check whether we've reached the end.
143 auto Done =
144 Builder.CreateICmpEQ(DestElement, DestBegin, "omp.arraycpy.done");
145 Builder.CreateCondBr(Done, DoneBB, BodyBB);
146 DestElementPast->addIncoming(DestElement, Builder.GetInsertBlock());
147 SrcElementPast->addIncoming(SrcElement, Builder.GetInsertBlock());
148
149 // Done.
150 EmitBlock(DoneBB, true);
151 }
152 EmitBlock(createBasicBlock(".omp.assign.end."));
153}
154
155void CodeGenFunction::EmitOMPFirstprivateClause(
156 const OMPExecutableDirective &D,
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000157 CodeGenFunction::OMPPrivateScope &PrivateScope) {
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000158 auto PrivateFilter = [](const OMPClause *C) -> bool {
159 return C->getClauseKind() == OMPC_firstprivate;
160 };
161 for (OMPExecutableDirective::filtered_clause_iterator<decltype(PrivateFilter)>
162 I(D.clauses(), PrivateFilter); I; ++I) {
163 auto *C = cast<OMPFirstprivateClause>(*I);
164 auto IRef = C->varlist_begin();
165 auto InitsRef = C->inits().begin();
166 for (auto IInit : C->private_copies()) {
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000167 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
168 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
169 bool IsRegistered;
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000170 if (*InitsRef != nullptr) {
171 // Emit VarDecl with copy init for arrays.
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000172 auto *FD = CapturedStmtInfo->lookup(OrigVD);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000173 LValue Base = MakeNaturalAlignAddrLValue(
174 CapturedStmtInfo->getContextValue(),
175 getContext().getTagDeclType(FD->getParent()));
176 auto OriginalAddr = EmitLValueForField(Base, FD);
177 auto VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000178 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * {
179 auto Emission = EmitAutoVarAlloca(*VD);
180 // Emit initialization of aggregate firstprivate vars.
181 EmitOMPAggregateAssign(OriginalAddr, Emission.getAllocatedAddress(),
182 VD->getInit(), (*IRef)->getType(), VDInit);
183 EmitAutoVarCleanups(Emission);
184 return Emission.getAllocatedAddress();
185 });
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000186 } else
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000187 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * {
188 // Emit private VarDecl with copy init.
189 EmitDecl(*VD);
190 return GetAddrOfLocalVar(VD);
191 });
192 assert(IsRegistered && "counter already registered as private");
193 // Silence the warning about unused variable.
194 (void)IsRegistered;
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000195 ++IRef, ++InitsRef;
196 }
197 }
198}
199
Alexey Bataev03b340a2014-10-21 03:16:40 +0000200void CodeGenFunction::EmitOMPPrivateClause(
201 const OMPExecutableDirective &D,
202 CodeGenFunction::OMPPrivateScope &PrivateScope) {
203 auto PrivateFilter = [](const OMPClause *C) -> bool {
204 return C->getClauseKind() == OMPC_private;
205 };
206 for (OMPExecutableDirective::filtered_clause_iterator<decltype(PrivateFilter)>
207 I(D.clauses(), PrivateFilter); I; ++I) {
208 auto *C = cast<OMPPrivateClause>(*I);
209 auto IRef = C->varlist_begin();
210 for (auto IInit : C->private_copies()) {
211 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
212 auto VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
213 bool IsRegistered =
214 PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * {
215 // Emit private VarDecl with copy init.
216 EmitDecl(*VD);
217 return GetAddrOfLocalVar(VD);
218 });
219 assert(IsRegistered && "counter already registered as private");
220 // Silence the warning about unused variable.
221 (void)IsRegistered;
222 ++IRef;
223 }
224 }
225}
226
Alexey Bataevb2059782014-10-13 08:23:51 +0000227/// \brief Emits code for OpenMP parallel directive in the parallel region.
228static void EmitOMPParallelCall(CodeGenFunction &CGF,
229 const OMPParallelDirective &S,
230 llvm::Value *OutlinedFn,
231 llvm::Value *CapturedStruct) {
232 if (auto C = S.getSingleClause(/*K*/ OMPC_num_threads)) {
233 CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
234 auto NumThreadsClause = cast<OMPNumThreadsClause>(C);
235 auto NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(),
236 /*IgnoreResultAssign*/ true);
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000237 CGF.CGM.getOpenMPRuntime().emitNumThreadsClause(
Alexey Bataevb2059782014-10-13 08:23:51 +0000238 CGF, NumThreads, NumThreadsClause->getLocStart());
239 }
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000240 CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getLocStart(), OutlinedFn,
241 CapturedStruct);
Alexey Bataevb2059782014-10-13 08:23:51 +0000242}
243
Alexey Bataev9959db52014-05-06 10:08:46 +0000244void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
Alexey Bataev18095712014-10-10 12:19:54 +0000245 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
246 auto CapturedStruct = GenerateCapturedStmtArgument(*CS);
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000247 auto OutlinedFn = CGM.getOpenMPRuntime().emitOutlinedFunction(
Alexey Bataev18095712014-10-10 12:19:54 +0000248 S, *CS->getCapturedDecl()->param_begin());
Alexey Bataevd74d0602014-10-13 06:02:40 +0000249 if (auto C = S.getSingleClause(/*K*/ OMPC_if)) {
250 auto Cond = cast<OMPIfClause>(C)->getCondition();
251 EmitOMPIfClause(*this, Cond, [&](bool ThenBlock) {
252 if (ThenBlock)
Alexey Bataevb2059782014-10-13 08:23:51 +0000253 EmitOMPParallelCall(*this, S, OutlinedFn, CapturedStruct);
Alexey Bataevd74d0602014-10-13 06:02:40 +0000254 else
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000255 CGM.getOpenMPRuntime().emitSerialCall(*this, S.getLocStart(),
256 OutlinedFn, CapturedStruct);
Alexey Bataevd74d0602014-10-13 06:02:40 +0000257 });
Alexey Bataevb2059782014-10-13 08:23:51 +0000258 } else
259 EmitOMPParallelCall(*this, S, OutlinedFn, CapturedStruct);
Alexey Bataev9959db52014-05-06 10:08:46 +0000260}
Alexander Musman515ad8c2014-05-22 08:54:05 +0000261
Alexander Musmand196ef22014-10-07 08:57:09 +0000262void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &S,
Alexander Musmana5f070a2014-10-01 06:03:56 +0000263 bool SeparateIter) {
264 RunCleanupsScope BodyScope(*this);
265 // Update counters values on current iteration.
266 for (auto I : S.updates()) {
267 EmitIgnoredExpr(I);
268 }
269 // On a continue in the body, jump to the end.
Alexander Musmand196ef22014-10-07 08:57:09 +0000270 auto Continue = getJumpDestInCurrentScope("omp.body.continue");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000271 BreakContinueStack.push_back(BreakContinue(JumpDest(), Continue));
272 // Emit loop body.
273 EmitStmt(S.getBody());
274 // The end (updates/cleanups).
275 EmitBlock(Continue.getBlock());
276 BreakContinueStack.pop_back();
277 if (SeparateIter) {
278 // TODO: Update lastprivates if the SeparateIter flag is true.
279 // This will be implemented in a follow-up OMPLastprivateClause patch, but
280 // result should be still correct without it, as we do not make these
281 // variables private yet.
282 }
283}
284
Alexey Bataev2df54a02015-03-12 08:53:29 +0000285void CodeGenFunction::EmitOMPInnerLoop(const Stmt &S, bool RequiresCleanup,
286 const Expr *LoopCond,
287 const Expr *IncExpr,
288 const std::function<void()> &BodyGen) {
Alexander Musmand196ef22014-10-07 08:57:09 +0000289 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000290 auto Cnt = getPGORegionCounter(&S);
291
292 // Start the loop with a block that tests the condition.
Alexander Musmand196ef22014-10-07 08:57:09 +0000293 auto CondBlock = createBasicBlock("omp.inner.for.cond");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000294 EmitBlock(CondBlock);
295 LoopStack.push(CondBlock);
296
297 // If there are any cleanups between here and the loop-exit scope,
298 // create a block to stage a loop exit along.
299 auto ExitBlock = LoopExit.getBlock();
Alexey Bataev2df54a02015-03-12 08:53:29 +0000300 if (RequiresCleanup)
Alexander Musmand196ef22014-10-07 08:57:09 +0000301 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000302
Alexander Musmand196ef22014-10-07 08:57:09 +0000303 auto LoopBody = createBasicBlock("omp.inner.for.body");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000304
Alexey Bataev2df54a02015-03-12 08:53:29 +0000305 // Emit condition.
306 EmitBranchOnBoolExpr(LoopCond, LoopBody, ExitBlock, Cnt.getCount());
Alexander Musmana5f070a2014-10-01 06:03:56 +0000307 if (ExitBlock != LoopExit.getBlock()) {
308 EmitBlock(ExitBlock);
309 EmitBranchThroughCleanup(LoopExit);
310 }
311
312 EmitBlock(LoopBody);
313 Cnt.beginRegion(Builder);
314
315 // Create a block for the increment.
Alexander Musmand196ef22014-10-07 08:57:09 +0000316 auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000317 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
318
Alexey Bataev2df54a02015-03-12 08:53:29 +0000319 BodyGen();
Alexander Musmana5f070a2014-10-01 06:03:56 +0000320
321 // Emit "IV = IV + 1" and a back-edge to the condition block.
322 EmitBlock(Continue.getBlock());
Alexey Bataev2df54a02015-03-12 08:53:29 +0000323 EmitIgnoredExpr(IncExpr);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000324 BreakContinueStack.pop_back();
325 EmitBranch(CondBlock);
326 LoopStack.pop();
327 // Emit the fall-through block.
328 EmitBlock(LoopExit.getBlock());
329}
330
331void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) {
332 auto IC = S.counters().begin();
333 for (auto F : S.finals()) {
334 if (LocalDeclMap.lookup(cast<DeclRefExpr>((*IC))->getDecl())) {
335 EmitIgnoredExpr(F);
336 }
337 ++IC;
338 }
339}
340
Alexander Musman09184fe2014-09-30 05:29:28 +0000341static void EmitOMPAlignedClause(CodeGenFunction &CGF, CodeGenModule &CGM,
342 const OMPAlignedClause &Clause) {
343 unsigned ClauseAlignment = 0;
344 if (auto AlignmentExpr = Clause.getAlignment()) {
345 auto AlignmentCI =
346 cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
347 ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue());
348 }
349 for (auto E : Clause.varlists()) {
350 unsigned Alignment = ClauseAlignment;
351 if (Alignment == 0) {
352 // OpenMP [2.8.1, Description]
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000353 // If no optional parameter is specified, implementation-defined default
Alexander Musman09184fe2014-09-30 05:29:28 +0000354 // alignments for SIMD instructions on the target platforms are assumed.
355 Alignment = CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment(
356 E->getType());
357 }
358 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
359 "alignment is not power of 2");
360 if (Alignment != 0) {
361 llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
362 CGF.EmitAlignmentAssumption(PtrValue, Alignment);
363 }
364 }
365}
366
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000367static void EmitPrivateLoopCounters(CodeGenFunction &CGF,
368 CodeGenFunction::OMPPrivateScope &LoopScope,
369 ArrayRef<Expr *> Counters) {
370 for (auto *E : Counters) {
371 auto VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
372 bool IsRegistered = LoopScope.addPrivate(VD, [&]() -> llvm::Value * {
373 // Emit var without initialization.
374 auto VarEmission = CGF.EmitAutoVarAlloca(*VD);
375 CGF.EmitAutoVarCleanups(VarEmission);
376 return VarEmission.getAllocatedAddress();
377 });
378 assert(IsRegistered && "counter already registered as private");
379 // Silence the warning about unused variable.
380 (void)IsRegistered;
381 }
382 (void)LoopScope.Privatize();
383}
384
Alexander Musman515ad8c2014-05-22 08:54:05 +0000385void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
Alexander Musmana5f070a2014-10-01 06:03:56 +0000386 // Pragma 'simd' code depends on presence of 'lastprivate'.
387 // If present, we have to separate last iteration of the loop:
388 //
389 // if (LastIteration != 0) {
390 // for (IV in 0..LastIteration-1) BODY;
391 // BODY with updates of lastprivate vars;
392 // <Final counter/linear vars updates>;
393 // }
394 //
395 // otherwise (when there's no lastprivate):
396 //
397 // for (IV in 0..LastIteration) BODY;
398 // <Final counter/linear vars updates>;
399 //
400
401 // Walk clauses and process safelen/lastprivate.
402 bool SeparateIter = false;
Alexander Musman515ad8c2014-05-22 08:54:05 +0000403 LoopStack.setParallel();
404 LoopStack.setVectorizerEnable(true);
405 for (auto C : S.clauses()) {
406 switch (C->getClauseKind()) {
407 case OMPC_safelen: {
408 RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(),
409 AggValueSlot::ignored(), true);
410 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
411 LoopStack.setVectorizerWidth(Val->getZExtValue());
412 // In presence of finite 'safelen', it may be unsafe to mark all
413 // the memory instructions parallel, because loop-carried
414 // dependences of 'safelen' iterations are possible.
415 LoopStack.setParallel(false);
416 break;
417 }
Alexander Musman09184fe2014-09-30 05:29:28 +0000418 case OMPC_aligned:
419 EmitOMPAlignedClause(*this, CGM, cast<OMPAlignedClause>(*C));
420 break;
Alexander Musmana5f070a2014-10-01 06:03:56 +0000421 case OMPC_lastprivate:
422 SeparateIter = true;
423 break;
Alexander Musman515ad8c2014-05-22 08:54:05 +0000424 default:
425 // Not handled yet
426 ;
427 }
428 }
Alexander Musmana5f070a2014-10-01 06:03:56 +0000429
Alexey Bataev36bf0112015-03-10 05:15:26 +0000430 InlinedOpenMPRegionScopeRAII Region(*this, S);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000431
432 // Emit the loop iteration variable.
433 const Expr *IVExpr = S.getIterationVariable();
434 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
435 EmitVarDecl(*IVDecl);
436 EmitIgnoredExpr(S.getInit());
437
438 // Emit the iterations count variable.
439 // If it is not a variable, Sema decided to calculate iterations count on each
440 // iteration (e.g., it is foldable into a constant).
441 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
442 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
443 // Emit calculation of the iterations count.
444 EmitIgnoredExpr(S.getCalcLastIteration());
445 }
446
447 if (SeparateIter) {
448 // Emit: if (LastIteration > 0) - begin.
449 RegionCounter Cnt = getPGORegionCounter(&S);
450 auto ThenBlock = createBasicBlock("simd.if.then");
451 auto ContBlock = createBasicBlock("simd.if.end");
452 EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount());
453 EmitBlock(ThenBlock);
454 Cnt.beginRegion(Builder);
455 // Emit 'then' code.
456 {
457 OMPPrivateScope LoopScope(*this);
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000458 EmitPrivateLoopCounters(*this, LoopScope, S.counters());
Alexey Bataev2df54a02015-03-12 08:53:29 +0000459 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(),
460 S.getCond(/*SeparateIter=*/true), S.getInc(),
461 [&S, this]() {
462 EmitOMPLoopBody(S);
463 EmitStopPoint(&S);
464 });
Alexander Musmand196ef22014-10-07 08:57:09 +0000465 EmitOMPLoopBody(S, /* SeparateIter */ true);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000466 }
467 EmitOMPSimdFinal(S);
468 // Emit: if (LastIteration != 0) - end.
469 EmitBranch(ContBlock);
470 EmitBlock(ContBlock, true);
471 } else {
472 {
473 OMPPrivateScope LoopScope(*this);
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000474 EmitPrivateLoopCounters(*this, LoopScope, S.counters());
Alexey Bataev2df54a02015-03-12 08:53:29 +0000475 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(),
476 S.getCond(/*SeparateIter=*/false), S.getInc(),
477 [&S, this]() {
478 EmitOMPLoopBody(S);
479 EmitStopPoint(&S);
480 });
Alexander Musmana5f070a2014-10-01 06:03:56 +0000481 }
482 EmitOMPSimdFinal(S);
483 }
Alexander Musman515ad8c2014-05-22 08:54:05 +0000484}
485
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000486void CodeGenFunction::EmitOMPForOuterLoop(OpenMPScheduleClauseKind ScheduleKind,
487 const OMPLoopDirective &S,
488 OMPPrivateScope &LoopScope,
489 llvm::Value *LB, llvm::Value *UB,
490 llvm::Value *ST, llvm::Value *IL,
491 llvm::Value *Chunk) {
492 auto &RT = CGM.getOpenMPRuntime();
493 assert(!RT.isStaticNonchunked(ScheduleKind, /* Chunked */ Chunk != nullptr) &&
494 "static non-chunked schedule does not need outer loop");
495 if (RT.isDynamic(ScheduleKind)) {
496 ErrorUnsupported(&S, "OpenMP loop with dynamic schedule");
497 return;
498 }
499
500 // Emit outer loop.
501 //
502 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
503 // When schedule(static, chunk_size) is specified, iterations are divided into
504 // chunks of size chunk_size, and the chunks are assigned to the threads in
505 // the team in a round-robin fashion in the order of the thread number.
506 //
507 // while(UB = min(UB, GlobalUB), idx = LB, idx < UB) {
508 // while (idx <= UB) { BODY; ++idx; } // inner loop
509 // LB = LB + ST;
510 // UB = UB + ST;
511 // }
512 //
513 const Expr *IVExpr = S.getIterationVariable();
514 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
515 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
516
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000517 RT.emitForInit(*this, S.getLocStart(), ScheduleKind, IVSize, IVSigned, IL, LB,
518 UB, ST, Chunk);
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000519 auto LoopExit = getJumpDestInCurrentScope("omp.dispatch.end");
520
521 // Start the loop with a block that tests the condition.
522 auto CondBlock = createBasicBlock("omp.dispatch.cond");
523 EmitBlock(CondBlock);
524 LoopStack.push(CondBlock);
525
526 llvm::Value *BoolCondVal = nullptr;
527 // UB = min(UB, GlobalUB)
528 EmitIgnoredExpr(S.getEnsureUpperBound());
529 // IV = LB
530 EmitIgnoredExpr(S.getInit());
531 // IV < UB
532 BoolCondVal = EvaluateExprAsBool(S.getCond(false));
533
534 // If there are any cleanups between here and the loop-exit scope,
535 // create a block to stage a loop exit along.
536 auto ExitBlock = LoopExit.getBlock();
537 if (LoopScope.requiresCleanups())
538 ExitBlock = createBasicBlock("omp.dispatch.cleanup");
539
540 auto LoopBody = createBasicBlock("omp.dispatch.body");
541 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
542 if (ExitBlock != LoopExit.getBlock()) {
543 EmitBlock(ExitBlock);
544 EmitBranchThroughCleanup(LoopExit);
545 }
546 EmitBlock(LoopBody);
547
548 // Create a block for the increment.
549 auto Continue = getJumpDestInCurrentScope("omp.dispatch.inc");
550 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
551
Alexey Bataev2df54a02015-03-12 08:53:29 +0000552 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(),
553 S.getCond(/*SeparateIter=*/false), S.getInc(), [&S, this]() {
554 EmitOMPLoopBody(S);
555 EmitStopPoint(&S);
556 });
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000557
558 EmitBlock(Continue.getBlock());
559 BreakContinueStack.pop_back();
560 // Emit "LB = LB + Stride", "UB = UB + Stride".
561 EmitIgnoredExpr(S.getNextLowerBound());
562 EmitIgnoredExpr(S.getNextUpperBound());
563
564 EmitBranch(CondBlock);
565 LoopStack.pop();
566 // Emit the fall-through block.
567 EmitBlock(LoopExit.getBlock());
568
569 // Tell the runtime we are done.
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000570 RT.emitForFinish(*this, S.getLocStart(), ScheduleKind);
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000571}
572
Alexander Musmanc6388682014-12-15 07:07:06 +0000573/// \brief Emit a helper variable and return corresponding lvalue.
574static LValue EmitOMPHelperVar(CodeGenFunction &CGF,
575 const DeclRefExpr *Helper) {
576 auto VDecl = cast<VarDecl>(Helper->getDecl());
577 CGF.EmitVarDecl(*VDecl);
578 return CGF.EmitLValue(Helper);
579}
580
581void CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) {
582 // Emit the loop iteration variable.
583 auto IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
584 auto IVDecl = cast<VarDecl>(IVExpr->getDecl());
585 EmitVarDecl(*IVDecl);
586
587 // Emit the iterations count variable.
588 // If it is not a variable, Sema decided to calculate iterations count on each
589 // iteration (e.g., it is foldable into a constant).
590 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
591 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
592 // Emit calculation of the iterations count.
593 EmitIgnoredExpr(S.getCalcLastIteration());
594 }
595
596 auto &RT = CGM.getOpenMPRuntime();
597
598 // Check pre-condition.
599 {
600 // Skip the entire loop if we don't meet the precondition.
601 RegionCounter Cnt = getPGORegionCounter(&S);
602 auto ThenBlock = createBasicBlock("omp.precond.then");
603 auto ContBlock = createBasicBlock("omp.precond.end");
604 EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount());
605 EmitBlock(ThenBlock);
606 Cnt.beginRegion(Builder);
607 // Emit 'then' code.
608 {
609 // Emit helper vars inits.
610 LValue LB =
611 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getLowerBoundVariable()));
612 LValue UB =
613 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getUpperBoundVariable()));
614 LValue ST =
615 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable()));
616 LValue IL =
617 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
618
619 OMPPrivateScope LoopScope(*this);
620 EmitPrivateLoopCounters(*this, LoopScope, S.counters());
621
622 // Detect the loop schedule kind and chunk.
623 auto ScheduleKind = OMPC_SCHEDULE_unknown;
624 llvm::Value *Chunk = nullptr;
625 if (auto C = cast_or_null<OMPScheduleClause>(
626 S.getSingleClause(OMPC_schedule))) {
627 ScheduleKind = C->getScheduleKind();
628 if (auto Ch = C->getChunkSize()) {
629 Chunk = EmitScalarExpr(Ch);
630 Chunk = EmitScalarConversion(Chunk, Ch->getType(),
631 S.getIterationVariable()->getType());
632 }
633 }
634 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
635 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
636 if (RT.isStaticNonchunked(ScheduleKind,
637 /* Chunked */ Chunk != nullptr)) {
638 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
639 // When no chunk_size is specified, the iteration space is divided into
640 // chunks that are approximately equal in size, and at most one chunk is
641 // distributed to each thread. Note that the size of the chunks is
642 // unspecified in this case.
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000643 RT.emitForInit(*this, S.getLocStart(), ScheduleKind, IVSize, IVSigned,
644 IL.getAddress(), LB.getAddress(), UB.getAddress(),
645 ST.getAddress());
Alexander Musmanc6388682014-12-15 07:07:06 +0000646 // UB = min(UB, GlobalUB);
647 EmitIgnoredExpr(S.getEnsureUpperBound());
648 // IV = LB;
649 EmitIgnoredExpr(S.getInit());
650 // while (idx <= UB) { BODY; ++idx; }
Alexey Bataev2df54a02015-03-12 08:53:29 +0000651 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(),
652 S.getCond(/*SeparateIter=*/false), S.getInc(),
653 [&S, this]() {
654 EmitOMPLoopBody(S);
655 EmitStopPoint(&S);
656 });
Alexander Musmanc6388682014-12-15 07:07:06 +0000657 // Tell the runtime we are done.
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000658 RT.emitForFinish(*this, S.getLocStart(), ScheduleKind);
Alexander Musmandf7a8e22015-01-22 08:49:35 +0000659 } else {
660 // Emit the outer loop, which requests its work chunk [LB..UB] from
661 // runtime and runs the inner loop to process it.
662 EmitOMPForOuterLoop(ScheduleKind, S, LoopScope, LB.getAddress(),
663 UB.getAddress(), ST.getAddress(), IL.getAddress(),
664 Chunk);
665 }
Alexander Musmanc6388682014-12-15 07:07:06 +0000666 }
667 // We're now done with the loop, so jump to the continuation block.
668 EmitBranch(ContBlock);
669 EmitBlock(ContBlock, true);
670 }
671}
672
673void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {
Alexey Bataev36bf0112015-03-10 05:15:26 +0000674 InlinedOpenMPRegionScopeRAII Region(*this, S);
Alexander Musmanc6388682014-12-15 07:07:06 +0000675
676 EmitOMPWorksharingLoop(S);
677
678 // Emit an implicit barrier at the end.
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000679 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
680 /*IsExplicit*/ false);
Alexey Bataevf29276e2014-06-18 04:14:57 +0000681}
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000682
Alexander Musmanf82886e2014-09-18 05:12:34 +0000683void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &) {
684 llvm_unreachable("CodeGen for 'omp for simd' is not supported yet.");
685}
686
Alexey Bataev2df54a02015-03-12 08:53:29 +0000687static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty,
688 const Twine &Name,
689 llvm::Value *Init = nullptr) {
690 auto LVal = CGF.MakeNaturalAlignAddrLValue(CGF.CreateMemTemp(Ty, Name), Ty);
691 if (Init)
692 CGF.EmitScalarInit(Init, LVal);
693 return LVal;
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000694}
695
Alexey Bataev2df54a02015-03-12 08:53:29 +0000696void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
697 InlinedOpenMPRegionScopeRAII Region(*this, S);
698
699 auto *Stmt = cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt();
700 auto *CS = dyn_cast<CompoundStmt>(Stmt);
701 if (CS && CS->size() > 1) {
702 auto &C = CGM.getContext();
703 auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
704 // Emit helper vars inits.
705 LValue LB = createSectionLVal(*this, KmpInt32Ty, ".omp.sections.lb.",
706 Builder.getInt32(0));
707 auto *GlobalUBVal = Builder.getInt32(CS->size() - 1);
708 LValue UB =
709 createSectionLVal(*this, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal);
710 LValue ST = createSectionLVal(*this, KmpInt32Ty, ".omp.sections.st.",
711 Builder.getInt32(1));
712 LValue IL = createSectionLVal(*this, KmpInt32Ty, ".omp.sections.il.",
713 Builder.getInt32(0));
714 // Loop counter.
715 LValue IV = createSectionLVal(*this, KmpInt32Ty, ".omp.sections.iv.");
716 OpaqueValueExpr IVRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
717 OpaqueValueMapping OpaqueIV(*this, &IVRefExpr, IV);
718 OpaqueValueExpr UBRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
719 OpaqueValueMapping OpaqueUB(*this, &UBRefExpr, UB);
720 // Generate condition for loop.
721 BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue,
722 OK_Ordinary, S.getLocStart(), /*fpContractable=*/false);
723 // Increment for loop counter.
724 UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary,
725 S.getLocStart());
726 auto BodyGen = [this, CS, &S, &IV]() {
727 // Iterate through all sections and emit a switch construct:
728 // switch (IV) {
729 // case 0:
730 // <SectionStmt[0]>;
731 // break;
732 // ...
733 // case <NumSection> - 1:
734 // <SectionStmt[<NumSection> - 1]>;
735 // break;
736 // }
737 // .omp.sections.exit:
738 auto *ExitBB = createBasicBlock(".omp.sections.exit");
739 auto *SwitchStmt = Builder.CreateSwitch(
740 EmitLoadOfLValue(IV, S.getLocStart()).getScalarVal(), ExitBB,
741 CS->size());
742 unsigned CaseNumber = 0;
743 for (auto C = CS->children(); C; ++C, ++CaseNumber) {
744 auto CaseBB = createBasicBlock(".omp.sections.case");
745 EmitBlock(CaseBB);
746 SwitchStmt->addCase(Builder.getInt32(CaseNumber), CaseBB);
747 EmitStmt(*C);
748 EmitBranch(ExitBB);
749 }
750 EmitBlock(ExitBB, /*IsFinished=*/true);
751 };
752 // Emit static non-chunked loop.
753 CGM.getOpenMPRuntime().emitForInit(
754 *this, S.getLocStart(), OMPC_SCHEDULE_static, /*IVSize=*/32,
755 /*IVSigned=*/true, IL.getAddress(), LB.getAddress(), UB.getAddress(),
756 ST.getAddress());
757 // UB = min(UB, GlobalUB);
758 auto *UBVal = EmitLoadOfScalar(UB, S.getLocStart());
759 auto *MinUBGlobalUB = Builder.CreateSelect(
760 Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
761 EmitStoreOfScalar(MinUBGlobalUB, UB);
762 // IV = LB;
763 EmitStoreOfScalar(EmitLoadOfScalar(LB, S.getLocStart()), IV);
764 // while (idx <= UB) { BODY; ++idx; }
765 EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen);
766 // Tell the runtime we are done.
767 CGM.getOpenMPRuntime().emitForFinish(*this, S.getLocStart(),
768 OMPC_SCHEDULE_static);
769 } else {
770 // If only one section is found - no need to generate loop, emit as a single
771 // region.
772 CGM.getOpenMPRuntime().emitSingleRegion(*this, [&]() -> void {
773 InlinedOpenMPRegionScopeRAII Region(*this, S);
774 EmitStmt(Stmt);
775 EnsureInsertPoint();
776 }, S.getLocStart());
777 }
778
779 // Emit an implicit barrier at the end.
780 if (!S.getSingleClause(OMPC_nowait))
781 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
782 /*IsExplicit=*/false);
783}
784
785void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) {
786 InlinedOpenMPRegionScopeRAII Region(*this, S);
787 EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
788 EnsureInsertPoint();
Alexey Bataev1e0498a2014-06-26 08:21:58 +0000789}
790
Alexey Bataev6956e2e2015-02-05 06:35:41 +0000791void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000792 CGM.getOpenMPRuntime().emitSingleRegion(*this, [&]() -> void {
Alexey Bataev36bf0112015-03-10 05:15:26 +0000793 InlinedOpenMPRegionScopeRAII Region(*this, S);
Alexey Bataev6956e2e2015-02-05 06:35:41 +0000794 EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
795 EnsureInsertPoint();
796 }, S.getLocStart());
Alexey Bataevd1e40fb2014-06-26 12:05:45 +0000797}
798
Alexey Bataev8d690652014-12-04 07:23:53 +0000799void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000800 CGM.getOpenMPRuntime().emitMasterRegion(*this, [&]() -> void {
Alexey Bataev36bf0112015-03-10 05:15:26 +0000801 InlinedOpenMPRegionScopeRAII Region(*this, S);
Alexey Bataev8d690652014-12-04 07:23:53 +0000802 EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
803 EnsureInsertPoint();
804 }, S.getLocStart());
Alexander Musman80c22892014-07-17 08:54:58 +0000805}
806
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +0000807void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000808 CGM.getOpenMPRuntime().emitCriticalRegion(
Alexey Bataev75ddfab2014-12-01 11:32:38 +0000809 *this, S.getDirectiveName().getAsString(), [&]() -> void {
Alexey Bataev36bf0112015-03-10 05:15:26 +0000810 InlinedOpenMPRegionScopeRAII Region(*this, S);
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000811 EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
812 EnsureInsertPoint();
813 }, S.getLocStart());
Alexander Musmand9ed09f2014-07-21 09:42:05 +0000814}
815
Alexey Bataev4acb8592014-07-07 13:01:15 +0000816void
817CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
818 llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet.");
819}
820
Alexander Musmane4e893b2014-09-23 09:33:00 +0000821void CodeGenFunction::EmitOMPParallelForSimdDirective(
822 const OMPParallelForSimdDirective &) {
823 llvm_unreachable("CodeGen for 'omp parallel for simd' is not supported yet.");
824}
825
Alexey Bataev84d0b3e2014-07-08 08:12:03 +0000826void CodeGenFunction::EmitOMPParallelSectionsDirective(
827 const OMPParallelSectionsDirective &) {
828 llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet.");
829}
830
Alexey Bataev62b63b12015-03-10 07:28:44 +0000831void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
832 // Emit outlined function for task construct.
833 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
834 auto CapturedStruct = GenerateCapturedStmtArgument(*CS);
835 auto *I = CS->getCapturedDecl()->param_begin();
836 // The first function argument for tasks is a thread id, the second one is a
837 // part id (0 for tied tasks, >=0 for untied task).
838 auto OutlinedFn =
839 CGM.getOpenMPRuntime().emitTaskOutlinedFunction(S, *I, *std::next(I));
840 // Check if we should emit tied or untied task.
841 bool Tied = !S.getSingleClause(OMPC_untied);
842 // Check if the task is final
843 llvm::PointerIntPair<llvm::Value *, 1, bool> Final;
844 if (auto *Clause = S.getSingleClause(OMPC_final)) {
845 // If the condition constant folds and can be elided, try to avoid emitting
846 // the condition and the dead arm of the if/else.
847 auto *Cond = cast<OMPFinalClause>(Clause)->getCondition();
848 bool CondConstant;
849 if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
850 Final.setInt(CondConstant);
851 else
852 Final.setPointer(EvaluateExprAsBool(Cond));
853 } else {
854 // By default the task is not final.
855 Final.setInt(/*IntVal=*/false);
856 }
857 auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
858 CGM.getOpenMPRuntime().emitTaskCall(*this, S.getLocStart(), Tied, Final,
859 OutlinedFn, SharedsTy, CapturedStruct);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +0000860}
861
Alexey Bataev9f797f32015-02-05 05:57:51 +0000862void CodeGenFunction::EmitOMPTaskyieldDirective(
863 const OMPTaskyieldDirective &S) {
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000864 CGM.getOpenMPRuntime().emitTaskyieldCall(*this, S.getLocStart());
Alexey Bataev68446b72014-07-18 07:47:19 +0000865}
866
Alexey Bataev8f7c1b02014-12-05 04:09:23 +0000867void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) {
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000868 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart());
Alexey Bataev4d1dfea2014-07-18 09:11:51 +0000869}
870
Alexey Bataev2df347a2014-07-18 10:17:07 +0000871void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &) {
872 llvm_unreachable("CodeGen for 'omp taskwait' is not supported yet.");
873}
874
Alexey Bataevcc37cc12014-11-20 04:34:54 +0000875void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) {
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000876 CGM.getOpenMPRuntime().emitFlush(*this, [&]() -> ArrayRef<const Expr *> {
877 if (auto C = S.getSingleClause(/*K*/ OMPC_flush)) {
878 auto FlushClause = cast<OMPFlushClause>(C);
879 return llvm::makeArrayRef(FlushClause->varlist_begin(),
880 FlushClause->varlist_end());
881 }
882 return llvm::None;
883 }(), S.getLocStart());
Alexey Bataev6125da92014-07-21 11:26:11 +0000884}
885
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000886void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &) {
887 llvm_unreachable("CodeGen for 'omp ordered' is not supported yet.");
888}
889
Alexey Bataevb57056f2015-01-22 06:17:56 +0000890static llvm::Value *convertToScalarValue(CodeGenFunction &CGF, RValue Val,
891 QualType SrcType, QualType DestType) {
892 assert(CGF.hasScalarEvaluationKind(DestType) &&
893 "DestType must have scalar evaluation kind.");
894 assert(!Val.isAggregate() && "Must be a scalar or complex.");
895 return Val.isScalar()
896 ? CGF.EmitScalarConversion(Val.getScalarVal(), SrcType, DestType)
897 : CGF.EmitComplexToScalarConversion(Val.getComplexVal(), SrcType,
898 DestType);
899}
900
901static CodeGenFunction::ComplexPairTy
902convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType,
903 QualType DestType) {
904 assert(CGF.getEvaluationKind(DestType) == TEK_Complex &&
905 "DestType must have complex evaluation kind.");
906 CodeGenFunction::ComplexPairTy ComplexVal;
907 if (Val.isScalar()) {
908 // Convert the input element to the element type of the complex.
909 auto DestElementType = DestType->castAs<ComplexType>()->getElementType();
910 auto ScalarVal =
911 CGF.EmitScalarConversion(Val.getScalarVal(), SrcType, DestElementType);
912 ComplexVal = CodeGenFunction::ComplexPairTy(
913 ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType()));
914 } else {
915 assert(Val.isComplex() && "Must be a scalar or complex.");
916 auto SrcElementType = SrcType->castAs<ComplexType>()->getElementType();
917 auto DestElementType = DestType->castAs<ComplexType>()->getElementType();
918 ComplexVal.first = CGF.EmitScalarConversion(
919 Val.getComplexVal().first, SrcElementType, DestElementType);
920 ComplexVal.second = CGF.EmitScalarConversion(
921 Val.getComplexVal().second, SrcElementType, DestElementType);
922 }
923 return ComplexVal;
924}
925
926static void EmitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst,
927 const Expr *X, const Expr *V,
928 SourceLocation Loc) {
929 // v = x;
930 assert(V->isLValue() && "V of 'omp atomic read' is not lvalue");
931 assert(X->isLValue() && "X of 'omp atomic read' is not lvalue");
932 LValue XLValue = CGF.EmitLValue(X);
933 LValue VLValue = CGF.EmitLValue(V);
David Majnemera5b195a2015-02-14 01:35:12 +0000934 RValue Res = XLValue.isGlobalReg()
935 ? CGF.EmitLoadOfLValue(XLValue, Loc)
936 : CGF.EmitAtomicLoad(XLValue, Loc,
937 IsSeqCst ? llvm::SequentiallyConsistent
Alexey Bataevb8329262015-02-27 06:33:30 +0000938 : llvm::Monotonic,
939 XLValue.isVolatile());
Alexey Bataevb57056f2015-01-22 06:17:56 +0000940 // OpenMP, 2.12.6, atomic Construct
941 // Any atomic construct with a seq_cst clause forces the atomically
942 // performed operation to include an implicit flush operation without a
943 // list.
944 if (IsSeqCst)
Alexey Bataev3eff5f42015-02-25 08:32:46 +0000945 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
Alexey Bataevb57056f2015-01-22 06:17:56 +0000946 switch (CGF.getEvaluationKind(V->getType())) {
947 case TEK_Scalar:
948 CGF.EmitStoreOfScalar(
949 convertToScalarValue(CGF, Res, X->getType(), V->getType()), VLValue);
950 break;
951 case TEK_Complex:
952 CGF.EmitStoreOfComplex(
953 convertToComplexValue(CGF, Res, X->getType(), V->getType()), VLValue,
954 /*isInit=*/false);
955 break;
956 case TEK_Aggregate:
957 llvm_unreachable("Must be a scalar or complex.");
958 }
959}
960
Alexey Bataevb8329262015-02-27 06:33:30 +0000961static void EmitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst,
962 const Expr *X, const Expr *E,
963 SourceLocation Loc) {
964 // x = expr;
965 assert(X->isLValue() && "X of 'omp atomic write' is not lvalue");
966 LValue XLValue = CGF.EmitLValue(X);
967 RValue ExprRValue = CGF.EmitAnyExpr(E);
968 if (XLValue.isGlobalReg())
969 CGF.EmitStoreThroughGlobalRegLValue(ExprRValue, XLValue);
970 else
971 CGF.EmitAtomicStore(ExprRValue, XLValue,
972 IsSeqCst ? llvm::SequentiallyConsistent
973 : llvm::Monotonic,
974 XLValue.isVolatile(), /*IsInit=*/false);
975 // OpenMP, 2.12.6, atomic Construct
976 // Any atomic construct with a seq_cst clause forces the atomically
977 // performed operation to include an implicit flush operation without a
978 // list.
979 if (IsSeqCst)
980 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
981}
982
Alexey Bataevb57056f2015-01-22 06:17:56 +0000983static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
984 bool IsSeqCst, const Expr *X, const Expr *V,
Alexey Bataevb8329262015-02-27 06:33:30 +0000985 const Expr *E, SourceLocation Loc) {
Alexey Bataevb57056f2015-01-22 06:17:56 +0000986 switch (Kind) {
987 case OMPC_read:
988 EmitOMPAtomicReadExpr(CGF, IsSeqCst, X, V, Loc);
989 break;
990 case OMPC_write:
Alexey Bataevb8329262015-02-27 06:33:30 +0000991 EmitOMPAtomicWriteExpr(CGF, IsSeqCst, X, E, Loc);
992 break;
Alexey Bataevb57056f2015-01-22 06:17:56 +0000993 case OMPC_update:
994 case OMPC_capture:
995 llvm_unreachable("CodeGen for 'omp atomic clause' is not supported yet.");
996 case OMPC_if:
997 case OMPC_final:
998 case OMPC_num_threads:
999 case OMPC_private:
1000 case OMPC_firstprivate:
1001 case OMPC_lastprivate:
1002 case OMPC_reduction:
1003 case OMPC_safelen:
1004 case OMPC_collapse:
1005 case OMPC_default:
1006 case OMPC_seq_cst:
1007 case OMPC_shared:
1008 case OMPC_linear:
1009 case OMPC_aligned:
1010 case OMPC_copyin:
1011 case OMPC_copyprivate:
1012 case OMPC_flush:
1013 case OMPC_proc_bind:
1014 case OMPC_schedule:
1015 case OMPC_ordered:
1016 case OMPC_nowait:
1017 case OMPC_untied:
1018 case OMPC_threadprivate:
1019 case OMPC_mergeable:
1020 case OMPC_unknown:
1021 llvm_unreachable("Clause is not allowed in 'omp atomic'.");
1022 }
1023}
1024
1025void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
1026 bool IsSeqCst = S.getSingleClause(/*K=*/OMPC_seq_cst);
1027 OpenMPClauseKind Kind = OMPC_unknown;
1028 for (auto *C : S.clauses()) {
1029 // Find first clause (skip seq_cst clause, if it is first).
1030 if (C->getClauseKind() != OMPC_seq_cst) {
1031 Kind = C->getClauseKind();
1032 break;
1033 }
1034 }
Alexey Bataev10fec572015-03-11 04:48:56 +00001035
1036 const auto *CS =
1037 S.getAssociatedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
1038 if (const auto *EWC = dyn_cast<ExprWithCleanups>(CS))
1039 enterFullExpression(EWC);
Alexey Bataev36bf0112015-03-10 05:15:26 +00001040 InlinedOpenMPRegionScopeRAII Region(*this, S);
Alexey Bataev10fec572015-03-11 04:48:56 +00001041
Alexey Bataevb57056f2015-01-22 06:17:56 +00001042 EmitOMPAtomicExpr(*this, Kind, IsSeqCst, S.getX(), S.getV(), S.getExpr(),
1043 S.getLocStart());
Alexey Bataev0162e452014-07-22 10:10:35 +00001044}
1045
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001046void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) {
1047 llvm_unreachable("CodeGen for 'omp target' is not supported yet.");
1048}
1049
Alexey Bataev13314bf2014-10-09 04:18:56 +00001050void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &) {
1051 llvm_unreachable("CodeGen for 'omp teams' is not supported yet.");
1052}
1053