1 //===--- 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"
19 #include "TargetInfo.h"
20 using namespace clang;
21 using namespace CodeGen;
22 
23 //===----------------------------------------------------------------------===//
24 //                              OpenMP Directive Emission
25 //===----------------------------------------------------------------------===//
26 
27 void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
28   const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt());
29   llvm::Value *CapturedStruct = GenerateCapturedStmtArgument(*CS);
30 
31   llvm::Value *OutlinedFn;
32   {
33     CodeGenFunction CGF(CGM, true);
34     CGCapturedStmtInfo CGInfo(*CS, CS->getCapturedRegionKind());
35     CGF.CapturedStmtInfo = &CGInfo;
36     OutlinedFn = CGF.GenerateCapturedStmtFunction(*CS);
37   }
38 
39   // Build call __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/)
40   llvm::Value *Args[] = {
41       CGM.getOpenMPRuntime().EmitOpenMPUpdateLocation(*this, S.getLocStart()),
42       Builder.getInt32(1), // Number of arguments after 'microtask' argument
43       // (there is only one additional argument - 'context')
44       Builder.CreateBitCast(OutlinedFn,
45                             CGM.getOpenMPRuntime().getKmpc_MicroPointerTy()),
46       EmitCastToVoidPtr(CapturedStruct)};
47   llvm::Constant *RTLFn = CGM.getOpenMPRuntime().CreateRuntimeFunction(
48       CGOpenMPRuntime::OMPRTL__kmpc_fork_call);
49   EmitRuntimeCall(RTLFn, Args);
50 }
51 
52 void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &S,
53                                       bool SeparateIter) {
54   RunCleanupsScope BodyScope(*this);
55   // Update counters values on current iteration.
56   for (auto I : S.updates()) {
57     EmitIgnoredExpr(I);
58   }
59   // On a continue in the body, jump to the end.
60   auto Continue = getJumpDestInCurrentScope("omp.body.continue");
61   BreakContinueStack.push_back(BreakContinue(JumpDest(), Continue));
62   // Emit loop body.
63   EmitStmt(S.getBody());
64   // The end (updates/cleanups).
65   EmitBlock(Continue.getBlock());
66   BreakContinueStack.pop_back();
67   if (SeparateIter) {
68     // TODO: Update lastprivates if the SeparateIter flag is true.
69     // This will be implemented in a follow-up OMPLastprivateClause patch, but
70     // result should be still correct without it, as we do not make these
71     // variables private yet.
72   }
73 }
74 
75 void CodeGenFunction::EmitOMPInnerLoop(const OMPLoopDirective &S,
76                                        OMPPrivateScope &LoopScope,
77                                        bool SeparateIter) {
78   auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
79   auto Cnt = getPGORegionCounter(&S);
80 
81   // Start the loop with a block that tests the condition.
82   auto CondBlock = createBasicBlock("omp.inner.for.cond");
83   EmitBlock(CondBlock);
84   LoopStack.push(CondBlock);
85 
86   // If there are any cleanups between here and the loop-exit scope,
87   // create a block to stage a loop exit along.
88   auto ExitBlock = LoopExit.getBlock();
89   if (LoopScope.requiresCleanups())
90     ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
91 
92   auto LoopBody = createBasicBlock("omp.inner.for.body");
93 
94   // Emit condition: "IV < LastIteration + 1 [ - 1]"
95   // ("- 1" when lastprivate clause is present - separate one iteration).
96   llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond(SeparateIter));
97   Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock,
98                        PGO.createLoopWeights(S.getCond(SeparateIter), Cnt));
99 
100   if (ExitBlock != LoopExit.getBlock()) {
101     EmitBlock(ExitBlock);
102     EmitBranchThroughCleanup(LoopExit);
103   }
104 
105   EmitBlock(LoopBody);
106   Cnt.beginRegion(Builder);
107 
108   // Create a block for the increment.
109   auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
110   BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
111 
112   EmitOMPLoopBody(S);
113   EmitStopPoint(&S);
114 
115   // Emit "IV = IV + 1" and a back-edge to the condition block.
116   EmitBlock(Continue.getBlock());
117   EmitIgnoredExpr(S.getInc());
118   BreakContinueStack.pop_back();
119   EmitBranch(CondBlock);
120   LoopStack.pop();
121   // Emit the fall-through block.
122   EmitBlock(LoopExit.getBlock());
123 }
124 
125 void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) {
126   auto IC = S.counters().begin();
127   for (auto F : S.finals()) {
128     if (LocalDeclMap.lookup(cast<DeclRefExpr>((*IC))->getDecl())) {
129       EmitIgnoredExpr(F);
130     }
131     ++IC;
132   }
133 }
134 
135 static void EmitOMPAlignedClause(CodeGenFunction &CGF, CodeGenModule &CGM,
136                                  const OMPAlignedClause &Clause) {
137   unsigned ClauseAlignment = 0;
138   if (auto AlignmentExpr = Clause.getAlignment()) {
139     auto AlignmentCI =
140         cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
141     ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue());
142   }
143   for (auto E : Clause.varlists()) {
144     unsigned Alignment = ClauseAlignment;
145     if (Alignment == 0) {
146       // OpenMP [2.8.1, Description]
147       // If no optional parameter isspecified, implementation-defined default
148       // alignments for SIMD instructions on the target platforms are assumed.
149       Alignment = CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment(
150           E->getType());
151     }
152     assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
153            "alignment is not power of 2");
154     if (Alignment != 0) {
155       llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
156       CGF.EmitAlignmentAssumption(PtrValue, Alignment);
157     }
158   }
159 }
160 
161 void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
162   // Pragma 'simd' code depends on presence of 'lastprivate'.
163   // If present, we have to separate last iteration of the loop:
164   //
165   // if (LastIteration != 0) {
166   //   for (IV in 0..LastIteration-1) BODY;
167   //   BODY with updates of lastprivate vars;
168   //   <Final counter/linear vars updates>;
169   // }
170   //
171   // otherwise (when there's no lastprivate):
172   //
173   //   for (IV in 0..LastIteration) BODY;
174   //   <Final counter/linear vars updates>;
175   //
176 
177   // Walk clauses and process safelen/lastprivate.
178   bool SeparateIter = false;
179   LoopStack.setParallel();
180   LoopStack.setVectorizerEnable(true);
181   for (auto C : S.clauses()) {
182     switch (C->getClauseKind()) {
183     case OMPC_safelen: {
184       RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(),
185                                AggValueSlot::ignored(), true);
186       llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
187       LoopStack.setVectorizerWidth(Val->getZExtValue());
188       // In presence of finite 'safelen', it may be unsafe to mark all
189       // the memory instructions parallel, because loop-carried
190       // dependences of 'safelen' iterations are possible.
191       LoopStack.setParallel(false);
192       break;
193     }
194     case OMPC_aligned:
195       EmitOMPAlignedClause(*this, CGM, cast<OMPAlignedClause>(*C));
196       break;
197     case OMPC_lastprivate:
198       SeparateIter = true;
199       break;
200     default:
201       // Not handled yet
202       ;
203     }
204   }
205 
206   RunCleanupsScope DirectiveScope(*this);
207 
208   CGDebugInfo *DI = getDebugInfo();
209   if (DI)
210     DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin());
211 
212   // Emit the loop iteration variable.
213   const Expr *IVExpr = S.getIterationVariable();
214   const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
215   EmitVarDecl(*IVDecl);
216   EmitIgnoredExpr(S.getInit());
217 
218   // Emit the iterations count variable.
219   // If it is not a variable, Sema decided to calculate iterations count on each
220   // iteration (e.g., it is foldable into a constant).
221   if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
222     EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
223     // Emit calculation of the iterations count.
224     EmitIgnoredExpr(S.getCalcLastIteration());
225   }
226 
227   if (SeparateIter) {
228     // Emit: if (LastIteration > 0) - begin.
229     RegionCounter Cnt = getPGORegionCounter(&S);
230     auto ThenBlock = createBasicBlock("simd.if.then");
231     auto ContBlock = createBasicBlock("simd.if.end");
232     EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount());
233     EmitBlock(ThenBlock);
234     Cnt.beginRegion(Builder);
235     // Emit 'then' code.
236     {
237       OMPPrivateScope LoopScope(*this);
238       LoopScope.addPrivates(S.counters());
239       EmitOMPInnerLoop(S, LoopScope, /* SeparateIter */ true);
240       EmitOMPLoopBody(S, /* SeparateIter */ true);
241     }
242     EmitOMPSimdFinal(S);
243     // Emit: if (LastIteration != 0) - end.
244     EmitBranch(ContBlock);
245     EmitBlock(ContBlock, true);
246   } else {
247     {
248       OMPPrivateScope LoopScope(*this);
249       LoopScope.addPrivates(S.counters());
250       EmitOMPInnerLoop(S, LoopScope);
251     }
252     EmitOMPSimdFinal(S);
253   }
254 
255   if (DI)
256     DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd());
257 }
258 
259 void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &) {
260   llvm_unreachable("CodeGen for 'omp for' is not supported yet.");
261 }
262 
263 void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &) {
264   llvm_unreachable("CodeGen for 'omp for simd' is not supported yet.");
265 }
266 
267 void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &) {
268   llvm_unreachable("CodeGen for 'omp sections' is not supported yet.");
269 }
270 
271 void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &) {
272   llvm_unreachable("CodeGen for 'omp section' is not supported yet.");
273 }
274 
275 void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) {
276   llvm_unreachable("CodeGen for 'omp single' is not supported yet.");
277 }
278 
279 void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &) {
280   llvm_unreachable("CodeGen for 'omp master' is not supported yet.");
281 }
282 
283 void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
284   // __kmpc_critical();
285   // <captured_body>
286   // __kmpc_end_critical();
287   //
288 
289   auto Lock = CGM.getOpenMPRuntime().GetCriticalRegionLock(
290       S.getDirectiveName().getAsString());
291   CGM.getOpenMPRuntime().EmitOMPCriticalRegionStart(*this, Lock,
292                                                     S.getLocStart());
293   {
294     RunCleanupsScope Scope(*this);
295     EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
296     EnsureInsertPoint();
297   }
298   CGM.getOpenMPRuntime().EmitOMPCriticalRegionEnd(*this, Lock, S.getLocEnd());
299 }
300 
301 void
302 CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
303   llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet.");
304 }
305 
306 void CodeGenFunction::EmitOMPParallelForSimdDirective(
307     const OMPParallelForSimdDirective &) {
308   llvm_unreachable("CodeGen for 'omp parallel for simd' is not supported yet.");
309 }
310 
311 void CodeGenFunction::EmitOMPParallelSectionsDirective(
312     const OMPParallelSectionsDirective &) {
313   llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet.");
314 }
315 
316 void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &) {
317   llvm_unreachable("CodeGen for 'omp task' is not supported yet.");
318 }
319 
320 void CodeGenFunction::EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &) {
321   llvm_unreachable("CodeGen for 'omp taskyield' is not supported yet.");
322 }
323 
324 void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &) {
325   llvm_unreachable("CodeGen for 'omp barrier' is not supported yet.");
326 }
327 
328 void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &) {
329   llvm_unreachable("CodeGen for 'omp taskwait' is not supported yet.");
330 }
331 
332 void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &) {
333   llvm_unreachable("CodeGen for 'omp flush' is not supported yet.");
334 }
335 
336 void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &) {
337   llvm_unreachable("CodeGen for 'omp ordered' is not supported yet.");
338 }
339 
340 void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &) {
341   llvm_unreachable("CodeGen for 'omp atomic' is not supported yet.");
342 }
343 
344 void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) {
345   llvm_unreachable("CodeGen for 'omp target' is not supported yet.");
346 }
347 
348