blob: 78fd37ce6562e871538d36c1fccc78a317b54407 [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
Alexey Bataevf841bd92014-12-16 07:00:22 +000023namespace {
24/// \brief RAII for emitting code of CapturedStmt without function outlining.
25class InlinedOpenMPRegion {
26 CodeGenFunction &CGF;
27 CodeGenFunction::CGCapturedStmtInfo *PrevCapturedStmtInfo;
28 const Decl *StoredCurCodeDecl;
29
30 /// \brief A class to emit CapturedStmt construct as inlined statement without
31 /// generating a function for outlined code.
32 class CGInlinedOpenMPRegionInfo : public CodeGenFunction::CGCapturedStmtInfo {
33 public:
34 CGInlinedOpenMPRegionInfo() : CGCapturedStmtInfo() {}
35 };
36
37public:
38 InlinedOpenMPRegion(CodeGenFunction &CGF, const Stmt *S)
39 : CGF(CGF), PrevCapturedStmtInfo(CGF.CapturedStmtInfo),
40 StoredCurCodeDecl(CGF.CurCodeDecl) {
41 CGF.CurCodeDecl = cast<CapturedStmt>(S)->getCapturedDecl();
42 CGF.CapturedStmtInfo = new CGInlinedOpenMPRegionInfo();
43 }
44 ~InlinedOpenMPRegion() {
45 delete CGF.CapturedStmtInfo;
46 CGF.CapturedStmtInfo = PrevCapturedStmtInfo;
47 CGF.CurCodeDecl = StoredCurCodeDecl;
48 }
49};
50} // namespace
51
Alexey Bataev9959db52014-05-06 10:08:46 +000052//===----------------------------------------------------------------------===//
53// OpenMP Directive Emission
54//===----------------------------------------------------------------------===//
55
Alexey Bataevd74d0602014-10-13 06:02:40 +000056/// \brief Emits code for OpenMP 'if' clause using specified \a CodeGen
57/// function. Here is the logic:
58/// if (Cond) {
59/// CodeGen(true);
60/// } else {
61/// CodeGen(false);
62/// }
63static void EmitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
64 const std::function<void(bool)> &CodeGen) {
65 CodeGenFunction::LexicalScope ConditionScope(CGF, Cond->getSourceRange());
66
67 // If the condition constant folds and can be elided, try to avoid emitting
68 // the condition and the dead arm of the if/else.
69 bool CondConstant;
70 if (CGF.ConstantFoldsToSimpleInteger(Cond, CondConstant)) {
71 CodeGen(CondConstant);
72 return;
73 }
74
75 // Otherwise, the condition did not fold, or we couldn't elide it. Just
76 // emit the conditional branch.
77 auto ThenBlock = CGF.createBasicBlock(/*name*/ "omp_if.then");
78 auto ElseBlock = CGF.createBasicBlock(/*name*/ "omp_if.else");
79 auto ContBlock = CGF.createBasicBlock(/*name*/ "omp_if.end");
80 CGF.EmitBranchOnBoolExpr(Cond, ThenBlock, ElseBlock, /*TrueCount*/ 0);
81
82 // Emit the 'then' code.
83 CGF.EmitBlock(ThenBlock);
84 CodeGen(/*ThenBlock*/ true);
85 CGF.EmitBranch(ContBlock);
86 // Emit the 'else' code if present.
87 {
88 // There is no need to emit line number for unconditional branch.
David Blaikie66e41972015-01-14 07:38:27 +000089 ApplyDebugLocation DL(CGF);
Alexey Bataevd74d0602014-10-13 06:02:40 +000090 CGF.EmitBlock(ElseBlock);
91 }
92 CodeGen(/*ThenBlock*/ false);
93 {
94 // There is no need to emit line number for unconditional branch.
David Blaikie66e41972015-01-14 07:38:27 +000095 ApplyDebugLocation DL(CGF);
Alexey Bataevd74d0602014-10-13 06:02:40 +000096 CGF.EmitBranch(ContBlock);
97 }
98 // Emit the continuation block for code after the if.
99 CGF.EmitBlock(ContBlock, /*IsFinished*/ true);
100}
101
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000102void CodeGenFunction::EmitOMPAggregateAssign(LValue OriginalAddr,
103 llvm::Value *PrivateAddr,
104 const Expr *AssignExpr,
105 QualType OriginalType,
106 const VarDecl *VDInit) {
107 EmitBlock(createBasicBlock(".omp.assign.begin."));
108 if (!isa<CXXConstructExpr>(AssignExpr) || isTrivialInitializer(AssignExpr)) {
109 // Perform simple memcpy.
110 EmitAggregateAssign(PrivateAddr, OriginalAddr.getAddress(),
111 AssignExpr->getType());
112 } else {
113 // Perform element-by-element initialization.
114 QualType ElementTy;
115 auto SrcBegin = OriginalAddr.getAddress();
116 auto DestBegin = PrivateAddr;
117 auto ArrayTy = OriginalType->getAsArrayTypeUnsafe();
118 auto SrcNumElements = emitArrayLength(ArrayTy, ElementTy, SrcBegin);
119 auto DestNumElements = emitArrayLength(ArrayTy, ElementTy, DestBegin);
120 auto SrcEnd = Builder.CreateGEP(SrcBegin, SrcNumElements);
121 auto DestEnd = Builder.CreateGEP(DestBegin, DestNumElements);
122 // The basic structure here is a do-while loop, because we don't
123 // need to check for the zero-element case.
124 auto BodyBB = createBasicBlock("omp.arraycpy.body");
125 auto DoneBB = createBasicBlock("omp.arraycpy.done");
126 auto IsEmpty =
127 Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty");
128 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
129
130 // Enter the loop body, making that address the current address.
131 auto EntryBB = Builder.GetInsertBlock();
132 EmitBlock(BodyBB);
133 auto SrcElementPast = Builder.CreatePHI(SrcBegin->getType(), 2,
134 "omp.arraycpy.srcElementPast");
135 SrcElementPast->addIncoming(SrcEnd, EntryBB);
136 auto DestElementPast = Builder.CreatePHI(DestBegin->getType(), 2,
137 "omp.arraycpy.destElementPast");
138 DestElementPast->addIncoming(DestEnd, EntryBB);
139
140 // Shift the address back by one element.
141 auto NegativeOne = llvm::ConstantInt::get(SizeTy, -1, true);
142 auto DestElement = Builder.CreateGEP(DestElementPast, NegativeOne,
143 "omp.arraycpy.dest.element");
144 auto SrcElement = Builder.CreateGEP(SrcElementPast, NegativeOne,
145 "omp.arraycpy.src.element");
146 {
147 // Create RunCleanScope to cleanup possible temps.
148 CodeGenFunction::RunCleanupsScope Init(*this);
149 // Emit initialization for single element.
150 LocalDeclMap[VDInit] = SrcElement;
151 EmitAnyExprToMem(AssignExpr, DestElement,
152 AssignExpr->getType().getQualifiers(),
153 /*IsInitializer*/ false);
154 LocalDeclMap.erase(VDInit);
155 }
156
157 // Check whether we've reached the end.
158 auto Done =
159 Builder.CreateICmpEQ(DestElement, DestBegin, "omp.arraycpy.done");
160 Builder.CreateCondBr(Done, DoneBB, BodyBB);
161 DestElementPast->addIncoming(DestElement, Builder.GetInsertBlock());
162 SrcElementPast->addIncoming(SrcElement, Builder.GetInsertBlock());
163
164 // Done.
165 EmitBlock(DoneBB, true);
166 }
167 EmitBlock(createBasicBlock(".omp.assign.end."));
168}
169
170void CodeGenFunction::EmitOMPFirstprivateClause(
171 const OMPExecutableDirective &D,
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000172 CodeGenFunction::OMPPrivateScope &PrivateScope) {
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000173 auto PrivateFilter = [](const OMPClause *C) -> bool {
174 return C->getClauseKind() == OMPC_firstprivate;
175 };
176 for (OMPExecutableDirective::filtered_clause_iterator<decltype(PrivateFilter)>
177 I(D.clauses(), PrivateFilter); I; ++I) {
178 auto *C = cast<OMPFirstprivateClause>(*I);
179 auto IRef = C->varlist_begin();
180 auto InitsRef = C->inits().begin();
181 for (auto IInit : C->private_copies()) {
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000182 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
183 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
184 bool IsRegistered;
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000185 if (*InitsRef != nullptr) {
186 // Emit VarDecl with copy init for arrays.
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000187 auto *FD = CapturedStmtInfo->lookup(OrigVD);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000188 LValue Base = MakeNaturalAlignAddrLValue(
189 CapturedStmtInfo->getContextValue(),
190 getContext().getTagDeclType(FD->getParent()));
191 auto OriginalAddr = EmitLValueForField(Base, FD);
192 auto VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000193 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * {
194 auto Emission = EmitAutoVarAlloca(*VD);
195 // Emit initialization of aggregate firstprivate vars.
196 EmitOMPAggregateAssign(OriginalAddr, Emission.getAllocatedAddress(),
197 VD->getInit(), (*IRef)->getType(), VDInit);
198 EmitAutoVarCleanups(Emission);
199 return Emission.getAllocatedAddress();
200 });
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000201 } else
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000202 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * {
203 // Emit private VarDecl with copy init.
204 EmitDecl(*VD);
205 return GetAddrOfLocalVar(VD);
206 });
207 assert(IsRegistered && "counter already registered as private");
208 // Silence the warning about unused variable.
209 (void)IsRegistered;
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000210 ++IRef, ++InitsRef;
211 }
212 }
213}
214
Alexey Bataev03b340a2014-10-21 03:16:40 +0000215void CodeGenFunction::EmitOMPPrivateClause(
216 const OMPExecutableDirective &D,
217 CodeGenFunction::OMPPrivateScope &PrivateScope) {
218 auto PrivateFilter = [](const OMPClause *C) -> bool {
219 return C->getClauseKind() == OMPC_private;
220 };
221 for (OMPExecutableDirective::filtered_clause_iterator<decltype(PrivateFilter)>
222 I(D.clauses(), PrivateFilter); I; ++I) {
223 auto *C = cast<OMPPrivateClause>(*I);
224 auto IRef = C->varlist_begin();
225 for (auto IInit : C->private_copies()) {
226 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
227 auto VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
228 bool IsRegistered =
229 PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * {
230 // Emit private VarDecl with copy init.
231 EmitDecl(*VD);
232 return GetAddrOfLocalVar(VD);
233 });
234 assert(IsRegistered && "counter already registered as private");
235 // Silence the warning about unused variable.
236 (void)IsRegistered;
237 ++IRef;
238 }
239 }
240}
241
Alexey Bataevb2059782014-10-13 08:23:51 +0000242/// \brief Emits code for OpenMP parallel directive in the parallel region.
243static void EmitOMPParallelCall(CodeGenFunction &CGF,
244 const OMPParallelDirective &S,
245 llvm::Value *OutlinedFn,
246 llvm::Value *CapturedStruct) {
247 if (auto C = S.getSingleClause(/*K*/ OMPC_num_threads)) {
248 CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
249 auto NumThreadsClause = cast<OMPNumThreadsClause>(C);
250 auto NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(),
251 /*IgnoreResultAssign*/ true);
252 CGF.CGM.getOpenMPRuntime().EmitOMPNumThreadsClause(
253 CGF, NumThreads, NumThreadsClause->getLocStart());
254 }
255 CGF.CGM.getOpenMPRuntime().EmitOMPParallelCall(CGF, S.getLocStart(),
256 OutlinedFn, CapturedStruct);
257}
258
Alexey Bataev9959db52014-05-06 10:08:46 +0000259void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
Alexey Bataev18095712014-10-10 12:19:54 +0000260 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
261 auto CapturedStruct = GenerateCapturedStmtArgument(*CS);
262 auto OutlinedFn = CGM.getOpenMPRuntime().EmitOpenMPOutlinedFunction(
263 S, *CS->getCapturedDecl()->param_begin());
Alexey Bataevd74d0602014-10-13 06:02:40 +0000264 if (auto C = S.getSingleClause(/*K*/ OMPC_if)) {
265 auto Cond = cast<OMPIfClause>(C)->getCondition();
266 EmitOMPIfClause(*this, Cond, [&](bool ThenBlock) {
267 if (ThenBlock)
Alexey Bataevb2059782014-10-13 08:23:51 +0000268 EmitOMPParallelCall(*this, S, OutlinedFn, CapturedStruct);
Alexey Bataevd74d0602014-10-13 06:02:40 +0000269 else
270 CGM.getOpenMPRuntime().EmitOMPSerialCall(*this, S.getLocStart(),
271 OutlinedFn, CapturedStruct);
272 });
Alexey Bataevb2059782014-10-13 08:23:51 +0000273 } else
274 EmitOMPParallelCall(*this, S, OutlinedFn, CapturedStruct);
Alexey Bataev9959db52014-05-06 10:08:46 +0000275}
Alexander Musman515ad8c2014-05-22 08:54:05 +0000276
Alexander Musmand196ef22014-10-07 08:57:09 +0000277void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &S,
Alexander Musmana5f070a2014-10-01 06:03:56 +0000278 bool SeparateIter) {
279 RunCleanupsScope BodyScope(*this);
280 // Update counters values on current iteration.
281 for (auto I : S.updates()) {
282 EmitIgnoredExpr(I);
283 }
284 // On a continue in the body, jump to the end.
Alexander Musmand196ef22014-10-07 08:57:09 +0000285 auto Continue = getJumpDestInCurrentScope("omp.body.continue");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000286 BreakContinueStack.push_back(BreakContinue(JumpDest(), Continue));
287 // Emit loop body.
288 EmitStmt(S.getBody());
289 // The end (updates/cleanups).
290 EmitBlock(Continue.getBlock());
291 BreakContinueStack.pop_back();
292 if (SeparateIter) {
293 // TODO: Update lastprivates if the SeparateIter flag is true.
294 // This will be implemented in a follow-up OMPLastprivateClause patch, but
295 // result should be still correct without it, as we do not make these
296 // variables private yet.
297 }
298}
299
Alexander Musmand196ef22014-10-07 08:57:09 +0000300void CodeGenFunction::EmitOMPInnerLoop(const OMPLoopDirective &S,
301 OMPPrivateScope &LoopScope,
302 bool SeparateIter) {
303 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000304 auto Cnt = getPGORegionCounter(&S);
305
306 // Start the loop with a block that tests the condition.
Alexander Musmand196ef22014-10-07 08:57:09 +0000307 auto CondBlock = createBasicBlock("omp.inner.for.cond");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000308 EmitBlock(CondBlock);
309 LoopStack.push(CondBlock);
310
311 // If there are any cleanups between here and the loop-exit scope,
312 // create a block to stage a loop exit along.
313 auto ExitBlock = LoopExit.getBlock();
314 if (LoopScope.requiresCleanups())
Alexander Musmand196ef22014-10-07 08:57:09 +0000315 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000316
Alexander Musmand196ef22014-10-07 08:57:09 +0000317 auto LoopBody = createBasicBlock("omp.inner.for.body");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000318
319 // Emit condition: "IV < LastIteration + 1 [ - 1]"
320 // ("- 1" when lastprivate clause is present - separate one iteration).
321 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond(SeparateIter));
322 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock,
323 PGO.createLoopWeights(S.getCond(SeparateIter), Cnt));
324
325 if (ExitBlock != LoopExit.getBlock()) {
326 EmitBlock(ExitBlock);
327 EmitBranchThroughCleanup(LoopExit);
328 }
329
330 EmitBlock(LoopBody);
331 Cnt.beginRegion(Builder);
332
333 // Create a block for the increment.
Alexander Musmand196ef22014-10-07 08:57:09 +0000334 auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000335 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
336
Alexander Musmand196ef22014-10-07 08:57:09 +0000337 EmitOMPLoopBody(S);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000338 EmitStopPoint(&S);
339
340 // Emit "IV = IV + 1" and a back-edge to the condition block.
341 EmitBlock(Continue.getBlock());
342 EmitIgnoredExpr(S.getInc());
343 BreakContinueStack.pop_back();
344 EmitBranch(CondBlock);
345 LoopStack.pop();
346 // Emit the fall-through block.
347 EmitBlock(LoopExit.getBlock());
348}
349
350void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) {
351 auto IC = S.counters().begin();
352 for (auto F : S.finals()) {
353 if (LocalDeclMap.lookup(cast<DeclRefExpr>((*IC))->getDecl())) {
354 EmitIgnoredExpr(F);
355 }
356 ++IC;
357 }
358}
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 }
401 (void)LoopScope.Privatize();
402}
403
Alexander Musman515ad8c2014-05-22 08:54:05 +0000404void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
Alexander Musmana5f070a2014-10-01 06:03:56 +0000405 // Pragma 'simd' code depends on presence of 'lastprivate'.
406 // If present, we have to separate last iteration of the loop:
407 //
408 // if (LastIteration != 0) {
409 // for (IV in 0..LastIteration-1) BODY;
410 // BODY with updates of lastprivate vars;
411 // <Final counter/linear vars updates>;
412 // }
413 //
414 // otherwise (when there's no lastprivate):
415 //
416 // for (IV in 0..LastIteration) BODY;
417 // <Final counter/linear vars updates>;
418 //
419
420 // Walk clauses and process safelen/lastprivate.
421 bool SeparateIter = false;
Alexander Musman515ad8c2014-05-22 08:54:05 +0000422 LoopStack.setParallel();
423 LoopStack.setVectorizerEnable(true);
424 for (auto C : S.clauses()) {
425 switch (C->getClauseKind()) {
426 case OMPC_safelen: {
427 RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(),
428 AggValueSlot::ignored(), true);
429 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
430 LoopStack.setVectorizerWidth(Val->getZExtValue());
431 // In presence of finite 'safelen', it may be unsafe to mark all
432 // the memory instructions parallel, because loop-carried
433 // dependences of 'safelen' iterations are possible.
434 LoopStack.setParallel(false);
435 break;
436 }
Alexander Musman09184fe2014-09-30 05:29:28 +0000437 case OMPC_aligned:
438 EmitOMPAlignedClause(*this, CGM, cast<OMPAlignedClause>(*C));
439 break;
Alexander Musmana5f070a2014-10-01 06:03:56 +0000440 case OMPC_lastprivate:
441 SeparateIter = true;
442 break;
Alexander Musman515ad8c2014-05-22 08:54:05 +0000443 default:
444 // Not handled yet
445 ;
446 }
447 }
Alexander Musmana5f070a2014-10-01 06:03:56 +0000448
Alexey Bataevf841bd92014-12-16 07:00:22 +0000449 InlinedOpenMPRegion Region(*this, S.getAssociatedStmt());
Alexander Musmana5f070a2014-10-01 06:03:56 +0000450 RunCleanupsScope DirectiveScope(*this);
451
452 CGDebugInfo *DI = getDebugInfo();
453 if (DI)
454 DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin());
455
456 // Emit the loop iteration variable.
457 const Expr *IVExpr = S.getIterationVariable();
458 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
459 EmitVarDecl(*IVDecl);
460 EmitIgnoredExpr(S.getInit());
461
462 // Emit the iterations count variable.
463 // If it is not a variable, Sema decided to calculate iterations count on each
464 // iteration (e.g., it is foldable into a constant).
465 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
466 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
467 // Emit calculation of the iterations count.
468 EmitIgnoredExpr(S.getCalcLastIteration());
469 }
470
471 if (SeparateIter) {
472 // Emit: if (LastIteration > 0) - begin.
473 RegionCounter Cnt = getPGORegionCounter(&S);
474 auto ThenBlock = createBasicBlock("simd.if.then");
475 auto ContBlock = createBasicBlock("simd.if.end");
476 EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount());
477 EmitBlock(ThenBlock);
478 Cnt.beginRegion(Builder);
479 // Emit 'then' code.
480 {
481 OMPPrivateScope LoopScope(*this);
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000482 EmitPrivateLoopCounters(*this, LoopScope, S.counters());
Alexander Musmand196ef22014-10-07 08:57:09 +0000483 EmitOMPInnerLoop(S, LoopScope, /* SeparateIter */ true);
484 EmitOMPLoopBody(S, /* SeparateIter */ true);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000485 }
486 EmitOMPSimdFinal(S);
487 // Emit: if (LastIteration != 0) - end.
488 EmitBranch(ContBlock);
489 EmitBlock(ContBlock, true);
490 } else {
491 {
492 OMPPrivateScope LoopScope(*this);
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000493 EmitPrivateLoopCounters(*this, LoopScope, S.counters());
Alexander Musmand196ef22014-10-07 08:57:09 +0000494 EmitOMPInnerLoop(S, LoopScope);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000495 }
496 EmitOMPSimdFinal(S);
497 }
498
499 if (DI)
500 DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd());
Alexander Musman515ad8c2014-05-22 08:54:05 +0000501}
502
Alexander Musmanc6388682014-12-15 07:07:06 +0000503/// \brief Emit a helper variable and return corresponding lvalue.
504static LValue EmitOMPHelperVar(CodeGenFunction &CGF,
505 const DeclRefExpr *Helper) {
506 auto VDecl = cast<VarDecl>(Helper->getDecl());
507 CGF.EmitVarDecl(*VDecl);
508 return CGF.EmitLValue(Helper);
509}
510
511void CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) {
512 // Emit the loop iteration variable.
513 auto IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
514 auto IVDecl = cast<VarDecl>(IVExpr->getDecl());
515 EmitVarDecl(*IVDecl);
516
517 // Emit the iterations count variable.
518 // If it is not a variable, Sema decided to calculate iterations count on each
519 // iteration (e.g., it is foldable into a constant).
520 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
521 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
522 // Emit calculation of the iterations count.
523 EmitIgnoredExpr(S.getCalcLastIteration());
524 }
525
526 auto &RT = CGM.getOpenMPRuntime();
527
528 // Check pre-condition.
529 {
530 // Skip the entire loop if we don't meet the precondition.
531 RegionCounter Cnt = getPGORegionCounter(&S);
532 auto ThenBlock = createBasicBlock("omp.precond.then");
533 auto ContBlock = createBasicBlock("omp.precond.end");
534 EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount());
535 EmitBlock(ThenBlock);
536 Cnt.beginRegion(Builder);
537 // Emit 'then' code.
538 {
539 // Emit helper vars inits.
540 LValue LB =
541 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getLowerBoundVariable()));
542 LValue UB =
543 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getUpperBoundVariable()));
544 LValue ST =
545 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable()));
546 LValue IL =
547 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
548
549 OMPPrivateScope LoopScope(*this);
550 EmitPrivateLoopCounters(*this, LoopScope, S.counters());
551
552 // Detect the loop schedule kind and chunk.
553 auto ScheduleKind = OMPC_SCHEDULE_unknown;
554 llvm::Value *Chunk = nullptr;
555 if (auto C = cast_or_null<OMPScheduleClause>(
556 S.getSingleClause(OMPC_schedule))) {
557 ScheduleKind = C->getScheduleKind();
558 if (auto Ch = C->getChunkSize()) {
559 Chunk = EmitScalarExpr(Ch);
560 Chunk = EmitScalarConversion(Chunk, Ch->getType(),
561 S.getIterationVariable()->getType());
562 }
563 }
564 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
565 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
566 if (RT.isStaticNonchunked(ScheduleKind,
567 /* Chunked */ Chunk != nullptr)) {
568 // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
569 // When no chunk_size is specified, the iteration space is divided into
570 // chunks that are approximately equal in size, and at most one chunk is
571 // distributed to each thread. Note that the size of the chunks is
572 // unspecified in this case.
573 RT.EmitOMPForInit(*this, S.getLocStart(), ScheduleKind, IVSize, IVSigned,
574 IL.getAddress(), LB.getAddress(), UB.getAddress(),
575 ST.getAddress());
576 // UB = min(UB, GlobalUB);
577 EmitIgnoredExpr(S.getEnsureUpperBound());
578 // IV = LB;
579 EmitIgnoredExpr(S.getInit());
580 // while (idx <= UB) { BODY; ++idx; }
581 EmitOMPInnerLoop(S, LoopScope);
582 // Tell the runtime we are done.
583 RT.EmitOMPForFinish(*this, S.getLocStart(), ScheduleKind);
584 } else
585 ErrorUnsupported(&S, "OpenMP loop with requested schedule");
586 }
587 // We're now done with the loop, so jump to the continuation block.
588 EmitBranch(ContBlock);
589 EmitBlock(ContBlock, true);
590 }
591}
592
593void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {
Alexey Bataevf841bd92014-12-16 07:00:22 +0000594 InlinedOpenMPRegion Region(*this, S.getAssociatedStmt());
Alexander Musmanc6388682014-12-15 07:07:06 +0000595 RunCleanupsScope DirectiveScope(*this);
596
597 CGDebugInfo *DI = getDebugInfo();
598 if (DI)
599 DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin());
600
601 EmitOMPWorksharingLoop(S);
602
603 // Emit an implicit barrier at the end.
604 CGM.getOpenMPRuntime().EmitOMPBarrierCall(*this, S.getLocStart(),
605 /*IsExplicit*/ false);
606 if (DI)
607 DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd());
Alexey Bataevf29276e2014-06-18 04:14:57 +0000608}
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000609
Alexander Musmanf82886e2014-09-18 05:12:34 +0000610void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &) {
611 llvm_unreachable("CodeGen for 'omp for simd' is not supported yet.");
612}
613
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000614void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &) {
615 llvm_unreachable("CodeGen for 'omp sections' is not supported yet.");
616}
617
Alexey Bataev1e0498a2014-06-26 08:21:58 +0000618void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &) {
619 llvm_unreachable("CodeGen for 'omp section' is not supported yet.");
620}
621
Alexey Bataevd1e40fb2014-06-26 12:05:45 +0000622void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) {
623 llvm_unreachable("CodeGen for 'omp single' is not supported yet.");
624}
625
Alexey Bataev8d690652014-12-04 07:23:53 +0000626void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {
Alexey Bataevf841bd92014-12-16 07:00:22 +0000627 CGM.getOpenMPRuntime().EmitOMPMasterRegion(*this, [&]() -> void {
628 InlinedOpenMPRegion Region(*this, S.getAssociatedStmt());
Alexey Bataev8d690652014-12-04 07:23:53 +0000629 RunCleanupsScope Scope(*this);
630 EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
631 EnsureInsertPoint();
632 }, S.getLocStart());
Alexander Musman80c22892014-07-17 08:54:58 +0000633}
634
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +0000635void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
Alexey Bataev75ddfab2014-12-01 11:32:38 +0000636 CGM.getOpenMPRuntime().EmitOMPCriticalRegion(
637 *this, S.getDirectiveName().getAsString(), [&]() -> void {
Alexey Bataevf841bd92014-12-16 07:00:22 +0000638 InlinedOpenMPRegion Region(*this, S.getAssociatedStmt());
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +0000639 RunCleanupsScope Scope(*this);
Alexey Bataevf841bd92014-12-16 07:00:22 +0000640 EmitStmt(
641 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +0000642 EnsureInsertPoint();
Alexey Bataev75ddfab2014-12-01 11:32:38 +0000643 }, S.getLocStart());
Alexander Musmand9ed09f2014-07-21 09:42:05 +0000644}
645
Alexey Bataev4acb8592014-07-07 13:01:15 +0000646void
647CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
648 llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet.");
649}
650
Alexander Musmane4e893b2014-09-23 09:33:00 +0000651void CodeGenFunction::EmitOMPParallelForSimdDirective(
652 const OMPParallelForSimdDirective &) {
653 llvm_unreachable("CodeGen for 'omp parallel for simd' is not supported yet.");
654}
655
Alexey Bataev84d0b3e2014-07-08 08:12:03 +0000656void CodeGenFunction::EmitOMPParallelSectionsDirective(
657 const OMPParallelSectionsDirective &) {
658 llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet.");
659}
660
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +0000661void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &) {
662 llvm_unreachable("CodeGen for 'omp task' is not supported yet.");
663}
664
Alexey Bataev68446b72014-07-18 07:47:19 +0000665void CodeGenFunction::EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &) {
666 llvm_unreachable("CodeGen for 'omp taskyield' is not supported yet.");
667}
668
Alexey Bataev8f7c1b02014-12-05 04:09:23 +0000669void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) {
670 CGM.getOpenMPRuntime().EmitOMPBarrierCall(*this, S.getLocStart());
Alexey Bataev4d1dfea2014-07-18 09:11:51 +0000671}
672
Alexey Bataev2df347a2014-07-18 10:17:07 +0000673void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &) {
674 llvm_unreachable("CodeGen for 'omp taskwait' is not supported yet.");
675}
676
Alexey Bataevcc37cc12014-11-20 04:34:54 +0000677void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) {
678 CGM.getOpenMPRuntime().EmitOMPFlush(
679 *this, [&]() -> ArrayRef<const Expr *> {
680 if (auto C = S.getSingleClause(/*K*/ OMPC_flush)) {
681 auto FlushClause = cast<OMPFlushClause>(C);
682 return llvm::makeArrayRef(FlushClause->varlist_begin(),
683 FlushClause->varlist_end());
684 }
685 return llvm::None;
686 }(),
687 S.getLocStart());
Alexey Bataev6125da92014-07-21 11:26:11 +0000688}
689
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000690void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &) {
691 llvm_unreachable("CodeGen for 'omp ordered' is not supported yet.");
692}
693
Alexey Bataev0162e452014-07-22 10:10:35 +0000694void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &) {
695 llvm_unreachable("CodeGen for 'omp atomic' is not supported yet.");
696}
697
Alexey Bataev0bd520b2014-09-19 08:19:49 +0000698void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) {
699 llvm_unreachable("CodeGen for 'omp target' is not supported yet.");
700}
701
Alexey Bataev13314bf2014-10-09 04:18:56 +0000702void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &) {
703 llvm_unreachable("CodeGen for 'omp teams' is not supported yet.");
704}
705