blob: 2b0fb043be002761f07be5526784dd2a6f078616 [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 Bataevb2059782014-10-13 08:23:51 +0000186/// \brief Emits code for OpenMP parallel directive in the parallel region.
187static void EmitOMPParallelCall(CodeGenFunction &CGF,
188 const OMPParallelDirective &S,
189 llvm::Value *OutlinedFn,
190 llvm::Value *CapturedStruct) {
191 if (auto C = S.getSingleClause(/*K*/ OMPC_num_threads)) {
192 CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
193 auto NumThreadsClause = cast<OMPNumThreadsClause>(C);
194 auto NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(),
195 /*IgnoreResultAssign*/ true);
196 CGF.CGM.getOpenMPRuntime().EmitOMPNumThreadsClause(
197 CGF, NumThreads, NumThreadsClause->getLocStart());
198 }
199 CGF.CGM.getOpenMPRuntime().EmitOMPParallelCall(CGF, S.getLocStart(),
200 OutlinedFn, CapturedStruct);
201}
202
Alexey Bataev9959db52014-05-06 10:08:46 +0000203void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
Alexey Bataev18095712014-10-10 12:19:54 +0000204 auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
205 auto CapturedStruct = GenerateCapturedStmtArgument(*CS);
206 auto OutlinedFn = CGM.getOpenMPRuntime().EmitOpenMPOutlinedFunction(
207 S, *CS->getCapturedDecl()->param_begin());
Alexey Bataevd74d0602014-10-13 06:02:40 +0000208 if (auto C = S.getSingleClause(/*K*/ OMPC_if)) {
209 auto Cond = cast<OMPIfClause>(C)->getCondition();
210 EmitOMPIfClause(*this, Cond, [&](bool ThenBlock) {
211 if (ThenBlock)
Alexey Bataevb2059782014-10-13 08:23:51 +0000212 EmitOMPParallelCall(*this, S, OutlinedFn, CapturedStruct);
Alexey Bataevd74d0602014-10-13 06:02:40 +0000213 else
214 CGM.getOpenMPRuntime().EmitOMPSerialCall(*this, S.getLocStart(),
215 OutlinedFn, CapturedStruct);
216 });
Alexey Bataevb2059782014-10-13 08:23:51 +0000217 } else
218 EmitOMPParallelCall(*this, S, OutlinedFn, CapturedStruct);
Alexey Bataev9959db52014-05-06 10:08:46 +0000219}
Alexander Musman515ad8c2014-05-22 08:54:05 +0000220
Alexander Musmand196ef22014-10-07 08:57:09 +0000221void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &S,
Alexander Musmana5f070a2014-10-01 06:03:56 +0000222 bool SeparateIter) {
223 RunCleanupsScope BodyScope(*this);
224 // Update counters values on current iteration.
225 for (auto I : S.updates()) {
226 EmitIgnoredExpr(I);
227 }
228 // On a continue in the body, jump to the end.
Alexander Musmand196ef22014-10-07 08:57:09 +0000229 auto Continue = getJumpDestInCurrentScope("omp.body.continue");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000230 BreakContinueStack.push_back(BreakContinue(JumpDest(), Continue));
231 // Emit loop body.
232 EmitStmt(S.getBody());
233 // The end (updates/cleanups).
234 EmitBlock(Continue.getBlock());
235 BreakContinueStack.pop_back();
236 if (SeparateIter) {
237 // TODO: Update lastprivates if the SeparateIter flag is true.
238 // This will be implemented in a follow-up OMPLastprivateClause patch, but
239 // result should be still correct without it, as we do not make these
240 // variables private yet.
241 }
242}
243
Alexander Musmand196ef22014-10-07 08:57:09 +0000244void CodeGenFunction::EmitOMPInnerLoop(const OMPLoopDirective &S,
245 OMPPrivateScope &LoopScope,
246 bool SeparateIter) {
247 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000248 auto Cnt = getPGORegionCounter(&S);
249
250 // Start the loop with a block that tests the condition.
Alexander Musmand196ef22014-10-07 08:57:09 +0000251 auto CondBlock = createBasicBlock("omp.inner.for.cond");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000252 EmitBlock(CondBlock);
253 LoopStack.push(CondBlock);
254
255 // If there are any cleanups between here and the loop-exit scope,
256 // create a block to stage a loop exit along.
257 auto ExitBlock = LoopExit.getBlock();
258 if (LoopScope.requiresCleanups())
Alexander Musmand196ef22014-10-07 08:57:09 +0000259 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000260
Alexander Musmand196ef22014-10-07 08:57:09 +0000261 auto LoopBody = createBasicBlock("omp.inner.for.body");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000262
263 // Emit condition: "IV < LastIteration + 1 [ - 1]"
264 // ("- 1" when lastprivate clause is present - separate one iteration).
265 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond(SeparateIter));
266 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock,
267 PGO.createLoopWeights(S.getCond(SeparateIter), Cnt));
268
269 if (ExitBlock != LoopExit.getBlock()) {
270 EmitBlock(ExitBlock);
271 EmitBranchThroughCleanup(LoopExit);
272 }
273
274 EmitBlock(LoopBody);
275 Cnt.beginRegion(Builder);
276
277 // Create a block for the increment.
Alexander Musmand196ef22014-10-07 08:57:09 +0000278 auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
Alexander Musmana5f070a2014-10-01 06:03:56 +0000279 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
280
Alexander Musmand196ef22014-10-07 08:57:09 +0000281 EmitOMPLoopBody(S);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000282 EmitStopPoint(&S);
283
284 // Emit "IV = IV + 1" and a back-edge to the condition block.
285 EmitBlock(Continue.getBlock());
286 EmitIgnoredExpr(S.getInc());
287 BreakContinueStack.pop_back();
288 EmitBranch(CondBlock);
289 LoopStack.pop();
290 // Emit the fall-through block.
291 EmitBlock(LoopExit.getBlock());
292}
293
294void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) {
295 auto IC = S.counters().begin();
296 for (auto F : S.finals()) {
297 if (LocalDeclMap.lookup(cast<DeclRefExpr>((*IC))->getDecl())) {
298 EmitIgnoredExpr(F);
299 }
300 ++IC;
301 }
302}
303
Alexander Musman09184fe2014-09-30 05:29:28 +0000304static void EmitOMPAlignedClause(CodeGenFunction &CGF, CodeGenModule &CGM,
305 const OMPAlignedClause &Clause) {
306 unsigned ClauseAlignment = 0;
307 if (auto AlignmentExpr = Clause.getAlignment()) {
308 auto AlignmentCI =
309 cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
310 ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue());
311 }
312 for (auto E : Clause.varlists()) {
313 unsigned Alignment = ClauseAlignment;
314 if (Alignment == 0) {
315 // OpenMP [2.8.1, Description]
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000316 // If no optional parameter is specified, implementation-defined default
Alexander Musman09184fe2014-09-30 05:29:28 +0000317 // alignments for SIMD instructions on the target platforms are assumed.
318 Alignment = CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment(
319 E->getType());
320 }
321 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
322 "alignment is not power of 2");
323 if (Alignment != 0) {
324 llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
325 CGF.EmitAlignmentAssumption(PtrValue, Alignment);
326 }
327 }
328}
329
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000330static void EmitPrivateLoopCounters(CodeGenFunction &CGF,
331 CodeGenFunction::OMPPrivateScope &LoopScope,
332 ArrayRef<Expr *> Counters) {
333 for (auto *E : Counters) {
334 auto VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
335 bool IsRegistered = LoopScope.addPrivate(VD, [&]() -> llvm::Value * {
336 // Emit var without initialization.
337 auto VarEmission = CGF.EmitAutoVarAlloca(*VD);
338 CGF.EmitAutoVarCleanups(VarEmission);
339 return VarEmission.getAllocatedAddress();
340 });
341 assert(IsRegistered && "counter already registered as private");
342 // Silence the warning about unused variable.
343 (void)IsRegistered;
344 }
345 (void)LoopScope.Privatize();
346}
347
Alexander Musman515ad8c2014-05-22 08:54:05 +0000348void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
Alexander Musmana5f070a2014-10-01 06:03:56 +0000349 // Pragma 'simd' code depends on presence of 'lastprivate'.
350 // If present, we have to separate last iteration of the loop:
351 //
352 // if (LastIteration != 0) {
353 // for (IV in 0..LastIteration-1) BODY;
354 // BODY with updates of lastprivate vars;
355 // <Final counter/linear vars updates>;
356 // }
357 //
358 // otherwise (when there's no lastprivate):
359 //
360 // for (IV in 0..LastIteration) BODY;
361 // <Final counter/linear vars updates>;
362 //
363
364 // Walk clauses and process safelen/lastprivate.
365 bool SeparateIter = false;
Alexander Musman515ad8c2014-05-22 08:54:05 +0000366 LoopStack.setParallel();
367 LoopStack.setVectorizerEnable(true);
368 for (auto C : S.clauses()) {
369 switch (C->getClauseKind()) {
370 case OMPC_safelen: {
371 RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(),
372 AggValueSlot::ignored(), true);
373 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
374 LoopStack.setVectorizerWidth(Val->getZExtValue());
375 // In presence of finite 'safelen', it may be unsafe to mark all
376 // the memory instructions parallel, because loop-carried
377 // dependences of 'safelen' iterations are possible.
378 LoopStack.setParallel(false);
379 break;
380 }
Alexander Musman09184fe2014-09-30 05:29:28 +0000381 case OMPC_aligned:
382 EmitOMPAlignedClause(*this, CGM, cast<OMPAlignedClause>(*C));
383 break;
Alexander Musmana5f070a2014-10-01 06:03:56 +0000384 case OMPC_lastprivate:
385 SeparateIter = true;
386 break;
Alexander Musman515ad8c2014-05-22 08:54:05 +0000387 default:
388 // Not handled yet
389 ;
390 }
391 }
Alexander Musmana5f070a2014-10-01 06:03:56 +0000392
393 RunCleanupsScope DirectiveScope(*this);
394
395 CGDebugInfo *DI = getDebugInfo();
396 if (DI)
397 DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin());
398
399 // Emit the loop iteration variable.
400 const Expr *IVExpr = S.getIterationVariable();
401 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
402 EmitVarDecl(*IVDecl);
403 EmitIgnoredExpr(S.getInit());
404
405 // Emit the iterations count variable.
406 // If it is not a variable, Sema decided to calculate iterations count on each
407 // iteration (e.g., it is foldable into a constant).
408 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
409 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
410 // Emit calculation of the iterations count.
411 EmitIgnoredExpr(S.getCalcLastIteration());
412 }
413
414 if (SeparateIter) {
415 // Emit: if (LastIteration > 0) - begin.
416 RegionCounter Cnt = getPGORegionCounter(&S);
417 auto ThenBlock = createBasicBlock("simd.if.then");
418 auto ContBlock = createBasicBlock("simd.if.end");
419 EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount());
420 EmitBlock(ThenBlock);
421 Cnt.beginRegion(Builder);
422 // Emit 'then' code.
423 {
424 OMPPrivateScope LoopScope(*this);
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000425 EmitPrivateLoopCounters(*this, LoopScope, S.counters());
Alexander Musmand196ef22014-10-07 08:57:09 +0000426 EmitOMPInnerLoop(S, LoopScope, /* SeparateIter */ true);
427 EmitOMPLoopBody(S, /* SeparateIter */ true);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000428 }
429 EmitOMPSimdFinal(S);
430 // Emit: if (LastIteration != 0) - end.
431 EmitBranch(ContBlock);
432 EmitBlock(ContBlock, true);
433 } else {
434 {
435 OMPPrivateScope LoopScope(*this);
Alexey Bataev435ad7b2014-10-10 09:48:26 +0000436 EmitPrivateLoopCounters(*this, LoopScope, S.counters());
Alexander Musmand196ef22014-10-07 08:57:09 +0000437 EmitOMPInnerLoop(S, LoopScope);
Alexander Musmana5f070a2014-10-01 06:03:56 +0000438 }
439 EmitOMPSimdFinal(S);
440 }
441
442 if (DI)
443 DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd());
Alexander Musman515ad8c2014-05-22 08:54:05 +0000444}
445
Alexey Bataevf29276e2014-06-18 04:14:57 +0000446void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &) {
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000447 llvm_unreachable("CodeGen for 'omp for' is not supported yet.");
Alexey Bataevf29276e2014-06-18 04:14:57 +0000448}
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000449
Alexander Musmanf82886e2014-09-18 05:12:34 +0000450void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &) {
451 llvm_unreachable("CodeGen for 'omp for simd' is not supported yet.");
452}
453
Alexey Bataevd3f8dd22014-06-25 11:44:49 +0000454void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &) {
455 llvm_unreachable("CodeGen for 'omp sections' is not supported yet.");
456}
457
Alexey Bataev1e0498a2014-06-26 08:21:58 +0000458void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &) {
459 llvm_unreachable("CodeGen for 'omp section' is not supported yet.");
460}
461
Alexey Bataevd1e40fb2014-06-26 12:05:45 +0000462void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) {
463 llvm_unreachable("CodeGen for 'omp single' is not supported yet.");
464}
465
Alexander Musman80c22892014-07-17 08:54:58 +0000466void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &) {
467 llvm_unreachable("CodeGen for 'omp master' is not supported yet.");
468}
469
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +0000470void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
471 // __kmpc_critical();
472 // <captured_body>
473 // __kmpc_end_critical();
474 //
475
476 auto Lock = CGM.getOpenMPRuntime().GetCriticalRegionLock(
477 S.getDirectiveName().getAsString());
478 CGM.getOpenMPRuntime().EmitOMPCriticalRegionStart(*this, Lock,
479 S.getLocStart());
480 {
481 RunCleanupsScope Scope(*this);
482 EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
483 EnsureInsertPoint();
484 }
485 CGM.getOpenMPRuntime().EmitOMPCriticalRegionEnd(*this, Lock, S.getLocEnd());
Alexander Musmand9ed09f2014-07-21 09:42:05 +0000486}
487
Alexey Bataev4acb8592014-07-07 13:01:15 +0000488void
489CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
490 llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet.");
491}
492
Alexander Musmane4e893b2014-09-23 09:33:00 +0000493void CodeGenFunction::EmitOMPParallelForSimdDirective(
494 const OMPParallelForSimdDirective &) {
495 llvm_unreachable("CodeGen for 'omp parallel for simd' is not supported yet.");
496}
497
Alexey Bataev84d0b3e2014-07-08 08:12:03 +0000498void CodeGenFunction::EmitOMPParallelSectionsDirective(
499 const OMPParallelSectionsDirective &) {
500 llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet.");
501}
502
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +0000503void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &) {
504 llvm_unreachable("CodeGen for 'omp task' is not supported yet.");
505}
506
Alexey Bataev68446b72014-07-18 07:47:19 +0000507void CodeGenFunction::EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &) {
508 llvm_unreachable("CodeGen for 'omp taskyield' is not supported yet.");
509}
510
Alexey Bataev4d1dfea2014-07-18 09:11:51 +0000511void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &) {
512 llvm_unreachable("CodeGen for 'omp barrier' is not supported yet.");
513}
514
Alexey Bataev2df347a2014-07-18 10:17:07 +0000515void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &) {
516 llvm_unreachable("CodeGen for 'omp taskwait' is not supported yet.");
517}
518
Alexey Bataev6125da92014-07-21 11:26:11 +0000519void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &) {
520 llvm_unreachable("CodeGen for 'omp flush' is not supported yet.");
521}
522
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000523void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &) {
524 llvm_unreachable("CodeGen for 'omp ordered' is not supported yet.");
525}
526
Alexey Bataev0162e452014-07-22 10:10:35 +0000527void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &) {
528 llvm_unreachable("CodeGen for 'omp atomic' is not supported yet.");
529}
530
Alexey Bataev0bd520b2014-09-19 08:19:49 +0000531void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) {
532 llvm_unreachable("CodeGen for 'omp target' is not supported yet.");
533}
534
Alexey Bataev13314bf2014-10-09 04:18:56 +0000535void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &) {
536 llvm_unreachable("CodeGen for 'omp teams' is not supported yet.");
537}
538