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::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 
95 void CodeGenFunction::EmitOMPFirstprivateClause(
96     const OMPExecutableDirective &D,
97     CodeGenFunction::OuterDeclMapTy &OuterDeclMap) {
98   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()) {
107       auto VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
108       if (*InitsRef != nullptr) {
109         // Emit VarDecl with copy init for arrays.
110         auto *FD = CapturedStmtInfo->lookup(
111             cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()));
112         LValue Base = MakeNaturalAlignAddrLValue(
113             CapturedStmtInfo->getContextValue(),
114             getContext().getTagDeclType(FD->getParent()));
115         auto OriginalAddr = EmitLValueForField(Base, FD);
116         auto VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
117         auto Emission = EmitAutoVarAlloca(*VD);
118         // Emit initialization of aggregate firstprivate vars.
119         EmitOMPAggregateAssign(OriginalAddr, Emission.getAllocatedAddress(),
120                                VD->getInit(), (*IRef)->getType(), VDInit);
121         EmitAutoVarCleanups(Emission);
122       } else
123         // Emit VarDecl with copy init.
124         EmitDecl(*VD);
125       OuterDeclMap[cast<DeclRefExpr>(*IRef)->getDecl()] = GetAddrOfLocalVar(VD);
126       ++IRef, ++InitsRef;
127     }
128   }
129 }
130 
131 void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
132   const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt());
133   llvm::Value *CapturedStruct = GenerateCapturedStmtArgument(*CS);
134 
135   llvm::Value *OutlinedFn;
136   {
137     CodeGenFunction CGF(CGM, true);
138     CGOpenMPRegionInfo CGInfo(S, *CS, *CS->getCapturedDecl()->param_begin());
139     CGF.CapturedStmtInfo = &CGInfo;
140     OutlinedFn = CGF.GenerateCapturedStmtFunction(*CS);
141   }
142 
143   CGM.getOpenMPRuntime().EmitOMPParallelCall(*this, S.getLocStart(), OutlinedFn,
144                                              CapturedStruct);
145 }
146 
147 void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &S,
148                                       bool SeparateIter) {
149   RunCleanupsScope BodyScope(*this);
150   // Update counters values on current iteration.
151   for (auto I : S.updates()) {
152     EmitIgnoredExpr(I);
153   }
154   // On a continue in the body, jump to the end.
155   auto Continue = getJumpDestInCurrentScope("omp.body.continue");
156   BreakContinueStack.push_back(BreakContinue(JumpDest(), Continue));
157   // Emit loop body.
158   EmitStmt(S.getBody());
159   // The end (updates/cleanups).
160   EmitBlock(Continue.getBlock());
161   BreakContinueStack.pop_back();
162   if (SeparateIter) {
163     // TODO: Update lastprivates if the SeparateIter flag is true.
164     // This will be implemented in a follow-up OMPLastprivateClause patch, but
165     // result should be still correct without it, as we do not make these
166     // variables private yet.
167   }
168 }
169 
170 void CodeGenFunction::EmitOMPInnerLoop(const OMPLoopDirective &S,
171                                        OMPPrivateScope &LoopScope,
172                                        bool SeparateIter) {
173   auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
174   auto Cnt = getPGORegionCounter(&S);
175 
176   // Start the loop with a block that tests the condition.
177   auto CondBlock = createBasicBlock("omp.inner.for.cond");
178   EmitBlock(CondBlock);
179   LoopStack.push(CondBlock);
180 
181   // If there are any cleanups between here and the loop-exit scope,
182   // create a block to stage a loop exit along.
183   auto ExitBlock = LoopExit.getBlock();
184   if (LoopScope.requiresCleanups())
185     ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
186 
187   auto LoopBody = createBasicBlock("omp.inner.for.body");
188 
189   // Emit condition: "IV < LastIteration + 1 [ - 1]"
190   // ("- 1" when lastprivate clause is present - separate one iteration).
191   llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond(SeparateIter));
192   Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock,
193                        PGO.createLoopWeights(S.getCond(SeparateIter), Cnt));
194 
195   if (ExitBlock != LoopExit.getBlock()) {
196     EmitBlock(ExitBlock);
197     EmitBranchThroughCleanup(LoopExit);
198   }
199 
200   EmitBlock(LoopBody);
201   Cnt.beginRegion(Builder);
202 
203   // Create a block for the increment.
204   auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
205   BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
206 
207   EmitOMPLoopBody(S);
208   EmitStopPoint(&S);
209 
210   // Emit "IV = IV + 1" and a back-edge to the condition block.
211   EmitBlock(Continue.getBlock());
212   EmitIgnoredExpr(S.getInc());
213   BreakContinueStack.pop_back();
214   EmitBranch(CondBlock);
215   LoopStack.pop();
216   // Emit the fall-through block.
217   EmitBlock(LoopExit.getBlock());
218 }
219 
220 void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) {
221   auto IC = S.counters().begin();
222   for (auto F : S.finals()) {
223     if (LocalDeclMap.lookup(cast<DeclRefExpr>((*IC))->getDecl())) {
224       EmitIgnoredExpr(F);
225     }
226     ++IC;
227   }
228 }
229 
230 static void EmitOMPAlignedClause(CodeGenFunction &CGF, CodeGenModule &CGM,
231                                  const OMPAlignedClause &Clause) {
232   unsigned ClauseAlignment = 0;
233   if (auto AlignmentExpr = Clause.getAlignment()) {
234     auto AlignmentCI =
235         cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
236     ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue());
237   }
238   for (auto E : Clause.varlists()) {
239     unsigned Alignment = ClauseAlignment;
240     if (Alignment == 0) {
241       // OpenMP [2.8.1, Description]
242       // If no optional parameter isspecified, implementation-defined default
243       // alignments for SIMD instructions on the target platforms are assumed.
244       Alignment = CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment(
245           E->getType());
246     }
247     assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
248            "alignment is not power of 2");
249     if (Alignment != 0) {
250       llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
251       CGF.EmitAlignmentAssumption(PtrValue, Alignment);
252     }
253   }
254 }
255 
256 void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
257   // Pragma 'simd' code depends on presence of 'lastprivate'.
258   // If present, we have to separate last iteration of the loop:
259   //
260   // if (LastIteration != 0) {
261   //   for (IV in 0..LastIteration-1) BODY;
262   //   BODY with updates of lastprivate vars;
263   //   <Final counter/linear vars updates>;
264   // }
265   //
266   // otherwise (when there's no lastprivate):
267   //
268   //   for (IV in 0..LastIteration) BODY;
269   //   <Final counter/linear vars updates>;
270   //
271 
272   // Walk clauses and process safelen/lastprivate.
273   bool SeparateIter = false;
274   LoopStack.setParallel();
275   LoopStack.setVectorizerEnable(true);
276   for (auto C : S.clauses()) {
277     switch (C->getClauseKind()) {
278     case OMPC_safelen: {
279       RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(),
280                                AggValueSlot::ignored(), true);
281       llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
282       LoopStack.setVectorizerWidth(Val->getZExtValue());
283       // In presence of finite 'safelen', it may be unsafe to mark all
284       // the memory instructions parallel, because loop-carried
285       // dependences of 'safelen' iterations are possible.
286       LoopStack.setParallel(false);
287       break;
288     }
289     case OMPC_aligned:
290       EmitOMPAlignedClause(*this, CGM, cast<OMPAlignedClause>(*C));
291       break;
292     case OMPC_lastprivate:
293       SeparateIter = true;
294       break;
295     default:
296       // Not handled yet
297       ;
298     }
299   }
300 
301   RunCleanupsScope DirectiveScope(*this);
302 
303   CGDebugInfo *DI = getDebugInfo();
304   if (DI)
305     DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin());
306 
307   // Emit the loop iteration variable.
308   const Expr *IVExpr = S.getIterationVariable();
309   const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
310   EmitVarDecl(*IVDecl);
311   EmitIgnoredExpr(S.getInit());
312 
313   // Emit the iterations count variable.
314   // If it is not a variable, Sema decided to calculate iterations count on each
315   // iteration (e.g., it is foldable into a constant).
316   if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
317     EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
318     // Emit calculation of the iterations count.
319     EmitIgnoredExpr(S.getCalcLastIteration());
320   }
321 
322   if (SeparateIter) {
323     // Emit: if (LastIteration > 0) - begin.
324     RegionCounter Cnt = getPGORegionCounter(&S);
325     auto ThenBlock = createBasicBlock("simd.if.then");
326     auto ContBlock = createBasicBlock("simd.if.end");
327     EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount());
328     EmitBlock(ThenBlock);
329     Cnt.beginRegion(Builder);
330     // Emit 'then' code.
331     {
332       OMPPrivateScope LoopScope(*this);
333       LoopScope.addPrivates(S.counters());
334       EmitOMPInnerLoop(S, LoopScope, /* SeparateIter */ true);
335       EmitOMPLoopBody(S, /* SeparateIter */ true);
336     }
337     EmitOMPSimdFinal(S);
338     // Emit: if (LastIteration != 0) - end.
339     EmitBranch(ContBlock);
340     EmitBlock(ContBlock, true);
341   } else {
342     {
343       OMPPrivateScope LoopScope(*this);
344       LoopScope.addPrivates(S.counters());
345       EmitOMPInnerLoop(S, LoopScope);
346     }
347     EmitOMPSimdFinal(S);
348   }
349 
350   if (DI)
351     DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd());
352 }
353 
354 void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &) {
355   llvm_unreachable("CodeGen for 'omp for' is not supported yet.");
356 }
357 
358 void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &) {
359   llvm_unreachable("CodeGen for 'omp for simd' is not supported yet.");
360 }
361 
362 void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &) {
363   llvm_unreachable("CodeGen for 'omp sections' is not supported yet.");
364 }
365 
366 void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &) {
367   llvm_unreachable("CodeGen for 'omp section' is not supported yet.");
368 }
369 
370 void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) {
371   llvm_unreachable("CodeGen for 'omp single' is not supported yet.");
372 }
373 
374 void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &) {
375   llvm_unreachable("CodeGen for 'omp master' is not supported yet.");
376 }
377 
378 void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
379   // __kmpc_critical();
380   // <captured_body>
381   // __kmpc_end_critical();
382   //
383 
384   auto Lock = CGM.getOpenMPRuntime().GetCriticalRegionLock(
385       S.getDirectiveName().getAsString());
386   CGM.getOpenMPRuntime().EmitOMPCriticalRegionStart(*this, Lock,
387                                                     S.getLocStart());
388   {
389     RunCleanupsScope Scope(*this);
390     EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
391     EnsureInsertPoint();
392   }
393   CGM.getOpenMPRuntime().EmitOMPCriticalRegionEnd(*this, Lock, S.getLocEnd());
394 }
395 
396 void
397 CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
398   llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet.");
399 }
400 
401 void CodeGenFunction::EmitOMPParallelForSimdDirective(
402     const OMPParallelForSimdDirective &) {
403   llvm_unreachable("CodeGen for 'omp parallel for simd' is not supported yet.");
404 }
405 
406 void CodeGenFunction::EmitOMPParallelSectionsDirective(
407     const OMPParallelSectionsDirective &) {
408   llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet.");
409 }
410 
411 void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &) {
412   llvm_unreachable("CodeGen for 'omp task' is not supported yet.");
413 }
414 
415 void CodeGenFunction::EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &) {
416   llvm_unreachable("CodeGen for 'omp taskyield' is not supported yet.");
417 }
418 
419 void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &) {
420   llvm_unreachable("CodeGen for 'omp barrier' is not supported yet.");
421 }
422 
423 void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &) {
424   llvm_unreachable("CodeGen for 'omp taskwait' is not supported yet.");
425 }
426 
427 void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &) {
428   llvm_unreachable("CodeGen for 'omp flush' is not supported yet.");
429 }
430 
431 void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &) {
432   llvm_unreachable("CodeGen for 'omp ordered' is not supported yet.");
433 }
434 
435 void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &) {
436   llvm_unreachable("CodeGen for 'omp atomic' is not supported yet.");
437 }
438 
439 void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) {
440   llvm_unreachable("CodeGen for 'omp target' is not supported yet.");
441 }
442 
443