blob: 985cc0e62aeb12001b7ebff97ad0f8ae932315ef [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"
17#include "clang/AST/Stmt.h"
18#include "clang/AST/StmtOpenMP.h"
Alexander Musman09184fe2014-09-30 05:29:28 +000019#include "TargetInfo.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000020using namespace clang;
21using namespace CodeGen;
22
23//===----------------------------------------------------------------------===//
24// OpenMP Directive Emission
25//===----------------------------------------------------------------------===//
26
27void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
28 const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt());
29 llvm::Value *CapturedStruct = GenerateCapturedStmtArgument(*CS);
30
31 llvm::Value *OutlinedFn;
32 {
33 CodeGenFunction CGF(CGM, true);
34 CGCapturedStmtInfo CGInfo(*CS, CS->getCapturedRegionKind());
35 CGF.CapturedStmtInfo = &CGInfo;
Alexey Bataevaca7fcf2014-06-30 02:55:54 +000036 OutlinedFn = CGF.GenerateCapturedStmtFunction(*CS);
Alexey Bataev9959db52014-05-06 10:08:46 +000037 }
38
39 // Build call __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/)
40 llvm::Value *Args[] = {
Alexey Bataev23b69422014-06-18 07:08:49 +000041 CGM.getOpenMPRuntime().EmitOpenMPUpdateLocation(*this, S.getLocStart()),
42 Builder.getInt32(1), // Number of arguments after 'microtask' argument
43 // (there is only one additional argument - 'context')
44 Builder.CreateBitCast(OutlinedFn,
45 CGM.getOpenMPRuntime().getKmpc_MicroPointerTy()),
46 EmitCastToVoidPtr(CapturedStruct)};
Alexey Bataev9959db52014-05-06 10:08:46 +000047 llvm::Constant *RTLFn = CGM.getOpenMPRuntime().CreateRuntimeFunction(
48 CGOpenMPRuntime::OMPRTL__kmpc_fork_call);
49 EmitRuntimeCall(RTLFn, Args);
50}
Alexander Musman515ad8c2014-05-22 08:54:05 +000051
Alexander Musmand196ef22014-10-07 08:57:09 +000052void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &S,
Alexander Musmana5f070a2014-10-01 06:03:56 +000053 bool SeparateIter) {
54 RunCleanupsScope BodyScope(*this);
55 // Update counters values on current iteration.
56 for (auto I : S.updates()) {
57 EmitIgnoredExpr(I);
58 }
59 // On a continue in the body, jump to the end.
Alexander Musmand196ef22014-10-07 08:57:09 +000060 auto Continue = getJumpDestInCurrentScope("omp.body.continue");
Alexander Musmana5f070a2014-10-01 06:03:56 +000061 BreakContinueStack.push_back(BreakContinue(JumpDest(), Continue));
62 // Emit loop body.
63 EmitStmt(S.getBody());
64 // The end (updates/cleanups).
65 EmitBlock(Continue.getBlock());
66 BreakContinueStack.pop_back();
67 if (SeparateIter) {
68 // TODO: Update lastprivates if the SeparateIter flag is true.
69 // This will be implemented in a follow-up OMPLastprivateClause patch, but
70 // result should be still correct without it, as we do not make these
71 // variables private yet.
72 }
73}
74
Alexander Musmand196ef22014-10-07 08:57:09 +000075void CodeGenFunction::EmitOMPInnerLoop(const OMPLoopDirective &S,
76 OMPPrivateScope &LoopScope,
77 bool SeparateIter) {
78 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
Alexander Musmana5f070a2014-10-01 06:03:56 +000079 auto Cnt = getPGORegionCounter(&S);
80
81 // Start the loop with a block that tests the condition.
Alexander Musmand196ef22014-10-07 08:57:09 +000082 auto CondBlock = createBasicBlock("omp.inner.for.cond");
Alexander Musmana5f070a2014-10-01 06:03:56 +000083 EmitBlock(CondBlock);
84 LoopStack.push(CondBlock);
85
86 // If there are any cleanups between here and the loop-exit scope,
87 // create a block to stage a loop exit along.
88 auto ExitBlock = LoopExit.getBlock();
89 if (LoopScope.requiresCleanups())
Alexander Musmand196ef22014-10-07 08:57:09 +000090 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
Alexander Musmana5f070a2014-10-01 06:03:56 +000091
Alexander Musmand196ef22014-10-07 08:57:09 +000092 auto LoopBody = createBasicBlock("omp.inner.for.body");
Alexander Musmana5f070a2014-10-01 06:03:56 +000093
94 // Emit condition: "IV < LastIteration + 1 [ - 1]"
95 // ("- 1" when lastprivate clause is present - separate one iteration).
96 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond(SeparateIter));
97 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock,
98 PGO.createLoopWeights(S.getCond(SeparateIter), Cnt));
99
100 if (ExitBlock != LoopExit.getBlock()) {
101 EmitBlock(ExitBlock);
102 EmitBranchThroughCleanup(LoopExit);
103 }
104
105 EmitBlock(LoopBody);
106 Cnt.beginRegion(Builder);
107
108 // Create a block for the increment.
Alexander Musmand196ef22014-10-07 08:57:09 +0000109 auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000110 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
111
Alexander Musmand196ef22014-10-07 08:57:09 +0000112 EmitOMPLoopBody(S);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000113 EmitStopPoint(&S);
114
115 // Emit "IV = IV + 1" and a back-edge to the condition block.
116 EmitBlock(Continue.getBlock());
117 EmitIgnoredExpr(S.getInc());
118 BreakContinueStack.pop_back();
119 EmitBranch(CondBlock);
120 LoopStack.pop();
121 // Emit the fall-through block.
122 EmitBlock(LoopExit.getBlock());
123}
124
125void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) {
126 auto IC = S.counters().begin();
127 for (auto F : S.finals()) {
128 if (LocalDeclMap.lookup(cast<DeclRefExpr>((*IC))->getDecl())) {
129 EmitIgnoredExpr(F);
130 }
131 ++IC;
132 }
133}
134
Alexander Musman09184fe2014-09-30 05:29:28 +0000135static void EmitOMPAlignedClause(CodeGenFunction &CGF, CodeGenModule &CGM,
136 const OMPAlignedClause &Clause) {
137 unsigned ClauseAlignment = 0;
138 if (auto AlignmentExpr = Clause.getAlignment()) {
139 auto AlignmentCI =
140 cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
141 ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue());
142 }
143 for (auto E : Clause.varlists()) {
144 unsigned Alignment = ClauseAlignment;
145 if (Alignment == 0) {
146 // OpenMP [2.8.1, Description]
147 // If no optional parameter isspecified, implementation-defined default
148 // alignments for SIMD instructions on the target platforms are assumed.
149 Alignment = CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment(
150 E->getType());
151 }
152 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
153 "alignment is not power of 2");
154 if (Alignment != 0) {
155 llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
156 CGF.EmitAlignmentAssumption(PtrValue, Alignment);
157 }
158 }
159}
160
Alexander Musman515ad8c2014-05-22 08:54:05 +0000161void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
Alexander Musmana5f070a2014-10-01 06:03:56 +0000162 // Pragma 'simd' code depends on presence of 'lastprivate'.
163 // If present, we have to separate last iteration of the loop:
164 //
165 // if (LastIteration != 0) {
166 // for (IV in 0..LastIteration-1) BODY;
167 // BODY with updates of lastprivate vars;
168 // <Final counter/linear vars updates>;
169 // }
170 //
171 // otherwise (when there's no lastprivate):
172 //
173 // for (IV in 0..LastIteration) BODY;
174 // <Final counter/linear vars updates>;
175 //
176
177 // Walk clauses and process safelen/lastprivate.
178 bool SeparateIter = false;
Alexander Musman515ad8c2014-05-22 08:54:05 +0000179 LoopStack.setParallel();
180 LoopStack.setVectorizerEnable(true);
181 for (auto C : S.clauses()) {
182 switch (C->getClauseKind()) {
183 case OMPC_safelen: {
184 RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(),
185 AggValueSlot::ignored(), true);
186 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
187 LoopStack.setVectorizerWidth(Val->getZExtValue());
188 // In presence of finite 'safelen', it may be unsafe to mark all
189 // the memory instructions parallel, because loop-carried
190 // dependences of 'safelen' iterations are possible.
191 LoopStack.setParallel(false);
192 break;
193 }
Alexander Musman09184fe2014-09-30 05:29:28 +0000194 case OMPC_aligned:
195 EmitOMPAlignedClause(*this, CGM, cast<OMPAlignedClause>(*C));
196 break;
Alexander Musmana5f070a2014-10-01 06:03:56 +0000197 case OMPC_lastprivate:
198 SeparateIter = true;
199 break;
Alexander Musman515ad8c2014-05-22 08:54:05 +0000200 default:
201 // Not handled yet
202 ;
203 }
204 }
Alexander Musmana5f070a2014-10-01 06:03:56 +0000205
206 RunCleanupsScope DirectiveScope(*this);
207
208 CGDebugInfo *DI = getDebugInfo();
209 if (DI)
210 DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin());
211
212 // Emit the loop iteration variable.
213 const Expr *IVExpr = S.getIterationVariable();
214 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
215 EmitVarDecl(*IVDecl);
216 EmitIgnoredExpr(S.getInit());
217
218 // Emit the iterations count variable.
219 // If it is not a variable, Sema decided to calculate iterations count on each
220 // iteration (e.g., it is foldable into a constant).
221 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
222 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
223 // Emit calculation of the iterations count.
224 EmitIgnoredExpr(S.getCalcLastIteration());
225 }
226
227 if (SeparateIter) {
228 // Emit: if (LastIteration > 0) - begin.
229 RegionCounter Cnt = getPGORegionCounter(&S);
230 auto ThenBlock = createBasicBlock("simd.if.then");
231 auto ContBlock = createBasicBlock("simd.if.end");
232 EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount());
233 EmitBlock(ThenBlock);
234 Cnt.beginRegion(Builder);
235 // Emit 'then' code.
236 {
237 OMPPrivateScope LoopScope(*this);
238 LoopScope.addPrivates(S.counters());
Alexander Musmand196ef22014-10-07 08:57:09 +0000239 EmitOMPInnerLoop(S, LoopScope, /* SeparateIter */ true);
240 EmitOMPLoopBody(S, /* SeparateIter */ true);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000241 }
242 EmitOMPSimdFinal(S);
243 // Emit: if (LastIteration != 0) - end.
244 EmitBranch(ContBlock);
245 EmitBlock(ContBlock, true);
246 } else {
247 {
248 OMPPrivateScope LoopScope(*this);
249 LoopScope.addPrivates(S.counters());
Alexander Musmand196ef22014-10-07 08:57:09 +0000250 EmitOMPInnerLoop(S, LoopScope);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000251 }
252 EmitOMPSimdFinal(S);
253 }
254
255 if (DI)
256 DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd());
Alexander Musman515ad8c2014-05-22 08:54:05 +0000257}
258
Alexey Bataevf29276e2014-06-18 04:14:57 +0000259void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &) {
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000260 llvm_unreachable("CodeGen for 'omp for' is not supported yet.");
Alexey Bataevf29276e2014-06-18 04:14:57 +0000261}
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000262
Alexander Musmanf82886e2014-09-18 05:12:34 +0000263void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &) {
264 llvm_unreachable("CodeGen for 'omp for simd' is not supported yet.");
265}
266
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000267void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &) {
268 llvm_unreachable("CodeGen for 'omp sections' is not supported yet.");
269}
270
Alexey Bataev1e0498a2014-06-26 08:21:58 +0000271void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &) {
272 llvm_unreachable("CodeGen for 'omp section' is not supported yet.");
273}
274
Alexey Bataevd1e40fb2014-06-26 12:05:45 +0000275void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) {
276 llvm_unreachable("CodeGen for 'omp single' is not supported yet.");
277}
278
Alexander Musman80c22892014-07-17 08:54:58 +0000279void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &) {
280 llvm_unreachable("CodeGen for 'omp master' is not supported yet.");
281}
282
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +0000283void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
284 // __kmpc_critical();
285 // <captured_body>
286 // __kmpc_end_critical();
287 //
288
289 auto Lock = CGM.getOpenMPRuntime().GetCriticalRegionLock(
290 S.getDirectiveName().getAsString());
291 CGM.getOpenMPRuntime().EmitOMPCriticalRegionStart(*this, Lock,
292 S.getLocStart());
293 {
294 RunCleanupsScope Scope(*this);
295 EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
296 EnsureInsertPoint();
297 }
298 CGM.getOpenMPRuntime().EmitOMPCriticalRegionEnd(*this, Lock, S.getLocEnd());
Alexander Musmand9ed09f2014-07-21 09:42:05 +0000299}
300
Alexey Bataev4acb8592014-07-07 13:01:15 +0000301void
302CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
303 llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet.");
304}
305
Alexander Musmane4e893b2014-09-23 09:33:00 +0000306void CodeGenFunction::EmitOMPParallelForSimdDirective(
307 const OMPParallelForSimdDirective &) {
308 llvm_unreachable("CodeGen for 'omp parallel for simd' is not supported yet.");
309}
310
Alexey Bataev84d0b3e2014-07-08 08:12:03 +0000311void CodeGenFunction::EmitOMPParallelSectionsDirective(
312 const OMPParallelSectionsDirective &) {
313 llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet.");
314}
315
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +0000316void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &) {
317 llvm_unreachable("CodeGen for 'omp task' is not supported yet.");
318}
319
Alexey Bataev68446b72014-07-18 07:47:19 +0000320void CodeGenFunction::EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &) {
321 llvm_unreachable("CodeGen for 'omp taskyield' is not supported yet.");
322}
323
Alexey Bataev4d1dfea2014-07-18 09:11:51 +0000324void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &) {
325 llvm_unreachable("CodeGen for 'omp barrier' is not supported yet.");
326}
327
Alexey Bataev2df347a2014-07-18 10:17:07 +0000328void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &) {
329 llvm_unreachable("CodeGen for 'omp taskwait' is not supported yet.");
330}
331
Alexey Bataev6125da92014-07-21 11:26:11 +0000332void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &) {
333 llvm_unreachable("CodeGen for 'omp flush' is not supported yet.");
334}
335
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000336void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &) {
337 llvm_unreachable("CodeGen for 'omp ordered' is not supported yet.");
338}
339
Alexey Bataev0162e452014-07-22 10:10:35 +0000340void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &) {
341 llvm_unreachable("CodeGen for 'omp atomic' is not supported yet.");
342}
343
Alexey Bataev0bd520b2014-09-19 08:19:49 +0000344void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) {
345 llvm_unreachable("CodeGen for 'omp target' is not supported yet.");
346}
347