blob: 2aec28f3051c47d9c992863e6c0ba3cfb86f5963 [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) {
Alexey Bataev18095712014-10-10 12:19:54 +0000141 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
142 auto CapturedStruct = GenerateCapturedStmtArgument(*CS);
143 auto OutlinedFn = CGM.getOpenMPRuntime().EmitOpenMPOutlinedFunction(
144 S, *CS->getCapturedDecl()->param_begin());
Alexey Bataev4a5bb772014-10-08 14:01:46 +0000145 CGM.getOpenMPRuntime().EmitOMPParallelCall(*this, S.getLocStart(), OutlinedFn,
146 CapturedStruct);
Alexey Bataev9959db52014-05-06 10:08:46 +0000147}
Alexander Musman515ad8c2014-05-22 08:54:05 +0000148
Alexander Musmand196ef22014-10-07 08:57:09 +0000149void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &S,
Alexander Musmana5f070a2014-10-01 06:03:56 +0000150 bool SeparateIter) {
151 RunCleanupsScope BodyScope(*this);
152 // Update counters values on current iteration.
153 for (auto I : S.updates()) {
154 EmitIgnoredExpr(I);
155 }
156 // On a continue in the body, jump to the end.
Alexander Musmand196ef22014-10-07 08:57:09 +0000157 auto Continue = getJumpDestInCurrentScope("omp.body.continue");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000158 BreakContinueStack.push_back(BreakContinue(JumpDest(), Continue));
159 // Emit loop body.
160 EmitStmt(S.getBody());
161 // The end (updates/cleanups).
162 EmitBlock(Continue.getBlock());
163 BreakContinueStack.pop_back();
164 if (SeparateIter) {
165 // TODO: Update lastprivates if the SeparateIter flag is true.
166 // This will be implemented in a follow-up OMPLastprivateClause patch, but
167 // result should be still correct without it, as we do not make these
168 // variables private yet.
169 }
170}
171
Alexander Musmand196ef22014-10-07 08:57:09 +0000172void CodeGenFunction::EmitOMPInnerLoop(const OMPLoopDirective &S,
173 OMPPrivateScope &LoopScope,
174 bool SeparateIter) {
175 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000176 auto Cnt = getPGORegionCounter(&S);
177
178 // Start the loop with a block that tests the condition.
Alexander Musmand196ef22014-10-07 08:57:09 +0000179 auto CondBlock = createBasicBlock("omp.inner.for.cond");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000180 EmitBlock(CondBlock);
181 LoopStack.push(CondBlock);
182
183 // If there are any cleanups between here and the loop-exit scope,
184 // create a block to stage a loop exit along.
185 auto ExitBlock = LoopExit.getBlock();
186 if (LoopScope.requiresCleanups())
Alexander Musmand196ef22014-10-07 08:57:09 +0000187 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000188
Alexander Musmand196ef22014-10-07 08:57:09 +0000189 auto LoopBody = createBasicBlock("omp.inner.for.body");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000190
191 // Emit condition: "IV < LastIteration + 1 [ - 1]"
192 // ("- 1" when lastprivate clause is present - separate one iteration).
193 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond(SeparateIter));
194 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock,
195 PGO.createLoopWeights(S.getCond(SeparateIter), Cnt));
196
197 if (ExitBlock != LoopExit.getBlock()) {
198 EmitBlock(ExitBlock);
199 EmitBranchThroughCleanup(LoopExit);
200 }
201
202 EmitBlock(LoopBody);
203 Cnt.beginRegion(Builder);
204
205 // Create a block for the increment.
Alexander Musmand196ef22014-10-07 08:57:09 +0000206 auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000207 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
208
Alexander Musmand196ef22014-10-07 08:57:09 +0000209 EmitOMPLoopBody(S);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000210 EmitStopPoint(&S);
211
212 // Emit "IV = IV + 1" and a back-edge to the condition block.
213 EmitBlock(Continue.getBlock());
214 EmitIgnoredExpr(S.getInc());
215 BreakContinueStack.pop_back();
216 EmitBranch(CondBlock);
217 LoopStack.pop();
218 // Emit the fall-through block.
219 EmitBlock(LoopExit.getBlock());
220}
221
222void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) {
223 auto IC = S.counters().begin();
224 for (auto F : S.finals()) {
225 if (LocalDeclMap.lookup(cast<DeclRefExpr>((*IC))->getDecl())) {
226 EmitIgnoredExpr(F);
227 }
228 ++IC;
229 }
230}
231
Alexander Musman09184fe2014-09-30 05:29:28 +0000232static void EmitOMPAlignedClause(CodeGenFunction &CGF, CodeGenModule &CGM,
233 const OMPAlignedClause &Clause) {
234 unsigned ClauseAlignment = 0;
235 if (auto AlignmentExpr = Clause.getAlignment()) {
236 auto AlignmentCI =
237 cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
238 ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue());
239 }
240 for (auto E : Clause.varlists()) {
241 unsigned Alignment = ClauseAlignment;
242 if (Alignment == 0) {
243 // OpenMP [2.8.1, Description]
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000244 // If no optional parameter is specified, implementation-defined default
Alexander Musman09184fe2014-09-30 05:29:28 +0000245 // alignments for SIMD instructions on the target platforms are assumed.
246 Alignment = CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment(
247 E->getType());
248 }
249 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
250 "alignment is not power of 2");
251 if (Alignment != 0) {
252 llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
253 CGF.EmitAlignmentAssumption(PtrValue, Alignment);
254 }
255 }
256}
257
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000258static void EmitPrivateLoopCounters(CodeGenFunction &CGF,
259 CodeGenFunction::OMPPrivateScope &LoopScope,
260 ArrayRef<Expr *> Counters) {
261 for (auto *E : Counters) {
262 auto VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
263 bool IsRegistered = LoopScope.addPrivate(VD, [&]() -> llvm::Value * {
264 // Emit var without initialization.
265 auto VarEmission = CGF.EmitAutoVarAlloca(*VD);
266 CGF.EmitAutoVarCleanups(VarEmission);
267 return VarEmission.getAllocatedAddress();
268 });
269 assert(IsRegistered && "counter already registered as private");
270 // Silence the warning about unused variable.
271 (void)IsRegistered;
272 }
273 (void)LoopScope.Privatize();
274}
275
Alexander Musman515ad8c2014-05-22 08:54:05 +0000276void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
Alexander Musmana5f070a2014-10-01 06:03:56 +0000277 // Pragma 'simd' code depends on presence of 'lastprivate'.
278 // If present, we have to separate last iteration of the loop:
279 //
280 // if (LastIteration != 0) {
281 // for (IV in 0..LastIteration-1) BODY;
282 // BODY with updates of lastprivate vars;
283 // <Final counter/linear vars updates>;
284 // }
285 //
286 // otherwise (when there's no lastprivate):
287 //
288 // for (IV in 0..LastIteration) BODY;
289 // <Final counter/linear vars updates>;
290 //
291
292 // Walk clauses and process safelen/lastprivate.
293 bool SeparateIter = false;
Alexander Musman515ad8c2014-05-22 08:54:05 +0000294 LoopStack.setParallel();
295 LoopStack.setVectorizerEnable(true);
296 for (auto C : S.clauses()) {
297 switch (C->getClauseKind()) {
298 case OMPC_safelen: {
299 RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(),
300 AggValueSlot::ignored(), true);
301 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
302 LoopStack.setVectorizerWidth(Val->getZExtValue());
303 // In presence of finite 'safelen', it may be unsafe to mark all
304 // the memory instructions parallel, because loop-carried
305 // dependences of 'safelen' iterations are possible.
306 LoopStack.setParallel(false);
307 break;
308 }
Alexander Musman09184fe2014-09-30 05:29:28 +0000309 case OMPC_aligned:
310 EmitOMPAlignedClause(*this, CGM, cast<OMPAlignedClause>(*C));
311 break;
Alexander Musmana5f070a2014-10-01 06:03:56 +0000312 case OMPC_lastprivate:
313 SeparateIter = true;
314 break;
Alexander Musman515ad8c2014-05-22 08:54:05 +0000315 default:
316 // Not handled yet
317 ;
318 }
319 }
Alexander Musmana5f070a2014-10-01 06:03:56 +0000320
321 RunCleanupsScope DirectiveScope(*this);
322
323 CGDebugInfo *DI = getDebugInfo();
324 if (DI)
325 DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin());
326
327 // Emit the loop iteration variable.
328 const Expr *IVExpr = S.getIterationVariable();
329 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
330 EmitVarDecl(*IVDecl);
331 EmitIgnoredExpr(S.getInit());
332
333 // Emit the iterations count variable.
334 // If it is not a variable, Sema decided to calculate iterations count on each
335 // iteration (e.g., it is foldable into a constant).
336 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
337 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
338 // Emit calculation of the iterations count.
339 EmitIgnoredExpr(S.getCalcLastIteration());
340 }
341
342 if (SeparateIter) {
343 // Emit: if (LastIteration > 0) - begin.
344 RegionCounter Cnt = getPGORegionCounter(&S);
345 auto ThenBlock = createBasicBlock("simd.if.then");
346 auto ContBlock = createBasicBlock("simd.if.end");
347 EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount());
348 EmitBlock(ThenBlock);
349 Cnt.beginRegion(Builder);
350 // Emit 'then' code.
351 {
352 OMPPrivateScope LoopScope(*this);
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000353 EmitPrivateLoopCounters(*this, LoopScope, S.counters());
Alexander Musmand196ef22014-10-07 08:57:09 +0000354 EmitOMPInnerLoop(S, LoopScope, /* SeparateIter */ true);
355 EmitOMPLoopBody(S, /* SeparateIter */ true);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000356 }
357 EmitOMPSimdFinal(S);
358 // Emit: if (LastIteration != 0) - end.
359 EmitBranch(ContBlock);
360 EmitBlock(ContBlock, true);
361 } else {
362 {
363 OMPPrivateScope LoopScope(*this);
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000364 EmitPrivateLoopCounters(*this, LoopScope, S.counters());
Alexander Musmand196ef22014-10-07 08:57:09 +0000365 EmitOMPInnerLoop(S, LoopScope);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000366 }
367 EmitOMPSimdFinal(S);
368 }
369
370 if (DI)
371 DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd());
Alexander Musman515ad8c2014-05-22 08:54:05 +0000372}
373
Alexey Bataevf29276e2014-06-18 04:14:57 +0000374void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &) {
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000375 llvm_unreachable("CodeGen for 'omp for' is not supported yet.");
Alexey Bataevf29276e2014-06-18 04:14:57 +0000376}
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000377
Alexander Musmanf82886e2014-09-18 05:12:34 +0000378void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &) {
379 llvm_unreachable("CodeGen for 'omp for simd' is not supported yet.");
380}
381
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000382void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &) {
383 llvm_unreachable("CodeGen for 'omp sections' is not supported yet.");
384}
385
Alexey Bataev1e0498a2014-06-26 08:21:58 +0000386void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &) {
387 llvm_unreachable("CodeGen for 'omp section' is not supported yet.");
388}
389
Alexey Bataevd1e40fb2014-06-26 12:05:45 +0000390void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) {
391 llvm_unreachable("CodeGen for 'omp single' is not supported yet.");
392}
393
Alexander Musman80c22892014-07-17 08:54:58 +0000394void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &) {
395 llvm_unreachable("CodeGen for 'omp master' is not supported yet.");
396}
397
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +0000398void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
399 // __kmpc_critical();
400 // <captured_body>
401 // __kmpc_end_critical();
402 //
403
404 auto Lock = CGM.getOpenMPRuntime().GetCriticalRegionLock(
405 S.getDirectiveName().getAsString());
406 CGM.getOpenMPRuntime().EmitOMPCriticalRegionStart(*this, Lock,
407 S.getLocStart());
408 {
409 RunCleanupsScope Scope(*this);
410 EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
411 EnsureInsertPoint();
412 }
413 CGM.getOpenMPRuntime().EmitOMPCriticalRegionEnd(*this, Lock, S.getLocEnd());
Alexander Musmand9ed09f2014-07-21 09:42:05 +0000414}
415
Alexey Bataev4acb8592014-07-07 13:01:15 +0000416void
417CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
418 llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet.");
419}
420
Alexander Musmane4e893b2014-09-23 09:33:00 +0000421void CodeGenFunction::EmitOMPParallelForSimdDirective(
422 const OMPParallelForSimdDirective &) {
423 llvm_unreachable("CodeGen for 'omp parallel for simd' is not supported yet.");
424}
425
Alexey Bataev84d0b3e2014-07-08 08:12:03 +0000426void CodeGenFunction::EmitOMPParallelSectionsDirective(
427 const OMPParallelSectionsDirective &) {
428 llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet.");
429}
430
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +0000431void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &) {
432 llvm_unreachable("CodeGen for 'omp task' is not supported yet.");
433}
434
Alexey Bataev68446b72014-07-18 07:47:19 +0000435void CodeGenFunction::EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &) {
436 llvm_unreachable("CodeGen for 'omp taskyield' is not supported yet.");
437}
438
Alexey Bataev4d1dfea2014-07-18 09:11:51 +0000439void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &) {
440 llvm_unreachable("CodeGen for 'omp barrier' is not supported yet.");
441}
442
Alexey Bataev2df347a2014-07-18 10:17:07 +0000443void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &) {
444 llvm_unreachable("CodeGen for 'omp taskwait' is not supported yet.");
445}
446
Alexey Bataev6125da92014-07-21 11:26:11 +0000447void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &) {
448 llvm_unreachable("CodeGen for 'omp flush' is not supported yet.");
449}
450
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000451void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &) {
452 llvm_unreachable("CodeGen for 'omp ordered' is not supported yet.");
453}
454
Alexey Bataev0162e452014-07-22 10:10:35 +0000455void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &) {
456 llvm_unreachable("CodeGen for 'omp atomic' is not supported yet.");
457}
458
Alexey Bataev0bd520b2014-09-19 08:19:49 +0000459void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) {
460 llvm_unreachable("CodeGen for 'omp target' is not supported yet.");
461}
462
Alexey Bataev13314bf2014-10-09 04:18:56 +0000463void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &) {
464 llvm_unreachable("CodeGen for 'omp teams' is not supported yet.");
465}
466