blob: 6906044b62cf398916673c413ad2df4f83db4b0e [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"
19using namespace clang;
20using namespace CodeGen;
21
22//===----------------------------------------------------------------------===//
23// OpenMP Directive Emission
24//===----------------------------------------------------------------------===//
25
26void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
27 const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt());
28 llvm::Value *CapturedStruct = GenerateCapturedStmtArgument(*CS);
29
30 llvm::Value *OutlinedFn;
31 {
32 CodeGenFunction CGF(CGM, true);
33 CGCapturedStmtInfo CGInfo(*CS, CS->getCapturedRegionKind());
34 CGF.CapturedStmtInfo = &CGInfo;
Alexey Bataevaca7fcf2014-06-30 02:55:54 +000035 OutlinedFn = CGF.GenerateCapturedStmtFunction(*CS);
Alexey Bataev9959db52014-05-06 10:08:46 +000036 }
37
38 // Build call __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/)
39 llvm::Value *Args[] = {
Alexey Bataev23b69422014-06-18 07:08:49 +000040 CGM.getOpenMPRuntime().EmitOpenMPUpdateLocation(*this, S.getLocStart()),
41 Builder.getInt32(1), // Number of arguments after 'microtask' argument
42 // (there is only one additional argument - 'context')
43 Builder.CreateBitCast(OutlinedFn,
44 CGM.getOpenMPRuntime().getKmpc_MicroPointerTy()),
45 EmitCastToVoidPtr(CapturedStruct)};
Alexey Bataev9959db52014-05-06 10:08:46 +000046 llvm::Constant *RTLFn = CGM.getOpenMPRuntime().CreateRuntimeFunction(
47 CGOpenMPRuntime::OMPRTL__kmpc_fork_call);
48 EmitRuntimeCall(RTLFn, Args);
49}
Alexander Musman515ad8c2014-05-22 08:54:05 +000050
51void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
52 const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt());
53 const Stmt *Body = CS->getCapturedStmt();
54 LoopStack.setParallel();
55 LoopStack.setVectorizerEnable(true);
56 for (auto C : S.clauses()) {
57 switch (C->getClauseKind()) {
58 case OMPC_safelen: {
59 RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(),
60 AggValueSlot::ignored(), true);
61 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
62 LoopStack.setVectorizerWidth(Val->getZExtValue());
63 // In presence of finite 'safelen', it may be unsafe to mark all
64 // the memory instructions parallel, because loop-carried
65 // dependences of 'safelen' iterations are possible.
66 LoopStack.setParallel(false);
67 break;
68 }
69 default:
70 // Not handled yet
71 ;
72 }
73 }
74 EmitStmt(Body);
75}
76
Alexey Bataevf29276e2014-06-18 04:14:57 +000077void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &) {
Alexey Bataevd3f8dd22014-06-25 11:44:49 +000078 llvm_unreachable("CodeGen for 'omp for' is not supported yet.");
Alexey Bataevf29276e2014-06-18 04:14:57 +000079}
Alexey Bataevd3f8dd22014-06-25 11:44:49 +000080
Alexander Musmanf82886e2014-09-18 05:12:34 +000081void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &) {
82 llvm_unreachable("CodeGen for 'omp for simd' is not supported yet.");
83}
84
Alexey Bataevd3f8dd22014-06-25 11:44:49 +000085void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &) {
86 llvm_unreachable("CodeGen for 'omp sections' is not supported yet.");
87}
88
Alexey Bataev1e0498a2014-06-26 08:21:58 +000089void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &) {
90 llvm_unreachable("CodeGen for 'omp section' is not supported yet.");
91}
92
Alexey Bataevd1e40fb2014-06-26 12:05:45 +000093void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) {
94 llvm_unreachable("CodeGen for 'omp single' is not supported yet.");
95}
96
Alexander Musman80c22892014-07-17 08:54:58 +000097void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &) {
98 llvm_unreachable("CodeGen for 'omp master' is not supported yet.");
99}
100
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +0000101void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
102 // __kmpc_critical();
103 // <captured_body>
104 // __kmpc_end_critical();
105 //
106
107 auto Lock = CGM.getOpenMPRuntime().GetCriticalRegionLock(
108 S.getDirectiveName().getAsString());
109 CGM.getOpenMPRuntime().EmitOMPCriticalRegionStart(*this, Lock,
110 S.getLocStart());
111 {
112 RunCleanupsScope Scope(*this);
113 EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
114 EnsureInsertPoint();
115 }
116 CGM.getOpenMPRuntime().EmitOMPCriticalRegionEnd(*this, Lock, S.getLocEnd());
Alexander Musmand9ed09f2014-07-21 09:42:05 +0000117}
118
Alexey Bataev4acb8592014-07-07 13:01:15 +0000119void
120CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
121 llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet.");
122}
123
Alexey Bataev84d0b3e2014-07-08 08:12:03 +0000124void CodeGenFunction::EmitOMPParallelSectionsDirective(
125 const OMPParallelSectionsDirective &) {
126 llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet.");
127}
128
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +0000129void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &) {
130 llvm_unreachable("CodeGen for 'omp task' is not supported yet.");
131}
132
Alexey Bataev68446b72014-07-18 07:47:19 +0000133void CodeGenFunction::EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &) {
134 llvm_unreachable("CodeGen for 'omp taskyield' is not supported yet.");
135}
136
Alexey Bataev4d1dfea2014-07-18 09:11:51 +0000137void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &) {
138 llvm_unreachable("CodeGen for 'omp barrier' is not supported yet.");
139}
140
Alexey Bataev2df347a2014-07-18 10:17:07 +0000141void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &) {
142 llvm_unreachable("CodeGen for 'omp taskwait' is not supported yet.");
143}
144
Alexey Bataev6125da92014-07-21 11:26:11 +0000145void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &) {
146 llvm_unreachable("CodeGen for 'omp flush' is not supported yet.");
147}
148
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000149void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &) {
150 llvm_unreachable("CodeGen for 'omp ordered' is not supported yet.");
151}
152
Alexey Bataev0162e452014-07-22 10:10:35 +0000153void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &) {
154 llvm_unreachable("CodeGen for 'omp atomic' is not supported yet.");
155}
156
Alexey Bataev0bd520b2014-09-19 08:19:49 +0000157void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) {
158 llvm_unreachable("CodeGen for 'omp target' is not supported yet.");
159}
160