blob: a459d07a7236ef71d7978855b2606a1f0bc451e4 [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
Alexey Bataevd74d0602014-10-13 06:02:40 +000027/// \brief Emits code for OpenMP 'if' clause using specified \a CodeGen
28/// function. Here is the logic:
29/// if (Cond) {
30/// CodeGen(true);
31/// } else {
32/// CodeGen(false);
33/// }
34static void EmitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
35 const std::function<void(bool)> &CodeGen) {
36 CodeGenFunction::LexicalScope ConditionScope(CGF, Cond->getSourceRange());
37
38 // If the condition constant folds and can be elided, try to avoid emitting
39 // the condition and the dead arm of the if/else.
40 bool CondConstant;
41 if (CGF.ConstantFoldsToSimpleInteger(Cond, CondConstant)) {
42 CodeGen(CondConstant);
43 return;
44 }
45
46 // Otherwise, the condition did not fold, or we couldn't elide it. Just
47 // emit the conditional branch.
48 auto ThenBlock = CGF.createBasicBlock(/*name*/ "omp_if.then");
49 auto ElseBlock = CGF.createBasicBlock(/*name*/ "omp_if.else");
50 auto ContBlock = CGF.createBasicBlock(/*name*/ "omp_if.end");
51 CGF.EmitBranchOnBoolExpr(Cond, ThenBlock, ElseBlock, /*TrueCount*/ 0);
52
53 // Emit the 'then' code.
54 CGF.EmitBlock(ThenBlock);
55 CodeGen(/*ThenBlock*/ true);
56 CGF.EmitBranch(ContBlock);
57 // Emit the 'else' code if present.
58 {
59 // There is no need to emit line number for unconditional branch.
60 SuppressDebugLocation SDL(CGF.Builder);
61 CGF.EmitBlock(ElseBlock);
62 }
63 CodeGen(/*ThenBlock*/ false);
64 {
65 // There is no need to emit line number for unconditional branch.
66 SuppressDebugLocation SDL(CGF.Builder);
67 CGF.EmitBranch(ContBlock);
68 }
69 // Emit the continuation block for code after the if.
70 CGF.EmitBlock(ContBlock, /*IsFinished*/ true);
71}
72
Alexey Bataev4a5bb772014-10-08 14:01:46 +000073void CodeGenFunction::EmitOMPAggregateAssign(LValue OriginalAddr,
74 llvm::Value *PrivateAddr,
75 const Expr *AssignExpr,
76 QualType OriginalType,
77 const VarDecl *VDInit) {
78 EmitBlock(createBasicBlock(".omp.assign.begin."));
79 if (!isa<CXXConstructExpr>(AssignExpr) || isTrivialInitializer(AssignExpr)) {
80 // Perform simple memcpy.
81 EmitAggregateAssign(PrivateAddr, OriginalAddr.getAddress(),
82 AssignExpr->getType());
83 } else {
84 // Perform element-by-element initialization.
85 QualType ElementTy;
86 auto SrcBegin = OriginalAddr.getAddress();
87 auto DestBegin = PrivateAddr;
88 auto ArrayTy = OriginalType->getAsArrayTypeUnsafe();
89 auto SrcNumElements = emitArrayLength(ArrayTy, ElementTy, SrcBegin);
90 auto DestNumElements = emitArrayLength(ArrayTy, ElementTy, DestBegin);
91 auto SrcEnd = Builder.CreateGEP(SrcBegin, SrcNumElements);
92 auto DestEnd = Builder.CreateGEP(DestBegin, DestNumElements);
93 // The basic structure here is a do-while loop, because we don't
94 // need to check for the zero-element case.
95 auto BodyBB = createBasicBlock("omp.arraycpy.body");
96 auto DoneBB = createBasicBlock("omp.arraycpy.done");
97 auto IsEmpty =
98 Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty");
99 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
100
101 // Enter the loop body, making that address the current address.
102 auto EntryBB = Builder.GetInsertBlock();
103 EmitBlock(BodyBB);
104 auto SrcElementPast = Builder.CreatePHI(SrcBegin->getType(), 2,
105 "omp.arraycpy.srcElementPast");
106 SrcElementPast->addIncoming(SrcEnd, EntryBB);
107 auto DestElementPast = Builder.CreatePHI(DestBegin->getType(), 2,
108 "omp.arraycpy.destElementPast");
109 DestElementPast->addIncoming(DestEnd, EntryBB);
110
111 // Shift the address back by one element.
112 auto NegativeOne = llvm::ConstantInt::get(SizeTy, -1, true);
113 auto DestElement = Builder.CreateGEP(DestElementPast, NegativeOne,
114 "omp.arraycpy.dest.element");
115 auto SrcElement = Builder.CreateGEP(SrcElementPast, NegativeOne,
116 "omp.arraycpy.src.element");
117 {
118 // Create RunCleanScope to cleanup possible temps.
119 CodeGenFunction::RunCleanupsScope Init(*this);
120 // Emit initialization for single element.
121 LocalDeclMap[VDInit] = SrcElement;
122 EmitAnyExprToMem(AssignExpr, DestElement,
123 AssignExpr->getType().getQualifiers(),
124 /*IsInitializer*/ false);
125 LocalDeclMap.erase(VDInit);
126 }
127
128 // Check whether we've reached the end.
129 auto Done =
130 Builder.CreateICmpEQ(DestElement, DestBegin, "omp.arraycpy.done");
131 Builder.CreateCondBr(Done, DoneBB, BodyBB);
132 DestElementPast->addIncoming(DestElement, Builder.GetInsertBlock());
133 SrcElementPast->addIncoming(SrcElement, Builder.GetInsertBlock());
134
135 // Done.
136 EmitBlock(DoneBB, true);
137 }
138 EmitBlock(createBasicBlock(".omp.assign.end."));
139}
140
141void CodeGenFunction::EmitOMPFirstprivateClause(
142 const OMPExecutableDirective &D,
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000143 CodeGenFunction::OMPPrivateScope &PrivateScope) {
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000144 auto PrivateFilter = [](const OMPClause *C) -> bool {
145 return C->getClauseKind() == OMPC_firstprivate;
146 };
147 for (OMPExecutableDirective::filtered_clause_iterator<decltype(PrivateFilter)>
148 I(D.clauses(), PrivateFilter); I; ++I) {
149 auto *C = cast<OMPFirstprivateClause>(*I);
150 auto IRef = C->varlist_begin();
151 auto InitsRef = C->inits().begin();
152 for (auto IInit : C->private_copies()) {
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000153 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
154 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
155 bool IsRegistered;
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000156 if (*InitsRef != nullptr) {
157 // Emit VarDecl with copy init for arrays.
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000158 auto *FD = CapturedStmtInfo->lookup(OrigVD);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000159 LValue Base = MakeNaturalAlignAddrLValue(
160 CapturedStmtInfo->getContextValue(),
161 getContext().getTagDeclType(FD->getParent()));
162 auto OriginalAddr = EmitLValueForField(Base, FD);
163 auto VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000164 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * {
165 auto Emission = EmitAutoVarAlloca(*VD);
166 // Emit initialization of aggregate firstprivate vars.
167 EmitOMPAggregateAssign(OriginalAddr, Emission.getAllocatedAddress(),
168 VD->getInit(), (*IRef)->getType(), VDInit);
169 EmitAutoVarCleanups(Emission);
170 return Emission.getAllocatedAddress();
171 });
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000172 } else
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000173 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * {
174 // Emit private VarDecl with copy init.
175 EmitDecl(*VD);
176 return GetAddrOfLocalVar(VD);
177 });
178 assert(IsRegistered && "counter already registered as private");
179 // Silence the warning about unused variable.
180 (void)IsRegistered;
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000181 ++IRef, ++InitsRef;
182 }
183 }
184}
185
Alexey Bataev9959db52014-05-06 10:08:46 +0000186void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
Alexey Bataev18095712014-10-10 12:19:54 +0000187 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
188 auto CapturedStruct = GenerateCapturedStmtArgument(*CS);
189 auto OutlinedFn = CGM.getOpenMPRuntime().EmitOpenMPOutlinedFunction(
190 S, *CS->getCapturedDecl()->param_begin());
Alexey Bataevd74d0602014-10-13 06:02:40 +0000191 if (auto C = S.getSingleClause(/*K*/ OMPC_if)) {
192 auto Cond = cast<OMPIfClause>(C)->getCondition();
193 EmitOMPIfClause(*this, Cond, [&](bool ThenBlock) {
194 if (ThenBlock)
195 CGM.getOpenMPRuntime().EmitOMPParallelCall(*this, S.getLocStart(),
196 OutlinedFn, CapturedStruct);
197 else
198 CGM.getOpenMPRuntime().EmitOMPSerialCall(*this, S.getLocStart(),
199 OutlinedFn, CapturedStruct);
200 });
201 } else {
202 CGM.getOpenMPRuntime().EmitOMPParallelCall(*this, S.getLocStart(),
203 OutlinedFn, CapturedStruct);
204 }
Alexey Bataev9959db52014-05-06 10:08:46 +0000205}
Alexander Musman515ad8c2014-05-22 08:54:05 +0000206
Alexander Musmand196ef22014-10-07 08:57:09 +0000207void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &S,
Alexander Musmana5f070a2014-10-01 06:03:56 +0000208 bool SeparateIter) {
209 RunCleanupsScope BodyScope(*this);
210 // Update counters values on current iteration.
211 for (auto I : S.updates()) {
212 EmitIgnoredExpr(I);
213 }
214 // On a continue in the body, jump to the end.
Alexander Musmand196ef22014-10-07 08:57:09 +0000215 auto Continue = getJumpDestInCurrentScope("omp.body.continue");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000216 BreakContinueStack.push_back(BreakContinue(JumpDest(), Continue));
217 // Emit loop body.
218 EmitStmt(S.getBody());
219 // The end (updates/cleanups).
220 EmitBlock(Continue.getBlock());
221 BreakContinueStack.pop_back();
222 if (SeparateIter) {
223 // TODO: Update lastprivates if the SeparateIter flag is true.
224 // This will be implemented in a follow-up OMPLastprivateClause patch, but
225 // result should be still correct without it, as we do not make these
226 // variables private yet.
227 }
228}
229
Alexander Musmand196ef22014-10-07 08:57:09 +0000230void CodeGenFunction::EmitOMPInnerLoop(const OMPLoopDirective &S,
231 OMPPrivateScope &LoopScope,
232 bool SeparateIter) {
233 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000234 auto Cnt = getPGORegionCounter(&S);
235
236 // Start the loop with a block that tests the condition.
Alexander Musmand196ef22014-10-07 08:57:09 +0000237 auto CondBlock = createBasicBlock("omp.inner.for.cond");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000238 EmitBlock(CondBlock);
239 LoopStack.push(CondBlock);
240
241 // If there are any cleanups between here and the loop-exit scope,
242 // create a block to stage a loop exit along.
243 auto ExitBlock = LoopExit.getBlock();
244 if (LoopScope.requiresCleanups())
Alexander Musmand196ef22014-10-07 08:57:09 +0000245 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000246
Alexander Musmand196ef22014-10-07 08:57:09 +0000247 auto LoopBody = createBasicBlock("omp.inner.for.body");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000248
249 // Emit condition: "IV < LastIteration + 1 [ - 1]"
250 // ("- 1" when lastprivate clause is present - separate one iteration).
251 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond(SeparateIter));
252 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock,
253 PGO.createLoopWeights(S.getCond(SeparateIter), Cnt));
254
255 if (ExitBlock != LoopExit.getBlock()) {
256 EmitBlock(ExitBlock);
257 EmitBranchThroughCleanup(LoopExit);
258 }
259
260 EmitBlock(LoopBody);
261 Cnt.beginRegion(Builder);
262
263 // Create a block for the increment.
Alexander Musmand196ef22014-10-07 08:57:09 +0000264 auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000265 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
266
Alexander Musmand196ef22014-10-07 08:57:09 +0000267 EmitOMPLoopBody(S);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000268 EmitStopPoint(&S);
269
270 // Emit "IV = IV + 1" and a back-edge to the condition block.
271 EmitBlock(Continue.getBlock());
272 EmitIgnoredExpr(S.getInc());
273 BreakContinueStack.pop_back();
274 EmitBranch(CondBlock);
275 LoopStack.pop();
276 // Emit the fall-through block.
277 EmitBlock(LoopExit.getBlock());
278}
279
280void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) {
281 auto IC = S.counters().begin();
282 for (auto F : S.finals()) {
283 if (LocalDeclMap.lookup(cast<DeclRefExpr>((*IC))->getDecl())) {
284 EmitIgnoredExpr(F);
285 }
286 ++IC;
287 }
288}
289
Alexander Musman09184fe2014-09-30 05:29:28 +0000290static void EmitOMPAlignedClause(CodeGenFunction &CGF, CodeGenModule &CGM,
291 const OMPAlignedClause &Clause) {
292 unsigned ClauseAlignment = 0;
293 if (auto AlignmentExpr = Clause.getAlignment()) {
294 auto AlignmentCI =
295 cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
296 ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue());
297 }
298 for (auto E : Clause.varlists()) {
299 unsigned Alignment = ClauseAlignment;
300 if (Alignment == 0) {
301 // OpenMP [2.8.1, Description]
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000302 // If no optional parameter is specified, implementation-defined default
Alexander Musman09184fe2014-09-30 05:29:28 +0000303 // alignments for SIMD instructions on the target platforms are assumed.
304 Alignment = CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment(
305 E->getType());
306 }
307 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
308 "alignment is not power of 2");
309 if (Alignment != 0) {
310 llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
311 CGF.EmitAlignmentAssumption(PtrValue, Alignment);
312 }
313 }
314}
315
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000316static void EmitPrivateLoopCounters(CodeGenFunction &CGF,
317 CodeGenFunction::OMPPrivateScope &LoopScope,
318 ArrayRef<Expr *> Counters) {
319 for (auto *E : Counters) {
320 auto VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
321 bool IsRegistered = LoopScope.addPrivate(VD, [&]() -> llvm::Value * {
322 // Emit var without initialization.
323 auto VarEmission = CGF.EmitAutoVarAlloca(*VD);
324 CGF.EmitAutoVarCleanups(VarEmission);
325 return VarEmission.getAllocatedAddress();
326 });
327 assert(IsRegistered && "counter already registered as private");
328 // Silence the warning about unused variable.
329 (void)IsRegistered;
330 }
331 (void)LoopScope.Privatize();
332}
333
Alexander Musman515ad8c2014-05-22 08:54:05 +0000334void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
Alexander Musmana5f070a2014-10-01 06:03:56 +0000335 // Pragma 'simd' code depends on presence of 'lastprivate'.
336 // If present, we have to separate last iteration of the loop:
337 //
338 // if (LastIteration != 0) {
339 // for (IV in 0..LastIteration-1) BODY;
340 // BODY with updates of lastprivate vars;
341 // <Final counter/linear vars updates>;
342 // }
343 //
344 // otherwise (when there's no lastprivate):
345 //
346 // for (IV in 0..LastIteration) BODY;
347 // <Final counter/linear vars updates>;
348 //
349
350 // Walk clauses and process safelen/lastprivate.
351 bool SeparateIter = false;
Alexander Musman515ad8c2014-05-22 08:54:05 +0000352 LoopStack.setParallel();
353 LoopStack.setVectorizerEnable(true);
354 for (auto C : S.clauses()) {
355 switch (C->getClauseKind()) {
356 case OMPC_safelen: {
357 RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(),
358 AggValueSlot::ignored(), true);
359 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
360 LoopStack.setVectorizerWidth(Val->getZExtValue());
361 // In presence of finite 'safelen', it may be unsafe to mark all
362 // the memory instructions parallel, because loop-carried
363 // dependences of 'safelen' iterations are possible.
364 LoopStack.setParallel(false);
365 break;
366 }
Alexander Musman09184fe2014-09-30 05:29:28 +0000367 case OMPC_aligned:
368 EmitOMPAlignedClause(*this, CGM, cast<OMPAlignedClause>(*C));
369 break;
Alexander Musmana5f070a2014-10-01 06:03:56 +0000370 case OMPC_lastprivate:
371 SeparateIter = true;
372 break;
Alexander Musman515ad8c2014-05-22 08:54:05 +0000373 default:
374 // Not handled yet
375 ;
376 }
377 }
Alexander Musmana5f070a2014-10-01 06:03:56 +0000378
379 RunCleanupsScope DirectiveScope(*this);
380
381 CGDebugInfo *DI = getDebugInfo();
382 if (DI)
383 DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin());
384
385 // Emit the loop iteration variable.
386 const Expr *IVExpr = S.getIterationVariable();
387 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
388 EmitVarDecl(*IVDecl);
389 EmitIgnoredExpr(S.getInit());
390
391 // Emit the iterations count variable.
392 // If it is not a variable, Sema decided to calculate iterations count on each
393 // iteration (e.g., it is foldable into a constant).
394 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
395 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
396 // Emit calculation of the iterations count.
397 EmitIgnoredExpr(S.getCalcLastIteration());
398 }
399
400 if (SeparateIter) {
401 // Emit: if (LastIteration > 0) - begin.
402 RegionCounter Cnt = getPGORegionCounter(&S);
403 auto ThenBlock = createBasicBlock("simd.if.then");
404 auto ContBlock = createBasicBlock("simd.if.end");
405 EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount());
406 EmitBlock(ThenBlock);
407 Cnt.beginRegion(Builder);
408 // Emit 'then' code.
409 {
410 OMPPrivateScope LoopScope(*this);
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000411 EmitPrivateLoopCounters(*this, LoopScope, S.counters());
Alexander Musmand196ef22014-10-07 08:57:09 +0000412 EmitOMPInnerLoop(S, LoopScope, /* SeparateIter */ true);
413 EmitOMPLoopBody(S, /* SeparateIter */ true);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000414 }
415 EmitOMPSimdFinal(S);
416 // Emit: if (LastIteration != 0) - end.
417 EmitBranch(ContBlock);
418 EmitBlock(ContBlock, true);
419 } else {
420 {
421 OMPPrivateScope LoopScope(*this);
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000422 EmitPrivateLoopCounters(*this, LoopScope, S.counters());
Alexander Musmand196ef22014-10-07 08:57:09 +0000423 EmitOMPInnerLoop(S, LoopScope);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000424 }
425 EmitOMPSimdFinal(S);
426 }
427
428 if (DI)
429 DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd());
Alexander Musman515ad8c2014-05-22 08:54:05 +0000430}
431
Alexey Bataevf29276e2014-06-18 04:14:57 +0000432void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &) {
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000433 llvm_unreachable("CodeGen for 'omp for' is not supported yet.");
Alexey Bataevf29276e2014-06-18 04:14:57 +0000434}
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000435
Alexander Musmanf82886e2014-09-18 05:12:34 +0000436void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &) {
437 llvm_unreachable("CodeGen for 'omp for simd' is not supported yet.");
438}
439
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000440void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &) {
441 llvm_unreachable("CodeGen for 'omp sections' is not supported yet.");
442}
443
Alexey Bataev1e0498a2014-06-26 08:21:58 +0000444void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &) {
445 llvm_unreachable("CodeGen for 'omp section' is not supported yet.");
446}
447
Alexey Bataevd1e40fb2014-06-26 12:05:45 +0000448void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) {
449 llvm_unreachable("CodeGen for 'omp single' is not supported yet.");
450}
451
Alexander Musman80c22892014-07-17 08:54:58 +0000452void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &) {
453 llvm_unreachable("CodeGen for 'omp master' is not supported yet.");
454}
455
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +0000456void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
457 // __kmpc_critical();
458 // <captured_body>
459 // __kmpc_end_critical();
460 //
461
462 auto Lock = CGM.getOpenMPRuntime().GetCriticalRegionLock(
463 S.getDirectiveName().getAsString());
464 CGM.getOpenMPRuntime().EmitOMPCriticalRegionStart(*this, Lock,
465 S.getLocStart());
466 {
467 RunCleanupsScope Scope(*this);
468 EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
469 EnsureInsertPoint();
470 }
471 CGM.getOpenMPRuntime().EmitOMPCriticalRegionEnd(*this, Lock, S.getLocEnd());
Alexander Musmand9ed09f2014-07-21 09:42:05 +0000472}
473
Alexey Bataev4acb8592014-07-07 13:01:15 +0000474void
475CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
476 llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet.");
477}
478
Alexander Musmane4e893b2014-09-23 09:33:00 +0000479void CodeGenFunction::EmitOMPParallelForSimdDirective(
480 const OMPParallelForSimdDirective &) {
481 llvm_unreachable("CodeGen for 'omp parallel for simd' is not supported yet.");
482}
483
Alexey Bataev84d0b3e2014-07-08 08:12:03 +0000484void CodeGenFunction::EmitOMPParallelSectionsDirective(
485 const OMPParallelSectionsDirective &) {
486 llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet.");
487}
488
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +0000489void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &) {
490 llvm_unreachable("CodeGen for 'omp task' is not supported yet.");
491}
492
Alexey Bataev68446b72014-07-18 07:47:19 +0000493void CodeGenFunction::EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &) {
494 llvm_unreachable("CodeGen for 'omp taskyield' is not supported yet.");
495}
496
Alexey Bataev4d1dfea2014-07-18 09:11:51 +0000497void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &) {
498 llvm_unreachable("CodeGen for 'omp barrier' is not supported yet.");
499}
500
Alexey Bataev2df347a2014-07-18 10:17:07 +0000501void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &) {
502 llvm_unreachable("CodeGen for 'omp taskwait' is not supported yet.");
503}
504
Alexey Bataev6125da92014-07-21 11:26:11 +0000505void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &) {
506 llvm_unreachable("CodeGen for 'omp flush' is not supported yet.");
507}
508
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000509void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &) {
510 llvm_unreachable("CodeGen for 'omp ordered' is not supported yet.");
511}
512
Alexey Bataev0162e452014-07-22 10:10:35 +0000513void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &) {
514 llvm_unreachable("CodeGen for 'omp atomic' is not supported yet.");
515}
516
Alexey Bataev0bd520b2014-09-19 08:19:49 +0000517void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) {
518 llvm_unreachable("CodeGen for 'omp target' is not supported yet.");
519}
520
Alexey Bataev13314bf2014-10-09 04:18:56 +0000521void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &) {
522 llvm_unreachable("CodeGen for 'omp teams' is not supported yet.");
523}
524