blob: 1b3e786b30bd3c795ee050126b4e6cdabacdb248 [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 Bataev4a5bb772014-10-08 14:01:46 +000027void CodeGenFunction::EmitOMPAggregateAssign(LValue OriginalAddr,
28 llvm::Value *PrivateAddr,
29 const Expr *AssignExpr,
30 QualType OriginalType,
31 const VarDecl *VDInit) {
32 EmitBlock(createBasicBlock(".omp.assign.begin."));
33 if (!isa<CXXConstructExpr>(AssignExpr) || isTrivialInitializer(AssignExpr)) {
34 // Perform simple memcpy.
35 EmitAggregateAssign(PrivateAddr, OriginalAddr.getAddress(),
36 AssignExpr->getType());
37 } else {
38 // Perform element-by-element initialization.
39 QualType ElementTy;
40 auto SrcBegin = OriginalAddr.getAddress();
41 auto DestBegin = PrivateAddr;
42 auto ArrayTy = OriginalType->getAsArrayTypeUnsafe();
43 auto SrcNumElements = emitArrayLength(ArrayTy, ElementTy, SrcBegin);
44 auto DestNumElements = emitArrayLength(ArrayTy, ElementTy, DestBegin);
45 auto SrcEnd = Builder.CreateGEP(SrcBegin, SrcNumElements);
46 auto DestEnd = Builder.CreateGEP(DestBegin, DestNumElements);
47 // The basic structure here is a do-while loop, because we don't
48 // need to check for the zero-element case.
49 auto BodyBB = createBasicBlock("omp.arraycpy.body");
50 auto DoneBB = createBasicBlock("omp.arraycpy.done");
51 auto IsEmpty =
52 Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty");
53 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
54
55 // Enter the loop body, making that address the current address.
56 auto EntryBB = Builder.GetInsertBlock();
57 EmitBlock(BodyBB);
58 auto SrcElementPast = Builder.CreatePHI(SrcBegin->getType(), 2,
59 "omp.arraycpy.srcElementPast");
60 SrcElementPast->addIncoming(SrcEnd, EntryBB);
61 auto DestElementPast = Builder.CreatePHI(DestBegin->getType(), 2,
62 "omp.arraycpy.destElementPast");
63 DestElementPast->addIncoming(DestEnd, EntryBB);
64
65 // Shift the address back by one element.
66 auto NegativeOne = llvm::ConstantInt::get(SizeTy, -1, true);
67 auto DestElement = Builder.CreateGEP(DestElementPast, NegativeOne,
68 "omp.arraycpy.dest.element");
69 auto SrcElement = Builder.CreateGEP(SrcElementPast, NegativeOne,
70 "omp.arraycpy.src.element");
71 {
72 // Create RunCleanScope to cleanup possible temps.
73 CodeGenFunction::RunCleanupsScope Init(*this);
74 // Emit initialization for single element.
75 LocalDeclMap[VDInit] = SrcElement;
76 EmitAnyExprToMem(AssignExpr, DestElement,
77 AssignExpr->getType().getQualifiers(),
78 /*IsInitializer*/ false);
79 LocalDeclMap.erase(VDInit);
80 }
81
82 // Check whether we've reached the end.
83 auto Done =
84 Builder.CreateICmpEQ(DestElement, DestBegin, "omp.arraycpy.done");
85 Builder.CreateCondBr(Done, DoneBB, BodyBB);
86 DestElementPast->addIncoming(DestElement, Builder.GetInsertBlock());
87 SrcElementPast->addIncoming(SrcElement, Builder.GetInsertBlock());
88
89 // Done.
90 EmitBlock(DoneBB, true);
91 }
92 EmitBlock(createBasicBlock(".omp.assign.end."));
93}
94
95void CodeGenFunction::EmitOMPFirstprivateClause(
96 const OMPExecutableDirective &D,
Alexey Bataev435ad7b2014-10-10 09:48:26 +000097 CodeGenFunction::OMPPrivateScope &PrivateScope) {
Alexey Bataev4a5bb772014-10-08 14:01:46 +000098 auto PrivateFilter = [](const OMPClause *C) -> bool {
99 return C->getClauseKind() == OMPC_firstprivate;
100 };
101 for (OMPExecutableDirective::filtered_clause_iterator<decltype(PrivateFilter)>
102 I(D.clauses(), PrivateFilter); I; ++I) {
103 auto *C = cast<OMPFirstprivateClause>(*I);
104 auto IRef = C->varlist_begin();
105 auto InitsRef = C->inits().begin();
106 for (auto IInit : C->private_copies()) {
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000107 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
108 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
109 bool IsRegistered;
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000110 if (*InitsRef != nullptr) {
111 // Emit VarDecl with copy init for arrays.
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000112 auto *FD = CapturedStmtInfo->lookup(OrigVD);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000113 LValue Base = MakeNaturalAlignAddrLValue(
114 CapturedStmtInfo->getContextValue(),
115 getContext().getTagDeclType(FD->getParent()));
116 auto OriginalAddr = EmitLValueForField(Base, FD);
117 auto VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000118 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * {
119 auto Emission = EmitAutoVarAlloca(*VD);
120 // Emit initialization of aggregate firstprivate vars.
121 EmitOMPAggregateAssign(OriginalAddr, Emission.getAllocatedAddress(),
122 VD->getInit(), (*IRef)->getType(), VDInit);
123 EmitAutoVarCleanups(Emission);
124 return Emission.getAllocatedAddress();
125 });
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000126 } else
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000127 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * {
128 // Emit private VarDecl with copy init.
129 EmitDecl(*VD);
130 return GetAddrOfLocalVar(VD);
131 });
132 assert(IsRegistered && "counter already registered as private");
133 // Silence the warning about unused variable.
134 (void)IsRegistered;
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000135 ++IRef, ++InitsRef;
136 }
137 }
138}
139
Alexey Bataev9959db52014-05-06 10:08:46 +0000140void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
141 const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt());
142 llvm::Value *CapturedStruct = GenerateCapturedStmtArgument(*CS);
143
144 llvm::Value *OutlinedFn;
145 {
146 CodeGenFunction CGF(CGM, true);
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000147 CGOpenMPRegionInfo CGInfo(S, *CS, *CS->getCapturedDecl()->param_begin());
Alexey Bataev9959db52014-05-06 10:08:46 +0000148 CGF.CapturedStmtInfo = &CGInfo;
Alexey Bataevaca7fcf2014-06-30 02:55:54 +0000149 OutlinedFn = CGF.GenerateCapturedStmtFunction(*CS);
Alexey Bataev9959db52014-05-06 10:08:46 +0000150 }
151
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000152 CGM.getOpenMPRuntime().EmitOMPParallelCall(*this, S.getLocStart(), OutlinedFn,
153 CapturedStruct);
Alexey Bataev9959db52014-05-06 10:08:46 +0000154}
Alexander Musman515ad8c2014-05-22 08:54:05 +0000155
Alexander Musmand196ef22014-10-07 08:57:09 +0000156void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &S,
Alexander Musmana5f070a2014-10-01 06:03:56 +0000157 bool SeparateIter) {
158 RunCleanupsScope BodyScope(*this);
159 // Update counters values on current iteration.
160 for (auto I : S.updates()) {
161 EmitIgnoredExpr(I);
162 }
163 // On a continue in the body, jump to the end.
Alexander Musmand196ef22014-10-07 08:57:09 +0000164 auto Continue = getJumpDestInCurrentScope("omp.body.continue");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000165 BreakContinueStack.push_back(BreakContinue(JumpDest(), Continue));
166 // Emit loop body.
167 EmitStmt(S.getBody());
168 // The end (updates/cleanups).
169 EmitBlock(Continue.getBlock());
170 BreakContinueStack.pop_back();
171 if (SeparateIter) {
172 // TODO: Update lastprivates if the SeparateIter flag is true.
173 // This will be implemented in a follow-up OMPLastprivateClause patch, but
174 // result should be still correct without it, as we do not make these
175 // variables private yet.
176 }
177}
178
Alexander Musmand196ef22014-10-07 08:57:09 +0000179void CodeGenFunction::EmitOMPInnerLoop(const OMPLoopDirective &S,
180 OMPPrivateScope &LoopScope,
181 bool SeparateIter) {
182 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000183 auto Cnt = getPGORegionCounter(&S);
184
185 // Start the loop with a block that tests the condition.
Alexander Musmand196ef22014-10-07 08:57:09 +0000186 auto CondBlock = createBasicBlock("omp.inner.for.cond");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000187 EmitBlock(CondBlock);
188 LoopStack.push(CondBlock);
189
190 // If there are any cleanups between here and the loop-exit scope,
191 // create a block to stage a loop exit along.
192 auto ExitBlock = LoopExit.getBlock();
193 if (LoopScope.requiresCleanups())
Alexander Musmand196ef22014-10-07 08:57:09 +0000194 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000195
Alexander Musmand196ef22014-10-07 08:57:09 +0000196 auto LoopBody = createBasicBlock("omp.inner.for.body");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000197
198 // Emit condition: "IV < LastIteration + 1 [ - 1]"
199 // ("- 1" when lastprivate clause is present - separate one iteration).
200 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond(SeparateIter));
201 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock,
202 PGO.createLoopWeights(S.getCond(SeparateIter), Cnt));
203
204 if (ExitBlock != LoopExit.getBlock()) {
205 EmitBlock(ExitBlock);
206 EmitBranchThroughCleanup(LoopExit);
207 }
208
209 EmitBlock(LoopBody);
210 Cnt.beginRegion(Builder);
211
212 // Create a block for the increment.
Alexander Musmand196ef22014-10-07 08:57:09 +0000213 auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000214 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
215
Alexander Musmand196ef22014-10-07 08:57:09 +0000216 EmitOMPLoopBody(S);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000217 EmitStopPoint(&S);
218
219 // Emit "IV = IV + 1" and a back-edge to the condition block.
220 EmitBlock(Continue.getBlock());
221 EmitIgnoredExpr(S.getInc());
222 BreakContinueStack.pop_back();
223 EmitBranch(CondBlock);
224 LoopStack.pop();
225 // Emit the fall-through block.
226 EmitBlock(LoopExit.getBlock());
227}
228
229void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) {
230 auto IC = S.counters().begin();
231 for (auto F : S.finals()) {
232 if (LocalDeclMap.lookup(cast<DeclRefExpr>((*IC))->getDecl())) {
233 EmitIgnoredExpr(F);
234 }
235 ++IC;
236 }
237}
238
Alexander Musman09184fe2014-09-30 05:29:28 +0000239static void EmitOMPAlignedClause(CodeGenFunction &CGF, CodeGenModule &CGM,
240 const OMPAlignedClause &Clause) {
241 unsigned ClauseAlignment = 0;
242 if (auto AlignmentExpr = Clause.getAlignment()) {
243 auto AlignmentCI =
244 cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
245 ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue());
246 }
247 for (auto E : Clause.varlists()) {
248 unsigned Alignment = ClauseAlignment;
249 if (Alignment == 0) {
250 // OpenMP [2.8.1, Description]
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000251 // If no optional parameter is specified, implementation-defined default
Alexander Musman09184fe2014-09-30 05:29:28 +0000252 // alignments for SIMD instructions on the target platforms are assumed.
253 Alignment = CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment(
254 E->getType());
255 }
256 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
257 "alignment is not power of 2");
258 if (Alignment != 0) {
259 llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
260 CGF.EmitAlignmentAssumption(PtrValue, Alignment);
261 }
262 }
263}
264
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000265static void EmitPrivateLoopCounters(CodeGenFunction &CGF,
266 CodeGenFunction::OMPPrivateScope &LoopScope,
267 ArrayRef<Expr *> Counters) {
268 for (auto *E : Counters) {
269 auto VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
270 bool IsRegistered = LoopScope.addPrivate(VD, [&]() -> llvm::Value * {
271 // Emit var without initialization.
272 auto VarEmission = CGF.EmitAutoVarAlloca(*VD);
273 CGF.EmitAutoVarCleanups(VarEmission);
274 return VarEmission.getAllocatedAddress();
275 });
276 assert(IsRegistered && "counter already registered as private");
277 // Silence the warning about unused variable.
278 (void)IsRegistered;
279 }
280 (void)LoopScope.Privatize();
281}
282
Alexander Musman515ad8c2014-05-22 08:54:05 +0000283void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
Alexander Musmana5f070a2014-10-01 06:03:56 +0000284 // Pragma 'simd' code depends on presence of 'lastprivate'.
285 // If present, we have to separate last iteration of the loop:
286 //
287 // if (LastIteration != 0) {
288 // for (IV in 0..LastIteration-1) BODY;
289 // BODY with updates of lastprivate vars;
290 // <Final counter/linear vars updates>;
291 // }
292 //
293 // otherwise (when there's no lastprivate):
294 //
295 // for (IV in 0..LastIteration) BODY;
296 // <Final counter/linear vars updates>;
297 //
298
299 // Walk clauses and process safelen/lastprivate.
300 bool SeparateIter = false;
Alexander Musman515ad8c2014-05-22 08:54:05 +0000301 LoopStack.setParallel();
302 LoopStack.setVectorizerEnable(true);
303 for (auto C : S.clauses()) {
304 switch (C->getClauseKind()) {
305 case OMPC_safelen: {
306 RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(),
307 AggValueSlot::ignored(), true);
308 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
309 LoopStack.setVectorizerWidth(Val->getZExtValue());
310 // In presence of finite 'safelen', it may be unsafe to mark all
311 // the memory instructions parallel, because loop-carried
312 // dependences of 'safelen' iterations are possible.
313 LoopStack.setParallel(false);
314 break;
315 }
Alexander Musman09184fe2014-09-30 05:29:28 +0000316 case OMPC_aligned:
317 EmitOMPAlignedClause(*this, CGM, cast<OMPAlignedClause>(*C));
318 break;
Alexander Musmana5f070a2014-10-01 06:03:56 +0000319 case OMPC_lastprivate:
320 SeparateIter = true;
321 break;
Alexander Musman515ad8c2014-05-22 08:54:05 +0000322 default:
323 // Not handled yet
324 ;
325 }
326 }
Alexander Musmana5f070a2014-10-01 06:03:56 +0000327
328 RunCleanupsScope DirectiveScope(*this);
329
330 CGDebugInfo *DI = getDebugInfo();
331 if (DI)
332 DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin());
333
334 // Emit the loop iteration variable.
335 const Expr *IVExpr = S.getIterationVariable();
336 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
337 EmitVarDecl(*IVDecl);
338 EmitIgnoredExpr(S.getInit());
339
340 // Emit the iterations count variable.
341 // If it is not a variable, Sema decided to calculate iterations count on each
342 // iteration (e.g., it is foldable into a constant).
343 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
344 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
345 // Emit calculation of the iterations count.
346 EmitIgnoredExpr(S.getCalcLastIteration());
347 }
348
349 if (SeparateIter) {
350 // Emit: if (LastIteration > 0) - begin.
351 RegionCounter Cnt = getPGORegionCounter(&S);
352 auto ThenBlock = createBasicBlock("simd.if.then");
353 auto ContBlock = createBasicBlock("simd.if.end");
354 EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount());
355 EmitBlock(ThenBlock);
356 Cnt.beginRegion(Builder);
357 // Emit 'then' code.
358 {
359 OMPPrivateScope LoopScope(*this);
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000360 EmitPrivateLoopCounters(*this, LoopScope, S.counters());
Alexander Musmand196ef22014-10-07 08:57:09 +0000361 EmitOMPInnerLoop(S, LoopScope, /* SeparateIter */ true);
362 EmitOMPLoopBody(S, /* SeparateIter */ true);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000363 }
364 EmitOMPSimdFinal(S);
365 // Emit: if (LastIteration != 0) - end.
366 EmitBranch(ContBlock);
367 EmitBlock(ContBlock, true);
368 } else {
369 {
370 OMPPrivateScope LoopScope(*this);
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000371 EmitPrivateLoopCounters(*this, LoopScope, S.counters());
Alexander Musmand196ef22014-10-07 08:57:09 +0000372 EmitOMPInnerLoop(S, LoopScope);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000373 }
374 EmitOMPSimdFinal(S);
375 }
376
377 if (DI)
378 DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd());
Alexander Musman515ad8c2014-05-22 08:54:05 +0000379}
380
Alexey Bataevf29276e2014-06-18 04:14:57 +0000381void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &) {
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000382 llvm_unreachable("CodeGen for 'omp for' is not supported yet.");
Alexey Bataevf29276e2014-06-18 04:14:57 +0000383}
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000384
Alexander Musmanf82886e2014-09-18 05:12:34 +0000385void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &) {
386 llvm_unreachable("CodeGen for 'omp for simd' is not supported yet.");
387}
388
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000389void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &) {
390 llvm_unreachable("CodeGen for 'omp sections' is not supported yet.");
391}
392
Alexey Bataev1e0498a2014-06-26 08:21:58 +0000393void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &) {
394 llvm_unreachable("CodeGen for 'omp section' is not supported yet.");
395}
396
Alexey Bataevd1e40fb2014-06-26 12:05:45 +0000397void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) {
398 llvm_unreachable("CodeGen for 'omp single' is not supported yet.");
399}
400
Alexander Musman80c22892014-07-17 08:54:58 +0000401void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &) {
402 llvm_unreachable("CodeGen for 'omp master' is not supported yet.");
403}
404
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +0000405void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
406 // __kmpc_critical();
407 // <captured_body>
408 // __kmpc_end_critical();
409 //
410
411 auto Lock = CGM.getOpenMPRuntime().GetCriticalRegionLock(
412 S.getDirectiveName().getAsString());
413 CGM.getOpenMPRuntime().EmitOMPCriticalRegionStart(*this, Lock,
414 S.getLocStart());
415 {
416 RunCleanupsScope Scope(*this);
417 EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
418 EnsureInsertPoint();
419 }
420 CGM.getOpenMPRuntime().EmitOMPCriticalRegionEnd(*this, Lock, S.getLocEnd());
Alexander Musmand9ed09f2014-07-21 09:42:05 +0000421}
422
Alexey Bataev4acb8592014-07-07 13:01:15 +0000423void
424CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
425 llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet.");
426}
427
Alexander Musmane4e893b2014-09-23 09:33:00 +0000428void CodeGenFunction::EmitOMPParallelForSimdDirective(
429 const OMPParallelForSimdDirective &) {
430 llvm_unreachable("CodeGen for 'omp parallel for simd' is not supported yet.");
431}
432
Alexey Bataev84d0b3e2014-07-08 08:12:03 +0000433void CodeGenFunction::EmitOMPParallelSectionsDirective(
434 const OMPParallelSectionsDirective &) {
435 llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet.");
436}
437
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +0000438void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &) {
439 llvm_unreachable("CodeGen for 'omp task' is not supported yet.");
440}
441
Alexey Bataev68446b72014-07-18 07:47:19 +0000442void CodeGenFunction::EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &) {
443 llvm_unreachable("CodeGen for 'omp taskyield' is not supported yet.");
444}
445
Alexey Bataev4d1dfea2014-07-18 09:11:51 +0000446void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &) {
447 llvm_unreachable("CodeGen for 'omp barrier' is not supported yet.");
448}
449
Alexey Bataev2df347a2014-07-18 10:17:07 +0000450void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &) {
451 llvm_unreachable("CodeGen for 'omp taskwait' is not supported yet.");
452}
453
Alexey Bataev6125da92014-07-21 11:26:11 +0000454void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &) {
455 llvm_unreachable("CodeGen for 'omp flush' is not supported yet.");
456}
457
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000458void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &) {
459 llvm_unreachable("CodeGen for 'omp ordered' is not supported yet.");
460}
461
Alexey Bataev0162e452014-07-22 10:10:35 +0000462void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &) {
463 llvm_unreachable("CodeGen for 'omp atomic' is not supported yet.");
464}
465
Alexey Bataev0bd520b2014-09-19 08:19:49 +0000466void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) {
467 llvm_unreachable("CodeGen for 'omp target' is not supported yet.");
468}
469
Alexey Bataev13314bf2014-10-09 04:18:56 +0000470void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &) {
471 llvm_unreachable("CodeGen for 'omp teams' is not supported yet.");
472}
473